diff --git a/api/queries_pr.go b/api/queries_pr.go index c0b16f3c4..80428ae07 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -3,6 +3,8 @@ package api import ( "context" "fmt" + "io/ioutil" + "net/http" "strings" "github.com/shurcooL/githubv4" @@ -201,6 +203,30 @@ func (pr *PullRequest) ChecksStatus() (summary PullRequestChecksStatus) { return } +func (c Client) PullRequestDiff(baseRepo ghrepo.Interface, prNum int) (string, error) { + url := fmt.Sprintf("https://api.github.com/repos/%s/pulls/%d", + ghrepo.FullName(baseRepo), prNum) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return "", err + } + + req.Header.Set("Accept", "application/vnd.github.v3.diff; charset=utf-8") + + resp, err := c.http.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + return string(b), nil +} + func PullRequests(client *Client, repo ghrepo.Interface, currentPRNumber int, currentPRHeadRef, currentUsername string) (*PullRequestsPayload, error) { type edges struct { TotalCount int diff --git a/command/pr_diff.go b/command/pr_diff.go index db44bdef3..56e52f551 100644 --- a/command/pr_diff.go +++ b/command/pr_diff.go @@ -3,10 +3,12 @@ package command import ( "errors" "fmt" + "os" "strconv" "strings" "github.com/cli/cli/api" + "github.com/cli/cli/utils" "github.com/spf13/cobra" ) @@ -34,6 +36,7 @@ func prDiff(cmd *cobra.Command, args []string) error { return fmt.Errorf("could not determine base repo: %w", err) } + // begin pr resolution boilerplate var prNum int branchWithOwner := "" @@ -68,8 +71,44 @@ func prDiff(cmd *cobra.Command, args []string) error { } prNum = pr.Number } + // end pr resolution boilerplate - fmt.Println(pr.Title) + diff, err := apiClient.PullRequestDiff(baseRepo, prNum) + if err != nil { + return err + } + + color, err := cmd.Flags().GetString("color") + if err != nil { + return err + } + + out := cmd.OutOrStdout() + if color == "auto" { + color = "never" + isTTY := false + if outFile, isFile := out.(*os.File); isFile { + isTTY = utils.IsTerminal(outFile) + if isTTY { + color = "always" + } + } + } + + switch color { + case "always": + out = colorableOut(cmd) + rendered, err := utils.RenderMarkdown(fmt.Sprintf("```diff\n%s\n```", diff)) + fmt.Fprintf(out, rendered) + if err != nil { + return fmt.Errorf("failed to colorize diff: %w", err) + } + case "never": + out := cmd.OutOrStdout() + fmt.Fprintf(out, diff) + default: + return fmt.Errorf("did not understand color setting %q", color) + } return nil }