github.com/gfleury/gobbs@v0.0.0-20200831213239-44ca2b94c1a1/pullrequests/diff.go (about) 1 package pullrequests 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "net" 8 "net/http" 9 "strconv" 10 11 "github.com/gfleury/gobbs/common" 12 "github.com/gfleury/gobbs/common/log" 13 14 bitbucketv1 "github.com/gfleury/go-bitbucket-v1" 15 "github.com/spf13/cobra" 16 ) 17 18 var ( 19 WhiteColor = "\033[1;97m" 20 GreenColor = "\033[0;32m" 21 RedColor = "\033[0;31m" 22 CyanColor = "\033[0;36m" 23 ResetColor = "\033[0m" 24 diffContextLines *int32 25 noColor *bool 26 ) 27 28 func init() { 29 diffContextLines = Diff.Flags().Int32P("lines", "L", 3, "Diff context lines (how many lines before/after)") 30 noColor = Diff.Flags().BoolP("nocolor", "N", false, "Disable color output (getting a working diff)") 31 } 32 33 // Digg is the cmd implementation for getting Raw diff of PullRequests 34 var Diff = &cobra.Command{ 35 Use: "diff pullRequestID", 36 Aliases: []string{"inf"}, 37 Short: "Diff pull requests for repository", 38 Args: cobra.MinimumNArgs(1), 39 RunE: func(cmd *cobra.Command, args []string) error { 40 prID, err := strconv.Atoi(args[0]) 41 if err != nil { 42 log.Critical("Argument must be a pull request ID. Err: %s", err.Error()) 43 return err 44 } 45 46 apiClient, cancel, err := common.APIClient(cmd) 47 defer cancel() 48 49 if err != nil { 50 return err 51 } 52 53 if *noColor { 54 WhiteColor = "" 55 GreenColor = "" 56 RedColor = "" 57 CyanColor = "" 58 ResetColor = "" 59 } 60 61 stashInfo := cmd.Context().Value(common.StashInfoKey).(*common.StashInfo) 62 err = mustHaveProjectRepo(stashInfo) 63 if err != nil { 64 return err 65 } 66 67 opts := map[string]interface{}{ 68 "contextLines": *diffContextLines, 69 } 70 71 response, err := apiClient.DefaultApi.GetPullRequestDiff(*stashInfo.Project(), *stashInfo.Repo(), prID, opts) 72 73 if netError, ok := err.(net.Error); (!ok || (ok && !netError.Timeout())) && 74 !errors.Is(err, context.Canceled) && 75 !errors.Is(err, context.DeadlineExceeded) && 76 response != nil && response.Response != nil && 77 response.Response.StatusCode >= http.StatusMultipleChoices { 78 common.PrintApiError(response.Values) 79 cmd.SilenceUsage = true 80 log.Debugf(err.Error()) 81 return fmt.Errorf("Unable to process request, API Error") 82 } else if err != nil { 83 cmd.SilenceUsage = true 84 return err 85 } 86 87 diffs, err := bitbucketv1.GetDiffResponse(response) 88 if err != nil { 89 return err 90 } 91 92 less, stdin := common.Pager() 93 94 go func() { 95 for _, diff := range diffs.Diffs { 96 // --- a/pullrequests/pr.go 97 // +++ b/pullrequests/pr.go 98 fmt.Fprintf(stdin, "%s--- %s%s\n", WhiteColor, diff.Source.ToString, ResetColor) 99 fmt.Fprintf(stdin, "%s+++ %s%s\n", WhiteColor, diff.Destination.ToString, ResetColor) 100 for _, hunk := range diff.Hunks { 101 // @@ -15,6 +15,7 @@ 102 fmt.Fprintf(stdin, "%s@@ -%d,%d +%d,%d @@%s\n", CyanColor, hunk.SourceLine, hunk.SourceSpan, hunk.DestinationLine, hunk.DestinationSpan, CyanColor) 103 for _, segment := range hunk.Segments { 104 lineStart := " " 105 if segment.Type == "ADDED" { 106 lineStart = GreenColor + "+" 107 } else if segment.Type == "REMOVED" { 108 lineStart = RedColor + "-" 109 } 110 for _, line := range segment.Lines { 111 fmt.Fprintf(stdin, "%s%s%s\n", lineStart, line.Line, ResetColor) 112 } 113 } 114 } 115 } 116 defer stdin.Close() 117 }() 118 119 err = less.Run() 120 return err 121 }, 122 }