Skip to content

Commit

Permalink
refactor github/gitlab choices into Provider
Browse files Browse the repository at this point in the history
The high level goal here is to setup the provider once during
initialize. After that, all following steps will respect this
configuration.

1. created `package lib`, which now holds
  - `Provider` abstraction (for Github or Gitlab)
  - `Repo` - allows us to pass along the `Provider` configuration
2. centralized the logic to setup a Github or Gitlab client, in the
`Provider`
  • Loading branch information
nathanleiby committed Mar 21, 2021
1 parent 3ec30bf commit bc56dbb
Show file tree
Hide file tree
Showing 15 changed files with 265 additions and 193 deletions.
4 changes: 2 additions & 2 deletions cmd/clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"path/filepath"

"github.com/Clever/microplane/clone"
"github.com/Clever/microplane/initialize"
"github.com/Clever/microplane/lib"
"github.com/spf13/cobra"
)

Expand All @@ -28,7 +28,7 @@ var cloneCmd = &cobra.Command{
},
}

func cloneOneRepo(r initialize.Repo, ctx context.Context) error {
func cloneOneRepo(r lib.Repo, ctx context.Context) error {
log.Printf("cloning: %s/%s", r.Owner, r.Name)

// Prepare workdir for current step's output
Expand Down
17 changes: 9 additions & 8 deletions cmd/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/ioutil"

"github.com/Clever/microplane/initialize"
"github.com/Clever/microplane/lib"
"github.com/facebookgo/errgroup"
"github.com/spf13/cobra"
"golang.org/x/sync/semaphore"
Expand All @@ -28,18 +29,18 @@ func writeJSON(obj interface{}, path string) error {
return ioutil.WriteFile(path, b, 0644)
}

func parallelize(repos []initialize.Repo, f func(initialize.Repo, context.Context) error) error {
func parallelize(repos []lib.Repo, f func(lib.Repo, context.Context) error) error {
return parallelizeLimited(repos, f, 10)
}

// parallelize take a list of repos and applies a function (clone, plan, ...) to them
func parallelizeLimited(repos []initialize.Repo, f func(initialize.Repo, context.Context) error, parallelismLimit int64) error {
func parallelizeLimited(repos []lib.Repo, f func(lib.Repo, context.Context) error, parallelismLimit int64) error {
ctx := context.Background()
var eg errgroup.Group
parallelLimit := semaphore.NewWeighted(parallelismLimit)
for _, r := range repos {
eg.Add(1)
go func(repo initialize.Repo) {
go func(repo lib.Repo) {
parallelLimit.Acquire(ctx, 1)
defer parallelLimit.Release(1)
defer eg.Done()
Expand All @@ -57,15 +58,15 @@ func parallelizeLimited(repos []initialize.Repo, f func(initialize.Repo, context

// whichRepos determines which repos are relevant to the current command.
// It also handles the `singleRepo` flag, allowing a user to target just one repo.
func whichRepos(cmd *cobra.Command) ([]initialize.Repo, error) {
func whichRepos(cmd *cobra.Command) ([]lib.Repo, error) {
var initOutput initialize.Output
if err := loadJSON(outputPath("", "init"), &initOutput); err != nil {
return []initialize.Repo{}, err
return []lib.Repo{}, err
}

singleRepo, err := cmd.Flags().GetString("repo")
if err != nil {
return []initialize.Repo{}, err
return []lib.Repo{}, err
}

// All repos
Expand All @@ -76,9 +77,9 @@ func whichRepos(cmd *cobra.Command) ([]initialize.Repo, error) {
// Single repo
for _, r := range initOutput.Repos {
if r.Name == singleRepo {
return []initialize.Repo{r}, nil
return []lib.Repo{r}, nil
}
}
// TODO: showing valid repo names would be helpful
return []initialize.Repo{}, fmt.Errorf("%s not a targeted repo name", singleRepo)
return []lib.Repo{}, fmt.Errorf("%s not a targeted repo name", singleRepo)
}
12 changes: 6 additions & 6 deletions cmd/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import (
"sync"
"testing"

"github.com/Clever/microplane/initialize"
"github.com/Clever/microplane/lib"
"github.com/stretchr/testify/assert"
)

var total = 0
var mutex = sync.RWMutex{}

func doNothingOneRepo(r initialize.Repo, ctx context.Context) error {
func doNothingOneRepo(r lib.Repo, ctx context.Context) error {
// TODO: Write to a channel
fmt.Println("do nothing: ", r.Name)
// Side effect ... write a temp file
Expand All @@ -25,14 +25,14 @@ func doNothingOneRepo(r initialize.Repo, ctx context.Context) error {
}

func TestParallelize(t *testing.T) {
repos := []initialize.Repo{
initialize.Repo{
repos := []lib.Repo{
lib.Repo{
Name: "repo1",
},
initialize.Repo{
lib.Repo{
Name: "repo2",
},
initialize.Repo{
lib.Repo{
Name: "repo3",
},
}
Expand Down
26 changes: 18 additions & 8 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ import (
"github.com/spf13/cobra"
)

var repoProviderFlag string
var initFlagReposFile string
var repoSearch bool
var allRepos bool

var initCmd = &cobra.Command{
Use: "init [query]",
Short: "Initialize a microplane workflow",
Expand Down Expand Up @@ -95,13 +90,14 @@ See https://docs.gitlab.com/ee/user/search/advanced_search_syntax.html for more
}

output, err := initialize.Initialize(initialize.Input{
AllRepos: allRepos,
AllRepos: initAllrepos,
Query: query,
WorkDir: workDir,
Version: cliVersion,
RepoProvider: repoProviderFlag,
Provider: initProvider,
ProviderURL: initProviderURL,
ReposFromFile: initFlagReposFile,
RepoSearch: repoSearch,
RepoSearch: initRepoSearch,
})
if err != nil {
log.Fatal(err)
Expand All @@ -117,3 +113,17 @@ See https://docs.gitlab.com/ee/user/search/advanced_search_syntax.html for more
}
},
}

var initFlagReposFile string
var initRepoSearch bool
var initAllrepos bool
var initProvider string
var initProviderURL string

func init() {
initCmd.Flags().StringVarP(&initFlagReposFile, "file", "f", "", "get repos from a file instead of searching")
initCmd.Flags().BoolVar(&initRepoSearch, "repo-search", false, "get repos from a github repo search")
initCmd.Flags().BoolVar(&initAllrepos, "all-repos", false, "get all repos for a given org")
initCmd.Flags().StringVar(&initProvider, "provider", "github", "'github' or 'gitlab'")
initCmd.Flags().StringVar(&initProviderURL, "provider-url", "https://api.github.com/api/v3/", "custom URL for enterprise setups")
}
11 changes: 5 additions & 6 deletions cmd/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"strings"
"time"

"github.com/Clever/microplane/initialize"
"github.com/Clever/microplane/lib"
"github.com/Clever/microplane/merge"
"github.com/Clever/microplane/push"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -53,7 +53,7 @@ var mergeCmd = &cobra.Command{
},
}

func mergeOneRepo(r initialize.Repo, ctx context.Context) error {
func mergeOneRepo(r lib.Repo, ctx context.Context) error {
log.Printf("%s/%s - merging...", r.Owner, r.Name)

// Exit early if already merged
Expand Down Expand Up @@ -87,17 +87,16 @@ func mergeOneRepo(r initialize.Repo, ctx context.Context) error {

// Execute
input := merge.Input{
Org: r.Owner,
Repo: r.Name,
Repo: r,
PRNumber: prNumber,
CommitSHA: pushOutput.CommitSHA,
RequireReviewApproval: !mergeFlagIgnoreReviewApproval,
RequireBuildSuccess: !mergeFlagIgnoreBuildStatus,
}
var output merge.Output
if r.Provider == "gitlab" {
if r.IsGitlab() {
output, err = merge.GitlabMerge(ctx, input, repoLimiter, mergeThrottle)
} else if r.Provider == "github" {
} else if r.IsGithub() {
output, err = merge.GitHubMerge(ctx, input, repoLimiter, mergeThrottle)
} else {
log.Fatal("Provider must be github or gitlab")
Expand Down
4 changes: 2 additions & 2 deletions cmd/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"strings"

"github.com/Clever/microplane/clone"
"github.com/Clever/microplane/initialize"
"github.com/Clever/microplane/lib"
"github.com/Clever/microplane/merge"
"github.com/Clever/microplane/plan"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -75,7 +75,7 @@ mp plan -b microplaning -m 'microplane fun' -r app-service -- python /absolute/p
},
}

func planOneRepo(r initialize.Repo, ctx context.Context) error {
func planOneRepo(r lib.Repo, ctx context.Context) error {
log.Printf("planning: %s/%s", r.Owner, r.Name)

// Get previous step's output
Expand Down
11 changes: 5 additions & 6 deletions cmd/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"path/filepath"
"time"

"github.com/Clever/microplane/initialize"
"github.com/Clever/microplane/lib"
"github.com/Clever/microplane/merge"
"github.com/Clever/microplane/plan"
"github.com/Clever/microplane/push"
Expand Down Expand Up @@ -93,7 +93,7 @@ var pushCmd = &cobra.Command{
},
}

func pushOneRepo(r initialize.Repo, ctx context.Context) error {
func pushOneRepo(r lib.Repo, ctx context.Context) error {
log.Printf("pushing: %s/%s", r.Owner, r.Name)

// Exit early if already merged
Expand Down Expand Up @@ -122,21 +122,20 @@ func pushOneRepo(r initialize.Repo, ctx context.Context) error {

// Execute
input := push.Input{
RepoName: r.Name,
Repo: r,
PlanDir: planOutput.PlanDir,
WorkDir: pushWorkDir,
CommitMessage: planOutput.CommitMessage,
PRBody: prBody,
PRAssignee: prAssignee,
BranchName: planOutput.BranchName,
RepoOwner: r.Owner,
Labels: prLabels,
}
var output push.Output
var err error
if r.Provider == "gitlab" {
if r.IsGitlab() {
output, err = push.GitlabPush(ctx, input, repoLimiter, pushThrottle)
} else if r.Provider == "github" {
} else if r.IsGithub() {
output, err = push.GithubPush(ctx, input, repoLimiter, pushThrottle)
}
if err != nil {
Expand Down
15 changes: 0 additions & 15 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,6 @@ var rootCmd = &cobra.Command{
}

func init() {
if os.Getenv("GITLAB_API_TOKEN") != "" && os.Getenv("GITHUB_API_TOKEN") != "" {
log.Fatalf("GITLAB_API_TOKEN and GITHUB_API_TOKEN can't be set both")
} else if os.Getenv("GITHUB_API_TOKEN") != "" {
repoProviderFlag = "github"
} else if os.Getenv("GITLAB_API_TOKEN") != "" {
repoProviderFlag = "gitlab"
} else {
log.Fatalf(`Neither GITHUB_API_TOKEN or GITLAB_API_TOKEN env var is not set.
In order to use microplane with Github, create a token (https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) then set the env var.
In order to use microplane with Gitlab, create a token (https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) then set the env var.`)
}

rootCmd.PersistentFlags().StringP("repo", "r", "", "single repo to operate on")
rootCmd.AddCommand(cloneCmd)
rootCmd.AddCommand(docsCmd)
Expand All @@ -61,9 +49,6 @@ func init() {
rootCmd.AddCommand(statusCmd)

rootCmd.AddCommand(initCmd)
initCmd.Flags().StringVarP(&initFlagReposFile, "file", "f", "", "get repos from a file instead of searching")
initCmd.Flags().BoolVar(&repoSearch, "repo-search", false, "get repos from a github repo search")
initCmd.Flags().BoolVar(&allRepos, "all-repos", false, "get all repos for a given org")

var err error
workDir, err = filepath.Abs("./mp")
Expand Down
Loading

0 comments on commit bc56dbb

Please sign in to comment.