Skip to content

Commit 5b47424

Browse files
authored
Refactor zipfetcher and consistently use rev, not baseref (#598)
Before, sometimes we used Rev, sometimes BaseRef, which could in the worst case lead to inconsistencies. Search results might not match the fetched zip archive, or detected workspaces might differ from what's on disk in the end.
1 parent 7abfb95 commit 5b47424

28 files changed

Lines changed: 264 additions & 289 deletions

internal/batches/errors.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,3 @@ func (e IgnoredRepoSet) Append(repo *graphql.Repository) {
7777
func (e IgnoredRepoSet) HasIgnored() bool {
7878
return len(e) > 0
7979
}
80-
81-
type ValidationError struct{ Reason string }
82-
83-
func (e ValidationError) Error() string {
84-
return fmt.Sprintf("validation failed: %s", e.Reason)
85-
}

internal/batches/executor/changeset_specs.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,17 @@ import (
1313
"github.com/sourcegraph/src-cli/internal/batches/util"
1414
)
1515

16-
var errOptionalPublishedUnsupported = errors.New(`This Sourcegraph version requires the "published" field to be specified in the batch spec; upgrade to version 3.30.0 or later to be able to omit the published field and control publication from the UI.`)
16+
var errOptionalPublishedUnsupported = batcheslib.NewValidationError(errors.New(`This Sourcegraph version requires the "published" field to be specified in the batch spec; upgrade to version 3.30.0 or later to be able to omit the published field and control publication from the UI.`))
1717

1818
func createChangesetSpecs(task *Task, result executionResult, features batches.FeatureFlags) ([]*batcheslib.ChangesetSpec, error) {
19-
repo := task.Repository.Name
20-
2119
tmplCtx := &template.ChangesetTemplateContext{
2220
BatchChangeAttributes: *task.BatchChangeAttributes,
2321
Steps: template.StepsContext{
2422
Changes: result.ChangedFiles,
2523
Path: result.Path,
2624
},
2725
Outputs: result.Outputs,
28-
Repository: util.GraphQLRepoToTemplatingRepo(task.Repository),
26+
Repository: util.NewTemplatingRepo(task.Repository.Name, task.Repository.FileMatches),
2927
}
3028

3129
var authorName string
@@ -75,7 +73,7 @@ func createChangesetSpecs(task *Task, result executionResult, features batches.F
7573
newSpec := func(branch, diff string) (*batcheslib.ChangesetSpec, error) {
7674
var published interface{} = nil
7775
if task.Template.Published != nil {
78-
published = task.Template.Published.ValueWithSuffix(repo, branch)
76+
published = task.Template.Published.ValueWithSuffix(task.Repository.Name, branch)
7977

8078
// Backward compatibility: before optional published fields were
8179
// allowed, ValueWithSuffix() would fall back to false, not nil. We
@@ -93,7 +91,7 @@ func createChangesetSpecs(task *Task, result executionResult, features batches.F
9391
BaseRef: task.Repository.BaseRef(),
9492
BaseRev: task.Repository.Rev(),
9593
HeadRepository: task.Repository.ID,
96-
HeadRef: "refs/heads/" + branch,
94+
HeadRef: util.EnsureRefPrefix(branch),
9795
Title: title,
9896
Body: body,
9997
Commits: []batcheslib.GitCommitDescription{
@@ -141,16 +139,16 @@ func createChangesetSpecs(task *Task, result executionResult, features batches.F
141139
return specs, nil
142140
}
143141

144-
func groupsForRepository(repo string, transform *batcheslib.TransformChanges) []batcheslib.Group {
145-
var groups []batcheslib.Group
142+
func groupsForRepository(repoName string, transform *batcheslib.TransformChanges) []batcheslib.Group {
143+
groups := []batcheslib.Group{}
146144

147145
if transform == nil {
148146
return groups
149147
}
150148

151149
for _, g := range transform.Group {
152150
if g.Repository != "" {
153-
if g.Repository == repo {
151+
if g.Repository == repoName {
154152
groups = append(groups, g)
155153
}
156154
} else {
@@ -161,18 +159,18 @@ func groupsForRepository(repo string, transform *batcheslib.TransformChanges) []
161159
return groups
162160
}
163161

164-
func validateGroups(repo, defaultBranch string, groups []batcheslib.Group) error {
162+
func validateGroups(repoName, defaultBranch string, groups []batcheslib.Group) error {
165163
uniqueBranches := make(map[string]struct{}, len(groups))
166164

167165
for _, g := range groups {
168166
if _, ok := uniqueBranches[g.Branch]; ok {
169-
return fmt.Errorf("transformChanges would lead to multiple changesets in repository %s to have the same branch %q", repo, g.Branch)
167+
return batcheslib.NewValidationError(fmt.Errorf("transformChanges would lead to multiple changesets in repository %s to have the same branch %q", repoName, g.Branch))
170168
} else {
171169
uniqueBranches[g.Branch] = struct{}{}
172170
}
173171

174172
if g.Branch == defaultBranch {
175-
return fmt.Errorf("transformChanges group branch for repository %s is the same as branch %q in changesetTemplate", repo, defaultBranch)
173+
return batcheslib.NewValidationError(fmt.Errorf("transformChanges group branch for repository %s is the same as branch %q in changesetTemplate", repoName, defaultBranch))
176174
}
177175
}
178176

internal/batches/executor/changeset_specs_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ func TestCreateChangesetSpecs(t *testing.T) {
1717
defaultChangesetSpec := &batcheslib.ChangesetSpec{
1818
BaseRepository: testRepo1.ID,
1919

20-
BaseRef: testRepo1.DefaultBranch.Name,
21-
BaseRev: testRepo1.DefaultBranch.Target.OID,
20+
BaseRef: testRepo1.BaseRef(),
21+
BaseRev: testRepo1.Rev(),
2222
HeadRepository: testRepo1.ID,
2323
HeadRef: "refs/heads/my-branch",
2424
Title: "The title",

internal/batches/executor/coordinator.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import (
1010
"github.com/cockroachdb/errors"
1111
"github.com/hashicorp/go-multierror"
1212
batcheslib "github.com/sourcegraph/sourcegraph/lib/batches"
13+
1314
"github.com/sourcegraph/src-cli/internal/api"
1415
"github.com/sourcegraph/src-cli/internal/batches"
1516
"github.com/sourcegraph/src-cli/internal/batches/docker"
1617
"github.com/sourcegraph/src-cli/internal/batches/graphql"
1718
"github.com/sourcegraph/src-cli/internal/batches/log"
19+
"github.com/sourcegraph/src-cli/internal/batches/repozip"
1820
"github.com/sourcegraph/src-cli/internal/batches/workspace"
1921
)
2022

@@ -67,15 +69,14 @@ func NewCoordinator(opts NewCoordinatorOpts) *Coordinator {
6769
logManager := log.NewManager(opts.TempDir, opts.KeepLogs)
6870

6971
exec := newExecutor(newExecutorOpts{
70-
Fetcher: batches.NewRepoFetcher(opts.Client, opts.CacheDir, opts.CleanArchives),
71-
EnsureImage: opts.EnsureImage,
72-
Creator: opts.Creator,
73-
Logger: logManager,
74-
75-
AutoAuthorDetails: opts.Features.IncludeAutoAuthorDetails,
76-
Parallelism: opts.Parallelism,
77-
Timeout: opts.Timeout,
78-
TempDir: opts.TempDir,
72+
RepoArchiveRegistry: repozip.NewArchiveRegistry(opts.Client, opts.CacheDir, opts.CleanArchives),
73+
EnsureImage: opts.EnsureImage,
74+
Creator: opts.Creator,
75+
Logger: logManager,
76+
77+
Parallelism: opts.Parallelism,
78+
Timeout: opts.Timeout,
79+
TempDir: opts.TempDir,
7980
})
8081

8182
return &Coordinator{
@@ -290,7 +291,7 @@ func (c *Coordinator) Execute(ctx context.Context, tasks []*Task, spec *batchesl
290291
case float64:
291292
sid = strconv.FormatFloat(tid, 'f', -1, 64)
292293
default:
293-
return nil, nil, errors.Errorf("cannot convert value of type %T into a valid external ID: expected string or int", id)
294+
return nil, nil, batcheslib.NewValidationError(errors.Errorf("cannot convert value of type %T into a valid external ID: expected string or int", id))
294295
}
295296

296297
specs = append(specs, &batcheslib.ChangesetSpec{

internal/batches/executor/coordinator_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717

1818
"github.com/sourcegraph/src-cli/internal/batches/graphql"
1919
"github.com/sourcegraph/src-cli/internal/batches/mock"
20+
"github.com/sourcegraph/src-cli/internal/batches/util"
2021
)
2122

2223
func TestCoordinator_Execute(t *testing.T) {
@@ -31,7 +32,7 @@ func TestCoordinator_Execute(t *testing.T) {
3132
BaseRef: repo.BaseRef(),
3233
BaseRev: repo.Rev(),
3334
HeadRepository: repo.ID,
34-
HeadRef: "refs/heads/" + testChangesetTemplate.Branch,
35+
HeadRef: util.EnsureRefPrefix(testChangesetTemplate.Branch),
3536
Title: testChangesetTemplate.Title,
3637
Body: testChangesetTemplate.Body,
3738
Commits: []batcheslib.GitCommitDescription{
@@ -217,7 +218,7 @@ func TestCoordinator_Execute(t *testing.T) {
217218
spec.Commits[0].Diff = nestedChangesDiffSubdirC
218219
}),
219220
buildSpecFor(testRepo2, func(spec *batcheslib.ChangesetSpec) {
220-
spec.HeadRef = "refs/heads/" + testChangesetTemplate.Branch
221+
spec.HeadRef = util.EnsureRefPrefix(testChangesetTemplate.Branch)
221222
spec.Commits[0].Diff = nestedChangesDiffSubdirA
222223
}),
223224
},

internal/batches/executor/execution_cache.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/cockroachdb/errors"
1414
batcheslib "github.com/sourcegraph/sourcegraph/lib/batches"
15+
"github.com/sourcegraph/src-cli/internal/batches/util"
1516
)
1617

1718
func UserCacheDir() (string, error) {
@@ -101,7 +102,9 @@ func (key StepsCacheKey) Key() (string, error) {
101102
return fmt.Sprintf("%s-step-%d", hash, key.StepIndex), err
102103
}
103104

104-
func (key StepsCacheKey) Slug() string { return key.Repository.Slug() }
105+
func (key StepsCacheKey) Slug() string {
106+
return util.SlugForRepo(key.Repository.Name, key.Repository.Rev())
107+
}
105108

106109
// TaskCacheKey implements the CacheKeyer interface for a Task and all its
107110
// Steps.
@@ -132,7 +135,9 @@ func (key TaskCacheKey) Key() (string, error) {
132135
return base64.RawURLEncoding.EncodeToString(hash[:16]), nil
133136
}
134137

135-
func (key TaskCacheKey) Slug() string { return key.Repository.Slug() }
138+
func (key TaskCacheKey) Slug() string {
139+
return util.SlugForRepo(key.Repository.Name, key.Repository.Rev())
140+
}
136141

137142
type ExecutionCache interface {
138143
Get(ctx context.Context, key CacheKeyer) (result executionResult, found bool, err error)

internal/batches/executor/executor.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ import (
1010
"github.com/cockroachdb/errors"
1111
"github.com/neelance/parallel"
1212

13-
"github.com/sourcegraph/src-cli/internal/batches"
1413
"github.com/sourcegraph/src-cli/internal/batches/log"
14+
"github.com/sourcegraph/src-cli/internal/batches/repozip"
15+
"github.com/sourcegraph/src-cli/internal/batches/util"
1516
"github.com/sourcegraph/src-cli/internal/batches/workspace"
1617
)
1718

@@ -50,16 +51,15 @@ type taskResult struct {
5051

5152
type newExecutorOpts struct {
5253
// Dependencies
53-
Creator workspace.Creator
54-
Fetcher batches.RepoFetcher
55-
EnsureImage imageEnsurer
56-
Logger log.LogManager
54+
Creator workspace.Creator
55+
RepoArchiveRegistry repozip.ArchiveRegistry
56+
EnsureImage imageEnsurer
57+
Logger log.LogManager
5758

5859
// Config
59-
AutoAuthorDetails bool
60-
Parallelism int
61-
Timeout time.Duration
62-
TempDir string
60+
Parallelism int
61+
Timeout time.Duration
62+
TempDir string
6363
}
6464

6565
type executor struct {
@@ -144,7 +144,7 @@ func (x *executor) do(ctx context.Context, task *Task, ui TaskExecutionUI) (err
144144
ui.TaskStarted(task)
145145

146146
// Let's set up our logging.
147-
log, err := x.opts.Logger.AddTask(task.Repository.SlugForPath(task.Path))
147+
log, err := x.opts.Logger.AddTask(util.SlugForPathInRepo(task.Repository.Name, task.Repository.Rev(), task.Path))
148148
if err != nil {
149149
return errors.Wrap(err, "creating log file")
150150
}
@@ -160,8 +160,8 @@ func (x *executor) do(ctx context.Context, task *Task, ui TaskExecutionUI) (err
160160
log.Close()
161161
}()
162162

163-
// Now checkout the archive
164-
task.Archive = x.opts.Fetcher.Checkout(task.Repository, task.ArchivePathToFetch())
163+
// Now checkout the archive.
164+
task.Archive = x.opts.RepoArchiveRegistry.Checkout(repozip.RepoRevision{RepoName: task.Repository.Name, Commit: task.Repository.Rev()}, task.ArchivePathToFetch())
165165

166166
// Set up our timeout.
167167
runCtx, cancel := context.WithTimeout(ctx, x.opts.Timeout)

0 commit comments

Comments
 (0)