Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToon Claes <toon@gitlab.com>2022-10-19 17:37:09 +0300
committerToon Claes <toon@gitlab.com>2022-10-21 12:01:18 +0300
commitc488ac952f293d090020a4722edd5a864b219bc6 (patch)
tree6159f40748dd7ec22334ea735e2a2f5c5b930bfc
parent1e7c1a320633351a75bc4d56e977d6739ec4e349 (diff)
gitpipe: Handle error in DiffTree skip function
Change the prototype of the gitpipe.DiffTree skipResult function so it also can return an error and the gitpipe can be aborted.
-rw-r--r--internal/git/gitpipe/diff_tree.go17
-rw-r--r--internal/git/gitpipe/diff_tree_test.go27
-rw-r--r--internal/gitaly/linguist/linguist.go6
3 files changed, 41 insertions, 9 deletions
diff --git a/internal/git/gitpipe/diff_tree.go b/internal/git/gitpipe/diff_tree.go
index cf81a1ba3..4133c5085 100644
--- a/internal/git/gitpipe/diff_tree.go
+++ b/internal/git/gitpipe/diff_tree.go
@@ -15,7 +15,7 @@ import (
type diffTreeConfig struct {
recursive bool
ignoreSubmodules bool
- skipResult func(*RevisionResult) bool
+ skipResult func(*RevisionResult) (bool, error)
}
// DiffTreeOption is an option for the DiffTree pipeline step.
@@ -38,7 +38,7 @@ func DiffTreeWithIgnoreSubmodules() DiffTreeOption {
// DiffTreeWithSkip will execute the given function for each RevisionResult processed by the
// pipeline. If the callback returns `true`, then the object will be skipped and not passed down
// the pipeline.
-func DiffTreeWithSkip(skipResult func(*RevisionResult) bool) DiffTreeOption {
+func DiffTreeWithSkip(skipResult func(*RevisionResult) (bool, error)) DiffTreeOption {
return func(cfg *diffTreeConfig) {
cfg.skipResult = skipResult
}
@@ -116,8 +116,17 @@ func DiffTree(
ObjectName: attrsAndFile[1],
}
- if cfg.skipResult != nil && cfg.skipResult(&result) {
- continue
+ if cfg.skipResult != nil {
+ skip, err := cfg.skipResult(&result)
+ if err != nil {
+ sendRevisionResult(ctx, resultChan, RevisionResult{
+ err: fmt.Errorf("diff-tree skip: %q", err),
+ })
+ return
+ }
+ if skip {
+ continue
+ }
}
if isDone := sendRevisionResult(ctx, resultChan, result); isDone {
diff --git a/internal/git/gitpipe/diff_tree_test.go b/internal/git/gitpipe/diff_tree_test.go
index 616fb8291..fb90b01ac 100644
--- a/internal/git/gitpipe/diff_tree_test.go
+++ b/internal/git/gitpipe/diff_tree_test.go
@@ -188,12 +188,35 @@ func TestDiffTree(t *testing.T) {
}
},
options: []DiffTreeOption{
- DiffTreeWithSkip(func(r *RevisionResult) bool {
- return bytes.Equal(r.ObjectName, []byte("b"))
+ DiffTreeWithSkip(func(r *RevisionResult) (bool, error) {
+ return bytes.Equal(r.ObjectName, []byte("b")), nil
}),
},
},
{
+ desc: "with skip failure",
+ setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) {
+ treeA := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "a", Mode: "100644", Content: "1"},
+ {Path: "b", Mode: "100644", Content: "2"},
+ })
+
+ changedBlobA := gittest.WriteBlob(t, cfg, repoPath, []byte("x"))
+ treeB := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{
+ {Path: "a", Mode: "100644", OID: changedBlobA},
+ {Path: "b", Mode: "100644", Content: "y"},
+ })
+
+ return treeA.Revision(), treeB.Revision(), nil
+ },
+ options: []DiffTreeOption{
+ DiffTreeWithSkip(func(r *RevisionResult) (bool, error) {
+ return true, errors.New("broken")
+ }),
+ },
+ expectedErr: errors.New(`diff-tree skip: "broken"`),
+ },
+ {
desc: "invalid revision",
setup: func(t *testing.T, repoPath string) (git.Revision, git.Revision, []RevisionResult) {
gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"))
diff --git a/internal/gitaly/linguist/linguist.go b/internal/gitaly/linguist/linguist.go
index f5f11b067..8083bfea6 100644
--- a/internal/gitaly/linguist/linguist.go
+++ b/internal/gitaly/linguist/linguist.go
@@ -153,7 +153,7 @@ func (inst *Instance) enryStats(ctx context.Context, commitID string) (ByteCount
// Stats are cached for one commit, so get the git-diff-tree(1)
// between that commit and the one we're calculating stats for.
- skipFunc := func(result *gitpipe.RevisionResult) bool {
+ skipFunc := func(result *gitpipe.RevisionResult) (bool, error) {
// Skip files that are deleted, or
// an excluded filetype based on filename.
if git.ObjectHashSHA1.IsZeroOID(result.OID) ||
@@ -162,9 +162,9 @@ func (inst *Instance) enryStats(ctx context.Context, commitID string) (ByteCount
// function, but for every file that's deleted,
// remove the stats.
stats.drop(string(result.ObjectName))
- return true
+ return true, nil
}
- return false
+ return false, nil
}
revlistIt = gitpipe.DiffTree(ctx, inst.repo,