Implements no-op before CheckoutTag in gogit
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
This commit is contained in:
parent
8a3df9da42
commit
2bb3a1fea9
|
@ -29,6 +29,7 @@ import (
|
|||
"github.com/go-git/go-git/v5/config"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||
"github.com/go-git/go-git/v5/storage/memory"
|
||||
|
||||
"github.com/fluxcd/pkg/gitutil"
|
||||
|
@ -46,7 +47,7 @@ func CheckoutStrategyForOptions(_ context.Context, opts git.CheckoutOptions) git
|
|||
case opts.SemVer != "":
|
||||
return &CheckoutSemVer{SemVer: opts.SemVer, RecurseSubmodules: opts.RecurseSubmodules}
|
||||
case opts.Tag != "":
|
||||
return &CheckoutTag{Tag: opts.Tag, RecurseSubmodules: opts.RecurseSubmodules}
|
||||
return &CheckoutTag{Tag: opts.Tag, RecurseSubmodules: opts.RecurseSubmodules, LastRevision: opts.LastRevision}
|
||||
default:
|
||||
branch := opts.Branch
|
||||
if branch == "" {
|
||||
|
@ -71,19 +72,11 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, opts *g
|
|||
ref := plumbing.NewBranchReferenceName(c.Branch)
|
||||
// check if previous revision has changed before attempting to clone
|
||||
if c.LastRevision != "" {
|
||||
config := &config.RemoteConfig{
|
||||
Name: git.DefaultOrigin,
|
||||
URLs: []string{url},
|
||||
}
|
||||
rem := extgogit.NewRemote(memory.NewStorage(), config)
|
||||
refs, err := rem.List(&extgogit.ListOptions{
|
||||
Auth: authMethod,
|
||||
})
|
||||
currentRevision, err := getLastRevision(url, ref, opts, authMethod)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to list remote for '%s': %w", url, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
currentRevision := filterRefs(refs, ref)
|
||||
if currentRevision != "" && currentRevision == c.LastRevision {
|
||||
return nil, git.NoChangesError{
|
||||
Message: "no changes since last reconcilation",
|
||||
|
@ -119,9 +112,31 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, opts *g
|
|||
return buildCommitWithRef(cc, ref)
|
||||
}
|
||||
|
||||
func getLastRevision(url string, ref plumbing.ReferenceName, opts *git.AuthOptions, authMethod transport.AuthMethod) (string, error) {
|
||||
config := &config.RemoteConfig{
|
||||
Name: git.DefaultOrigin,
|
||||
URLs: []string{url},
|
||||
}
|
||||
rem := extgogit.NewRemote(memory.NewStorage(), config)
|
||||
listOpts := &extgogit.ListOptions{
|
||||
Auth: authMethod,
|
||||
}
|
||||
if opts != nil && opts.CAFile != nil {
|
||||
listOpts.CABundle = opts.CAFile
|
||||
}
|
||||
refs, err := rem.List(listOpts)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to list remote for '%s': %w", url, err)
|
||||
}
|
||||
|
||||
currentRevision := filterRefs(refs, ref)
|
||||
return currentRevision, nil
|
||||
}
|
||||
|
||||
type CheckoutTag struct {
|
||||
Tag string
|
||||
RecurseSubmodules bool
|
||||
LastRevision string
|
||||
}
|
||||
|
||||
func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, opts *git.AuthOptions) (*git.Commit, error) {
|
||||
|
@ -130,6 +145,20 @@ func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, opts *git.
|
|||
return nil, fmt.Errorf("failed to construct auth method with options: %w", err)
|
||||
}
|
||||
ref := plumbing.NewTagReferenceName(c.Tag)
|
||||
// check if previous revision has changed before attempting to clone
|
||||
if c.LastRevision != "" {
|
||||
currentRevision, err := getLastRevision(url, ref, opts, authMethod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if currentRevision != "" && currentRevision == c.LastRevision {
|
||||
return nil, git.NoChangesError{
|
||||
Message: "no changes since last reconcilation",
|
||||
ObservedRevision: currentRevision,
|
||||
}
|
||||
}
|
||||
}
|
||||
repo, err := extgogit.PlainCloneContext(ctx, path, false, &extgogit.CloneOptions{
|
||||
URL: url,
|
||||
Auth: authMethod,
|
||||
|
|
|
@ -137,6 +137,8 @@ func TestCheckoutTag_Checkout(t *testing.T) {
|
|||
checkoutTag string
|
||||
expectTag string
|
||||
expectErr string
|
||||
lastRev string
|
||||
setLastRev bool
|
||||
}{
|
||||
{
|
||||
name: "Tag",
|
||||
|
@ -144,6 +146,20 @@ func TestCheckoutTag_Checkout(t *testing.T) {
|
|||
checkoutTag: "tag-1",
|
||||
expectTag: "tag-1",
|
||||
},
|
||||
{
|
||||
name: "Skip Tag if last revision hasn't changed",
|
||||
tag: "tag-2",
|
||||
checkoutTag: "tag-2",
|
||||
setLastRev: true,
|
||||
expectErr: "no changes since last reconcilation",
|
||||
},
|
||||
{
|
||||
name: "Last revision changed",
|
||||
tag: "tag-3",
|
||||
checkoutTag: "tag-3",
|
||||
expectTag: "tag-3",
|
||||
lastRev: "tag-3/<fake-hash>",
|
||||
},
|
||||
{
|
||||
name: "Annotated",
|
||||
tag: "annotated",
|
||||
|
@ -168,12 +184,13 @@ func TestCheckoutTag_Checkout(t *testing.T) {
|
|||
}
|
||||
|
||||
var h plumbing.Hash
|
||||
var tagHash *plumbing.Reference
|
||||
if tt.tag != "" {
|
||||
h, err = commitFile(repo, "tag", tt.tag, time.Now())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = tag(repo, h, !tt.annotated, tt.tag, time.Now())
|
||||
tagHash, err = tag(repo, h, !tt.annotated, tt.tag, time.Now())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -182,10 +199,18 @@ func TestCheckoutTag_Checkout(t *testing.T) {
|
|||
tag := CheckoutTag{
|
||||
Tag: tt.checkoutTag,
|
||||
}
|
||||
if tt.setLastRev {
|
||||
tag.LastRevision = fmt.Sprintf("%s/%s", tt.tag, tagHash.Hash().String())
|
||||
}
|
||||
|
||||
if tt.lastRev != "" {
|
||||
tag.LastRevision = tt.lastRev
|
||||
}
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
cc, err := tag.Checkout(context.TODO(), tmpDir, path, nil)
|
||||
if tt.expectErr != "" {
|
||||
g.Expect(err).ToNot(BeNil())
|
||||
g.Expect(err.Error()).To(ContainSubstring(tt.expectErr))
|
||||
g.Expect(cc).To(BeNil())
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue