mirror of
https://github.com/harness/drone.git
synced 2025-05-17 09:30:00 +08:00
[code-953] diff merge base with annotated tags (#809)
This commit is contained in:
parent
ab9089d613
commit
6f83d8d07b
@ -39,6 +39,17 @@ func (a Adapter) RawDiff(
|
|||||||
if repoPath == "" {
|
if repoPath == "" {
|
||||||
return ErrRepositoryPathEmpty
|
return ErrRepositoryPathEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
baseTag, err := a.GetAnnotatedTag(ctx, repoPath, baseRef)
|
||||||
|
if err == nil {
|
||||||
|
baseRef = baseTag.TargetSha
|
||||||
|
}
|
||||||
|
|
||||||
|
headTag, err := a.GetAnnotatedTag(ctx, repoPath, headRef)
|
||||||
|
if err == nil {
|
||||||
|
headRef = headTag.TargetSha
|
||||||
|
}
|
||||||
|
|
||||||
args := make([]string, 0, 8)
|
args := make([]string, 0, 8)
|
||||||
args = append(args, "diff", "-M", "--full-index")
|
args = append(args, "diff", "-M", "--full-index")
|
||||||
if mergeBase {
|
if mergeBase {
|
||||||
@ -57,7 +68,7 @@ func (a Adapter) RawDiff(
|
|||||||
if errbuf.Len() > 0 {
|
if errbuf.Len() > 0 {
|
||||||
err = &runStdError{err: err, stderr: errbuf.String()}
|
err = &runStdError{err: err, stderr: errbuf.String()}
|
||||||
}
|
}
|
||||||
return processGiteaErrorf(err, "git diff failed between '%s' and '%s' with err: %v", baseRef, headRef, err)
|
return processGiteaErrorf(err, "git diff failed between '%s' and '%s'", baseRef, headRef)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
158
git/adapter/diff_test.go
Normal file
158
git/adapter/diff_test.go
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package adapter_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/git/adapter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAdapter_RawDiff(t *testing.T) {
|
||||||
|
git := setupGit(t)
|
||||||
|
repo, teardown := setupRepo(t, git, "testrawdiff")
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
baseBranch := "main"
|
||||||
|
// write file to main branch
|
||||||
|
parentSHA := writeFile(t, repo, "file.txt", "some content", nil)
|
||||||
|
|
||||||
|
err := repo.SetReference("refs/heads/"+baseBranch, parentSHA.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed updating reference '%s': %v", baseBranch, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
baseTag := "0.0.1"
|
||||||
|
err = repo.CreateAnnotatedTag(baseTag, "test tag 1", parentSHA.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating annotated tag '%s': %v", baseTag, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
headBranch := "dev"
|
||||||
|
|
||||||
|
// create branch
|
||||||
|
err = repo.CreateBranch(headBranch, baseBranch)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed creating a branch '%s': %v", headBranch, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write file to main branch
|
||||||
|
sha := writeFile(t, repo, "file.txt", "new content", []string{parentSHA.String()})
|
||||||
|
|
||||||
|
err = repo.SetReference("refs/heads/"+headBranch, sha.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed updating reference '%s': %v", headBranch, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
headTag := "0.0.2"
|
||||||
|
err = repo.CreateAnnotatedTag(headTag, "test tag 2", sha.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating annotated tag '%s': %v", headTag, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := `diff --git a/file.txt b/file.txt
|
||||||
|
index f0eec86f614944a81f87d879ebdc9a79aea0d7ea..47d2739ba2c34690248c8f91b84bb54e8936899a 100644
|
||||||
|
--- a/file.txt
|
||||||
|
+++ b/file.txt
|
||||||
|
@@ -1 +1 @@
|
||||||
|
-some content
|
||||||
|
\ No newline at end of file
|
||||||
|
+new content
|
||||||
|
\ No newline at end of file
|
||||||
|
`
|
||||||
|
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
repoPath string
|
||||||
|
baseRef string
|
||||||
|
headRef string
|
||||||
|
mergeBase bool
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
adapter adapter.Adapter
|
||||||
|
args args
|
||||||
|
wantW string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test branches",
|
||||||
|
adapter: git,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
repoPath: repo.Path,
|
||||||
|
baseRef: baseBranch,
|
||||||
|
headRef: headBranch,
|
||||||
|
mergeBase: false,
|
||||||
|
},
|
||||||
|
wantW: want,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test annotated tag",
|
||||||
|
adapter: git,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
repoPath: repo.Path,
|
||||||
|
baseRef: baseTag,
|
||||||
|
headRef: headTag,
|
||||||
|
mergeBase: false,
|
||||||
|
},
|
||||||
|
wantW: want,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test branches using merge-base",
|
||||||
|
adapter: git,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
repoPath: repo.Path,
|
||||||
|
baseRef: baseBranch,
|
||||||
|
headRef: headBranch,
|
||||||
|
mergeBase: true,
|
||||||
|
},
|
||||||
|
wantW: want,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test annotated tag using merge-base",
|
||||||
|
adapter: git,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
repoPath: repo.Path,
|
||||||
|
baseRef: baseTag,
|
||||||
|
headRef: headTag,
|
||||||
|
mergeBase: true,
|
||||||
|
},
|
||||||
|
wantW: want,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
w := &bytes.Buffer{}
|
||||||
|
err := tt.adapter.RawDiff(tt.args.ctx, tt.args.repoPath, tt.args.baseRef, tt.args.headRef, tt.args.mergeBase, w)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("RawDiff() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if gotW := w.String(); gotW != tt.wantW {
|
||||||
|
t.Errorf("RawDiff() gotW = %v, want %v", gotW, tt.wantW)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -547,9 +547,9 @@ func (a Adapter) GetMergeBase(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, _, err := git.NewCommand(ctx, "merge-base", "--", base, head).RunStdString(&git.RunOpts{Dir: repoPath})
|
stdout, stderr, err := git.NewCommand(ctx, "merge-base", "--", base, head).RunStdString(&git.RunOpts{Dir: repoPath})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", processGiteaErrorf(err, "failed to get merge-base")
|
return "", "", processGiteaErrorf(err, "failed to get merge-base: %v", stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.TrimSpace(stdout), base, nil
|
return strings.TrimSpace(stdout), base, nil
|
||||||
|
123
git/adapter/merge_test.go
Normal file
123
git/adapter/merge_test.go
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package adapter_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/git/adapter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAdapter_GetMergeBase(t *testing.T) {
|
||||||
|
git := setupGit(t)
|
||||||
|
repo, teardown := setupRepo(t, git, "testmergebase")
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
baseBranch := "main"
|
||||||
|
// write file to main branch
|
||||||
|
parentSHA := writeFile(t, repo, "file1.txt", "some content", nil)
|
||||||
|
|
||||||
|
err := repo.SetReference("refs/heads/"+baseBranch, parentSHA.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed updating reference '%s': %v", baseBranch, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
baseTag := "0.0.1"
|
||||||
|
err = repo.CreateAnnotatedTag(baseTag, "test tag 1", parentSHA.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating annotated tag '%s': %v", baseTag, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
headBranch := "dev"
|
||||||
|
|
||||||
|
// create branch
|
||||||
|
err = repo.CreateBranch(headBranch, baseBranch)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed creating a branch '%s': %v", headBranch, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write file to main branch
|
||||||
|
sha := writeFile(t, repo, "file1.txt", "new content", []string{parentSHA.String()})
|
||||||
|
|
||||||
|
err = repo.SetReference("refs/heads/"+headBranch, sha.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed updating reference '%s': %v", headBranch, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
headTag := "0.0.2"
|
||||||
|
err = repo.CreateAnnotatedTag(headTag, "test tag 2", sha.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating annotated tag '%s': %v", headTag, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
repoPath string
|
||||||
|
remote string
|
||||||
|
base string
|
||||||
|
head string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
git adapter.Adapter
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
want1 string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "git merge base using branch names",
|
||||||
|
git: git,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
repoPath: repo.Path,
|
||||||
|
remote: "",
|
||||||
|
base: baseBranch,
|
||||||
|
head: headBranch,
|
||||||
|
},
|
||||||
|
want: parentSHA.String(),
|
||||||
|
want1: baseBranch,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "git merge base using annotated tags",
|
||||||
|
git: git,
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
repoPath: repo.Path,
|
||||||
|
remote: "",
|
||||||
|
base: baseTag,
|
||||||
|
head: headTag,
|
||||||
|
},
|
||||||
|
want: parentSHA.String(),
|
||||||
|
want1: baseTag,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, got1, err := tt.git.GetMergeBase(tt.args.ctx, tt.args.repoPath, tt.args.remote, tt.args.base, tt.args.head)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("GetMergeBase() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("GetMergeBase() got = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
if got1 != tt.want1 {
|
||||||
|
t.Errorf("GetMergeBase() got1 = %v, want %v", got1, tt.want1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
133
git/adapter/setup_test.go
Normal file
133
git/adapter/setup_test.go
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package adapter_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/git/adapter"
|
||||||
|
"github.com/harness/gitness/types"
|
||||||
|
|
||||||
|
gitea "code.gitea.io/gitea/modules/git"
|
||||||
|
)
|
||||||
|
|
||||||
|
type teardown func()
|
||||||
|
|
||||||
|
var (
|
||||||
|
testAuthor = &gitea.Signature{
|
||||||
|
Name: "test",
|
||||||
|
Email: "test@test.com",
|
||||||
|
}
|
||||||
|
|
||||||
|
testCommitter = &gitea.Signature{
|
||||||
|
Name: "test",
|
||||||
|
Email: "test@test.com",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func setupGit(t *testing.T) adapter.Adapter {
|
||||||
|
t.Helper()
|
||||||
|
config := &types.Config{}
|
||||||
|
gogitProvider := adapter.ProvideGoGitRepoProvider()
|
||||||
|
git, err := adapter.New(
|
||||||
|
gogitProvider,
|
||||||
|
adapter.ProvideLastCommitCache(
|
||||||
|
config,
|
||||||
|
nil,
|
||||||
|
gogitProvider,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error initializing repository: %v", err)
|
||||||
|
}
|
||||||
|
return git
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupRepo(t *testing.T, git adapter.Adapter, name string) (*gitea.Repository, teardown) {
|
||||||
|
t.Helper()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
tmpdir := os.TempDir()
|
||||||
|
|
||||||
|
repoPath := path.Join(tmpdir, "test_repos", name)
|
||||||
|
|
||||||
|
err := git.InitRepository(ctx, repoPath, true)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error initializing repository: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := git.OpenRepository(ctx, repoPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error opening repository '%s': %v", name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = repo.SetDefaultBranch("main")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error setting default branch 'main': %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = git.Config(ctx, repoPath, "user.email", testCommitter.Email)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error setting config user.email %s: %v", testCommitter.Email, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = git.Config(ctx, repoPath, "user.name", testCommitter.Name)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error setting config user.name %s: %v", testCommitter.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return repo, func() {
|
||||||
|
if err := os.RemoveAll(repoPath); err != nil {
|
||||||
|
t.Errorf("error while removeng the repository '%s'", repoPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeFile(
|
||||||
|
t *testing.T,
|
||||||
|
repo *gitea.Repository,
|
||||||
|
path string,
|
||||||
|
content string,
|
||||||
|
parents []string,
|
||||||
|
) gitea.SHA1 {
|
||||||
|
t.Helper()
|
||||||
|
sha, err := repo.HashObject(strings.NewReader(content))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to hash object: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = repo.AddObjectToIndex("100644", sha, path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to add object to index: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tree, err := repo.WriteTree()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to write tree: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sha, err = repo.CommitTree(testAuthor, testCommitter, tree, gitea.CommitTreeOpts{
|
||||||
|
Message: "write file operation",
|
||||||
|
Parents: parents,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to commit tree: %v", err)
|
||||||
|
}
|
||||||
|
return sha
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user