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/config"
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"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/object"
|
||||||
|
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||||
"github.com/go-git/go-git/v5/storage/memory"
|
"github.com/go-git/go-git/v5/storage/memory"
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/gitutil"
|
"github.com/fluxcd/pkg/gitutil"
|
||||||
|
@ -46,7 +47,7 @@ func CheckoutStrategyForOptions(_ context.Context, opts git.CheckoutOptions) git
|
||||||
case opts.SemVer != "":
|
case opts.SemVer != "":
|
||||||
return &CheckoutSemVer{SemVer: opts.SemVer, RecurseSubmodules: opts.RecurseSubmodules}
|
return &CheckoutSemVer{SemVer: opts.SemVer, RecurseSubmodules: opts.RecurseSubmodules}
|
||||||
case opts.Tag != "":
|
case opts.Tag != "":
|
||||||
return &CheckoutTag{Tag: opts.Tag, RecurseSubmodules: opts.RecurseSubmodules}
|
return &CheckoutTag{Tag: opts.Tag, RecurseSubmodules: opts.RecurseSubmodules, LastRevision: opts.LastRevision}
|
||||||
default:
|
default:
|
||||||
branch := opts.Branch
|
branch := opts.Branch
|
||||||
if branch == "" {
|
if branch == "" {
|
||||||
|
@ -71,19 +72,11 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, opts *g
|
||||||
ref := plumbing.NewBranchReferenceName(c.Branch)
|
ref := plumbing.NewBranchReferenceName(c.Branch)
|
||||||
// check if previous revision has changed before attempting to clone
|
// check if previous revision has changed before attempting to clone
|
||||||
if c.LastRevision != "" {
|
if c.LastRevision != "" {
|
||||||
config := &config.RemoteConfig{
|
currentRevision, err := getLastRevision(url, ref, opts, authMethod)
|
||||||
Name: git.DefaultOrigin,
|
|
||||||
URLs: []string{url},
|
|
||||||
}
|
|
||||||
rem := extgogit.NewRemote(memory.NewStorage(), config)
|
|
||||||
refs, err := rem.List(&extgogit.ListOptions{
|
|
||||||
Auth: authMethod,
|
|
||||||
})
|
|
||||||
if err != nil {
|
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 {
|
if currentRevision != "" && currentRevision == c.LastRevision {
|
||||||
return nil, git.NoChangesError{
|
return nil, git.NoChangesError{
|
||||||
Message: "no changes since last reconcilation",
|
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)
|
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 {
|
type CheckoutTag struct {
|
||||||
Tag string
|
Tag string
|
||||||
RecurseSubmodules bool
|
RecurseSubmodules bool
|
||||||
|
LastRevision string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, opts *git.AuthOptions) (*git.Commit, error) {
|
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)
|
return nil, fmt.Errorf("failed to construct auth method with options: %w", err)
|
||||||
}
|
}
|
||||||
ref := plumbing.NewTagReferenceName(c.Tag)
|
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{
|
repo, err := extgogit.PlainCloneContext(ctx, path, false, &extgogit.CloneOptions{
|
||||||
URL: url,
|
URL: url,
|
||||||
Auth: authMethod,
|
Auth: authMethod,
|
||||||
|
|
|
@ -137,6 +137,8 @@ func TestCheckoutTag_Checkout(t *testing.T) {
|
||||||
checkoutTag string
|
checkoutTag string
|
||||||
expectTag string
|
expectTag string
|
||||||
expectErr string
|
expectErr string
|
||||||
|
lastRev string
|
||||||
|
setLastRev bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Tag",
|
name: "Tag",
|
||||||
|
@ -144,6 +146,20 @@ func TestCheckoutTag_Checkout(t *testing.T) {
|
||||||
checkoutTag: "tag-1",
|
checkoutTag: "tag-1",
|
||||||
expectTag: "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",
|
name: "Annotated",
|
||||||
tag: "annotated",
|
tag: "annotated",
|
||||||
|
@ -168,12 +184,13 @@ func TestCheckoutTag_Checkout(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var h plumbing.Hash
|
var h plumbing.Hash
|
||||||
|
var tagHash *plumbing.Reference
|
||||||
if tt.tag != "" {
|
if tt.tag != "" {
|
||||||
h, err = commitFile(repo, "tag", tt.tag, time.Now())
|
h, err = commitFile(repo, "tag", tt.tag, time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -182,10 +199,18 @@ func TestCheckoutTag_Checkout(t *testing.T) {
|
||||||
tag := CheckoutTag{
|
tag := CheckoutTag{
|
||||||
Tag: tt.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()
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
cc, err := tag.Checkout(context.TODO(), tmpDir, path, nil)
|
cc, err := tag.Checkout(context.TODO(), tmpDir, path, nil)
|
||||||
if tt.expectErr != "" {
|
if tt.expectErr != "" {
|
||||||
|
g.Expect(err).ToNot(BeNil())
|
||||||
g.Expect(err.Error()).To(ContainSubstring(tt.expectErr))
|
g.Expect(err.Error()).To(ContainSubstring(tt.expectErr))
|
||||||
g.Expect(cc).To(BeNil())
|
g.Expect(cc).To(BeNil())
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue