Skip to content

Commit

Permalink
feat: added base-branch flag
Browse files Browse the repository at this point in the history
  • Loading branch information
lindell committed Dec 10, 2020
1 parent 9aba0b7 commit 8c04b8d
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 18 deletions.
3 changes: 3 additions & 0 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func RunCmd() *cobra.Command {
}

cmd.Flags().StringP("branch", "B", "multi-gitter-branch", "The name of the branch where changes are committed.")
cmd.Flags().StringP("base-branch", "", "", "The branch which the changes will be based on.")
cmd.Flags().StringP("pr-title", "t", "", "The title of the PR. Will default to the first line of the commit message if none is set.")
cmd.Flags().StringP("pr-body", "b", "", "The body of the commit message. Will default to everything but the first line of the commit message if none is set.")
cmd.Flags().StringP("commit-message", "m", "", "The commit message. Will default to title + body if none is set.")
Expand All @@ -55,6 +56,7 @@ func run(cmd *cobra.Command, args []string) error {
flag := cmd.Flags()

branchName, _ := flag.GetString("branch")
baseBranchName, _ := flag.GetString("base-branch")
prTitle, _ := flag.GetString("pr-title")
prBody, _ := flag.GetString("pr-body")
commitMessage, _ := flag.GetString("commit-message")
Expand Down Expand Up @@ -162,6 +164,7 @@ func run(cmd *cobra.Command, args []string) error {
MaxReviewers: maxReviewers,
DryRun: dryRun,
CommitAuthor: commitAuthor,
BaseBranch: baseBranchName,

Concurrent: concurrent,
}
Expand Down
10 changes: 6 additions & 4 deletions internal/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@ type Git struct {
}

// Clone a repository
func (g *Git) Clone() error {
func (g *Git) Clone(branchName string) error {
u, err := url.Parse(g.Repo)
if err != nil {
return err
}

r, err := git.PlainClone(g.Directory, false, &git.CloneOptions{
URL: u.String(),
RemoteName: "origin",
Depth: 10,
URL: u.String(),
RemoteName: "origin",
Depth: 10,
ReferenceName: plumbing.NewBranchReferenceName(branchName),
SingleBranch: true,
})
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion internal/multigitter/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (r Printer) runSingleRepo(ctx context.Context, repo domain.Repository) erro
Repo: repo.URL(r.Token),
}

err = sourceController.Clone()
err = sourceController.Clone(repo.DefaultBranch())
if err != nil {
return err
}
Expand Down
16 changes: 11 additions & 5 deletions internal/multigitter/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package multigitter

import (
"context"
"errors"
"fmt"
"io"
"io/ioutil"
Expand All @@ -11,6 +10,7 @@ import (
"os/exec"
"sync"

"github.com/pkg/errors"
log "github.com/sirupsen/logrus"

"github.com/lindell/multi-gitter/internal/domain"
Expand Down Expand Up @@ -46,6 +46,7 @@ type Runner struct {
MaxReviewers int // If set to zero, all reviewers will be used
DryRun bool
CommitAuthor *domain.CommitAuthor
BaseBranch string // The base branch of the PR, use default branch if not set

Concurrent int
}
Expand Down Expand Up @@ -129,15 +130,20 @@ func (r Runner) runSingleRepo(ctx context.Context, repo domain.Repository) error
Repo: repo.URL(r.Token),
}

err = sourceController.Clone()
baseBranch := r.BaseBranch
if baseBranch == "" {
baseBranch = repo.DefaultBranch()
}

err = sourceController.Clone(baseBranch)
if err != nil {
return err
}

branchExist, err := sourceController.BranchExist(r.FeatureBranch)
featureBranchExist, err := sourceController.BranchExist(r.FeatureBranch)
if err != nil {
return err
} else if branchExist {
} else if featureBranchExist {
return domain.BranchExistError
}

Expand Down Expand Up @@ -190,7 +196,7 @@ func (r Runner) runSingleRepo(ctx context.Context, repo domain.Repository) error
Title: r.PullRequestTitle,
Body: r.PullRequestBody,
Head: r.FeatureBranch,
Base: repo.DefaultBranch(),
Base: r.BaseBranch,
Reviewers: getReviewers(r.Reviewers, r.MaxReviewers),
})
if err != nil {
Expand Down
39 changes: 38 additions & 1 deletion tests/repo_helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"github.com/stretchr/testify/require"
)

const fileName = "test.txt"

func createRepo(t *testing.T, name, dataInFile string) vcmock.Repository {
tmpDir, err := createDummyRepo(dataInFile)
require.NoError(t, err)
Expand Down Expand Up @@ -66,7 +68,7 @@ func createDummyRepo(dataInFile string) (string, error) {
return tmpDir, nil
}

func changeBranch(t *testing.T, path string, branchName string) {
func changeBranch(t *testing.T, path string, branchName string, create bool) {
repo, err := git.PlainOpen(path)
assert.NoError(t, err)

Expand All @@ -75,6 +77,41 @@ func changeBranch(t *testing.T, path string, branchName string) {

err = wt.Checkout(&git.CheckoutOptions{
Branch: plumbing.NewBranchReferenceName(branchName),
Create: create,
})
assert.NoError(t, err)
}

func changeTestFile(t *testing.T, basePath string, content string, commitMessage string) {
repo, err := git.PlainOpen(basePath)
require.NoError(t, err)

testFilePath := path.Join(basePath, fileName)

err = ioutil.WriteFile(testFilePath, []byte(content), 0600)
require.NoError(t, err)

wt, err := repo.Worktree()
require.NoError(t, err)

_, err = wt.Add(".")
require.NoError(t, err)

_, err = wt.Commit(commitMessage, &git.CommitOptions{
Author: &object.Signature{
Name: "test",
Email: "test@example.com",
When: time.Now(),
},
})
require.NoError(t, err)
}

func readTestFile(t *testing.T, basePath string) string {
testFilePath := path.Join(basePath, fileName)

b, err := ioutil.ReadFile(testFilePath)
require.NoError(t, err)

return string(b)
}
4 changes: 1 addition & 3 deletions tests/story_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import (
"github.com/stretchr/testify/require"
)

const fileName = "test.txt"

// TestStory tests the common usecase: run, status, merge, status
func TestStory(t *testing.T) {
vcMock := &vcmock.VersionController{}
Expand Down Expand Up @@ -56,7 +54,7 @@ func TestStory(t *testing.T) {
assert.Equal(t, []byte("i like apples"), data)

// Verify that the new branch is changed
changeBranch(t, changeRepo.Path, "custom-branch-name")
changeBranch(t, changeRepo.Path, "custom-branch-name", false)
data, err = ioutil.ReadFile(path.Join(changeRepo.Path, fileName))
assert.NoError(t, err)
assert.Equal(t, []byte("i like bananas"), data)
Expand Down
71 changes: 67 additions & 4 deletions tests/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ func TestTable(t *testing.T) {
assert.NoError(t, err)

tests := []struct {
name string
vc *vcmock.VersionController
name string
vc *vcmock.VersionController
vcCreate func(t *testing.T) *vcmock.VersionController // Can be used if advanced setup is needed for the vc

args []string
verify func(t *testing.T, vcMock *vcmock.VersionController, outputs outputs)

Expand Down Expand Up @@ -59,6 +61,61 @@ func TestTable(t *testing.T) {
`, outputs.out)
},
},

{
name: "failing base-branch",
vc: &vcmock.VersionController{
Repositories: []vcmock.Repository{
createRepo(t, "should-change", "i like apples"),
},
},
args: []string{
"run",
"--author-name", "Test Author",
"--author-email", "test@example.com",
"-B", "custom-branch-name",
"--base-branch", "custom-base-branch",
"-m", "custom message",
fmt.Sprintf(`go run %s`, path.Join(workingDir, "scripts/changer/main.go")),
},
verify: func(t *testing.T, vcMock *vcmock.VersionController, outputs outputs) {
require.Len(t, vcMock.PullRequests, 0)
assert.Contains(t, outputs.logOut, `msg="couldn't find remote ref \"refs/heads/custom-base-branch\""`)
},
},

{
name: "success base-branch",
vcCreate: func(t *testing.T) *vcmock.VersionController {
repo := createRepo(t, "should-change", "i like apples")
changeBranch(t, repo.Path, "custom-base-branch", true)
changeTestFile(t, repo.Path, "i like apple", "test change")
changeBranch(t, repo.Path, "master", false)
return &vcmock.VersionController{
Repositories: []vcmock.Repository{
repo,
},
}
},
args: []string{
"run",
"--author-name", "Test Author",
"--author-email", "test@example.com",
"-B", "custom-branch-name",
"--base-branch", "custom-base-branch",
"-m", "custom message",
fmt.Sprintf(`go run %s`, path.Join(workingDir, "scripts/changer/main.go")),
},
verify: func(t *testing.T, vcMock *vcmock.VersionController, outputs outputs) {
require.Len(t, vcMock.PullRequests, 1)
assert.Equal(t, "custom-base-branch", vcMock.PullRequests[0].Base)
assert.Equal(t, "custom-branch-name", vcMock.PullRequests[0].Head)
assert.Equal(t, "custom message", vcMock.PullRequests[0].Title)

changeBranch(t, vcMock.Repositories[0].Path, "custom-branch-name", false)
assert.Equal(t, "i like banana", readTestFile(t, vcMock.Repositories[0].Path))
},
},
}

for _, test := range tests {
Expand All @@ -71,7 +128,13 @@ func TestTable(t *testing.T) {
require.NoError(t, err)
defer os.Remove(outFile.Name())

cmd.OverrideVersionController = test.vc
var vc *vcmock.VersionController
if test.vcCreate != nil {
vc = test.vcCreate(t)
} else {
vc = test.vc
}
cmd.OverrideVersionController = vc

command := cmd.RootCmd()
command.SetArgs(append(
Expand All @@ -92,7 +155,7 @@ func TestTable(t *testing.T) {
outData, err := ioutil.ReadAll(outFile)
assert.NoError(t, err)

test.verify(t, test.vc, outputs{
test.verify(t, vc, outputs{
logOut: string(logData),
out: string(outData),
})
Expand Down

0 comments on commit 8c04b8d

Please sign in to comment.