Skip to content

Commit

Permalink
Query and use the repository.branch when defined in spec
Browse files Browse the repository at this point in the history
  • Loading branch information
mrnugget committed Nov 23, 2020
1 parent ac7ec26 commit e0fdeda
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 18 deletions.
4 changes: 4 additions & 0 deletions cmd/src/campaigns_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ func campaignsExecute(ctx context.Context, out *output.Output, svc *campaigns.Se
campaignsCompletePending(pending, "Resolved repositories")
}

for _, r := range repos {
fmt.Printf("Name=%s, BaseRef()=%s, Rev()=%s\n", r.Name, r.BaseRef(), r.Rev())
}

p := newCampaignProgressPrinter(out, *verbose, opts.Parallelism)
specs, err := svc.ExecuteCampaignSpec(ctx, repos, executor, campaignSpec, p.PrintStatuses)
if err != nil {
Expand Down
5 changes: 2 additions & 3 deletions internal/campaigns/archive_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,11 @@ func fetchRepositoryArchive(ctx context.Context, client api.Client, repo *graphq
}

func repositoryZipArchivePath(repo *graphql.Repository) string {
return path.Join("", repo.Name+"@"+repo.DefaultBranch.Name, "-", "raw")
return path.Join("", repo.Name+"@"+repo.BaseRef(), "-", "raw")
}

func localRepositoryZipArchivePath(dir string, repo *graphql.Repository) string {
ref := repo.DefaultBranch.Target.OID
return filepath.Join(dir, fmt.Sprintf("%s-%s.zip", repo.Slug(), ref))
return filepath.Join(dir, fmt.Sprintf("%s-%s.zip", repo.Slug(), repo.Rev()))
}

func unzip(zipFile, dest string) error {
Expand Down
44 changes: 43 additions & 1 deletion internal/campaigns/archive_fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestWorkspaceCreator_Create(t *testing.T) {
repo := &graphql.Repository{
ID: "src-cli",
Name: "github.com/sourcegraph/src-cli",
DefaultBranch: &graphql.Branch{Name: "main", Target: struct{ OID string }{OID: "d34db33f"}},
DefaultBranch: &graphql.Branch{Name: "main", Target: graphql.Target{OID: "d34db33f"}},
}

archive := mockRepoArchive{
Expand Down Expand Up @@ -156,6 +156,48 @@ func TestWorkspaceCreator_Create(t *testing.T) {
t.Fatalf("zip file in temp dir was not cleaned up")
}
})

t.Run("non-default branch", func(t *testing.T) {
otherBranchOID := "f00b4r"
repo := &graphql.Repository{
ID: "src-cli-with-non-main-branch",
Name: "github.com/sourcegraph/src-cli",
DefaultBranch: &graphql.Branch{Name: "main", Target: graphql.Target{OID: "d34db33f"}},
Branches: struct {
Nodes []*graphql.Branch
}{
Nodes: []*graphql.Branch{
&graphql.Branch{Name: "other-branch", Target: graphql.Target{OID: otherBranchOID}},
},
},
}

archive := mockRepoArchive{repo: repo, files: map[string]string{}}

ts := httptest.NewServer(newZipArchivesMux(t, nil, archive))
defer ts.Close()

var clientBuffer bytes.Buffer
client := api.NewClient(api.ClientOpts{Endpoint: ts.URL, Out: &clientBuffer})

testTempDir := workspaceTmpDir(t)

creator := &WorkspaceCreator{dir: testTempDir, client: client}

_, err := creator.Create(context.Background(), repo)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}

wantZipFile := "github.com-sourcegraph-src-cli-" + otherBranchOID + ".zip"
ok, err := dirContains(creator.dir, wantZipFile)
if err != nil {
t.Fatal(err)
}
if !ok {
t.Fatalf("temp dir doesnt contain zip file")
}
})
}

