Add name-only flag to gh pr diff sub command

This commit is contained in:
Bindu 2022-08-14 06:20:47 -07:00
parent d21d388b8d
commit 7036d055b5
2 changed files with 82 additions and 0 deletions

View file

@ -6,6 +6,7 @@ import (
"fmt"
"io"
"net/http"
"regexp"
"strings"
"github.com/MakeNowJust/heredoc"
@ -27,6 +28,7 @@ type DiffOptions struct {
SelectorArg string
UseColor bool
Patch bool
NameOnly bool
}
func NewCmdDiff(f *cmdutil.Factory, runF func(*DiffOptions) error) *cobra.Command {
@ -78,6 +80,7 @@ func NewCmdDiff(f *cmdutil.Factory, runF func(*DiffOptions) error) *cobra.Comman
cmdutil.StringEnumFlag(cmd, &colorFlag, "color", "", "auto", []string{"always", "never", "auto"}, "Use color in diff output")
cmd.Flags().BoolVar(&opts.Patch, "patch", false, "Display diff in patch format")
cmd.Flags().BoolVar(&opts.NameOnly, "name-only", false, "Display only names of changed files")
return cmd
}
@ -97,6 +100,10 @@ func diffRun(opts *DiffOptions) error {
return err
}
if opts.NameOnly {
opts.Patch = false
}
diff, err := fetchDiff(httpClient, baseRepo, pr.Number, opts.Patch)
if err != nil {
return fmt.Errorf("could not find pull request diff: %w", err)
@ -109,6 +116,10 @@ func diffRun(opts *DiffOptions) error {
fmt.Fprintf(opts.IO.ErrOut, "failed to start pager: %v\n", err)
}
if opts.NameOnly {
return changedFilesNames(opts.IO.Out, diff)
}
if !opts.UseColor {
_, err = io.Copy(opts.IO.Out, diff)
return err
@ -227,3 +238,22 @@ func isAdditionLine(l []byte) bool {
func isRemovalLine(l []byte) bool {
return len(l) > 0 && l[0] == '-'
}
func changedFilesNames(w io.Writer, r io.Reader) error {
diff, err := io.ReadAll(r)
if err != nil {
return err
}
pattern := regexp.MustCompile(`(?:^|\n)diff\s--git.*\sb/(.*)`)
matches := pattern.FindAllStringSubmatch(string(diff), -1)
for _, val := range matches {
name := strings.TrimSpace(val[1])
if _, err := w.Write([]byte(name + "\n")); err != nil {
return err
}
}
return nil
}

View file

@ -170,6 +170,18 @@ func Test_diffRun(t *testing.T) {
wantAccept: "application/vnd.github.v3.patch",
wantStdout: fmt.Sprintf(testDiff, "", "", "", ""),
},
{
name: "name only",
opts: DiffOptions{
SelectorArg: "123",
UseColor: false,
Patch: false,
NameOnly: true,
},
rawDiff: fmt.Sprintf(testDiff, "", "", "", ""),
wantAccept: "application/vnd.github.v3.diff",
wantStdout: fmt.Sprintf(".github/workflows/releases.yml\nMakefile\n"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -290,3 +302,43 @@ func Test_colorDiffLines(t *testing.T) {
}
}
}
func Test_changedFileNames(t *testing.T) {
inputs := []struct {
input, output string
}{
{
input: "",
output: "",
},
{
input: "\n",
output: "",
},
{
input: "diff --git a/cmd.go b/cmd.go\n--- /dev/null\n+++ b/cmd.go\n@@ -0,0 +1,313 @@",
output: "cmd.go\n",
},
{
input: "diff --git a/cmd.go b/cmd.go\n--- a/cmd.go\n+++ /dev/null\n@@ -0,0 +1,313 @@",
output: "cmd.go\n",
},
{
input: fmt.Sprintf("diff --git a/baz.go b/rename.go\n--- a/baz.go\n+++ b/rename.go\n+foo\n-b%sr", strings.Repeat("a", 2*lineBufferSize)),
output: "rename.go\n",
},
{
input: fmt.Sprintf("diff --git a/baz.go b/baz.go\n--- a/baz.go\n+++ b/baz.go\n+foo\n-b%sr", strings.Repeat("a", 2*lineBufferSize)),
output: "baz.go\n",
},
}
for _, tt := range inputs {
buf := bytes.Buffer{}
if err := changedFilesNames(&buf, strings.NewReader(tt.input)); err != nil {
t.Fatalf("unexpected error: %s", err)
}
if got := buf.String(); got != tt.output {
t.Errorf("expected: %q, got: %q", tt.output, got)
}
}
}