Skip to content

Commit

Permalink
util: Support getting MR ID from branch name
Browse files Browse the repository at this point in the history
If no MR ID is specified on the command line, the mr subcommands fall
back to looking for a MR associated with the current branch. Extend
that behavior to also try a branch name specified on the command line,
as branch names are usually easier to remember than MR numbers.
  • Loading branch information
fmuellner committed Dec 23, 2020
1 parent 98db094 commit 6437930
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 42 deletions.
60 changes: 47 additions & 13 deletions cmd/issue_note.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,32 @@ func NoteRunFn(cmd *cobra.Command, args []string) {
isMR = true
}

rn, idString, err := parseArgsRemoteAndProject(args)
reply, branchArgs, err := filterCommentArg(args)
if err != nil {
log.Fatal(err)
}

var (
rn string
idNum int = 0
reply int = 0
)

if strings.Contains(idString, ":") {
ids := strings.Split(idString, ":")
idNum, _ = strconv.Atoi(ids[0])
reply, _ = strconv.Atoi(ids[1])
} else {
idNum, _ = strconv.Atoi(idString)
}

if isMR && idNum == 0 {
idNum = getCurrentBranchMR(rn)
if idNum == 0 {
if isMR {
s, mrNum, _ := parseArgsWithGitBranchMR(branchArgs)
if mrNum == 0 {
fmt.Println("Error: Cannot determine MR id.")
os.Exit(1)
}
idNum = int(mrNum)
rn = s
} else {
s, issueNum, _ := parseArgsRemoteAndID(branchArgs)
if issueNum == 0 {
fmt.Println("Error: Cannot determine issue id.")
os.Exit(1)
}
idNum = int(issueNum)
rn = s
}

msgs, err := cmd.Flags().GetStringArray("message")
Expand Down Expand Up @@ -309,6 +311,38 @@ func replyNote(rn string, isMR bool, idNum int, reply int, quote bool, update bo
}
}

func filterCommentArg(args []string) (int, []string, error) {
branchArgs := []string{}
idString := ""

if len(args) == 1 {
ok, err := git.IsRemote(args[0])
if err != nil {
return 0, branchArgs, err
}
if ok {
branchArgs = append(branchArgs, args[0])
} else {
idString = args[0]
}
} else if len(args) > 1 {
branchArgs = append(branchArgs, args[0])
idString = args[1]
}

if strings.Contains(idString, ":") {
ps := strings.Split(idString, ":")
branchArgs = append(branchArgs, ps[0])
idString = ps[1]
} else {
branchArgs = append(branchArgs, idString)
idString = ""
}

idNum, _ := strconv.Atoi(idString)
return idNum, branchArgs, nil
}

func init() {
issueNoteCmd.Flags().StringArrayP("message", "m", []string{}, "use the given <msg>; multiple -m are concatenated as separate paragraphs")
issueNoteCmd.Flags().StringP("file", "F", "", "use the given file as the message")
Expand Down
25 changes: 8 additions & 17 deletions cmd/mr_edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,27 @@ var mrEditCmd = &cobra.Command{
Long: ``,
Example: `lab MR edit <id> # update MR via $EDITOR
lab MR update <id> # same as above
lab MR update <branch-name> # same, but get MR ID from local branch
lab MR edit <id> -m "new title" # update title
lab MR edit <id> -m "new title" -m "new desc" # update title & description
lab MR edit <id> -l newlabel --unlabel oldlabel # relabel MR
lab MR edit <id>:<comment_id> # update a comment on MR`,
PersistentPreRun: LabPersistentPreRun,
Run: func(cmd *cobra.Command, args []string) {
rn, idString, err := parseArgsRemoteAndProject(args)
commentNum, branchArgs, err := filterCommentArg(args)
if err != nil {
log.Fatal(err)
}

var (
mrNum int = 0
commentNum int = 0
)

if strings.Contains(idString, ":") {
ids := strings.Split(idString, ":")
mrNum, _ = strconv.Atoi(ids[0])
commentNum, _ = strconv.Atoi(ids[1])
} else {
mrNum, _ = strconv.Atoi(idString)
rn, id, err := parseArgsWithGitBranchMR(branchArgs)
if err != nil {
log.Fatal(err)
}
mrNum := int(id)

if mrNum == 0 {
mrNum = getCurrentBranchMR(rn)
if mrNum == 0 {
fmt.Println("Error: Cannot determine MR id.")
os.Exit(1)
}
fmt.Println("Error: Cannot determine MR id.")
os.Exit(1)
}

mr, err := lab.MRGet(rn, mrNum)
Expand Down
68 changes: 68 additions & 0 deletions cmd/mr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,74 @@ func Test_mrCmd_Draft(t *testing.T) {
})
}

func Test_mrCmd_ByBranch(t *testing.T) {
repo := copyTestRepo(t)
var mrID string
t.Run("prepare", func(t *testing.T) {
cmd := exec.Command("sh", "-c", labBinaryPath+` mr list lab-testing | grep -m1 'mr by branch' | cut -c2- | awk '{print $1}' | xargs `+labBinaryPath+` mr lab-testing -d`)
cmd.Dir = repo

b, err := cmd.CombinedOutput()
if err != nil {
t.Log(string(b))
//t.Fatal(err)
}
})
t.Run("create", func(t *testing.T) {
git := exec.Command("git", "checkout", "mrtest")
git.Dir = repo
b, err := git.CombinedOutput()
if err != nil {
t.Log(string(b))
t.Fatal(err)
}

cmd := exec.Command(labBinaryPath, "mr", "create", "--draft", "lab-testing", "master",
"-m", "mr by branch",
)
cmd.Dir = repo

b, _ = cmd.CombinedOutput()
out := string(b)
t.Log(out)
require.Contains(t, out, "https://gitlab.com/lab-testing/test/-/merge_requests")

i := strings.Index(out, "/diffs\n")
mrID = strings.TrimPrefix(out[:i], "https://gitlab.com/lab-testing/test/-/merge_requests/")
t.Log(mrID)
})
t.Run("show", func(t *testing.T) {
if mrID == "" {
t.Skip("mrID is empty, create likely failed")
}
cmd := exec.Command(labBinaryPath, "mr", "show", "lab-testing", "mrtest")
cmd.Dir = repo

b, err := cmd.CombinedOutput()
if err != nil {
t.Log(string(b))
t.Fatal(err)
}

out := string(b)
require.Contains(t, out, fmt.Sprintf("WebURL: https://gitlab.com/lab-testing/test/-/merge_requests/%s", mrID))
})
t.Run("delete", func(t *testing.T) {
if mrID == "" {
t.Skip("mrID is empty, create likely failed")
}
cmd := exec.Command(labBinaryPath, "mr", "close", "lab-testing", mrID)
cmd.Dir = repo

b, err := cmd.CombinedOutput()
if err != nil {
t.Log(string(b))
t.Fatal(err)
}
require.Contains(t, string(b), fmt.Sprintf("Merge Request !%s closed", mrID))
})
}

func Test_mrCmd_noArgs(t *testing.T) {
repo := copyTestRepo(t)
cmd := exec.Command(labBinaryPath, "mr")
Expand Down
51 changes: 39 additions & 12 deletions cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,21 @@ func flagConfig(fs *flag.FlagSet) {
// getCurrentBranchMR returns the MR ID associated with the current branch.
// If a MR ID cannot be found, the function returns 0.
func getCurrentBranchMR(rn string) int {
currentBranch, err := git.CurrentBranch()
if err != nil {
return 0
}

return getBranchMR(rn, currentBranch)
}

func getBranchMR(rn, branch string) int {
var num int = 0

currentBranch, err := git.CurrentUpstreamBranch()
if currentBranch == "" {
mrBranch, err := git.UpstreamBranch(branch)
if mrBranch == "" {
// Fall back to local branch
currentBranch, err = git.CurrentBranch()
}

if err != nil {
return 0
mrBranch = branch
}

mrs, err := lab.MRList(rn, gitlab.ListProjectMergeRequestsOptions{
Expand All @@ -88,7 +93,7 @@ func getCurrentBranchMR(rn string) int {
Labels: mrLabels,
State: &mrState,
OrderBy: gitlab.String("updated_at"),
SourceBranch: gitlab.String(currentBranch),
SourceBranch: gitlab.String(mrBranch),
}, -1)
if err != nil {
log.Fatal(err)
Expand Down Expand Up @@ -255,18 +260,40 @@ func parseArgsRemoteAndString(args []string) (string, string, error) {
}

// parseArgsWithGitBranchMR returns a remote name and a number if parsed.
// If no number is specified, the MR id associated with the current
// branch is returned.
// If no number is specified, the MR id associated with the given branch
// is returned, using the current branch as fallback.
func parseArgsWithGitBranchMR(args []string) (string, int64, error) {
var (
s string
branch string
err error
)
s, i, err := parseArgsRemoteAndID(args)
if i == 0 {
i = int64(getCurrentBranchMR(s))
s, branch, err = parseArgsRemoteAndString(args)
if err != nil {
return "", 0, err
}

if s == "" {
s = forkedFromRemote
}
s, err = getRemoteName(s)
if err != nil {
return "", 0, err
}

if branch == "" {
i = int64(getCurrentBranchMR(s))
} else {
i = int64(getBranchMR(s, branch))
}
if i == 0 {
fmt.Println("Error: Cannot determine MR id.")
os.Exit(1)
}
}
return s, i, err
return s, i, nil
}

// setCommandPrefix returns a concatenated value of some of the commandline.
Expand Down

0 comments on commit 6437930

Please sign in to comment.