func TestMkdirAll(t *testing.T) {
Expand Down
15 changes: 12 additions & 3 deletions internal/campaigns/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,23 @@ func TestExecutor_Integration(t *testing.T) {
srcCLIRepo := &graphql.Repository{
ID: "src-cli",
Name: "github.com/sourcegraph/src-cli",
DefaultBranch: &graphql.Branch{Name: "main", Target: struct{ OID string }{OID: "d34db33f"}},
DefaultBranch: &graphql.Branch{Name: "main", Target: graphql.Target{OID: "d34db33f"}},
}
sourcegraphRepo := &graphql.Repository{
ID: "sourcegraph",
Name: "github.com/sourcegraph/sourcegraph",
DefaultBranch: &graphql.Branch{
Name: "main",
Target: struct{ OID string }{OID: "f00b4r3r"},
Target: graphql.Target{OID: "f00b4r3r"},
},

Branches: graphql.Branches{
Nodes: []*graphql.Branch{
&graphql.Branch{
Name: "other-branch",
Target: graphql.Target{OID: "0therbr4nch"},
},
},
},
}

Expand Down Expand Up @@ -220,7 +229,7 @@ func newZipArchivesMux(t *testing.T, callback http.HandlerFunc, archives ...mock

for _, archive := range archives {
files := archive.files
path := fmt.Sprintf("/%s@%s/-/raw", archive.repo.Name, archive.repo.DefaultBranch.Name)
path := fmt.Sprintf("/%s@%s/-/raw", archive.repo.Name, archive.repo.BaseRef())

downloadName := filepath.Base(archive.repo.Name)
mediaType := mime.FormatMediaType("Attachment", map[string]string{
Expand Down
51 changes: 49 additions & 2 deletions internal/campaigns/graphql/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,73 @@ fragment repositoryFields on Repository {
}
`

const RepositoryWithBranchFragment = `
fragment repositoryFieldsWithBranch on Repository {
id
name
url
externalRepository {
serviceType
}
defaultBranch {
name
target {
oid
}
}
branches(query: $branch, first: 1) @include(if:$queryBranch){
nodes {
name
target {
oid
}
}
}
}
`

type Target struct {
OID string
}

type Branch struct {
Name string
Target struct{ OID string }
Target Target
}

type Branches struct {
Nodes []*Branch
}

type Repository struct {
ID string
Name string
URL string
ExternalRepository struct{ ServiceType string }
DefaultBranch *Branch

DefaultBranch *Branch
Branches Branches

FileMatches map[string]bool
}

func (r *Repository) HasBranch() bool {
return r.DefaultBranch != nil || len(r.Branches.Nodes) != 0
}

func (r *Repository) BaseRef() string {
if len(r.Branches.Nodes) != 0 {
return r.Branches.Nodes[0].Name
}

return r.DefaultBranch.Name
}

func (r *Repository) Rev() string {
if len(r.Branches.Nodes) != 0 {
return r.Branches.Nodes[0].Target.OID
}

return r.DefaultBranch.Target.OID
}

Expand Down
57 changes: 48 additions & 9 deletions internal/campaigns/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,7 @@ func (svc *Service) ResolveNamespace(ctx context.Context, namespace string) (str
}

func (svc *Service) ResolveRepositories(ctx context.Context, spec *CampaignSpec) ([]*graphql.Repository, error) {
final := []*graphql.Repository{}
seen := map[string]struct{}{}
seen := map[string]*graphql.Repository{}
unsupported := UnsupportedRepoSet{}

// TODO: this could be trivially parallelised in the future.
Expand All @@ -375,11 +374,12 @@ func (svc *Service) ResolveRepositories(ctx context.Context, spec *CampaignSpec)
}

for _, repo := range repos {
if _, ok := seen[repo.ID]; !ok {
if repo.DefaultBranch == nil {
continue
}
seen[repo.ID] = struct{}{}
if !repo.HasBranch() {
continue
}

if other, ok := seen[repo.ID]; !ok {
seen[repo.ID] = repo
switch st := strings.ToLower(repo.ExternalRepository.ServiceType); st {
case "github", "gitlab", "bitbucketserver":
default:
Expand All @@ -388,12 +388,19 @@ func (svc *Service) ResolveRepositories(ctx context.Context, spec *CampaignSpec)
continue
}
}

final = append(final, repo)
} else {
// If we've already seen this repository, we overwrite the
// Branches field with the latest value we have
other.Branches = repo.Branches
}
}
}

final := make([]*graphql.Repository, 0, len(seen))
for _, repo := range seen {
final = append(final, repo)
}

if unsupported.hasUnsupported() && !svc.allowUnsupported {
return final, unsupported
}
Expand All @@ -404,6 +411,12 @@ func (svc *Service) ResolveRepositories(ctx context.Context, spec *CampaignSpec)
func (svc *Service) ResolveRepositoriesOn(ctx context.Context, on *OnQueryOrRepository) ([]*graphql.Repository, error) {
if on.RepositoriesMatchingQuery != "" {
return svc.resolveRepositorySearch(ctx, on.RepositoriesMatchingQuery)
} else if on.Repository != "" && on.Branch != "" {
repo, err := svc.resolveRepositoryNameAndBranch(ctx, on.Repository, on.Branch)
if err != nil {
return nil, err
}
return []*graphql.Repository{repo}, nil
} else if on.Repository != "" {
repo, err := svc.resolveRepositoryName(ctx, on.Repository)
if err != nil {
Expand Down Expand Up @@ -438,6 +451,32 @@ func (svc *Service) resolveRepositoryName(ctx context.Context, name string) (*gr
return result.Repository, nil
}

const repositoryNameAndBranchQuery = `
query Repository($name: String!, $queryBranch: Boolean!, $branch: String!) {
repository(name: $name) {
...repositoryFieldsWithBranch
}
}
` + graphql.RepositoryWithBranchFragment

func (svc *Service) resolveRepositoryNameAndBranch(ctx context.Context, name, branch string) (*graphql.Repository, error) {
var result struct{ Repository *graphql.Repository }
if ok, err := svc.client.NewRequest(repositoryNameAndBranchQuery, map[string]interface{}{
"name": name,
"queryBranch": true,
"branch": branch,
}).Do(ctx, &result); err != nil || !ok {
return nil, err
}
if result.Repository == nil {
return nil, errors.New("no repository found")
}
if len(result.Repository.Branches.Nodes) == 0 {
return nil, fmt.Errorf("no branch matching %q found for repository %s", branch, name)
}
return result.Repository, nil
}

// TODO: search result alerts.
const repositorySearchQuery = `
query ChangesetRepos(
Expand Down

0 comments on commit e0fdeda

Please sign in to comment.