Skip to content

Commit

Permalink
Split config to user and repo configs
Browse files Browse the repository at this point in the history
commit-id:3b97470d
  • Loading branch information
ejoffe committed Jul 7, 2021
1 parent 6a7a32d commit 1e78e94
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 78 deletions.
5 changes: 0 additions & 5 deletions .spr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,3 @@ githubRepoOwner: ejoffe
githubRepoName: spr
requireChecks: true
requireApproval: false
showPRLink: true
cleanupRemoteBranch: true
logGitCommands: false
logGitHubCalls: false
statusBitsHeader: false
35 changes: 8 additions & 27 deletions cmd/spr/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func init() {
}

func main() {
gitcmd := realgit.NewGitCmd(&config.Config{})
gitcmd := realgit.NewGitCmd(config.DefaultConfig())
// check that we are inside a git dir
var output string
err := gitcmd.Git("status --porcelain", &output)
Expand All @@ -38,31 +38,12 @@ func main() {
os.Exit(2)
}

// parse configuration
cfg := config.Config{}
configfilepath := config.ConfigFilePath(gitcmd)
rake.LoadSources(&cfg,
rake.DefaultSource(),
config.GitHubRemoteSource(&cfg, gitcmd),
rake.YamlFileSource(configfilepath),
rake.YamlFileWriter(configfilepath),
)

if cfg.GitHubRepoOwner == "" {
fmt.Println("unable to auto configure repository owner - must be set manually in .spr.yml")
os.Exit(3)
}

if cfg.GitHubRepoName == "" {
fmt.Println("unable to auto configure repository name - must be set manually in .spr.yml")
os.Exit(4)
}

gitcmd = realgit.NewGitCmd(&cfg)
cfg := config.ParseConfig(gitcmd)
gitcmd = realgit.NewGitCmd(cfg)

ctx := context.Background()
client := githubclient.NewGitHubClient(ctx, &cfg)
stackedpr := spr.NewStackedPR(&cfg, client, gitcmd, os.Stdout)
client := githubclient.NewGitHubClient(ctx, cfg)
stackedpr := spr.NewStackedPR(cfg, client, gitcmd, os.Stdout)

detailFlag := &cli.BoolFlag{
Name: "detail",
Expand Down Expand Up @@ -127,12 +108,12 @@ VERSION: {{.Version}}
if c.IsSet("profile") {
stackedpr.ProfilingEnable()
}
if c.IsSet("detail") || cfg.StatusBitsHeader {
if c.IsSet("detail") || cfg.User.StatusBitsHeader {
stackedpr.DetailEnabled = true
}
if c.IsSet("verbose") {
cfg.LogGitCommands = true
cfg.LogGitHubCalls = true
cfg.User.LogGitCommands = true
cfg.User.LogGitHubCalls = true
}
return nil
},
Expand Down
82 changes: 76 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,104 @@ package config

import (
"fmt"
"os"
"path"
"path/filepath"
"regexp"
"strings"

"github.com/ejoffe/rake"
"github.com/ejoffe/spr/git"
)

// Config object to hold spr configuration
type Config struct {
Repo *RepoConfig
User *UserConfig
}

// Config object to hold spr configuration
type RepoConfig struct {
GitHubRepoOwner string `yaml:"githubRepoOwner"`
GitHubRepoName string `yaml:"githubRepoName"`

RequireChecks bool `default:"true" yaml:"requireChecks"`
RequireApproval bool `default:"true" yaml:"requireApproval"`
RequireChecks bool `default:"true" yaml:"requireChecks"`
RequireApproval bool `default:"true" yaml:"requireApproval"`
}

type UserConfig struct {
ShowPRLink bool `default:"true" yaml:"showPRLink"`
CleanupRemoteBranch bool `default:"true" yaml:"cleanupRemoteBranch"`
LogGitCommands bool `default:"false" yaml:"logGitCommands"`
LogGitHubCalls bool `default:"false" yaml:"logGitHubCalls"`
StatusBitsHeader bool `default:"true" yaml:"statusBitsHeader"`

Stargazer bool `default:"false" yaml:"stargazer"`
RunCount int `default:"0" yaml:"runcount"`
}

func ConfigFilePath(gitcmd git.GitInterface) string {
func EmptyConfig() *Config {
return &Config{
Repo: &RepoConfig{},
User: &UserConfig{},
}
}

func DefaultConfig() *Config {
cfg := EmptyConfig()
rake.LoadSources(cfg.Repo,
rake.DefaultSource(),
)
rake.LoadSources(cfg.User,
rake.DefaultSource(),
)
return cfg
}

func ParseConfig(gitcmd git.GitInterface) *Config {
cfg := EmptyConfig()

rake.LoadSources(cfg.Repo,
rake.DefaultSource(),
GitHubRemoteSource(cfg, gitcmd),
rake.YamlFileSource(RepoConfigFilePath(gitcmd)),
rake.YamlFileWriter(RepoConfigFilePath(gitcmd)),
)

if cfg.Repo.GitHubRepoOwner == "" {
fmt.Println("unable to auto configure repository owner - must be set manually in .spr.yml")
os.Exit(3)
}

if cfg.Repo.GitHubRepoName == "" {
fmt.Println("unable to auto configure repository name - must be set manually in .spr.yml")
os.Exit(4)
}

rake.LoadSources(cfg.User,
rake.DefaultSource(),
rake.YamlFileSource(UserConfigFilePath()),
)

cfg.User.RunCount = cfg.User.RunCount + 1
rake.LoadSources(cfg.User,
rake.YamlFileWriter(UserConfigFilePath()))

return cfg
}

func RepoConfigFilePath(gitcmd git.GitInterface) string {
rootdir := gitcmd.RootDir()
filepath := filepath.Clean(path.Join(rootdir, ".spr.yml"))
return filepath
}

func UserConfigFilePath() string {
rootdir, err := os.UserHomeDir()
check(err)
filepath := filepath.Clean(path.Join(rootdir, ".spr.yml"))
return filepath
}

func GitHubRemoteSource(config *Config, gitcmd git.GitInterface) *remoteSource {
return &remoteSource{
gitcmd: gitcmd,
Expand All @@ -51,8 +121,8 @@ func (s *remoteSource) Load(_ interface{}) {
for _, line := range lines {
repoOwner, repoName, match := getRepoDetailsFromRemote(line)
if match {
s.config.GitHubRepoOwner = repoOwner
s.config.GitHubRepoName = repoName
s.config.Repo.GitHubRepoOwner = repoOwner
s.config.Repo.GitHubRepoName = repoName
break
}
}
Expand Down
2 changes: 1 addition & 1 deletion git/realgit/realcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (c *gitcmd) Git(argStr string, output *string) error {
// if output is not nil it will be set to the output of the command

log.Debug().Msg("git " + argStr)
if c.config.LogGitCommands {
if c.config.User.LogGitCommands {
fmt.Printf("> git %s\n", argStr)
}
args := strings.Split(argStr, " ")
Expand Down
16 changes: 8 additions & 8 deletions github/githubclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type client struct {
var pullRequestRegex = regexp.MustCompile(`pr/[a-zA-Z0-9_\-]+/([a-zA-Z0-9_\-/]+)/([a-f0-9]{8})$`)

func (c *client) GetInfo(ctx context.Context, gitcmd git.GitInterface) *github.GitHubInfo {
if c.config.LogGitHubCalls {
if c.config.User.LogGitHubCalls {
fmt.Printf("> github fetch pull requests\n")
}
var query struct {
Expand Down Expand Up @@ -80,8 +80,8 @@ func (c *client) GetInfo(ctx context.Context, gitcmd git.GitInterface) *github.G
} `graphql:"repository(owner:$repo_owner, name:$repo_name)"`
}
variables := map[string]interface{}{
"repo_owner": githubv4.String(c.config.GitHubRepoOwner),
"repo_name": githubv4.String(c.config.GitHubRepoName),
"repo_owner": githubv4.String(c.config.Repo.GitHubRepoOwner),
"repo_name": githubv4.String(c.config.Repo.GitHubRepoName),
}
err := c.api.Query(ctx, &query, variables)
check(err)
Expand Down Expand Up @@ -191,7 +191,7 @@ func (c *client) CreatePullRequest(ctx context.Context,
},
}

if c.config.LogGitHubCalls {
if c.config.User.LogGitHubCalls {
fmt.Printf("> github create %d: %s\n", pr.Number, pr.Title)
}

Expand All @@ -201,7 +201,7 @@ func (c *client) CreatePullRequest(ctx context.Context,
func (c *client) UpdatePullRequest(ctx context.Context,
info *github.GitHubInfo, pr *github.PullRequest, commit git.Commit, prevCommit *git.Commit) {

if c.config.LogGitHubCalls {
if c.config.User.LogGitHubCalls {
fmt.Printf("> github update %d - %s\n", pr.Number, pr.Title)
}

Expand Down Expand Up @@ -261,7 +261,7 @@ func (c *client) CommentPullRequest(ctx context.Context, pr *github.PullRequest,
Msg("pull request update failed")
}

if c.config.LogGitHubCalls {
if c.config.User.LogGitHubCalls {
fmt.Printf("> github add comment %d: %s\n", pr.Number, pr.Title)
}
}
Expand Down Expand Up @@ -292,7 +292,7 @@ func (c *client) MergePullRequest(ctx context.Context, pr *github.PullRequest) {
}
check(err)

if c.config.LogGitHubCalls {
if c.config.User.LogGitHubCalls {
fmt.Printf("> github merge %d: %s\n", pr.Number, pr.Title)
}
}
Expand All @@ -319,7 +319,7 @@ func (c *client) ClosePullRequest(ctx context.Context, pr *github.PullRequest) {
Msg("pull request close failed")
}

if c.config.LogGitHubCalls {
if c.config.User.LogGitHubCalls {
fmt.Printf("> github close %d: %s\n", pr.Number, pr.Title)
}
}
Expand Down
16 changes: 8 additions & 8 deletions github/pullrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ func (pr *PullRequest) Mergeable(config *config.Config) bool {
if !pr.MergeStatus.Stacked {
return false
}
if config.RequireChecks && pr.MergeStatus.ChecksPass != CheckStatusPass {
if config.Repo.RequireChecks && pr.MergeStatus.ChecksPass != CheckStatusPass {
return false
}
if config.RequireApproval && !pr.MergeStatus.ReviewApproved {
if config.Repo.RequireApproval && !pr.MergeStatus.ReviewApproved {
return false
}
return true
Expand All @@ -114,10 +114,10 @@ func (pr *PullRequest) Ready(config *config.Config) bool {
if !pr.MergeStatus.NoConflicts {
return false
}
if config.RequireChecks && pr.MergeStatus.ChecksPass != CheckStatusPass {
if config.Repo.RequireChecks && pr.MergeStatus.ChecksPass != CheckStatusPass {
return false
}
if config.RequireApproval && !pr.MergeStatus.ReviewApproved {
if config.Repo.RequireApproval && !pr.MergeStatus.ReviewApproved {
return false
}
return true
Expand All @@ -133,7 +133,7 @@ func (pr *PullRequest) StatusString(config *config.Config) string {

statusString += pr.MergeStatus.ChecksPass.String(config)

if config.RequireApproval {
if config.Repo.RequireApproval {
if pr.MergeStatus.ReviewApproved {
statusString += checkmark
} else {
Expand Down Expand Up @@ -166,9 +166,9 @@ func (pr *PullRequest) String(config *config.Config) string {
}

prInfo := fmt.Sprintf("%3d", pr.Number)
if config.ShowPRLink {
if config.User.ShowPRLink {
prInfo = fmt.Sprintf("github.com/%s/%s/pull/%d",
config.GitHubRepoOwner, config.GitHubRepoName, pr.Number)
config.Repo.GitHubRepoOwner, config.Repo.GitHubRepoName, pr.Number)
}

line := fmt.Sprintf("%s %s : %s", prStatus, prInfo, pr.Title)
Expand All @@ -189,7 +189,7 @@ func (pr *PullRequest) String(config *config.Config) string {
}

func (cs checkStatus) String(config *config.Config) string {
if config.RequireChecks {
if config.Repo.RequireChecks {
switch cs {
case CheckStatusUnknown:
return "?"
Expand Down
4 changes: 2 additions & 2 deletions github/pullrequest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestSortPullRequests(t *testing.T) {
},
}

config := &config.Config{}
config := config.EmptyConfig()
prs = SortPullRequests(prs, config)
if prs[0].Number != 1 {
t.Fatalf("prs not sorted correctly %v\n", prs)
Expand Down Expand Up @@ -57,7 +57,7 @@ func TestSortPullRequestsMixed(t *testing.T) {
},
}

config := &config.Config{}
config := config.EmptyConfig()
prs = SortPullRequests(prs, config)
if prs[0].Number != 1 {
t.Fatalf("prs not sorted correctly %v\n", prs)
Expand Down
10 changes: 7 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,19 @@ Show Current Pull Requests

Configuration
-------------
When the script is run for the first time a config file **.spr.yml** is created in your repository base dir.
These are the available configurations:
When the script is run for the first time two config files are created.
Repository configuration is saved to .spr.yml in the repository base directory.
User specific configuration is saved to .spr.yml in the user home directory.

| Name | Type | Default | Description
| Repository Config | Type | Default | Description |
| ------------------- | ---- | ------- | -------------------------------------------------------------- |
| githubRepoOwner | str | | name of the github owner (fetched from git remote config) |
| githubRepoName | str | | name of the github repository (fetched from git remote config) |
| requireChecks | bool | true | require checks to pass in order to merge |
| requireApproval | bool | true | require pull request approval in order to merge |

| User Config | Type | Default | Description |
| ------------------- | ---- | ------- | -------------------------------------------------------------- |
| showPRLink | bool | true | show full pull request http link |
| cleanupRemoteBranch | bool | true | delete remote branch after pull request merges |
| logGitCommands | bool | false | logs all git commands to stdout |
Expand Down
6 changes: 3 additions & 3 deletions spr/spr.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func (sd *stackediff) MergePullRequests(ctx context.Context) {
sd.github.MergePullRequest(ctx, prToMerge)
sd.profiletimer.Step("MergePullRequests::merge pr")

if sd.config.CleanupRemoteBranch {
if sd.config.User.CleanupRemoteBranch {
sd.gitcmd.Git(fmt.Sprintf("push -d origin %s", prToMerge.FromBranch), nil)
}

Expand All @@ -191,12 +191,12 @@ func (sd *stackediff) MergePullRequests(ctx context.Context) {
pr := githubInfo.PullRequests[i]
comment := fmt.Sprintf(
"commit MERGED in pull request [#%d](https://github.com/%s/%s/pull/%d)",
prToMerge.Number, sd.config.GitHubRepoOwner, sd.config.GitHubRepoName, prToMerge.Number)
prToMerge.Number, sd.config.Repo.GitHubRepoOwner, sd.config.Repo.GitHubRepoName, prToMerge.Number)
sd.github.CommentPullRequest(ctx, pr, comment)

sd.github.ClosePullRequest(ctx, pr)

if sd.config.CleanupRemoteBranch {
if sd.config.User.CleanupRemoteBranch {
sd.gitcmd.Git(fmt.Sprintf("push -d origin %s", pr.FromBranch), nil)
}
}
Expand Down

0 comments on commit 1e78e94

Please sign in to comment.