Skip to content

Commit c47d54e

Browse files
committed
Rationalize git package construction
We now have a single codepath for discovering git packages in the tree; this allows us to include tasks in future.
1 parent c1b5d70 commit c47d54e

File tree

3 files changed

+196
-128
lines changed

3 files changed

+196
-128
lines changed

porch/repository/pkg/git/draft.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package git
1717
import (
1818
"context"
1919
"fmt"
20+
"os"
2021
"path"
2122
"time"
2223

@@ -51,7 +52,17 @@ func (d *gitPackageDraft) UpdateResources(ctx context.Context, new *v1alpha1.Pac
5152
ch.storeFile(path.Join(d.path, k), v)
5253
}
5354

54-
message := fmt.Sprintf("Intermittent commit: %s", change.Type)
55+
// Because we can't read the package back without a Kptfile, make sure one is present
56+
{
57+
p := path.Join(d.path, "Kptfile")
58+
_, err := ch.readFile(p)
59+
if os.IsNotExist(err) {
60+
// We could write the file here; currently we return an error
61+
return fmt.Errorf("package must contain Kptfile at root")
62+
}
63+
}
64+
65+
message := fmt.Sprintf("Intermediate commit: %s", change.Type)
5566
commitHash, packageTree, err := ch.commit(ctx, message, d.path)
5667
if err != nil {
5768
return fmt.Errorf("failed to commit package: %w", err)

porch/repository/pkg/git/git.go

Lines changed: 45 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"fmt"
2121
"io"
2222
"os"
23-
"path"
2423
"path/filepath"
2524
"strings"
2625
"time"
@@ -32,7 +31,6 @@ import (
3231
"github.com/go-git/go-git/v5"
3332
"github.com/go-git/go-git/v5/config"
3433
"github.com/go-git/go-git/v5/plumbing"
35-
"github.com/go-git/go-git/v5/plumbing/filemode"
3634
"github.com/go-git/go-git/v5/plumbing/object"
3735
"github.com/go-git/go-git/v5/plumbing/transport"
3836
"github.com/go-git/go-git/v5/plumbing/transport/http"
@@ -389,31 +387,23 @@ func (r *gitRepository) loadPackageRevision(version, path string, hash plumbing.
389387
}
390388
lock.Commit = commit.Hash.String()
391389

392-
commitTree, err := commit.Tree()
390+
krmPackages, err := r.DiscoverPackagesInTree(commit, path)
393391
if err != nil {
394-
return nil, lock, fmt.Errorf("cannot resolve git reference %s (hash %s) to tree: %w", version, hash, err)
392+
return nil, lock, err
395393
}
396-
treeHash := commitTree.Hash
397-
if path != "" {
398-
te, err := commitTree.FindEntry(path)
399-
if err != nil {
400-
return nil, lock, fmt.Errorf("cannot find package %s@%s: %w", path, version, err)
401-
}
402-
if te.Mode != filemode.Dir {
403-
return nil, lock, fmt.Errorf("path %s@%s is not a directory", path, version)
404-
}
405-
treeHash = te.Hash
406-
}
407-
408-
return &gitPackageRevision{
409-
parent: r,
410-
path: path,
411-
revision: version,
412-
updated: commit.Author.When,
413-
ref: nil, // Cannot determine ref; this package will be considered final (immutable).
414-
tree: treeHash,
415-
commit: hash,
416-
}, lock, nil
394+
395+
krmPackage := krmPackages.packages[path]
396+
if krmPackage == nil {
397+
return nil, lock, fmt.Errorf("cannot find package %s@%s", path, version)
398+
}
399+
400+
var ref *plumbing.Reference = nil // Cannot determine ref; this package will be considered final (immutable).
401+
402+
packageRevision, err := krmPackage.buildGitPackageRevision(version, ref)
403+
if err != nil {
404+
return nil, lock, err
405+
}
406+
return packageRevision, lock, nil
417407
}
418408

419409
func (r *gitRepository) discoverFinalizedPackages(ref *plumbing.Reference) ([]repository.PackageRevision, error) {
@@ -422,20 +412,6 @@ func (r *gitRepository) discoverFinalizedPackages(ref *plumbing.Reference) ([]re
422412
if err != nil {
423413
return nil, err
424414
}
425-
tree, err := commit.Tree()
426-
if err != nil {
427-
return nil, err
428-
}
429-
430-
var result []repository.PackageRevision
431-
432-
// Recurse into the specified directory
433-
if r.directory != "" {
434-
tree, err = tree.Tree(r.directory)
435-
if err == object.ErrDirectoryNotFound {
436-
return result, nil
437-
}
438-
}
439415

440416
var revision string
441417
if rev, ok := getBranchNameInLocalRepo(ref.Name()); ok {
@@ -447,51 +423,20 @@ func (r *gitRepository) discoverFinalizedPackages(ref *plumbing.Reference) ([]re
447423
return nil, fmt.Errorf("cannot determine revision from ref: %q", rev)
448424
}
449425

450-
if err := discoverPackagesInTree(git, tree, r.directory, func(dir string, tree, kptfile plumbing.Hash) error {
451-
result = append(result, &gitPackageRevision{
452-
parent: r,
453-
path: dir,
454-
revision: revision,
455-
updated: commit.Author.When,
456-
ref: ref,
457-
tree: tree,
458-
commit: ref.Hash(),
459-
})
460-
return nil
461-
}); err != nil {
426+
krmPackages, err := r.DiscoverPackagesInTree(commit, r.directory)
427+
if err != nil {
462428
return nil, err
463429
}
464-
return result, nil
465-
}
466-
467-
type foundPackageCallback func(dir string, tree, kptfile plumbing.Hash) error
468-
469-
func discoverPackagesInTree(r *git.Repository, tree *object.Tree, dir string, found foundPackageCallback) error {
470-
for _, e := range tree.Entries {
471-
if e.Mode.IsRegular() && e.Name == "Kptfile" {
472-
// Found a package
473-
klog.Infof("Found package %q with Kptfile hash %q", path.Join(dir, e.Name), e.Hash)
474-
if err := found(dir, tree.Hash, e.Hash); err != nil {
475-
return err
476-
}
477-
}
478-
}
479-
480-
for _, e := range tree.Entries {
481-
if e.Mode != filemode.Dir {
482-
continue
483-
}
484430

485-
dirTree, err := r.TreeObject(e.Hash)
431+
var result []repository.PackageRevision
432+
for _, krmPackage := range krmPackages.packages {
433+
packageRevision, err := krmPackage.buildGitPackageRevision(revision, ref)
486434
if err != nil {
487-
return fmt.Errorf("error getting git tree %v: %w", e.Hash, err)
488-
}
489-
490-
if err := discoverPackagesInTree(r, dirTree, path.Join(dir, e.Name), found); err != nil {
491-
return err
435+
return nil, err
492436
}
437+
result = append(result, packageRevision)
493438
}
494-
return nil
439+
return result, nil
495440
}
496441

497442
// loadDraft will load the draft package. If the package isn't found (we now require a Kptfile), it will return (nil, nil)
@@ -510,45 +455,25 @@ func (r *gitRepository) loadDraft(ref *plumbing.Reference) (*gitPackageRevision,
510455
if err != nil {
511456
return nil, fmt.Errorf("cannot resolve draft branch to commit (corrupted repository?): %w", err)
512457
}
513-
tree, err := commit.Tree()
514-
if err != nil {
515-
return nil, fmt.Errorf("cannot resolve package commit to tree (corrupted repository?): %w", err)
516-
}
517458

518-
dirTree, err := tree.Tree(name)
459+
prefix := name
460+
krmPackages, err := r.DiscoverPackagesInTree(commit, prefix)
519461
if err != nil {
520-
switch err {
521-
case object.ErrDirectoryNotFound, object.ErrEntryNotFound:
522-
// empty package
523-
return nil, nil
462+
return nil, err
463+
}
524464

525-
default:
526-
return nil, fmt.Errorf("error when looking for package in the repository: %w", err)
527-
}
465+
krmPackage := krmPackages.packages[name]
466+
if krmPackage == nil {
467+
klog.Warningf("draft package %q was not found in %#v", name, krmPackages.packages)
468+
return nil, nil
528469
}
529470

530-
packageTree := dirTree.Hash
531-
kptfileEntry, err := dirTree.FindEntry("Kptfile")
471+
packageRevision, err := krmPackage.buildGitPackageRevision(revision, ref)
532472
if err != nil {
533-
if err == object.ErrEntryNotFound {
534-
return nil, nil
535-
} else {
536-
return nil, fmt.Errorf("error finding Kptfile: %w", err)
537-
}
538-
}
539-
if !kptfileEntry.Mode.IsRegular() {
540-
return nil, fmt.Errorf("found Kptfile which is not a regular file: %s", kptfileEntry.Mode)
473+
return nil, err
541474
}
542475

543-
return &gitPackageRevision{
544-
parent: r,
545-
path: name,
546-
revision: revision,
547-
updated: commit.Author.When,
548-
ref: ref,
549-
tree: packageTree,
550-
commit: ref.Hash(),
551-
}, nil
476+
return packageRevision, nil
552477
}
553478

554479
func parseDraftName(draft *plumbing.Reference) (name, revision string, err error) {
@@ -593,36 +518,28 @@ func (r *gitRepository) loadTaggedPackages(tag *plumbing.Reference) ([]repositor
593518
if err != nil {
594519
return nil, fmt.Errorf("cannot resolve tag %q to commit (corrupted repository?): %w", name, err)
595520
}
596-
tree, err := commit.Tree()
597-
if err != nil {
598-
return nil, fmt.Errorf("cannot resolve tag %q to tree (corrupted repository?): %w", name, err)
599-
}
600521

601-
dirTree, err := tree.Tree(path)
522+
krmPackages, err := r.DiscoverPackagesInTree(commit, path)
602523
if err != nil {
603524
klog.Warningf("Skipping %q; cannot find %q (corrupted repository?): %w", name, path, err)
604525
return nil, nil
605526
}
606527

607-
if kptfileEntry, err := dirTree.FindEntry("Kptfile"); err != nil {
528+
krmPackage := krmPackages.packages[path]
529+
if krmPackage == nil {
608530
klog.Warningf("Skipping %q: Kptfile not found: %w", name, err)
609531
return nil, nil
610-
} else if !kptfileEntry.Mode.IsRegular() {
611-
klog.Warningf("Skippping %q: Kptfile is not a file", name)
612-
return nil, nil
532+
}
533+
534+
packageRevision, err := krmPackage.buildGitPackageRevision(revision, tag)
535+
if err != nil {
536+
return nil, err
613537
}
614538

615539
return []repository.PackageRevision{
616-
&gitPackageRevision{
617-
parent: r,
618-
path: path,
619-
revision: revision,
620-
updated: commit.Author.When,
621-
ref: tag,
622-
tree: dirTree.Hash,
623-
commit: tag.Hash(),
624-
},
540+
packageRevision,
625541
}, nil
542+
626543
}
627544

628545
func (r *gitRepository) dumpAllRefs() {
@@ -820,6 +737,7 @@ func (r *gitRepository) pushAndCleanup(ctx context.Context, ph *pushRefSpecBuild
820737
return err
821738
}
822739

740+
klog.Infof("pushing refs: %v", specs)
823741
if err := r.repo.Push(&git.PushOptions{
824742
RemoteName: OriginName,
825743
RefSpecs: specs,

0 commit comments

Comments
 (0)