Skip to content

Commit 9f9e7f9

Browse files
committed
porch: support package version as last component of path
This is a simpler way of laying out a repo.
1 parent 8cb5f8a commit 9f9e7f9

File tree

2 files changed

+62
-49
lines changed

2 files changed

+62
-49
lines changed

porch/pkg/git/git.go

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"github.com/go-git/go-git/v5/plumbing/transport"
3939
"go.opentelemetry.io/otel"
4040
"go.opentelemetry.io/otel/trace"
41+
"golang.org/x/mod/semver"
4142
"k8s.io/klog/v2"
4243
)
4344

@@ -238,7 +239,7 @@ func (r *gitRepository) ListPackageRevisions(ctx context.Context, filter reposit
238239
klog.Warningf("no package draft found for ref %v", ref)
239240
}
240241
case isTagInLocalRepo(ref.Name()):
241-
tagged, err := r.loadTaggedPackages(ctx, ref)
242+
tagged, err := r.loadPackagesForGitTag(ctx, ref)
242243
if err != nil {
243244
// this tag is not associated with any package (e.g. could be a release tag)
244245
continue
@@ -253,7 +254,7 @@ func (r *gitRepository) ListPackageRevisions(ctx context.Context, filter reposit
253254

254255
if main != nil {
255256
// TODO: ignore packages that are unchanged in main branch, compared to a tagged version?
256-
mainpkgs, err := r.discoverFinalizedPackages(ctx, main)
257+
mainpkgs, err := r.loadPackagesForGitBranch(ctx, main)
257258
if err != nil {
258259
return nil, err
259260
}
@@ -437,8 +438,6 @@ func (r *gitRepository) GetPackageRevision(ctx context.Context, version, path st
437438

438439
gitRepo := r.repo
439440

440-
var hash plumbing.Hash
441-
442441
// Trim leading and trailing slashes
443442
path = strings.Trim(path, "/")
444443

@@ -448,38 +447,38 @@ func (r *gitRepository) GetPackageRevision(ctx context.Context, version, path st
448447
// * prefixed (tag=<packageDir/<version>) - solving the co-versioning problem.
449448
//
450449
// We have to check both forms when looking up a version.
451-
refNames := []string{}
450+
var refNames []plumbing.ReferenceName
452451
if path != "" {
453-
refNames = append(refNames, path+"/"+version)
454-
// HACK: Is this always refs/remotes/origin ? Is it ever not (i.e. do we need both forms?)
455-
refNames = append(refNames, "refs/remotes/origin/"+path+"/"+version)
452+
// TODO: Need to support sub-paths, we can have any parent directory as the prefix
453+
refNames = append(refNames, plumbing.NewTagReferenceName(path+"/"+version))
454+
refNames = append(refNames, plumbing.NewRemoteReferenceName("origin", path+"/"+version))
456455
}
457-
refNames = append(refNames, version)
458-
// HACK: Is this always refs/remotes/origin ? Is it ever not (i.e. do we need both forms?)
459-
refNames = append(refNames, "refs/remotes/origin/"+version)
456+
refNames = append(refNames, plumbing.NewTagReferenceName(version))
457+
refNames = append(refNames, plumbing.NewRemoteReferenceName("origin", version))
460458

461-
for _, ref := range refNames {
462-
if resolved, err := gitRepo.ResolveRevision(plumbing.Revision(ref)); err != nil {
459+
var foundRef *plumbing.Reference
460+
for _, refName := range refNames {
461+
if ref, err := gitRepo.Reference(refName, true); err != nil {
463462
if errors.Is(err, plumbing.ErrReferenceNotFound) {
464463
continue
465464
}
466-
return nil, kptfilev1.GitLock{}, fmt.Errorf("error resolving git reference %q: %w", ref, err)
465+
return nil, kptfilev1.GitLock{}, fmt.Errorf("error resolving git reference %q: %w", refName, err)
467466
} else {
468-
hash = *resolved
467+
foundRef = ref
469468
break
470469
}
471470
}
472471

473-
if hash.IsZero() {
472+
if foundRef == nil {
474473
r.dumpAllRefs()
475474

476475
return nil, kptfilev1.GitLock{}, fmt.Errorf("cannot find git reference (tried %v)", refNames)
477476
}
478477

479-
return r.loadPackageRevision(ctx, version, path, hash)
478+
return r.loadPackageRevision(ctx, version, path, foundRef)
480479
}
481480

482-
func (r *gitRepository) loadPackageRevision(ctx context.Context, version, path string, hash plumbing.Hash) (repository.PackageRevision, kptfilev1.GitLock, error) {
481+
func (r *gitRepository) loadPackageRevision(ctx context.Context, version, path string, ref *plumbing.Reference) (repository.PackageRevision, kptfilev1.GitLock, error) {
483482
ctx, span := tracer.Start(ctx, "gitRepository::loadPackageRevision", trace.WithAttributes())
484483
defer span.End()
485484

@@ -500,9 +499,9 @@ func (r *gitRepository) loadPackageRevision(ctx context.Context, version, path s
500499
Ref: version,
501500
}
502501

503-
commit, err := git.CommitObject(hash)
502+
commit, err := git.CommitObject(ref.Hash())
504503
if err != nil {
505-
return nil, lock, fmt.Errorf("cannot resolve git reference %s (hash: %s) to commit: %w", version, hash, err)
504+
return nil, lock, fmt.Errorf("cannot resolve git reference %s (hash: %s) to commit: %w", version, ref.Hash(), err)
506505
}
507506
lock.Commit = commit.Hash.String()
508507

@@ -515,9 +514,7 @@ func (r *gitRepository) loadPackageRevision(ctx context.Context, version, path s
515514
return nil, lock, fmt.Errorf("cannot find package %s@%s", path, version)
516515
}
517516

518-
var ref *plumbing.Reference = nil // Cannot determine ref; this package will be considered final (immutable).
519-
520-
var revision string
517+
// var revision string
521518
var workspace v1alpha1.WorkspaceName
522519
last := strings.LastIndex(version, "/")
523520

@@ -526,44 +523,33 @@ func (r *gitRepository) loadPackageRevision(ctx context.Context, version, path s
526523
workspace = v1alpha1.WorkspaceName(version[last+1:])
527524
} else {
528525
// the passed in version is a ref to a published package revision
529-
if version == string(r.branch) || last < 0 {
530-
revision = version
531-
} else {
532-
revision = version[last+1:]
533-
}
526+
// if version == string(r.branch) || last < 0 {
527+
// revision = version
528+
// } else {
529+
// revision = version[last+1:]
530+
// }
534531
workspace, err = getPkgWorkspace(ctx, commit, krmPackage, ref)
535532
if err != nil {
536533
return nil, kptfilev1.GitLock{}, err
537534
}
538535
}
539536

540-
packageRevision, err := krmPackage.buildGitPackageRevision(ctx, revision, workspace, ref)
537+
packageRevision, err := krmPackage.buildGitPackageRevision(ctx, workspace, ref)
541538
if err != nil {
542539
return nil, lock, err
543540
}
544541
return packageRevision, lock, nil
545542
}
546543

547-
func (r *gitRepository) discoverFinalizedPackages(ctx context.Context, ref *plumbing.Reference) ([]repository.PackageRevision, error) {
544+
func (r *gitRepository) loadPackagesForGitBranch(ctx context.Context, ref *plumbing.Reference) ([]repository.PackageRevision, error) {
548545
ctx, span := tracer.Start(ctx, "gitRepository::discoverFinalizedPackages", trace.WithAttributes())
549546
defer span.End()
550547

551-
git := r.repo
552-
commit, err := git.CommitObject(ref.Hash())
548+
commit, err := r.repo.CommitObject(ref.Hash())
553549
if err != nil {
554550
return nil, err
555551
}
556552

557-
var revision string
558-
if rev, ok := getBranchNameInLocalRepo(ref.Name()); ok {
559-
revision = rev
560-
} else if rev, ok = getTagNameInLocalRepo(ref.Name()); ok {
561-
revision = rev
562-
} else {
563-
// TODO: ignore the ref instead?
564-
return nil, fmt.Errorf("cannot determine revision from ref: %q", rev)
565-
}
566-
567553
krmPackages, err := r.DiscoverPackagesInTree(commit, DiscoverPackagesOptions{FilterPrefix: r.directory, Recurse: true})
568554
if err != nil {
569555
return nil, err
@@ -575,7 +561,8 @@ func (r *gitRepository) discoverFinalizedPackages(ctx context.Context, ref *plum
575561
if err != nil {
576562
return nil, err
577563
}
578-
packageRevision, err := krmPackage.buildGitPackageRevision(ctx, revision, workspace, ref)
564+
565+
packageRevision, err := krmPackage.buildGitPackageRevision(ctx, workspace, ref)
579566
if err != nil {
580567
return nil, err
581568
}
@@ -611,7 +598,7 @@ func (r *gitRepository) loadDraft(ctx context.Context, ref *plumbing.Reference)
611598
return nil, nil
612599
}
613600

614-
packageRevision, err := krmPackage.buildGitPackageRevision(ctx, "", workspaceName, ref)
601+
packageRevision, err := krmPackage.buildGitPackageRevision(ctx, workspaceName, ref)
615602
if err != nil {
616603
return nil, err
617604
}
@@ -669,7 +656,11 @@ func parseDraftName(draft *plumbing.Reference) (name string, workspaceName v1alp
669656
return name, workspaceName, nil
670657
}
671658

672-
func (r *gitRepository) loadTaggedPackages(ctx context.Context, tag *plumbing.Reference) ([]repository.PackageRevision, error) {
659+
func isSemver(s string) bool {
660+
return semver.IsValid(s)
661+
}
662+
663+
func (r *gitRepository) loadPackagesForGitTag(ctx context.Context, tag *plumbing.Reference) ([]repository.PackageRevision, error) {
673664
name, ok := getTagNameInLocalRepo(tag.Name())
674665
if !ok {
675666
return nil, fmt.Errorf("invalid tag ref: %q", tag)
@@ -683,8 +674,9 @@ func (r *gitRepository) loadTaggedPackages(ctx context.Context, tag *plumbing.Re
683674

684675
}
685676

677+
// TODO: I think tag can actually be any prefix of path, so there can be multiple packages here
686678
// tag=<package path>/version
687-
path, revision := name[:slash], name[slash+1:]
679+
path, _ := name[:slash], name[slash+1:]
688680

689681
if !packageInDirectory(path, r.directory) {
690682
return nil, nil
@@ -711,7 +703,7 @@ func (r *gitRepository) loadTaggedPackages(ctx context.Context, tag *plumbing.Re
711703
return nil, err
712704
}
713705

714-
packageRevision, err := krmPackage.buildGitPackageRevision(ctx, revision, workspaceName, tag)
706+
packageRevision, err := krmPackage.buildGitPackageRevision(ctx, workspaceName, tag)
715707
if err != nil {
716708
return nil, err
717709
}

porch/pkg/git/package_tree.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ type packageListEntry struct {
5353

5454
// buildGitPackageRevision creates a gitPackageRevision for the packageListEntry
5555
// TODO: Can packageListEntry just _be_ a gitPackageRevision?
56-
func (p *packageListEntry) buildGitPackageRevision(ctx context.Context, revision string, workspace v1alpha1.WorkspaceName, ref *plumbing.Reference) (*gitPackageRevision, error) {
56+
func (p *packageListEntry) buildGitPackageRevision(ctx context.Context, workspace v1alpha1.WorkspaceName, ref *plumbing.Reference) (*gitPackageRevision, error) {
5757
repo := p.parent.parent
5858
tasks, err := repo.loadTasks(ctx, p.parent.commit, p.path, workspace)
5959
if err != nil {
@@ -89,6 +89,27 @@ func (p *packageListEntry) buildGitPackageRevision(ctx context.Context, revision
8989
// operation.
9090
}
9191

92+
packagePath := p.path
93+
94+
var revision string
95+
96+
lastPathComponent := path.Base(p.path)
97+
if isSemver(lastPathComponent) {
98+
packagePath = path.Dir(packagePath)
99+
revision = lastPathComponent
100+
} else {
101+
if rev, ok := getBranchNameInLocalRepo(ref.Name()); ok {
102+
revision = rev
103+
} else if tagName, ok := getTagNameInLocalRepo(ref.Name()); ok {
104+
revision = path.Base(tagName)
105+
} else if _, _, err := parseDraftName(ref); err == nil {
106+
revision = ""
107+
} else {
108+
// TODO: ignore the ref instead?
109+
return nil, fmt.Errorf("cannot determine revision from ref: %q", rev)
110+
}
111+
}
112+
92113
// for backwards compatibility with packages that existed before porch supported
93114
// workspaceNames, we populate the workspaceName as the revision number if it is empty
94115
if workspace == "" {
@@ -97,7 +118,7 @@ func (p *packageListEntry) buildGitPackageRevision(ctx context.Context, revision
97118

98119
return &gitPackageRevision{
99120
repo: repo,
100-
path: p.path,
121+
path: packagePath,
101122
workspaceName: workspace,
102123
revision: revision,
103124
updated: updated,

0 commit comments

Comments
 (0)