Skip to content

Commit

Permalink
Refactor project layout for better go build and get ergonomics (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
zackproser authored Apr 26, 2021
1 parent 21ac6e3 commit b55137d
Show file tree
Hide file tree
Showing 41 changed files with 575 additions and 433 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
- checkout
- run:
<<: *install_gruntwork_utils
- run: build-go-binaries --app-name git-xargs --src-path ./cmd --dest-path bin --ld-flags "-X main.VERSION=$CIRCLE_TAG"
- run: build-go-binaries --app-name git-xargs --src-path ./ --dest-path bin --ld-flags "-X main.VERSION=$CIRCLE_TAG"
- run: cd bin && sha256sum * > SHA256SUMS
- run: upload-github-release-assets bin/*
workflows:
Expand Down
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
git-xargs
test-repo/
.idea
*.iml
*.iml
git-xargs
155 changes: 95 additions & 60 deletions README.md

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions cmd/auth.go → auth/auth.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package main
package auth

import (
"context"
"os"

"github.com/google/go-github/v32/github"
"github.com/gruntwork-io/git-xargs/types"
"github.com/gruntwork-io/go-commons/errors"

"golang.org/x/oauth2"
Expand Down Expand Up @@ -39,7 +40,7 @@ func NewClient(client *github.Client) GithubClient {
}

// configureGithubClient creates a Github API client using the user-supplied GITHUB_OAUTH_TOKEN and return the configured Github client
func configureGithubClient() GithubClient {
func ConfigureGithubClient() GithubClient {
// Ensure user provided a GITHUB_OAUTH_TOKEN
GithubOauthToken := os.Getenv("GITHUB_OAUTH_TOKEN")

Expand All @@ -56,9 +57,9 @@ func configureGithubClient() GithubClient {
}

// ensureGithubOauthTokenSet is a sanity check that a value is exported for GITHUB_OAUTH_TOKEN
func ensureGithubOauthTokenSet() error {
func EnsureGithubOauthTokenSet() error {
if os.Getenv("GITHUB_OAUTH_TOKEN") == "" {
return errors.WithStackTrace(NoGithubOauthTokenProvidedErr{})
return errors.WithStackTrace(types.NoGithubOauthTokenProvidedErr{})
}
return nil
}
6 changes: 3 additions & 3 deletions cmd/auth_test.go → auth/auth_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package auth

import (
"os"
Expand All @@ -11,7 +11,7 @@ import (
func TestConfigureGithubClient(t *testing.T) {
t.Parallel()

client := configureGithubClient()
client := ConfigureGithubClient()
assert.NotNil(t, client)
}

Expand All @@ -24,6 +24,6 @@ func TestNoGithubOAuthTokenPassed(t *testing.T) {

os.Setenv("GITHUB_OAUTH_TOKEN", "")

err := ensureGithubOauthTokenSet()
err := EnsureGithubOauthTokenSet()
assert.Error(t, err)
}
70 changes: 19 additions & 51 deletions cmd/git-xargs.go
Original file line number Diff line number Diff line change
@@ -1,57 +1,25 @@
package main
package cmd

import (
"bufio"
"github.com/gruntwork-io/go-commons/errors"
"github.com/gruntwork-io/go-commons/logging"
"github.com/urfave/cli"
"io"
"os"
"strings"
)

// GitXargsConfig is the internal representation of a given git-xargs run as specified by the user
type GitXargsConfig struct {
DryRun bool
SkipPullRequests bool
BranchName string
CommitMessage string
PullRequestTitle string
PullRequestDescription string
ReposFile string
GithubOrg string
RepoSlice []string
RepoFromStdIn []string
Args []string
GithubClient GithubClient
GitClient GitClient
Stats *RunStats
}

// NewGitXargsConfig sets reasonable defaults for a GitXargsConfig and returns a pointer to a the config
func NewGitXargsConfig() *GitXargsConfig {
return &GitXargsConfig{
DryRun: false,
SkipPullRequests: false,
BranchName: "",
CommitMessage: DefaultCommitMessage,
PullRequestTitle: DefaultPullRequestTitle,
PullRequestDescription: DefaultPullRequestDescription,
ReposFile: "",
GithubOrg: "",
RepoSlice: []string{},
RepoFromStdIn: []string{},
Args: []string{},
GithubClient: configureGithubClient(),
GitClient: NewGitClient(GitProductionProvider{}),
Stats: NewStatsTracker(),
}
}
"github.com/gruntwork-io/git-xargs/auth"
"github.com/gruntwork-io/git-xargs/config"
gitxargs_io "github.com/gruntwork-io/git-xargs/io"
"github.com/gruntwork-io/git-xargs/repository"
"github.com/gruntwork-io/git-xargs/types"
"github.com/gruntwork-io/go-commons/errors"
"github.com/gruntwork-io/go-commons/logging"
"github.com/urfave/cli"
)

// parseGitXargsConfig accepts a urfave cli context and binds its values
// to an internal representation of the data supplied by the user
func parseGitXargsConfig(c *cli.Context) (*GitXargsConfig, error) {
config := NewGitXargsConfig()
func parseGitXargsConfig(c *cli.Context) (*config.GitXargsConfig, error) {
config := config.NewGitXargsConfig()
config.DryRun = c.Bool("dry-run")
config.SkipPullRequests = c.Bool("skip-pull-requests")
config.BranchName = c.String("branch-name")
Expand Down Expand Up @@ -117,14 +85,14 @@ func parseSliceFromReader(reader io.Reader) ([]string, error) {

// handleRepoProcessing encapsulates the main processing logic for the supplied repos and printing the run report that
// is built up throughout the processing
func handleRepoProcessing(config *GitXargsConfig) error {
func handleRepoProcessing(config *config.GitXargsConfig) error {
// Track whether or not pull requests were skipped
config.Stats.SetSkipPullRequests(config.SkipPullRequests)

// Update raw command supplied
config.Stats.SetCommand(config.Args)

if err := OperateOnRepos(config); err != nil {
if err := repository.OperateOnRepos(config); err != nil {
return err
}

Expand All @@ -138,24 +106,24 @@ func handleRepoProcessing(config *GitXargsConfig) error {
// 1. An exported GITHUB_OAUTH_TOKEN
// 2. Arguments passed to the binary itself which should be executed against the targeted repos
// 3. At least one of the three valid methods for selecting repositories
func sanityCheckInputs(config *GitXargsConfig) error {
if err := ensureGithubOauthTokenSet(); err != nil {
func sanityCheckInputs(config *config.GitXargsConfig) error {
if err := auth.EnsureGithubOauthTokenSet(); err != nil {
return err
}

if len(config.Args) < 1 {
return errors.WithStackTrace(NoArgumentsPassedErr{})
return errors.WithStackTrace(types.NoArgumentsPassedErr{})
}

if err := ensureValidOptionsPassed(config); err != nil {
if err := gitxargs_io.EnsureValidOptionsPassed(config); err != nil {
return errors.WithStackTrace(err)
}

return nil
}

// runGitXargs is the urfave cli app's Action that is called when the user executes the binary
func runGitXargs(c *cli.Context) error {
func RunGitXargs(c *cli.Context) error {
// If someone calls us with no args at all, show the help text and exit
if !c.Args().Present() {
return cli.ShowAppHelp(c)
Expand Down
21 changes: 12 additions & 9 deletions cmd/git-xargs_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package main
package cmd

import (
"github.com/stretchr/testify/require"
"strings"
"testing"

"github.com/gruntwork-io/git-xargs/config"
"github.com/gruntwork-io/git-xargs/mocks"
"github.com/stretchr/testify/require"

"github.com/stretchr/testify/assert"
)

Expand All @@ -13,13 +16,13 @@ import (
func TestHandleRepoProcessing(t *testing.T) {
t.Parallel()

config := NewGitXargsTestConfig()
config.ReposFile = "./_testdata/good-test-repos.txt"
config.BranchName = "test-branch-name"
config.CommitMessage = "test-commit-name"
config.Args = []string{"touch", "test.txt"}
config.GithubClient = configureMockGithubClient()
err := handleRepoProcessing(config)
testConfig := config.NewGitXargsTestConfig()
testConfig.ReposFile = "../data/test/good-test-repos.txt"
testConfig.BranchName = "test-branch-name"
testConfig.CommitMessage = "test-commit-name"
testConfig.Args = []string{"touch", "test.txt"}
testConfig.GithubClient = mocks.ConfigureMockGithubClient()
err := handleRepoProcessing(testConfig)

assert.NoError(t, err)
}
Expand Down
16 changes: 0 additions & 16 deletions cmd/git_test.go

This file was deleted.

33 changes: 0 additions & 33 deletions cmd/helper_test.go

This file was deleted.

14 changes: 0 additions & 14 deletions cmd/validate-input.go

This file was deleted.

24 changes: 12 additions & 12 deletions cmd/common.go → common/common.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package common

import "github.com/urfave/cli"

Expand All @@ -18,41 +18,41 @@ const (
)

var (
genericGithubOrgFlag = cli.StringFlag{
GenericGithubOrgFlag = cli.StringFlag{
Name: GithubOrgFlagName,
Usage: "The Github organization to fetch all repositories from.",
}
genericDryRunFlag = cli.BoolFlag{
GenericDryRunFlag = cli.BoolFlag{
Name: DryRunFlagName,
Usage: "When dry-run is set to true, no local branch changes will pushed and no pull requests will be opened.",
}
genericSkipPullRequestFlag = cli.BoolFlag{
GenericSkipPullRequestFlag = cli.BoolFlag{
Name: SkipPullRequestsFlagName,
Usage: "When skip-pull-requests is set to true, no pull requests will be opened. All changes will be committed and pushed to the specified branch directly.",
}
genericRepoFlag = cli.StringSliceFlag{
GenericRepoFlag = cli.StringSliceFlag{
Name: RepoFlagName,
Usage: "A single repo name to run the command on in the format of <github-organization/repo-name>. Can be invoked multiple times with different repo names",
}
genericRepoFileFlag = cli.StringFlag{
GenericRepoFileFlag = cli.StringFlag{
Name: ReposFileFlagName,
Usage: "The path to a file containing repos, one per line in the format of <github-organization/repo-name>",
}
genericBranchFlag = cli.StringFlag{
Name: BranchFlagName,
Usage: "The name of the branch on which changes will be made",
GenericBranchFlag = cli.StringFlag{
Name: BranchFlagName,
Usage: "The name of the branch on which changes will be made",
}
genericCommitMessageFlag = cli.StringFlag{
GenericCommitMessageFlag = cli.StringFlag{
Name: CommitMessageFlagName,
Usage: "The commit message to use when creating commits from changes introduced by your command or script",
Value: DefaultCommitMessage,
}
genericPullRequestTitleFlag = cli.StringFlag{
GenericPullRequestTitleFlag = cli.StringFlag{
Name: PullRequestTitleFlagName,
Usage: "The title to add to pull requests opened by git-xargs",
Value: DefaultPullRequestTitle,
}
genericPullRequestDescriptionFlag = cli.StringFlag{
GenericPullRequestDescriptionFlag = cli.StringFlag{
Name: PullRequestDescriptionFlagName,
Usage: "The description to add to pull requests opened by git-xargs",
Value: DefaultPullRequestDescription,
Expand Down
Loading

0 comments on commit b55137d

Please sign in to comment.