Skip to content

Commit 3175e11

Browse files
committed
WIP: rationalize git package construction
1 parent 49bc6c9 commit 3175e11

File tree

3 files changed

+182
-128
lines changed

3 files changed

+182
-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: 46 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"
@@ -374,31 +372,24 @@ func (r *gitRepository) loadPackageRevision(version, path string, hash plumbing.
374372
}
375373
lock.Commit = commit.Hash.String()
376374

377-
commitTree, err := commit.Tree()
375+
krmPackages, err := r.discoverPackagesInTree(commit, path)
378376
if err != nil {
379-
return nil, lock, fmt.Errorf("cannot resolve git reference %s (hash %s) to tree: %w", version, hash, err)
377+
return nil, lock, err
380378
}
381-
treeHash := commitTree.Hash
382-
if path != "" {
383-
te, err := commitTree.FindEntry(path)
384-
if err != nil {
385-
return nil, lock, fmt.Errorf("cannot find package %s@%s: %w", path, version, err)
386-
}
387-
if te.Mode != filemode.Dir {
388-
return nil, lock, fmt.Errorf("path %s@%s is not a directory", path, version)
389-
}
390-
treeHash = te.Hash
391-
}
392-
393-
return &gitPackageRevision{
394-
parent: r,
395-
path: path,
396-
revision: version,
397-
updated: commit.Author.When,
398-
ref: nil, // Cannot determine ref; this package will be considered final (immutable).
399-
tree: treeHash,
400-
commit: hash,
401-
}, lock, nil
379+
380+
krmPackage := krmPackages.packages[path]
381+
if krmPackage == nil {
382+
return nil, lock, fmt.Errorf("cannot find package %s@%s", path, version)
383+
}
384+
385+
// TODO: We could just pass the ref in
386+
var ref *plumbing.Reference = nil // Cannot determine ref; this package will be considered final (immutable).
387+
388+
packageRevision, err := krmPackage.buildGitPackageRevision(version, ref)
389+
if err != nil {
390+
return nil, lock, err
391+
}
392+
return packageRevision, lock, nil
402393
}
403394

