Skip to content

Commit

Permalink
Add a repository filter to the transformChanges.Group
Browse files Browse the repository at this point in the history
  • Loading branch information
mrnugget committed Dec 10, 2020
1 parent 81d9d18 commit a5269a2
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 22 deletions.
5 changes: 3 additions & 2 deletions internal/campaigns/campaign_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ type TransformChanges struct {
}

type Group struct {
Directory string `json:"directory,omitempty" yaml:"directory"`
Branch string `json:"branch,omitempty" yaml:"branch"`
Directory string `json:"directory,omitempty" yaml:"directory"`
Branch string `json:"branch,omitempty" yaml:"branch"`
Repository string `json:"repository,omitempty" yaml:"repository"`
}

func ParseCampaignSpec(data []byte, features featureFlags) (*CampaignSpec, error) {
Expand Down
38 changes: 27 additions & 11 deletions internal/campaigns/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"
"os/exec"
"sort"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -438,8 +437,9 @@ func createChangesetSpecs(task *Task, completeDiff string, features featureFlags

var specs []*ChangesetSpec

if task.TransformChanges != nil && len(task.TransformChanges.Group) > 0 {
diffsByBranch, err := groupFileDiffs(completeDiff, task.Template.Branch, task.TransformChanges.Group)
groups := groupsForRepository(task.Repository.Name, task.TransformChanges)
if len(groups) != 0 {
diffsByBranch, err := groupFileDiffs(completeDiff, task.Template.Branch, groups)
if err != nil {
return specs, errors.Wrap(err, "grouping diffs failed")
}
Expand All @@ -455,6 +455,26 @@ func createChangesetSpecs(task *Task, completeDiff string, features featureFlags
return specs, nil
}

func groupsForRepository(repo string, transform *TransformChanges) []Group {
var groups []Group

if transform == nil {
return groups
}

for _, g := range transform.Group {
if g.Repository != "" {
if g.Repository == repo {
groups = append(groups, g)
}
} else {
groups = append(groups, g)
}
}

return groups
}

func groupFileDiffs(completeDiff, defaultBranch string, groups []Group) (map[string]string, error) {
fileDiffs, err := diff.ParseMultiFileDiff([]byte(completeDiff))
if err != nil {
Expand All @@ -463,16 +483,13 @@ func groupFileDiffs(completeDiff, defaultBranch string, groups []Group) (map[str

// Housekeeping: we setup these two datastructures so we can
// - access the group.Branch by the directory for which they should be used
// - check against the given directories, starting with the longest one.
// - check against the given directories, in order.
branchesByDirectory := make(map[string]string, len(groups))
dirsByLen := make([]string, len(branchesByDirectory))
dirs := make([]string, len(branchesByDirectory))
for _, g := range groups {
branchesByDirectory[g.Directory] = g.Branch
dirsByLen = append(dirsByLen, g.Directory)
dirs = append(dirs, g.Directory)
}
sort.Slice(dirsByLen, func(i, j int) bool {
return len(dirsByLen[i]) > len(dirsByLen[j])
})

byBranch := make(map[string][]*diff.FileDiff, len(groups))
byBranch[defaultBranch] = []*diff.FileDiff{}
Expand All @@ -487,10 +504,9 @@ func groupFileDiffs(completeDiff, defaultBranch string, groups []Group) (map[str
// .. we check whether it matches one of the given directories in the
// group transformations, starting with the longest one first:
var matchingDir string
for _, d := range dirsByLen {
for _, d := range dirs {
if strings.Contains(name, d) {
matchingDir = d
break
}
}

Expand Down
33 changes: 24 additions & 9 deletions internal/campaigns/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,20 @@ func TestExecutor_Integration(t *testing.T) {
},
{
name: "transform group",
repos: []*graphql.Repository{srcCLIRepo},
repos: []*graphql.Repository{srcCLIRepo, sourcegraphRepo},
archives: []mockRepoArchive{
{repo: srcCLIRepo, files: map[string]string{
"README.md": "# Welcome to the README\n",
"a/a.go": "package a",
"a/b/b.go": "package b",
"a/b/c/c.go": "package c",
}},
{repo: sourcegraphRepo, files: map[string]string{
"README.md": "# Welcome to the README\n",
"a/a.go": "package a",
"a/b/b.go": "package b",
"a/b/c/c.go": "package c",
}},
},
steps: []Step{
{Run: `echo 'var a = 1' >> a/a.go`, Container: "doesntmatter:13"},
Expand All @@ -166,6 +172,7 @@ func TestExecutor_Integration(t *testing.T) {
transform: &TransformChanges{
Group: []Group{
{Directory: "a/b/c", Branch: "in-directory-c"},
{Directory: "a/b", Branch: "in-directory-b", Repository: sourcegraphRepo.Name},
},
},
wantFilesChanged: filesByRepository{
Expand All @@ -178,6 +185,15 @@ func TestExecutor_Integration(t *testing.T) {
"a/b/c/c.go",
},
},
sourcegraphRepo.ID: filesByBranch{
changesetTemplateBranch: []string{
"a/a.go",
},
"in-directory-b": []string{
"a/b/b.go",
"a/b/c/c.go",
},
},
},
},
}
Expand Down Expand Up @@ -384,9 +400,10 @@ index 0000000..1bd79fb
{
diff: allDiffs,
groups: []Group{
{Directory: "1/2/3", Branch: "only-in-3"},
{Directory: "1/2", Branch: "only-in-2"},
// Each diff is matched against each directory, last match wins
{Directory: "1", Branch: "only-in-1"},
{Directory: "1/2", Branch: "only-in-2"},
{Directory: "1/2/3", Branch: "only-in-3"},
},
want: map[string]string{
"my-default-branch": "",
Expand All @@ -398,16 +415,14 @@ index 0000000..1bd79fb
{
diff: allDiffs,
groups: []Group{
// Different order than above
{Directory: "1", Branch: "only-in-1"},
{Directory: "1/2", Branch: "only-in-2"},
// Last one wins here, because it matches every diff
{Directory: "1/2/3", Branch: "only-in-3"},
{Directory: "1/2", Branch: "only-in-2"},
{Directory: "1", Branch: "only-in-1"},
},
want: map[string]string{
"my-default-branch": "",
"only-in-3": diff3,
"only-in-2": diff2,
"only-in-1": diff1,
"only-in-1": diff1 + diff2 + diff3,
},
},
{
Expand Down
5 changes: 5 additions & 0 deletions schema/campaign_spec.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@
"branch": {
"type": "string",
"description": "The branch on the repository to propose changes to. If unset, the repository's default branch is used."
},
"repository": {
"type": "string",
"description": "Only apply this transformation in the repository with this name (as it is known to Sourcegraph).",
"examples": ["github.com/foo/bar"]
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions schema/campaign_spec_stringdata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a5269a2

Please sign in to comment.