diff options
author | Toon Claes <toon@gitlab.com> | 2022-10-19 17:38:50 +0300 |
---|---|---|
committer | Toon Claes <toon@gitlab.com> | 2022-10-21 12:01:18 +0300 |
commit | 938f12836caff9bbb3c27683bde8fe62a7e7f0c9 (patch) | |
tree | 601b64c0d4076d23a618354ba1627fbe316be88b | |
parent | c488ac952f293d090020a4722edd5a864b219bc6 (diff) |
gitpipe: Handle error in LsTree skip function
Change the prototype of the gitpipe.LsTree skipResult function so it
also can return an error and the gitpipe can be aborted.
-rw-r--r-- | internal/git/gitpipe/ls_tree.go | 17 | ||||
-rw-r--r-- | internal/git/gitpipe/ls_tree_test.go | 20 | ||||
-rw-r--r-- | internal/gitaly/linguist/linguist.go | 4 |
3 files changed, 33 insertions, 8 deletions
diff --git a/internal/git/gitpipe/ls_tree.go b/internal/git/gitpipe/ls_tree.go index b48489e4f..38c15a8c7 100644 --- a/internal/git/gitpipe/ls_tree.go +++ b/internal/git/gitpipe/ls_tree.go @@ -16,7 +16,7 @@ import ( type lsTreeConfig struct { recursive bool typeFilter func(*lstree.Entry) bool - skipResult func(*RevisionResult) bool + skipResult func(*RevisionResult) (bool, error) } // LsTreeOption is an option for the LsTree pipeline step. @@ -39,7 +39,7 @@ func LsTreeWithBlobFilter() LsTreeOption { // LsTreeWithSkip 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 LsTreeWithSkip(skipResult func(*RevisionResult) bool) LsTreeOption { +func LsTreeWithSkip(skipResult func(*RevisionResult) (bool, error)) LsTreeOption { return func(cfg *lsTreeConfig) { cfg.skipResult = skipResult } @@ -119,8 +119,17 @@ func LsTree( ObjectName: []byte(entry.Path), } - 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("ls-tree skip: %q", err), + }) + return + } + if skip { + continue + } } if isDone := sendRevisionResult(ctx, resultChan, result); isDone { diff --git a/internal/git/gitpipe/ls_tree_test.go b/internal/git/gitpipe/ls_tree_test.go index 52984a4d1..7ebc10316 100644 --- a/internal/git/gitpipe/ls_tree_test.go +++ b/internal/git/gitpipe/ls_tree_test.go @@ -170,12 +170,28 @@ func TestLsTree(t *testing.T) { } }, options: []LsTreeOption{ - LsTreeWithSkip(func(r *RevisionResult) bool { - return bytes.Equal(r.ObjectName, []byte(".gitignore")) + LsTreeWithSkip(func(r *RevisionResult) (bool, error) { + return bytes.Equal(r.ObjectName, []byte(".gitignore")), nil }), }, }, { + desc: "with skip failure", + setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) { + tree := gittest.WriteTree(t, cfg, repoPath, []gittest.TreeEntry{ + {Path: "README.md", Mode: "100644", Content: "Hello world"}, + }) + + return tree.Revision(), nil + }, + options: []LsTreeOption{ + LsTreeWithSkip(func(r *RevisionResult) (bool, error) { + return true, errors.New("broken") + }), + }, + expectedErr: errors.New(`ls-tree skip: "broken"`), + }, + { desc: "invalid revision", setup: func(t *testing.T, repoPath string) (git.Revision, []RevisionResult) { return "refs/heads/does-not-exist", nil diff --git a/internal/gitaly/linguist/linguist.go b/internal/gitaly/linguist/linguist.go index 8083bfea6..d032c3f9f 100644 --- a/internal/gitaly/linguist/linguist.go +++ b/internal/gitaly/linguist/linguist.go @@ -136,9 +136,9 @@ func (inst *Instance) enryStats(ctx context.Context, commitID string) (ByteCount if full { stats = newLanguageStats() - skipFunc := func(result *gitpipe.RevisionResult) bool { + skipFunc := func(result *gitpipe.RevisionResult) (bool, error) { // Skip files that are an excluded filetype based on filename. - return newFileInstance(string(result.ObjectName), attrMatcher).IsExcluded() + return newFileInstance(string(result.ObjectName), attrMatcher).IsExcluded(), nil } // Full recalculation is needed, so get all the files for the |