Skip to content

Commit

Permalink
Git repository test (kptdev#2706)
Browse files Browse the repository at this point in the history
We create a simple git server, and we try round-tripping a package.

Some hacks/todos uncovered that we need to tackle.
  • Loading branch information
justinsb committed Feb 2, 2022
1 parent 111cd99 commit dfed272
Show file tree
Hide file tree
Showing 4 changed files with 841 additions and 20 deletions.
17 changes: 11 additions & 6 deletions porch/repository/pkg/git/draft.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/go-git/go-git/v5/plumbing/filemode"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/storer"
"k8s.io/klog/v2"
)

type gitPackageDraft struct {
Expand Down Expand Up @@ -62,7 +63,9 @@ func (d *gitPackageDraft) UpdateResources(ctx context.Context, new *v1alpha1.Pac
return err
}

if err := storeBlobHashInTrees(dirs, k, hash); err != nil {
// TODO: decide whether paths should include package directory or not.
p := path.Join(d.path, k)
if err := storeBlobHashInTrees(dirs, p, hash); err != nil {
return err
}
}
Expand All @@ -87,15 +90,17 @@ func (d *gitPackageDraft) UpdateResources(ctx context.Context, new *v1alpha1.Pac

// Finish round of updates.
func (d *gitPackageDraft) Close(ctx context.Context) (repository.PackageRevision, error) {
// TODO: This removal of drafts is a hack
refSpec := config.RefSpec(fmt.Sprintf("%s:%s", d.draft.Name(), strings.ReplaceAll(d.draft.Name().String(), "/drafts/", "/")))
klog.Infof("pushing refspec %v", refSpec)

if err := d.parent.repo.Push(&git.PushOptions{
RemoteName: "origin",
RefSpecs: []config.RefSpec{
config.RefSpec(fmt.Sprintf("%s:%s", d.draft.Name(), d.draft.Name())),
},
RemoteName: "origin",
RefSpecs: []config.RefSpec{refSpec},
Auth: d.parent.auth,
RequireRemoteRefs: []config.RefSpec{},
}); err != nil {
return nil, err
return nil, fmt.Errorf("failed to push to git: %w", err)
}

// TODO: return Revision only.
Expand Down
70 changes: 58 additions & 12 deletions porch/repository/pkg/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func OpenRepository(name, namespace string, spec *configapi.GitRepository, authO
isBare := true
r, err := gogit.PlainClone(dir, isBare, &opts)
if err != nil {
return nil, err
return nil, fmt.Errorf("error cloning git repository %q: %w", spec.Repo, err)
}
repo = r
} else if !fi.IsDir() {
Expand Down Expand Up @@ -253,10 +253,16 @@ func (r *gitRepository) GetPackage(version, path string) (repository.PackageRevi
// * prefixed (tag=<packageDir/<version>) - solving the co-versioning problem.
//
// We have to check both forms when looking up a version.
refNames := []string{
path + "/" + version,
version,
refNames := []string{}
if path != "" {
refNames = append(refNames, path+"/"+version)
// HACK: Is this always refs/remotes/origin ? Is it ever not (i.e. do we need both forms?)
refNames = append(refNames, "refs/remotes/origin/"+path+"/"+version)
}
refNames = append(refNames, version)
// HACK: Is this always refs/remotes/origin ? Is it ever not (i.e. do we need both forms?)
refNames = append(refNames, "refs/remotes/origin/"+version)

for _, ref := range refNames {
if resolved, err := git.ResolveRevision(plumbing.Revision(ref)); err != nil {
if errors.Is(err, plumbing.ErrReferenceNotFound) {
Expand All @@ -270,6 +276,8 @@ func (r *gitRepository) GetPackage(version, path string) (repository.PackageRevi
}

if hash.IsZero() {
r.dumpAllRefs()

return nil, lock, fmt.Errorf("cannot find git reference (tried %v)", refNames)
}

Expand All @@ -279,24 +287,28 @@ func (r *gitRepository) GetPackage(version, path string) (repository.PackageRevi
}
lock.Commit = commit.Hash.String()

ctree, err := commit.Tree()
commitTree, err := commit.Tree()
if err != nil {
return nil, lock, fmt.Errorf("cannot resolve git reference %s (hash %s) to tree: %w", version, hash, err)
}
te, err := ctree.FindEntry(path)
if err != nil {
return nil, lock, fmt.Errorf("cannot find package %s@%s: %w", path, version, err)
}
if te.Mode != filemode.Dir {
return nil, lock, fmt.Errorf("path %s@%s is not a directory", path, version)
treeHash := commitTree.Hash
if path != "" {
te, err := commitTree.FindEntry(path)
if err != nil {
return nil, lock, fmt.Errorf("cannot find package %s@%s: %w", path, version, err)
}
if te.Mode != filemode.Dir {
return nil, lock, fmt.Errorf("path %s@%s is not a directory", path, version)
}
treeHash = te.Hash
}

return &gitPackageRevision{
parent: r,
path: path,
revision: version,
updated: commit.Author.When,
tree: te.Hash,
tree: treeHash,
sha: hash,
}, lock, nil
}
Expand Down Expand Up @@ -416,3 +428,37 @@ func createDraftRefName(name, revision string) plumbing.ReferenceName {
refName := fmt.Sprintf("refs/heads/drafts/%s/%s", name, revision)
return plumbing.ReferenceName(refName)
}

func (r *gitRepository) dumpAllRefs() {
refs, err := r.repo.References()
if err != nil {
klog.Warningf("failed to get references: %v", err)
} else {
for {
ref, err := refs.Next()
if err != nil {
if err != io.EOF {
klog.Warningf("failed to get next reference: %v", err)
}
break
}
klog.Infof("ref %#v", ref.Name())
}
}

branches, err := r.repo.Branches()
if err != nil {
klog.Warningf("failed to get branches: %v", err)
} else {
for {
branch, err := branches.Next()
if err != nil {
if err != io.EOF {
klog.Warningf("failed to get next branch: %v", err)
}
break
}
klog.Infof("branch %#v", branch.Name())
}
}
}

0 comments on commit dfed272

Please sign in to comment.