feat(ci): list the commits of a tag that no branch has
- commit
- e8931100c1a8bb1a74bbb1328cdab16c7301107f
- author
- brice · · 2026-10-13 03:21 UTC
- parent
- f93ee06
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
5 files · +181 -4
M internal/adapters/gitcli/changed.go +15 -0
| @@ -58,3 +58,18 @@ func (g *Git) ChangedPaths(ctx context.Context, repo domain.RepoName, base, head | |||
| 58 | 58 | } | |
| 59 | 59 | return paths, truncated, nil | |
| 60 | 60 | } | |
| 61 | + | ||
| 62 | + | // CommitsOffBranches lists the commits reachable from head and from no branch | |
| 63 | + | // (refs/heads/*), newest first, at most limit. It runs | |
| 64 | + | // `git log --not --branches --not <head>`: tags do not count, so the commit of | |
| 65 | + | // another tag that no branch has is listed. | |
| 66 | + | // | |
| 67 | + | //hexcheck:ignore suspicious-business-logic-in-adapter parses git output into domain values; the limit comes from the port | |
| 68 | + | func (g *Git) CommitsOffBranches(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int) ([]domain.Commit, bool, error) { | |
| 69 | + | if head.IsZero() { | |
| 70 | + | return nil, false, fmt.Errorf("commits off branches: %w: no head", domain.ErrInvalid) | |
| 71 | + | } | |
| 72 | + | // "--not --branches" excludes every branch, the second "--not" turns the | |
| 73 | + | // negation off again for the head that follows. | |
| 74 | + | return g.logCommits(ctx, repo, head, limit, []string{"--not", "--branches", "--not"}, nil) | |
| 75 | + | } | |
| @@ -58,3 +58,18 @@ func (g *Git) ChangedPaths(ctx context.Context, repo domain.RepoName, base, head | |||||
| 58 | } | 58 | } | ||
| 59 | return paths, truncated, nil | 59 | return paths, truncated, nil | ||
| 60 | } | 60 | } | ||
| 61 | + | ||||
| 62 | + | // CommitsOffBranches lists the commits reachable from head and from no branch | |||
| 63 | + | // (refs/heads/*), newest first, at most limit. It runs | |||
| 64 | + | // `git log --not --branches --not <head>`: tags do not count, so the commit of | |||
| 65 | + | // another tag that no branch has is listed. | |||
| 66 | + | // | |||
| 67 | + | //hexcheck:ignore suspicious-business-logic-in-adapter parses git output into domain values; the limit comes from the port | |||
| 68 | + | func (g *Git) CommitsOffBranches(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int) ([]domain.Commit, bool, error) { | |||
| 69 | + | if head.IsZero() { | |||
| 70 | + | return nil, false, fmt.Errorf("commits off branches: %w: no head", domain.ErrInvalid) | |||
| 71 | + | } | |||
| 72 | + | // "--not --branches" excludes every branch, the second "--not" turns the | |||
| 73 | + | // negation off again for the head that follows. | |||
| 74 | + | return g.logCommits(ctx, repo, head, limit, []string{"--not", "--branches", "--not"}, nil) | |||
| 75 | + | } | |||
M internal/adapters/gitcli/changed_test.go +58 -0
| @@ -67,3 +67,61 @@ func TestChangedPathsKeepsAWholeRenameAndOddNames(t *testing.T) { | |||
| 67 | 67 | require.NoError(t, err) | |
| 68 | 68 | assert.ElementsMatch(t, []string{"c.txt", "dir with space/é.txt"}, got, "both sides of a rename, verbatim") | |
| 69 | 69 | } | |
| 70 | + | ||
| 71 | + | func TestCommitsOffBranches(t *testing.T) { | |
| 72 | + | g, data := newGit(t) | |
| 73 | + | ctx := context.Background() | |
| 74 | + | m := newMergeFixture(t, data) | |
| 75 | + | t.Cleanup(func() { _ = g.Close(ctx) }) | |
| 76 | + | ||
| 77 | + | msgs := func(cs []domain.Commit) []string { | |
| 78 | + | var out []string | |
| 79 | + | for _, c := range cs { | |
| 80 | + | out = append(out, c.Summary) | |
| 81 | + | } | |
| 82 | + | return out | |
| 83 | + | } | |
| 84 | + | ||
| 85 | + | // Every commit of the fixture is on main or feat. | |
| 86 | + | got, more, err := g.CommitsOffBranches(ctx, m.f.Name, m.d, 10) | |
| 87 | + | require.NoError(t, err) | |
| 88 | + | assert.Empty(t, got, "feat has its tip") | |
| 89 | + | assert.False(t, more) | |
| 90 | + | ||
| 91 | + | // A commit no branch has, on top of feat: listed alone, then with its | |
| 92 | + | // parent when that has no branch either (a branch deleted, a detached tip). | |
| 93 | + | m.f.Git("checkout", "--quiet", "--detach", m.d.String()) | |
| 94 | + | m.f.Write("t1.txt", "one\n") | |
| 95 | + | t1 := oidOf(t, m.f.Commit("tagged one")) | |
| 96 | + | m.f.Write("t2.txt", "two\n") | |
| 97 | + | t2 := oidOf(t, m.f.Commit("tagged two")) | |
| 98 | + | m.f.Git("update-ref", "refs/tags/v1", t2.String()) | |
| 99 | + | ||
| 100 | + | got, more, err = g.CommitsOffBranches(ctx, m.f.Name, t2, 10) | |
| 101 | + | require.NoError(t, err) | |
| 102 | + | assert.Equal(t, []string{"tagged two", "tagged one"}, msgs(got), "newest first, down to the commits a branch has") | |
| 103 | + | assert.False(t, more) | |
| 104 | + | got, _, err = g.CommitsOffBranches(ctx, m.f.Name, t1, 10) | |
| 105 | + | require.NoError(t, err) | |
| 106 | + | assert.Equal(t, []string{"tagged one"}, msgs(got)) | |
| 107 | + | ||
| 108 | + | // A bound cuts the list and says so. | |
| 109 | + | got, more, err = g.CommitsOffBranches(ctx, m.f.Name, t2, 1) | |
| 110 | + | require.NoError(t, err) | |
| 111 | + | assert.Equal(t, []string{"tagged two"}, msgs(got)) | |
| 112 | + | assert.True(t, more) | |
| 113 | + | ||
| 114 | + | // Another tag is no branch: t2 stays listed although v1 points to it, and | |
| 115 | + | // moving a branch onto t1 takes t1 out of the list. | |
| 116 | + | m.f.Git("update-ref", "refs/heads/rel", t1.String()) | |
| 117 | + | got, _, err = g.CommitsOffBranches(ctx, m.f.Name, t2, 10) | |
| 118 | + | require.NoError(t, err) | |
| 119 | + | assert.Equal(t, []string{"tagged two"}, msgs(got)) | |
| 120 | + | ||
| 121 | + | _, _, err = g.CommitsOffBranches(ctx, m.f.Name, domain.ObjectID{}, 10) | |
| 122 | + | assert.ErrorIs(t, err, domain.ErrInvalid) | |
| 123 | + | _, _, err = g.CommitsOffBranches(ctx, m.f.Name, t2, 0) | |
| 124 | + | assert.ErrorIs(t, err, domain.ErrInvalidPageSize) | |
| 125 | + | _, _, err = g.CommitsOffBranches(ctx, name(t, "missing"), t2, 5) | |
| 126 | + | assert.ErrorIs(t, err, domain.ErrNotFound) | |
| 127 | + | } | |
| @@ -67,3 +67,61 @@ func TestChangedPathsKeepsAWholeRenameAndOddNames(t *testing.T) { | |||||
| 67 | require.NoError(t, err) | 67 | require.NoError(t, err) | ||
| 68 | assert.ElementsMatch(t, []string{"c.txt", "dir with space/é.txt"}, got, "both sides of a rename, verbatim") | 68 | assert.ElementsMatch(t, []string{"c.txt", "dir with space/é.txt"}, got, "both sides of a rename, verbatim") | ||
| 69 | } | 69 | } | ||
| 70 | + | ||||
| 71 | + | func TestCommitsOffBranches(t *testing.T) { | |||
| 72 | + | g, data := newGit(t) | |||
| 73 | + | ctx := context.Background() | |||
| 74 | + | m := newMergeFixture(t, data) | |||
| 75 | + | t.Cleanup(func() { _ = g.Close(ctx) }) | |||
| 76 | + | ||||
| 77 | + | msgs := func(cs []domain.Commit) []string { | |||
| 78 | + | var out []string | |||
| 79 | + | for _, c := range cs { | |||
| 80 | + | out = append(out, c.Summary) | |||
| 81 | + | } | |||
| 82 | + | return out | |||
| 83 | + | } | |||
| 84 | + | ||||
| 85 | + | // Every commit of the fixture is on main or feat. | |||
| 86 | + | got, more, err := g.CommitsOffBranches(ctx, m.f.Name, m.d, 10) | |||
| 87 | + | require.NoError(t, err) | |||
| 88 | + | assert.Empty(t, got, "feat has its tip") | |||
| 89 | + | assert.False(t, more) | |||
| 90 | + | ||||
| 91 | + | // A commit no branch has, on top of feat: listed alone, then with its | |||
| 92 | + | // parent when that has no branch either (a branch deleted, a detached tip). | |||
| 93 | + | m.f.Git("checkout", "--quiet", "--detach", m.d.String()) | |||
| 94 | + | m.f.Write("t1.txt", "one\n") | |||
| 95 | + | t1 := oidOf(t, m.f.Commit("tagged one")) | |||
| 96 | + | m.f.Write("t2.txt", "two\n") | |||
| 97 | + | t2 := oidOf(t, m.f.Commit("tagged two")) | |||
| 98 | + | m.f.Git("update-ref", "refs/tags/v1", t2.String()) | |||
| 99 | + | ||||
| 100 | + | got, more, err = g.CommitsOffBranches(ctx, m.f.Name, t2, 10) | |||
| 101 | + | require.NoError(t, err) | |||
| 102 | + | assert.Equal(t, []string{"tagged two", "tagged one"}, msgs(got), "newest first, down to the commits a branch has") | |||
| 103 | + | assert.False(t, more) | |||
| 104 | + | got, _, err = g.CommitsOffBranches(ctx, m.f.Name, t1, 10) | |||
| 105 | + | require.NoError(t, err) | |||
| 106 | + | assert.Equal(t, []string{"tagged one"}, msgs(got)) | |||
| 107 | + | ||||
| 108 | + | // A bound cuts the list and says so. | |||
| 109 | + | got, more, err = g.CommitsOffBranches(ctx, m.f.Name, t2, 1) | |||
| 110 | + | require.NoError(t, err) | |||
| 111 | + | assert.Equal(t, []string{"tagged two"}, msgs(got)) | |||
| 112 | + | assert.True(t, more) | |||
| 113 | + | ||||
| 114 | + | // Another tag is no branch: t2 stays listed although v1 points to it, and | |||
| 115 | + | // moving a branch onto t1 takes t1 out of the list. | |||
| 116 | + | m.f.Git("update-ref", "refs/heads/rel", t1.String()) | |||
| 117 | + | got, _, err = g.CommitsOffBranches(ctx, m.f.Name, t2, 10) | |||
| 118 | + | require.NoError(t, err) | |||
| 119 | + | assert.Equal(t, []string{"tagged two"}, msgs(got)) | |||
| 120 | + | ||||
| 121 | + | _, _, err = g.CommitsOffBranches(ctx, m.f.Name, domain.ObjectID{}, 10) | |||
| 122 | + | assert.ErrorIs(t, err, domain.ErrInvalid) | |||
| 123 | + | _, _, err = g.CommitsOffBranches(ctx, m.f.Name, t2, 0) | |||
| 124 | + | assert.ErrorIs(t, err, domain.ErrInvalidPageSize) | |||
| 125 | + | _, _, err = g.CommitsOffBranches(ctx, name(t, "missing"), t2, 5) | |||
| 126 | + | assert.ErrorIs(t, err, domain.ErrNotFound) | |||
| 127 | + | } | |||
M internal/adapters/gitcli/merge.go +17 -4
| @@ -132,6 +132,19 @@ func (g *Git) IsAncestor(ctx context.Context, repo domain.RepoName, ancestor, de | |||
| 132 | 132 | // | |
| 133 | 133 | //hexcheck:ignore suspicious-business-logic-in-adapter parses git output into domain values; the limit comes from the port | |
| 134 | 134 | func (g *Git) ListRange(ctx context.Context, repo domain.RepoName, exclude, head domain.ObjectID, limit int) ([]domain.Commit, bool, error) { | |
| 135 | + | var excluded []string | |
| 136 | + | if !exclude.IsZero() { | |
| 137 | + | excluded = []string{"^" + exclude.String()} | |
| 138 | + | } | |
| 139 | + | return g.logCommits(ctx, repo, head, limit, nil, excluded) | |
| 140 | + | } | |
| 141 | + | ||
| 142 | + | // logCommits runs `git log` for the commits reachable from head: revArgs go | |
| 143 | + | // before the head (options such as --not), excluded after it. Newest first, | |
| 144 | + | // at most limit; more says there were others. | |
| 145 | + | // | |
| 146 | + | //hexcheck:ignore suspicious-business-logic-in-adapter parses git output into domain values; the limit comes from the port | |
| 147 | + | func (g *Git) logCommits(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int, revArgs, excluded []string) ([]domain.Commit, bool, error) { | |
| 135 | 148 | if limit < 1 || limit > ports.MaxCommitLimit { | |
| 136 | 149 | return nil, false, fmt.Errorf("list range: %w: limit %d", domain.ErrInvalidPageSize, limit) | |
| 137 | 150 | } | |
| @@ -139,10 +152,10 @@ func (g *Git) ListRange(ctx context.Context, repo domain.RepoName, exclude, head | |||
| 139 | 152 | if err != nil { | |
| 140 | 153 | return nil, false, err | |
| 141 | 154 | } | |
| 142 | - | args := readArgs(dir, "log", "-z", "-n", strconv.Itoa(limit+1), "--format="+commitFormat, "--end-of-options", head.String()) | |
| 143 | - | if !exclude.IsZero() { | |
| 144 | - | args = append(args, "^"+exclude.String()) | |
| 145 | - | } | |
| 155 | + | args := readArgs(dir, "log", "-z", "-n", strconv.Itoa(limit+1), "--format="+commitFormat) | |
| 156 | + | args = append(args, revArgs...) | |
| 157 | + | args = append(args, "--end-of-options", head.String()) | |
| 158 | + | args = append(args, excluded...) | |
| 146 | 159 | var ( | |
| 147 | 160 | commits []domain.Commit | |
| 148 | 161 | more bool | |
| @@ -132,6 +132,19 @@ func (g *Git) IsAncestor(ctx context.Context, repo domain.RepoName, ancestor, de | |||||
| 132 | // | 132 | // | ||
| 133 | //hexcheck:ignore suspicious-business-logic-in-adapter parses git output into domain values; the limit comes from the port | 133 | //hexcheck:ignore suspicious-business-logic-in-adapter parses git output into domain values; the limit comes from the port | ||
| 134 | func (g *Git) ListRange(ctx context.Context, repo domain.RepoName, exclude, head domain.ObjectID, limit int) ([]domain.Commit, bool, error) { | 134 | func (g *Git) ListRange(ctx context.Context, repo domain.RepoName, exclude, head domain.ObjectID, limit int) ([]domain.Commit, bool, error) { | ||
| 135 | + | var excluded []string | |||
| 136 | + | if !exclude.IsZero() { | |||
| 137 | + | excluded = []string{"^" + exclude.String()} | |||
| 138 | + | } | |||
| 139 | + | return g.logCommits(ctx, repo, head, limit, nil, excluded) | |||
| 140 | + | } | |||
| 141 | + | ||||
| 142 | + | // logCommits runs `git log` for the commits reachable from head: revArgs go | |||
| 143 | + | // before the head (options such as --not), excluded after it. Newest first, | |||
| 144 | + | // at most limit; more says there were others. | |||
| 145 | + | // | |||
| 146 | + | //hexcheck:ignore suspicious-business-logic-in-adapter parses git output into domain values; the limit comes from the port | |||
| 147 | + | func (g *Git) logCommits(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int, revArgs, excluded []string) ([]domain.Commit, bool, error) { | |||
| 135 | if limit < 1 || limit > ports.MaxCommitLimit { | 148 | if limit < 1 || limit > ports.MaxCommitLimit { | ||
| 136 | return nil, false, fmt.Errorf("list range: %w: limit %d", domain.ErrInvalidPageSize, limit) | 149 | return nil, false, fmt.Errorf("list range: %w: limit %d", domain.ErrInvalidPageSize, limit) | ||
| 137 | } | 150 | } | ||
| @@ -139,10 +152,10 @@ func (g *Git) ListRange(ctx context.Context, repo domain.RepoName, exclude, head | |||||
| 139 | if err != nil { | 152 | if err != nil { | ||
| 140 | return nil, false, err | 153 | return nil, false, err | ||
| 141 | } | 154 | } | ||
| 142 | - | args := readArgs(dir, "log", "-z", "-n", strconv.Itoa(limit+1), "--format="+commitFormat, "--end-of-options", head.String()) | 155 | + | args := readArgs(dir, "log", "-z", "-n", strconv.Itoa(limit+1), "--format="+commitFormat) |
| 143 | - | if !exclude.IsZero() { | 156 | + | args = append(args, revArgs...) |
| 144 | - | args = append(args, "^"+exclude.String()) | 157 | + | args = append(args, "--end-of-options", head.String()) |
| 145 | - | } | 158 | + | args = append(args, excluded...) |
| 146 | var ( | 159 | var ( | ||
| 147 | commits []domain.Commit | 160 | commits []domain.Commit | ||
| 148 | more bool | 161 | more bool | ||
M internal/ports/ci.go +5 -0
| @@ -173,6 +173,11 @@ type CIGit interface { | |||
| 173 | 173 | // means the empty tree), in the order of the diff and without renames | |
| 174 | 174 | // detection, at most max; truncated is true when there were more. | |
| 175 | 175 | ChangedPaths(ctx context.Context, repo domain.RepoName, base, head domain.ObjectID, max int) (paths []string, truncated bool, err error) | |
| 176 | + | // CommitsOffBranches returns the commits reachable from head and from no | |
| 177 | + | // branch (refs/heads/*; tags do not count), newest first, at most limit | |
| 178 | + | // (1 to MaxCommitLimit); more is true when there are others. It is empty | |
| 179 | + | // for a commit that a branch already has. | |
| 180 | + | CommitsOffBranches(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int) (commits []domain.Commit, more bool, err error) | |
| 176 | 181 | } | |
| 177 | 182 | ||
| 178 | 183 | // --- inbound --- | |
| @@ -173,6 +173,11 @@ type CIGit interface { | |||||
| 173 | // means the empty tree), in the order of the diff and without renames | 173 | // means the empty tree), in the order of the diff and without renames | ||
| 174 | // detection, at most max; truncated is true when there were more. | 174 | // detection, at most max; truncated is true when there were more. | ||
| 175 | ChangedPaths(ctx context.Context, repo domain.RepoName, base, head domain.ObjectID, max int) (paths []string, truncated bool, err error) | 175 | ChangedPaths(ctx context.Context, repo domain.RepoName, base, head domain.ObjectID, max int) (paths []string, truncated bool, err error) | ||
| 176 | + | // CommitsOffBranches returns the commits reachable from head and from no | |||
| 177 | + | // branch (refs/heads/*; tags do not count), newest first, at most limit | |||
| 178 | + | // (1 to MaxCommitLimit); more is true when there are others. It is empty | |||
| 179 | + | // for a commit that a branch already has. | |||
| 180 | + | CommitsOffBranches(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int) (commits []domain.Commit, more bool, err error) | |||
| 176 | } | 181 | } | ||
| 177 | 182 | ||||
| 178 | // --- inbound --- | 183 | // --- inbound --- | ||
M internal/ports/mocks/CIGit.go +86 -0
| @@ -138,3 +138,89 @@ func (_c *CIGit_ChangedPaths_Call) RunAndReturn(run func(ctx context.Context, re | |||
| 138 | 138 | _c.Call.Return(run) | |
| 139 | 139 | return _c | |
| 140 | 140 | } | |
| 141 | + | ||
| 142 | + | // CommitsOffBranches provides a mock function for the type CIGit | |
| 143 | + | func (_mock *CIGit) CommitsOffBranches(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int) ([]domain.Commit, bool, error) { | |
| 144 | + | ret := _mock.Called(ctx, repo, head, limit) | |
| 145 | + | ||
| 146 | + | if len(ret) == 0 { | |
| 147 | + | panic("no return value specified for CommitsOffBranches") | |
| 148 | + | } | |
| 149 | + | ||
| 150 | + | var r0 []domain.Commit | |
| 151 | + | var r1 bool | |
| 152 | + | var r2 error | |
| 153 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, domain.RepoName, domain.ObjectID, int) ([]domain.Commit, bool, error)); ok { | |
| 154 | + | return returnFunc(ctx, repo, head, limit) | |
| 155 | + | } | |
| 156 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, domain.RepoName, domain.ObjectID, int) []domain.Commit); ok { | |
| 157 | + | r0 = returnFunc(ctx, repo, head, limit) | |
| 158 | + | } else { | |
| 159 | + | if ret.Get(0) != nil { | |
| 160 | + | r0 = ret.Get(0).([]domain.Commit) | |
| 161 | + | } | |
| 162 | + | } | |
| 163 | + | if returnFunc, ok := ret.Get(1).(func(context.Context, domain.RepoName, domain.ObjectID, int) bool); ok { | |
| 164 | + | r1 = returnFunc(ctx, repo, head, limit) | |
| 165 | + | } else { | |
| 166 | + | r1 = ret.Get(1).(bool) | |
| 167 | + | } | |
| 168 | + | if returnFunc, ok := ret.Get(2).(func(context.Context, domain.RepoName, domain.ObjectID, int) error); ok { | |
| 169 | + | r2 = returnFunc(ctx, repo, head, limit) | |
| 170 | + | } else { | |
| 171 | + | r2 = ret.Error(2) | |
| 172 | + | } | |
| 173 | + | return r0, r1, r2 | |
| 174 | + | } | |
| 175 | + | ||
| 176 | + | // CIGit_CommitsOffBranches_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CommitsOffBranches' | |
| 177 | + | type CIGit_CommitsOffBranches_Call struct { | |
| 178 | + | *mock.Call | |
| 179 | + | } | |
| 180 | + | ||
| 181 | + | // CommitsOffBranches is a helper method to define mock.On call | |
| 182 | + | // - ctx context.Context | |
| 183 | + | // - repo domain.RepoName | |
| 184 | + | // - head domain.ObjectID | |
| 185 | + | // - limit int | |
| 186 | + | func (_e *CIGit_Expecter) CommitsOffBranches(ctx any, repo any, head any, limit any) *CIGit_CommitsOffBranches_Call { | |
| 187 | + | return &CIGit_CommitsOffBranches_Call{Call: _e.mock.On("CommitsOffBranches", ctx, repo, head, limit)} | |
| 188 | + | } | |
| 189 | + | ||
| 190 | + | func (_c *CIGit_CommitsOffBranches_Call) Run(run func(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int)) *CIGit_CommitsOffBranches_Call { | |
| 191 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 192 | + | var arg0 context.Context | |
| 193 | + | if args[0] != nil { | |
| 194 | + | arg0 = args[0].(context.Context) | |
| 195 | + | } | |
| 196 | + | var arg1 domain.RepoName | |
| 197 | + | if args[1] != nil { | |
| 198 | + | arg1 = args[1].(domain.RepoName) | |
| 199 | + | } | |
| 200 | + | var arg2 domain.ObjectID | |
| 201 | + | if args[2] != nil { | |
| 202 | + | arg2 = args[2].(domain.ObjectID) | |
| 203 | + | } | |
| 204 | + | var arg3 int | |
| 205 | + | if args[3] != nil { | |
| 206 | + | arg3 = args[3].(int) | |
| 207 | + | } | |
| 208 | + | run( | |
| 209 | + | arg0, | |
| 210 | + | arg1, | |
| 211 | + | arg2, | |
| 212 | + | arg3, | |
| 213 | + | ) | |
| 214 | + | }) | |
| 215 | + | return _c | |
| 216 | + | } | |
| 217 | + | ||
| 218 | + | func (_c *CIGit_CommitsOffBranches_Call) Return(commits []domain.Commit, more bool, err error) *CIGit_CommitsOffBranches_Call { | |
| 219 | + | _c.Call.Return(commits, more, err) | |
| 220 | + | return _c | |
| 221 | + | } | |
| 222 | + | ||
| 223 | + | func (_c *CIGit_CommitsOffBranches_Call) RunAndReturn(run func(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int) ([]domain.Commit, bool, error)) *CIGit_CommitsOffBranches_Call { | |
| 224 | + | _c.Call.Return(run) | |
| 225 | + | return _c | |
| 226 | + | } | |
| @@ -138,3 +138,89 @@ func (_c *CIGit_ChangedPaths_Call) RunAndReturn(run func(ctx context.Context, re | |||||
| 138 | _c.Call.Return(run) | 138 | _c.Call.Return(run) | ||
| 139 | return _c | 139 | return _c | ||
| 140 | } | 140 | } | ||
| 141 | + | ||||
| 142 | + | // CommitsOffBranches provides a mock function for the type CIGit | |||
| 143 | + | func (_mock *CIGit) CommitsOffBranches(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int) ([]domain.Commit, bool, error) { | |||
| 144 | + | ret := _mock.Called(ctx, repo, head, limit) | |||
| 145 | + | ||||
| 146 | + | if len(ret) == 0 { | |||
| 147 | + | panic("no return value specified for CommitsOffBranches") | |||
| 148 | + | } | |||
| 149 | + | ||||
| 150 | + | var r0 []domain.Commit | |||
| 151 | + | var r1 bool | |||
| 152 | + | var r2 error | |||
| 153 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, domain.RepoName, domain.ObjectID, int) ([]domain.Commit, bool, error)); ok { | |||
| 154 | + | return returnFunc(ctx, repo, head, limit) | |||
| 155 | + | } | |||
| 156 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, domain.RepoName, domain.ObjectID, int) []domain.Commit); ok { | |||
| 157 | + | r0 = returnFunc(ctx, repo, head, limit) | |||
| 158 | + | } else { | |||
| 159 | + | if ret.Get(0) != nil { | |||
| 160 | + | r0 = ret.Get(0).([]domain.Commit) | |||
| 161 | + | } | |||
| 162 | + | } | |||
| 163 | + | if returnFunc, ok := ret.Get(1).(func(context.Context, domain.RepoName, domain.ObjectID, int) bool); ok { | |||
| 164 | + | r1 = returnFunc(ctx, repo, head, limit) | |||
| 165 | + | } else { | |||
| 166 | + | r1 = ret.Get(1).(bool) | |||
| 167 | + | } | |||
| 168 | + | if returnFunc, ok := ret.Get(2).(func(context.Context, domain.RepoName, domain.ObjectID, int) error); ok { | |||
| 169 | + | r2 = returnFunc(ctx, repo, head, limit) | |||
| 170 | + | } else { | |||
| 171 | + | r2 = ret.Error(2) | |||
| 172 | + | } | |||
| 173 | + | return r0, r1, r2 | |||
| 174 | + | } | |||
| 175 | + | ||||
| 176 | + | // CIGit_CommitsOffBranches_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CommitsOffBranches' | |||
| 177 | + | type CIGit_CommitsOffBranches_Call struct { | |||
| 178 | + | *mock.Call | |||
| 179 | + | } | |||
| 180 | + | ||||
| 181 | + | // CommitsOffBranches is a helper method to define mock.On call | |||
| 182 | + | // - ctx context.Context | |||
| 183 | + | // - repo domain.RepoName | |||
| 184 | + | // - head domain.ObjectID | |||
| 185 | + | // - limit int | |||
| 186 | + | func (_e *CIGit_Expecter) CommitsOffBranches(ctx any, repo any, head any, limit any) *CIGit_CommitsOffBranches_Call { | |||
| 187 | + | return &CIGit_CommitsOffBranches_Call{Call: _e.mock.On("CommitsOffBranches", ctx, repo, head, limit)} | |||
| 188 | + | } | |||
| 189 | + | ||||
| 190 | + | func (_c *CIGit_CommitsOffBranches_Call) Run(run func(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int)) *CIGit_CommitsOffBranches_Call { | |||
| 191 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 192 | + | var arg0 context.Context | |||
| 193 | + | if args[0] != nil { | |||
| 194 | + | arg0 = args[0].(context.Context) | |||
| 195 | + | } | |||
| 196 | + | var arg1 domain.RepoName | |||
| 197 | + | if args[1] != nil { | |||
| 198 | + | arg1 = args[1].(domain.RepoName) | |||
| 199 | + | } | |||
| 200 | + | var arg2 domain.ObjectID | |||
| 201 | + | if args[2] != nil { | |||
| 202 | + | arg2 = args[2].(domain.ObjectID) | |||
| 203 | + | } | |||
| 204 | + | var arg3 int | |||
| 205 | + | if args[3] != nil { | |||
| 206 | + | arg3 = args[3].(int) | |||
| 207 | + | } | |||
| 208 | + | run( | |||
| 209 | + | arg0, | |||
| 210 | + | arg1, | |||
| 211 | + | arg2, | |||
| 212 | + | arg3, | |||
| 213 | + | ) | |||
| 214 | + | }) | |||
| 215 | + | return _c | |||
| 216 | + | } | |||
| 217 | + | ||||
| 218 | + | func (_c *CIGit_CommitsOffBranches_Call) Return(commits []domain.Commit, more bool, err error) *CIGit_CommitsOffBranches_Call { | |||
| 219 | + | _c.Call.Return(commits, more, err) | |||
| 220 | + | return _c | |||
| 221 | + | } | |||
| 222 | + | ||||
| 223 | + | func (_c *CIGit_CommitsOffBranches_Call) RunAndReturn(run func(ctx context.Context, repo domain.RepoName, head domain.ObjectID, limit int) ([]domain.Commit, bool, error)) *CIGit_CommitsOffBranches_Call { | |||
| 224 | + | _c.Call.Return(run) | |||
| 225 | + | return _c | |||
| 226 | + | } | |||