Skip to content

Commit 8bfe64d

Browse files
cristiand391mislav
authored andcommitted
Accept --body-file flag if --body is supported
1 parent eddd8f0 commit 8bfe64d

File tree

13 files changed

+379
-13
lines changed

13 files changed

+379
-13
lines changed

pkg/cmd/issue/comment/comment.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ func NewCmdComment(f *cmdutil.Factory, runF func(*prShared.CommentableOptions) e
3535
return prShared.CommentablePreRun(cmd, opts)
3636
},
3737
RunE: func(_ *cobra.Command, args []string) error {
38+
if opts.BodyFile != "" {
39+
b, err := cmdutil.ReadFile(opts.BodyFile, opts.IO.In)
40+
if err != nil {
41+
return err
42+
}
43+
opts.Body = string(b)
44+
}
45+
3846
if runF != nil {
3947
return runF(opts)
4048
}
@@ -43,6 +51,7 @@ func NewCmdComment(f *cmdutil.Factory, runF func(*prShared.CommentableOptions) e
4351
}
4452

4553
cmd.Flags().StringVarP(&opts.Body, "body", "b", "", "Supply a body. Will prompt for one otherwise.")
54+
cmd.Flags().StringVarP(&opts.BodyFile, "body-file", "F", "", "Read body text from `file`")
4655
cmd.Flags().BoolP("editor", "e", false, "Add body using editor")
4756
cmd.Flags().BoolP("web", "w", false, "Add body in browser")
4857

pkg/cmd/issue/comment/comment_test.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package comment
22

33
import (
44
"bytes"
5+
"fmt"
6+
"io/ioutil"
57
"net/http"
8+
"path/filepath"
69
"testing"
710

811
"github.com/cli/cli/internal/ghrepo"
@@ -12,12 +15,18 @@ import (
1215
"github.com/cli/cli/pkg/iostreams"
1316
"github.com/google/shlex"
1417
"github.com/stretchr/testify/assert"
18+
"github.com/stretchr/testify/require"
1519
)
1620

1721
func TestNewCmdComment(t *testing.T) {
22+
tmpFile := filepath.Join(t.TempDir(), "my-body.md")
23+
err := ioutil.WriteFile(tmpFile, []byte("a body from file"), 0600)
24+
require.NoError(t, err)
25+
1826
tests := []struct {
1927
name string
2028
input string
29+
stdin string
2130
output shared.CommentableOptions
2231
wantsErr bool
2332
}{
@@ -57,6 +66,27 @@ func TestNewCmdComment(t *testing.T) {
5766
},
5867
wantsErr: false,
5968
},
69+
{
70+
name: "body from stdin",
71+
input: "1 --body-file -",
72+
stdin: "this is on standard input",
73+
output: shared.CommentableOptions{
74+
Interactive: false,
75+
InputType: shared.InputTypeInline,
76+
Body: "this is on standard input",
77+
},
78+
wantsErr: false,
79+
},
80+
{
81+
name: "body from file",
82+
input: fmt.Sprintf("1 --body-file '%s'", tmpFile),
83+
output: shared.CommentableOptions{
84+
Interactive: false,
85+
InputType: shared.InputTypeInline,
86+
Body: "a body from file",
87+
},
88+
wantsErr: false,
89+
},
6090
{
6191
name: "editor flag",
6292
input: "1 --editor",
@@ -77,6 +107,12 @@ func TestNewCmdComment(t *testing.T) {
77107
},
78108
wantsErr: false,
79109
},
110+
{
111+
name: "body and body-file flags",
112+
input: "1 --body 'test' --body-file 'test-file.txt'",
113+
output: shared.CommentableOptions{},
114+
wantsErr: true,
115+
},
80116
{
81117
name: "editor and web flags",
82118
input: "1 --editor --web",
@@ -105,11 +141,15 @@ func TestNewCmdComment(t *testing.T) {
105141

106142
for _, tt := range tests {
107143
t.Run(tt.name, func(t *testing.T) {
108-
io, _, _, _ := iostreams.Test()
144+
io, stdin, _, _ := iostreams.Test()
109145
io.SetStdoutTTY(true)
110146
io.SetStdinTTY(true)
111147
io.SetStderrTTY(true)
112148

149+
if tt.stdin != "" {
150+
_, _ = stdin.WriteString(tt.stdin)
151+
}
152+
113153
f := &cmdutil.Factory{
114154
IOStreams: io,
115155
}

pkg/cmd/issue/edit/edit.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman
4242
FetchOptions: prShared.FetchOptions,
4343
}
4444

45+
var bodyFile string
46+
4547
cmd := &cobra.Command{
4648
Use: "edit {<number> | <url>}",
4749
Short: "Edit an issue",
@@ -51,6 +53,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman
5153
$ gh issue edit 23 --add-assignee @me --remove-assignee monalisa,hubot
5254
$ gh issue edit 23 --add-project "Roadmap" --remove-project v1,v2
5355
$ gh issue edit 23 --milestone "Version 1"
56+
$ gh issue edit 23 --body-file body.txt
5457
`),
5558
Args: cobra.ExactArgs(1),
5659
RunE: func(cmd *cobra.Command, args []string) error {
@@ -60,11 +63,30 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman
6063
opts.SelectorArg = args[0]
6164

6265
flags := cmd.Flags()
63-
if flags.Changed("title") {
64-
opts.Editable.Title.Edited = true
66+
67+
bodyProvided := flags.Changed("body")
68+
bodyFileProvided := bodyFile != ""
69+
70+
if err := cmdutil.MutuallyExclusive(
71+
"specify only one of `--body` or `--body-file`",
72+
bodyProvided,
73+
bodyFileProvided,
74+
); err != nil {
75+
return err
6576
}
66-
if flags.Changed("body") {
77+
if bodyProvided || bodyFileProvided {
6778
opts.Editable.Body.Edited = true
79+
if bodyFileProvided {
80+
b, err := cmdutil.ReadFile(bodyFile, opts.IO.In)
81+
if err != nil {
82+
return err
83+
}
84+
opts.Editable.Body.Value = string(b)
85+
}
86+
}
87+
88+
if flags.Changed("title") {
89+
opts.Editable.Title.Edited = true
6890
}
6991
if flags.Changed("add-assignee") || flags.Changed("remove-assignee") {
7092
opts.Editable.Assignees.Edited = true
@@ -97,6 +119,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman
97119

98120
cmd.Flags().StringVarP(&opts.Editable.Title.Value, "title", "t", "", "Set the new title.")
99121
cmd.Flags().StringVarP(&opts.Editable.Body.Value, "body", "b", "", "Set the new body.")
122+
cmd.Flags().StringVarP(&bodyFile, "body-file", "F", "", "Read body text from `file`")
100123
cmd.Flags().StringSliceVar(&opts.Editable.Assignees.Add, "add-assignee", nil, "Add assigned users by their `login`. Use \"@me\" to assign yourself.")
101124
cmd.Flags().StringSliceVar(&opts.Editable.Assignees.Remove, "remove-assignee", nil, "Remove assigned users by their `login`. Use \"@me\" to unassign yourself.")
102125
cmd.Flags().StringSliceVar(&opts.Editable.Labels.Add, "add-label", nil, "Add labels by `name`")

pkg/cmd/issue/edit/edit_test.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package edit
22

33
import (
44
"bytes"
5+
"fmt"
6+
"io/ioutil"
57
"net/http"
8+
"path/filepath"
69
"testing"
710

811
"github.com/cli/cli/internal/ghrepo"
@@ -12,12 +15,18 @@ import (
1215
"github.com/cli/cli/pkg/iostreams"
1316
"github.com/google/shlex"
1417
"github.com/stretchr/testify/assert"
18+
"github.com/stretchr/testify/require"
1519
)
1620

1721
func TestNewCmdEdit(t *testing.T) {
22+
tmpFile := filepath.Join(t.TempDir(), "my-body.md")
23+
err := ioutil.WriteFile(tmpFile, []byte("a body from file"), 0600)
24+
require.NoError(t, err)
25+
1826
tests := []struct {
1927
name string
2028
input string
29+
stdin string
2130
output EditOptions
2231
wantsErr bool
2332
}{
@@ -64,6 +73,35 @@ func TestNewCmdEdit(t *testing.T) {
6473
},
6574
wantsErr: false,
6675
},
76+
{
77+
name: "body from stdin",
78+
input: "23 --body-file -",
79+
stdin: "this is on standard input",
80+
output: EditOptions{
81+
SelectorArg: "23",
82+
Editable: prShared.Editable{
83+
Body: prShared.EditableString{
84+
Value: "this is on standard input",
85+
Edited: true,
86+
},
87+
},
88+
},
89+
wantsErr: false,
90+
},
91+
{
92+
name: "body from file",
93+
input: fmt.Sprintf("23 --body-file '%s'", tmpFile),
94+
output: EditOptions{
95+
SelectorArg: "23",
96+
Editable: prShared.Editable{
97+
Body: prShared.EditableString{
98+
Value: "a body from file",
99+
Edited: true,
100+
},
101+
},
102+
},
103+
wantsErr: false,
104+
},
67105
{
68106
name: "add-assignee flag",
69107
input: "23 --add-assignee monalisa,hubot",
@@ -165,11 +203,15 @@ func TestNewCmdEdit(t *testing.T) {
165203
}
166204
for _, tt := range tests {
167205
t.Run(tt.name, func(t *testing.T) {
168-
io, _, _, _ := iostreams.Test()
206+
io, stdin, _, _ := iostreams.Test()
169207
io.SetStdoutTTY(true)
170208
io.SetStdinTTY(true)
171209
io.SetStderrTTY(true)
172210

211+
if tt.stdin != "" {
212+
_, _ = stdin.WriteString(tt.stdin)
213+
}
214+
173215
f := &cmdutil.Factory{
174216
IOStreams: io,
175217
}

pkg/cmd/pr/comment/comment.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ func NewCmdComment(f *cmdutil.Factory, runF func(*shared.CommentableOptions) err
4343
return shared.CommentablePreRun(cmd, opts)
4444
},
4545
RunE: func(cmd *cobra.Command, args []string) error {
46+
if opts.BodyFile != "" {
47+
b, err := cmdutil.ReadFile(opts.BodyFile, opts.IO.In)
48+
if err != nil {
49+
return err
50+
}
51+
opts.Body = string(b)
52+
}
53+
4654
if runF != nil {
4755
return runF(opts)
4856
}
@@ -51,6 +59,7 @@ func NewCmdComment(f *cmdutil.Factory, runF func(*shared.CommentableOptions) err
5159
}
5260

5361
cmd.Flags().StringVarP(&opts.Body, "body", "b", "", "Supply a body. Will prompt for one otherwise.")
62+
cmd.Flags().StringVarP(&opts.BodyFile, "body-file", "F", "", "Read body text from `file`")
5463
cmd.Flags().BoolP("editor", "e", false, "Add body using editor")
5564
cmd.Flags().BoolP("web", "w", false, "Add body in browser")
5665

pkg/cmd/pr/comment/comment_test.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package comment
22

33
import (
44
"bytes"
5+
"fmt"
6+
"io/ioutil"
57
"net/http"
8+
"path/filepath"
69
"testing"
710

811
"github.com/cli/cli/context"
@@ -13,12 +16,18 @@ import (
1316
"github.com/cli/cli/pkg/iostreams"
1417
"github.com/google/shlex"
1518
"github.com/stretchr/testify/assert"
19+
"github.com/stretchr/testify/require"
1620
)
1721

1822
func TestNewCmdComment(t *testing.T) {
23+
tmpFile := filepath.Join(t.TempDir(), "my-body.md")
24+
err := ioutil.WriteFile(tmpFile, []byte("a body from file"), 0600)
25+
require.NoError(t, err)
26+
1927
tests := []struct {
2028
name string
2129
input string
30+
stdin string
2231
output shared.CommentableOptions
2332
wantsErr bool
2433
}{
@@ -78,6 +87,27 @@ func TestNewCmdComment(t *testing.T) {
7887
},
7988
wantsErr: false,
8089
},
90+
{
91+
name: "body from stdin",
92+
input: "1 --body-file -",
93+
stdin: "this is on standard input",
94+
output: shared.CommentableOptions{
95+
Interactive: false,
96+
InputType: shared.InputTypeInline,
97+
Body: "this is on standard input",
98+
},
99+
wantsErr: false,
100+
},
101+
{
102+
name: "body from file",
103+
input: fmt.Sprintf("1 --body-file '%s'", tmpFile),
104+
output: shared.CommentableOptions{
105+
Interactive: false,
106+
InputType: shared.InputTypeInline,
107+
Body: "a body from file",
108+
},
109+
wantsErr: false,
110+
},
81111
{
82112
name: "editor flag",
83113
input: "1 --editor",
@@ -98,6 +128,12 @@ func TestNewCmdComment(t *testing.T) {
98128
},
99129
wantsErr: false,
100130
},
131+
{
132+
name: "body and body-file flags",
133+
input: "1 --body 'test' --body-file 'test-file.txt'",
134+
output: shared.CommentableOptions{},
135+
wantsErr: true,
136+
},
101137
{
102138
name: "editor and web flags",
103139
input: "1 --editor --web",
@@ -126,11 +162,15 @@ func TestNewCmdComment(t *testing.T) {
126162

127163
for _, tt := range tests {
128164
t.Run(tt.name, func(t *testing.T) {
129-
io, _, _, _ := iostreams.Test()
165+
io, stdin, _, _ := iostreams.Test()
130166
io.SetStdoutTTY(true)
131167
io.SetStdinTTY(true)
132168
io.SetStderrTTY(true)
133169

170+
if tt.stdin != "" {
171+
_, _ = stdin.WriteString(tt.stdin)
172+
}
173+
134174
f := &cmdutil.Factory{
135175
IOStreams: io,
136176
}

0 commit comments

Comments
 (0)