| 126 | } |
| 127 | |
| 128 | func diffRun(opts *DiffOptions) error { |
| 129 | findOptions := shared.FindOptions{ |
| 130 | Selector: opts.SelectorArg, |
| 131 | Fields: []string{"number"}, |
| 132 | } |
| 133 | |
| 134 | if opts.BrowserMode { |
| 135 | findOptions.Fields = []string{"url"} |
| 136 | } |
| 137 | |
| 138 | pr, baseRepo, err := opts.Finder.Find(findOptions) |
| 139 | if err != nil { |
| 140 | return err |
| 141 | } |
| 142 | |
| 143 | if opts.BrowserMode { |
| 144 | openUrl := fmt.Sprintf("%s/files", pr.URL) |
| 145 | if opts.IO.IsStdoutTTY() { |
| 146 | fmt.Fprintf(opts.IO.ErrOut, "Opening %s in your browser.\n", text.DisplayURL(openUrl)) |
| 147 | } |
| 148 | return opts.Browser.Browse(openUrl) |
| 149 | } |
| 150 | |
| 151 | httpClient, err := opts.HttpClient() |
| 152 | if err != nil { |
| 153 | return err |
| 154 | } |
| 155 | |
| 156 | if opts.NameOnly { |
| 157 | opts.Patch = false |
| 158 | } |
| 159 | |
| 160 | diffReadCloser, err := fetchDiff(httpClient, baseRepo, pr.Number, opts.Patch) |
| 161 | if err != nil { |
| 162 | return fmt.Errorf("could not find pull request diff: %w", err) |
| 163 | } |
| 164 | defer diffReadCloser.Close() |
| 165 | |
| 166 | var diff io.Reader = diffReadCloser |
| 167 | if len(opts.Exclude) > 0 { |
| 168 | filtered, err := filterDiff(diff, opts.Exclude) |
| 169 | if err != nil { |
| 170 | return err |
| 171 | } |
| 172 | diff = filtered |
| 173 | } |
| 174 | // A terminal shows escape sequences inert through ContentOut; piped output is |
| 175 | // faithful, so a diff carrying escape sequences is refused rather than silently |
| 176 | // altered. --allow-escape-sequences streams raw on both. The colored path |
| 177 | // always neutralizes, since it is terminal-bound. |
| 178 | if opts.AllowEscapeSequences { |
| 179 | opts.IO.SetContentSanitization(false) |
| 180 | } |
| 181 | |
| 182 | if err := opts.IO.StartPager(); err == nil { |
| 183 | defer opts.IO.StopPager() |
| 184 | } else { |
| 185 | fmt.Fprintf(opts.IO.ErrOut, "failed to start pager: %v\n", err) |