-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from dailymotion/repos-discovery
feat: discover repos from github query or env var
- Loading branch information
Showing
21 changed files
with
1,341 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package repository | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
"github.com/imdario/mergo" | ||
) | ||
|
||
func discoverRepositoriesFromEnvironment(ctx context.Context, envVar string, params map[string]string, githubToken string) ([]Repository, error) { | ||
separator := params["sep"] | ||
if len(separator) == 0 { | ||
separator = " " | ||
} | ||
delete(params, "sep") | ||
|
||
envValue := os.Getenv(envVar) | ||
repoNames := strings.Split(envValue, separator) | ||
|
||
if len(repoNames) == 0 { | ||
return nil, nil | ||
} | ||
if len(repoNames) == 1 && len(repoNames[0]) == 0 { | ||
return nil, nil | ||
} | ||
|
||
repos, err := Parse(ctx, repoNames, githubToken) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse %v: %w", repoNames, err) | ||
} | ||
|
||
for i := range repos { | ||
err = mergo.Merge(&repos[i].Params, params) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to merge params for repo %v: %w", repos[i], err) | ||
} | ||
} | ||
|
||
return repos, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package repository | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestDiscoverRepositoriesFromEnvironment(t *testing.T) { | ||
t.Parallel() | ||
tests := []struct { | ||
name string | ||
envVarValue string | ||
params map[string]string | ||
expected []Repository | ||
expectedErrorMsg string | ||
}{ | ||
{ | ||
name: "empty input", | ||
}, | ||
{ | ||
name: "invalid input", | ||
envVarValue: "whatever", | ||
expectedErrorMsg: "failed to parse [whatever]: invalid syntax for whatever: found 0 matches instead of 4: []", | ||
}, | ||
{ | ||
name: "single repository without parameters", | ||
envVarValue: "dailymotion/octopilot", | ||
expected: []Repository{ | ||
{ | ||
Owner: "dailymotion", | ||
Name: "octopilot", | ||
Params: map[string]string{}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "multiple repositories without parameters", | ||
envVarValue: "dailymotion/octopilot some-owner/MyGreatRepo", | ||
expected: []Repository{ | ||
{ | ||
Owner: "dailymotion", | ||
Name: "octopilot", | ||
Params: map[string]string{}, | ||
}, | ||
{ | ||
Owner: "some-owner", | ||
Name: "MyGreatRepo", | ||
Params: map[string]string{}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "multiple repositories with custom separator", | ||
envVarValue: "dailymotion/octopilot|some-owner/MyGreatRepo", | ||
params: map[string]string{ | ||
"sep": "|", | ||
}, | ||
expected: []Repository{ | ||
{ | ||
Owner: "dailymotion", | ||
Name: "octopilot", | ||
Params: map[string]string{}, | ||
}, | ||
{ | ||
Owner: "some-owner", | ||
Name: "MyGreatRepo", | ||
Params: map[string]string{}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "single repository with a single parameter", | ||
envVarValue: "dailymotion/octopilot(draft=true)", | ||
expected: []Repository{ | ||
{ | ||
Owner: "dailymotion", | ||
Name: "octopilot", | ||
Params: map[string]string{ | ||
"draft": "true", | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "multiple repositories with multiple parameters", | ||
envVarValue: "dailymotion/octopilot(draft=true,merge=true) some-owner/MyGreatRepo(merge=false)", | ||
expected: []Repository{ | ||
{ | ||
Owner: "dailymotion", | ||
Name: "octopilot", | ||
Params: map[string]string{ | ||
"draft": "true", | ||
"merge": "true", | ||
}, | ||
}, | ||
{ | ||
Owner: "some-owner", | ||
Name: "MyGreatRepo", | ||
Params: map[string]string{ | ||
"merge": "false", | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "multiple repositories with multiple parameters with overrides", | ||
envVarValue: "dailymotion/octopilot(draft=true,merge=false) some-owner/MyGreatRepo(draft=true)", | ||
params: map[string]string{ | ||
"merge": "true", | ||
}, | ||
expected: []Repository{ | ||
{ | ||
Owner: "dailymotion", | ||
Name: "octopilot", | ||
Params: map[string]string{ | ||
"draft": "true", | ||
"merge": "false", | ||
}, | ||
}, | ||
{ | ||
Owner: "some-owner", | ||
Name: "MyGreatRepo", | ||
Params: map[string]string{ | ||
"draft": "true", | ||
"merge": "true", | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
for i := range tests { | ||
test := tests[i] | ||
t.Run(test.name, func(t *testing.T) { | ||
envVar := fmt.Sprintf("DISCOVER_FROM_ENV_%v", i) | ||
os.Setenv(envVar, test.envVarValue) | ||
defer os.Unsetenv(envVar) | ||
|
||
actual, err := discoverRepositoriesFromEnvironment(context.Background(), envVar, test.params, "") | ||
if len(test.expectedErrorMsg) > 0 { | ||
require.EqualError(t, err, test.expectedErrorMsg) | ||
assert.Empty(t, actual) | ||
} else { | ||
require.NoError(t, err) | ||
assert.Equal(t, test.expected, actual) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package repository | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/google/go-github/v28/github" | ||
) | ||
|
||
func discoverRepositoriesFromQuery(ctx context.Context, query string, params map[string]string, githubToken string) ([]Repository, error) { | ||
repos := []Repository{} | ||
ghClient := githubClient(ctx, githubToken) | ||
|
||
page := 1 | ||
for { | ||
opts := &github.SearchOptions{ | ||
ListOptions: github.ListOptions{ | ||
Page: page, | ||
PerPage: 100, | ||
}, | ||
} | ||
result, resp, err := ghClient.Search.Repositories(ctx, query, opts) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to list all repositories matching query %s on GitHub (page %d): %w", query, page, err) | ||
} | ||
|
||
for _, ghRepo := range result.Repositories { | ||
repos = append(repos, Repository{ | ||
Owner: ghRepo.Owner.GetLogin(), | ||
Name: ghRepo.GetName(), | ||
Params: params, | ||
}) | ||
} | ||
|
||
page = resp.NextPage | ||
if resp.NextPage == 0 { | ||
break | ||
} | ||
} | ||
|
||
return repos, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.