404395
func (r *gitRepository) discoverFinalizedPackages(ref *plumbing.Reference) ([]repository.PackageRevision, error) {
@@ -407,20 +398,6 @@ func (r *gitRepository) discoverFinalizedPackages(ref *plumbing.Reference) ([]re
407398
if err != nil {
408399
return nil, err
409400
}
410-
tree, err := commit.Tree()
411-
if err != nil {
412-
return nil, err
413-
}
414-
415-
var result []repository.PackageRevision
416-
417-
// Recurse into the specified directory
418-
if r.directory != "" {
419-
tree, err = tree.Tree(r.directory)
420-
if err == object.ErrDirectoryNotFound {
421-
return result, nil
422-
}
423-
}
424401

425402
var revision string
426403
if rev, ok := getBranchNameInLocalRepo(ref.Name()); ok {
@@ -432,51 +409,20 @@ func (r *gitRepository) discoverFinalizedPackages(ref *plumbing.Reference) ([]re
432409
return nil, fmt.Errorf("cannot determine revision from ref: %q", rev)
433410
}
434411

435-
if err := discoverPackagesInTree(git, tree, r.directory, func(dir string, tree, kptfile plumbing.Hash) error {
436-
result = append(result, &gitPackageRevision{
437-
parent: r,
438-
path: dir,
439-
revision: revision,
440-
updated: commit.Author.When,
441-
ref: ref,
442-
tree: tree,
443-
commit: ref.Hash(),
444-
})
445-
return nil
446-
}); err != nil {
412+
krmPackages, err := r.discoverPackagesInTree(commit, r.directory)
413+
if err != nil {
447414
return nil, err
448415
}
449-
return result, nil
450-
}
451-
452-
type foundPackageCallback func(dir string, tree, kptfile plumbing.Hash) error
453-
454-
func discoverPackagesInTree(r *git.Repository, tree *object.Tree, dir string, found foundPackageCallback) error {
455-
for _, e := range tree.Entries {
456-
if e.Mode.IsRegular() && e.Name == "Kptfile" {
457-
// Found a package
458-
klog.Infof("Found package %q with Kptfile hash %q", path.Join(dir, e.Name), e.Hash)
459-
if err := found(dir, tree.Hash, e.Hash); err != nil {
460-
return err
461-
}
462-
}
463-
}
464-
465-
for _, e := range tree.Entries {
466-
if e.Mode != filemode.Dir {
467-
continue
468-
}
469416

470-
dirTree, err := r.TreeObject(e.Hash)
417+
var result []repository.PackageRevision
418+
for _, krmPackage := range krmPackages.packages {
419+
packageRevision, err := krmPackage.buildGitPackageRevision(revision, ref)
471420
if err != nil {
472-
return fmt.Errorf("error getting git tree %v: %w", e.Hash, err)
473-
}
474-
475-
if err := discoverPackagesInTree(r, dirTree, path.Join(dir, e.Name), found); err != nil {
476-
return err
421+
return nil, err
477422
}
423+
result = append(result, packageRevision)
478424
}
479-
return nil
425+
return result, nil
480426
}
481427

482428
// loadDraft will load the draft package. If the package isn't found (we now require a Kptfile), it will return (nil, nil)
@@ -495,45 +441,25 @@ func (r *gitRepository) loadDraft(ref *plumbing.Reference) (*gitPackageRevision,
495441
if err != nil {
496442
return nil, fmt.Errorf("cannot resolve draft branch to commit (corrupted repository?): %w", err)
497443
}
498-
tree, err := commit.Tree()
499-
if err != nil {
500-
return nil, fmt.Errorf("cannot resolve package commit to tree (corrupted repository?): %w", err)
501-
}
502444

503-
dirTree, err := tree.Tree(name)
445+
prefix := name
446+
krmPackages, err := r.discoverPackagesInTree(commit, prefix)
504447
if err != nil {
505-
switch err {
506-
case object.ErrDirectoryNotFound, object.ErrEntryNotFound:
507-
// empty package
508-
return nil, nil
448+
return nil, err
449+
}
509450

510-
default:
511-
return nil, fmt.Errorf("error when looking for package in the repository: %w", err)
512-
}
451+
krmPackage := krmPackages.packages[name]
452+
if krmPackage == nil {
453+
klog.Warningf("draft package %q was not found in %#v", name, krmPackages.packages)
454+
return nil, nil
513455
}
514456

515-
packageTree := dirTree.Hash
516-
kptfileEntry, err := dirTree.FindEntry("Kptfile")
457+
packageRevision, err := krmPackage.buildGitPackageRevision(revision, ref)
517458
if err != nil {
518-
if err == object.ErrEntryNotFound {
519-
return nil, nil
520-
} else {
521-
return nil, fmt.Errorf("error finding Kptfile: %w", err)
522-
}
523-
}
524-
if !kptfileEntry.Mode.IsRegular() {
525-
return nil, fmt.Errorf("found Kptfile which is not a regular file: %s", kptfileEntry.Mode)
459+
return nil, err
526460
}
527461

528-
return &gitPackageRevision{
529-
parent: r,
530-
path: name,
531-
revision: revision,
532-
updated: commit.Author.When,
533-
ref: ref,
534-
tree: packageTree,
535-
commit: ref.Hash(),
536-
}, nil
462+
return packageRevision, nil
537463
}
538464

539465
func parseDraftName(draft *plumbing.Reference) (name, revision string, err error) {
@@ -578,36 +504,28 @@ func (r *gitRepository) loadTaggedPackages(tag *plumbing.Reference) ([]repositor
578504
if err != nil {
579505
return nil, fmt.Errorf("cannot resolve tag %q to commit (corrupted repository?): %w", name, err)
580506
}
581-
tree, err := commit.Tree()
582-
if err != nil {
583-
return nil, fmt.Errorf("cannot resolve tag %q to tree (corrupted repository?): %w", name, err)
584-
}
585507

586-
dirTree, err := tree.Tree(path)
508+
krmPackages, err := r.discoverPackagesInTree(commit, path)
587509
if err != nil {
588510
klog.Warningf("Skipping %q; cannot find %q (corrupted repository?): %w", name, path, err)
589511
return nil, nil
590512
}
591513

592-
if kptfileEntry, err := dirTree.FindEntry("Kptfile"); err != nil {
514+
krmPackage := krmPackages.packages[path]
515+
if krmPackage == nil {
593516
klog.Warningf("Skipping %q: Kptfile not found: %w", name, err)
594517
return nil, nil
595-
} else if !kptfileEntry.Mode.IsRegular() {
596-
klog.Warningf("Skippping %q: Kptfile is not a file", name)
597-
return nil, nil
518+
}
519+
520+
packageRevision, err := krmPackage.buildGitPackageRevision(revision, tag)
521+
if err != nil {
522+
return nil, err
598523
}
599524

600525
return []repository.PackageRevision{
601-
&gitPackageRevision{
602-
parent: r,
603-
path: path,
604-
revision: revision,
605-
updated: commit.Author.When,
606-
ref: tag,
607-
tree: dirTree.Hash,
608-
commit: tag.Hash(),
609-
},
526+
packageRevision,
610527
}, nil
528+
611529
}
612530

613531
func (r *gitRepository) dumpAllRefs() {
@@ -789,6 +707,7 @@ func (r *gitRepository) pushAndCleanup(ctx context.Context, ph *pushRefSpecBuild
789707
return err
790708
}
791709

710+
klog.Infof("pushing refs: %v", specs)
792711
if err := r.repo.Push(&git.PushOptions{
793712
RemoteName: OriginName,
794713
RefSpecs: specs,

0 commit comments

Comments
 (0)