X Tutup
Skip to content

Commit c0fc31f

Browse files
committed
use CanPrompt in commands
1 parent fcc0e75 commit c0fc31f

File tree

16 files changed

+119
-67
lines changed

16 files changed

+119
-67
lines changed

pkg/cmd/auth/login/login.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
7272
if opts.Hostname == "" {
7373
opts.Hostname = ghinstance.Default()
7474
}
75+
} else {
76+
if !opts.IO.CanPrompt() {
77+
// TODO this error message kind of sucks since the prompting might be disabled from being
78+
// in a nontty or from the config setting. Is it enough info?
79+
return &cmdutil.FlagError{Err: errors.New("--with-token required when prompts disabled")}
80+
}
7581
}
7682

7783
if cmd.Flags().Changed("hostname") {

pkg/cmd/auth/login/login_test.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,13 @@ func Test_NewCmdLogin(t *testing.T) {
4949
name: "nontty, hostname",
5050
stdinTTY: false,
5151
cli: "--hostname claire.redfield",
52-
wants: LoginOptions{
53-
Hostname: "claire.redfield",
54-
Token: "",
55-
},
52+
wantsErr: true,
5653
},
5754
{
5855
name: "nontty",
5956
stdinTTY: false,
6057
cli: "",
61-
wants: LoginOptions{
62-
Hostname: "",
63-
Token: "",
64-
},
58+
wantsErr: true,
6559
},
6660
{
6761
name: "nontty, with-token, hostname",
@@ -109,6 +103,7 @@ func Test_NewCmdLogin(t *testing.T) {
109103
IOStreams: io,
110104
}
111105

106+
io.SetStdoutTTY(true)
112107
io.SetStdinTTY(tt.stdinTTY)
113108
if tt.stdin != "" {
114109
stdin.WriteString(tt.stdin)

pkg/cmd/auth/logout/logout.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ func NewCmdLogout(f *cmdutil.Factory, runF func(*LogoutOptions) error) *cobra.Co
4848
# => log out of specified host
4949
`),
5050
RunE: func(cmd *cobra.Command, args []string) error {
51+
if opts.Hostname == "" && !opts.IO.CanPrompt() {
52+
return &cmdutil.FlagError{Err: errors.New("--hostname required when prompts disabled")}
53+
}
54+
5155
if runF != nil {
5256
return runF(opts)
5357
}
@@ -62,16 +66,8 @@ func NewCmdLogout(f *cmdutil.Factory, runF func(*LogoutOptions) error) *cobra.Co
6266
}
6367

6468
func logoutRun(opts *LogoutOptions) error {
65-
isTTY := opts.IO.IsStdinTTY() && opts.IO.IsStdoutTTY()
66-
6769
hostname := opts.Hostname
6870

69-
if !isTTY && hostname == "" {
70-
return errors.New("--hostname required when not attached to a terminal")
71-
}
72-
73-
showConfirm := isTTY && hostname == ""
74-
7571
cfg, err := opts.Config()
7672
if err != nil {
7773
return err
@@ -131,7 +127,7 @@ func logoutRun(opts *LogoutOptions) error {
131127
usernameStr = fmt.Sprintf(" account '%s'", username)
132128
}
133129

134-
if showConfirm {
130+
if opts.IO.CanPrompt() {
135131
var keepGoing bool
136132
err := prompt.SurveyAskOne(&survey.Confirm{
137133
Message: fmt.Sprintf("Are you sure you want to log out of %s%s?", hostname, usernameStr),
@@ -152,6 +148,8 @@ func logoutRun(opts *LogoutOptions) error {
152148
return fmt.Errorf("failed to write config, authentication configuration not updated: %w", err)
153149
}
154150

151+
isTTY := opts.IO.IsStdinTTY() && opts.IO.IsStdoutTTY()
152+
155153
if isTTY {
156154
fmt.Fprintf(opts.IO.ErrOut, "%s Logged out of %s%s\n",
157155
utils.GreenCheck(), utils.Bold(hostname), usernameStr)

pkg/cmd/auth/logout/logout_test.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,49 @@ import (
1717

1818
func Test_NewCmdLogout(t *testing.T) {
1919
tests := []struct {
20-
name string
21-
cli string
22-
wants LogoutOptions
20+
name string
21+
cli string
22+
wants LogoutOptions
23+
wantsErr bool
24+
tty bool
2325
}{
2426
{
25-
name: "with hostname",
27+
name: "tty with hostname",
28+
tty: true,
2629
cli: "--hostname harry.mason",
2730
wants: LogoutOptions{
2831
Hostname: "harry.mason",
2932
},
3033
},
3134
{
32-
name: "no arguments",
35+
name: "tty no arguments",
36+
tty: true,
3337
cli: "",
3438
wants: LogoutOptions{
3539
Hostname: "",
3640
},
3741
},
42+
{
43+
name: "nontty with hostname",
44+
cli: "--hostname harry.mason",
45+
wants: LogoutOptions{
46+
Hostname: "harry.mason",
47+
},
48+
},
49+
{
50+
name: "nontty no arguments",
51+
cli: "",
52+
wantsErr: true,
53+
},
3854
}
3955
for _, tt := range tests {
4056
t.Run(tt.name, func(t *testing.T) {
4157
io, _, _, _ := iostreams.Test()
4258
f := &cmdutil.Factory{
4359
IOStreams: io,
4460
}
61+
io.SetStdinTTY(tt.tty)
62+
io.SetStdoutTTY(tt.tty)
4563

4664
argv, err := shlex.Split(tt.cli)
4765
assert.NoError(t, err)
@@ -60,6 +78,10 @@ func Test_NewCmdLogout(t *testing.T) {
6078
cmd.SetErr(&bytes.Buffer{})
6179

6280
_, err = cmd.ExecuteC()
81+
if tt.wantsErr {
82+
assert.Error(t, err)
83+
return
84+
}
6385
assert.NoError(t, err)
6486

6587
assert.Equal(t, tt.wants.Hostname, gotOpts.Hostname)
@@ -185,11 +207,6 @@ func Test_logoutRun_nontty(t *testing.T) {
185207
wantErr *regexp.Regexp
186208
ghtoken string
187209
}{
188-
{
189-
name: "no arguments",
190-
wantErr: regexp.MustCompile(`hostname required when not`),
191-
opts: &LogoutOptions{},
192-
},
193210
{
194211
name: "hostname, one host",
195212
opts: &LogoutOptions{

pkg/cmd/auth/refresh/refresh.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package refresh
22

33
import (
4+
"errors"
45
"fmt"
56

67
"github.com/AlecAivazis/survey/v2"
@@ -49,6 +50,17 @@ func NewCmdRefresh(f *cmdutil.Factory, runF func(*RefreshOptions) error) *cobra.
4950
# => open a browser to ensure your authentication credentials have the correct minimum scopes
5051
`),
5152
RunE: func(cmd *cobra.Command, args []string) error {
53+
isTTY := opts.IO.IsStdinTTY() && opts.IO.IsStdoutTTY()
54+
55+
if !isTTY {
56+
return fmt.Errorf("not attached to a terminal; in headless environments, GITHUB_TOKEN is recommended")
57+
}
58+
59+
if opts.Hostname == "" && !opts.IO.CanPrompt() {
60+
// here, we know we are attached to a TTY but prompts are disabled
61+
return &cmdutil.FlagError{Err: errors.New("--hostname required when prompts disabled")}
62+
}
63+
5264
if runF != nil {
5365
return runF(opts)
5466
}
@@ -64,12 +76,6 @@ func NewCmdRefresh(f *cmdutil.Factory, runF func(*RefreshOptions) error) *cobra.
6476
}
6577

6678
func refreshRun(opts *RefreshOptions) error {
67-
isTTY := opts.IO.IsStdinTTY() && opts.IO.IsStdoutTTY()
68-
69-
if !isTTY {
70-
return fmt.Errorf("not attached to a terminal; in headless environments, GITHUB_TOKEN is recommended")
71-
}
72-
7379
cfg, err := opts.Config()
7480
if err != nil {
7581
return err

pkg/cmd/auth/refresh/refresh_test.go

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,51 @@ import (
1414
"github.com/stretchr/testify/assert"
1515
)
1616

17+
// TODO prompt cfg test
18+
1719
func Test_NewCmdRefresh(t *testing.T) {
1820
tests := []struct {
19-
name string
20-
cli string
21-
wants RefreshOptions
21+
name string
22+
cli string
23+
wants RefreshOptions
24+
wantsErr bool
25+
tty bool
2226
}{
2327
{
24-
name: "no arguments",
28+
name: "tty no arguments",
29+
tty: true,
2530
wants: RefreshOptions{
2631
Hostname: "",
2732
},
2833
},
2934
{
30-
name: "hostname",
35+
name: "nontty no arguments",
36+
wantsErr: true,
37+
},
38+
{
39+
name: "nontty hostname",
40+
cli: "-h aline.cedrac",
41+
wantsErr: true,
42+
},
43+
{
44+
name: "tty hostname",
45+
tty: true,
3146
cli: "-h aline.cedrac",
3247
wants: RefreshOptions{
3348
Hostname: "aline.cedrac",
3449
},
3550
},
3651
{
37-
name: "one scope",
52+
name: "tty one scope",
53+
tty: true,
3854
cli: "--scopes repo:invite",
3955
wants: RefreshOptions{
4056
Scopes: []string{"repo:invite"},
4157
},
4258
},
4359
{
44-
name: "scopes",
60+
name: "tty scopes",
61+
tty: true,
4562
cli: "--scopes repo:invite,read:public_key",
4663
wants: RefreshOptions{
4764
Scopes: []string{"repo:invite", "read:public_key"},
@@ -55,6 +72,8 @@ func Test_NewCmdRefresh(t *testing.T) {
5572
f := &cmdutil.Factory{
5673
IOStreams: io,
5774
}
75+
io.SetStdinTTY(tt.tty)
76+
io.SetStdoutTTY(tt.tty)
5877

5978
argv, err := shlex.Split(tt.cli)
6079
assert.NoError(t, err)
@@ -73,11 +92,14 @@ func Test_NewCmdRefresh(t *testing.T) {
7392
cmd.SetErr(&bytes.Buffer{})
7493

7594
_, err = cmd.ExecuteC()
95+
if tt.wantsErr {
96+
assert.Error(t, err)
97+
return
98+
}
7699
assert.NoError(t, err)
77100
assert.Equal(t, tt.wants.Hostname, gotOpts.Hostname)
78101
assert.Equal(t, tt.wants.Scopes, gotOpts.Scopes)
79102
})
80-
81103
}
82104
}
83105

@@ -96,12 +118,6 @@ func Test_refreshRun(t *testing.T) {
96118
nontty bool
97119
wantAuthArgs authArgs
98120
}{
99-
{
100-
name: "non tty",
101-
opts: &RefreshOptions{},
102-
nontty: true,
103-
wantErr: regexp.MustCompile(`not attached to a terminal;`),
104-
},
105121
{
106122
name: "no hosts configured",
107123
opts: &RefreshOptions{},

pkg/cmd/issue/create/create.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ func createRun(opts *CreateOptions) error {
157157
return fmt.Errorf("must provide --title and --body when not attached to a terminal")
158158
}
159159

160+
if interactive && !opts.IO.CanPrompt() {
161+
return fmt.Errorf("must provide --title and --body when prompts are disabled")
162+
}
163+
160164
if interactive {
161165
var legacyTemplateFile *string
162166
if opts.RepoOverride == "" {

pkg/cmd/pr/create/create.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,8 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
7575
opts.BodyProvided = cmd.Flags().Changed("body")
7676
opts.RepoOverride, _ = cmd.Flags().GetString("repo")
7777

78-
isTerminal := opts.IO.IsStdinTTY() && opts.IO.IsStdoutTTY()
79-
if !isTerminal && !opts.WebMode && !opts.TitleProvided && !opts.Autofill {
80-
return errors.New("--title or --fill required when not attached to a terminal")
78+
if !opts.IO.CanPrompt() && !opts.WebMode && !opts.TitleProvided && !opts.Autofill {
79+
return errors.New("--title or --fill required when prompts are disabled")
8180
}
8281

8382
if opts.IsDraft && opts.WebMode {

pkg/cmd/pr/create/create_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func TestPRCreate_nontty_insufficient_flags(t *testing.T) {
135135
t.Fatal("expected error")
136136
}
137137

138-
assert.Equal(t, "--title or --fill required when not attached to a terminal", err.Error())
138+
assert.Equal(t, "--title or --fill required when prompts are disabled", err.Error())
139139

140140
assert.Equal(t, "", output.String())
141141
}

pkg/cmd/pr/merge/merge.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ func NewCmdMerge(f *cmdutil.Factory, runF func(*MergeOptions) error) *cobra.Comm
8686
methodFlags++
8787
}
8888
if methodFlags == 0 {
89-
if !opts.IO.IsStdoutTTY() || !opts.IO.IsStdinTTY() {
90-
return &cmdutil.FlagError{Err: errors.New("--merge, --rebase, or --squash required when not attached to a terminal")}
89+
if !opts.IO.CanPrompt() {
90+
return &cmdutil.FlagError{Err: errors.New("--merge, --rebase, or --squash required when prompts are disabled")}
9191
}
9292
opts.InteractiveMode = true
9393
} else if methodFlags > 1 {

0 commit comments

Comments
 (0)
X Tutup