pr command scriptability improvements

This commit improves behavior and error handling for pr commands when
run unattached to a tty.

- error if pr create and no -t/-f
- error if pr create and -w
- machine readable pr list
- machine readable pr view
- various cleanup of informational messages
This commit is contained in:
vilmibm 2020-07-14 16:47:32 -05:00
parent e18776c227
commit 168bd33bc9
7 changed files with 679 additions and 38 deletions

View file

@ -293,8 +293,9 @@ func prList(cmd *cobra.Command, args []string) error {
})
title := listHeader(ghrepo.FullName(baseRepo), "pull request", len(listResult.PullRequests), listResult.TotalCount, hasFilters)
// TODO: avoid printing header if piped to a script
fmt.Fprintf(colorableErr(cmd), "\n%s\n\n", title)
if connectedToTerminal(cmd) {
fmt.Fprintf(colorableErr(cmd), "\n%s\n\n", title)
}
table := utils.NewTablePrinter(cmd.OutOrStdout())
for _, pr := range listResult.PullRequests {
@ -303,6 +304,10 @@ func prList(cmd *cobra.Command, args []string) error {
prNum = "#" + prNum
}
table.AddField(prNum, nil, colorFuncForPR(pr))
if !table.IsTTY() {
table.AddField(pr.State, nil, nil)
table.AddField(prReadyState(&pr), nil, nil)
}
table.AddField(replaceExcessiveWhitespace(pr.Title), nil, nil)
table.AddField(pr.HeadLabel(), nil, utils.Cyan)
table.EndRow()
@ -357,6 +362,10 @@ func prView(cmd *cobra.Command, args []string) error {
return err
}
if web && !connectedToTerminal(cmd) {
return errors.New("--web unsupported when not attached to a tty")
}
pr, _, err := prFromArgs(ctx, apiClient, cmd, args)
if err != nil {
return err
@ -367,8 +376,13 @@ func prView(cmd *cobra.Command, args []string) error {
fmt.Fprintf(cmd.ErrOrStderr(), "Opening %s in your browser.\n", openURL)
return utils.OpenInBrowser(openURL)
}
out := colorableOut(cmd)
return printPrPreview(out, pr)
if connectedToTerminal(cmd) {
out := colorableOut(cmd)
return printHumanPrPreview(out, pr)
}
return printRawPrPreview(cmd.OutOrStdout(), pr)
}
func prClose(cmd *cobra.Command, args []string) error {
@ -482,6 +496,9 @@ func prMerge(cmd *cobra.Command, args []string) error {
}
if enabledFlagCount == 0 {
if !connectedToTerminal(cmd) {
return errors.New("--merge, --rebase, or --squash required when not attached to a tty")
}
isInteractive = true
} else if enabledFlagCount > 1 {
return errors.New("expected exactly one of --merge, --rebase, or --squash to be true")
@ -513,7 +530,9 @@ func prMerge(cmd *cobra.Command, args []string) error {
return fmt.Errorf("API call failed: %w", err)
}
fmt.Fprintf(colorableOut(cmd), "%s %s pull request #%d (%s)\n", utils.Magenta("✔"), action, pr.Number, pr.Title)
if connectedToTerminal(cmd) {
fmt.Fprintf(colorableOut(cmd), "%s %s pull request #%d (%s)\n", utils.Magenta("✔"), action, pr.Number, pr.Title)
}
if deleteBranch {
branchSwitchString := ""
@ -560,7 +579,9 @@ func prMerge(cmd *cobra.Command, args []string) error {
}
}
fmt.Fprintf(colorableOut(cmd), "%s Deleted branch %s%s\n", utils.Red("✔"), utils.Cyan(pr.HeadRefName), branchSwitchString)
if connectedToTerminal(cmd) {
fmt.Fprintf(colorableOut(cmd), "%s Deleted branch %s%s\n", utils.Red("✔"), utils.Cyan(pr.HeadRefName), branchSwitchString)
}
}
return nil
@ -620,7 +641,46 @@ func prInteractiveMerge(deleteLocalBranch bool, crossRepoPR bool) (api.PullReque
return mergeMethod, deleteBranch, nil
}
func printPrPreview(out io.Writer, pr *api.PullRequest) error {
func prReadyState(pr *api.PullRequest) string {
switch pr.State {
case "OPEN":
if pr.IsDraft {
return "draft"
} else {
return "ready"
}
case "CLOSED":
return "unreviewable"
case "MERGED":
return "unreviewable"
}
return "unknown"
}
func printRawPrPreview(out io.Writer, pr *api.PullRequest) error {
reviewers := prReviewerList(*pr)
assignees := prAssigneeList(*pr)
labels := prLabelList(*pr)
projects := prProjectList(*pr)
fmt.Fprintf(out, "title:\t%s\n", pr.Title)
fmt.Fprintf(out, "state:\t%s\n", pr.State)
fmt.Fprintf(out, "ready:\t%s\n", prReadyState(pr))
fmt.Fprintf(out, "author:\t%s\n", pr.Author.Login)
fmt.Fprintf(out, "labels:\t%s\n", labels)
fmt.Fprintf(out, "assignees:\t%s\n", assignees)
fmt.Fprintf(out, "reviewers:\t%s\n", reviewers)
fmt.Fprintf(out, "projects:\t%s\n", projects)
fmt.Fprintf(out, "milestone:\t%s\n", pr.Milestone.Title)
fmt.Fprintln(out, "--")
fmt.Fprintln(out, pr.Body)
return nil
}
func printHumanPrPreview(out io.Writer, pr *api.PullRequest) error {
// Header (Title and State)
fmt.Fprintln(out, utils.Bold(pr.Title))
fmt.Fprintf(out, "%s", prStateTitleWithColor(*pr))