Skip to content

Commit 0af61ff

Browse files
committed
Merge remote-tracking branch 'origin/trunk' into more-gists
2 parents 1887fc0 + 2071c72 commit 0af61ff

File tree

13 files changed

+862
-71
lines changed

13 files changed

+862
-71
lines changed

.github/CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Please avoid:
2727

2828
Prerequisites:
2929
- Go 1.13+ for building the binary
30-
- Go 1.14+ for running the test suite
30+
- Go 1.15+ for running the test suite
3131

3232
Build with: `make` or `go build -o bin/gh ./cmd/gh`
3333

.github/ISSUE_TEMPLATE/feedback.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
name: "\U0001F4E3 Feedback"
3+
about: Give us general feedback about the GitHub CLI
4+
title: ''
5+
labels: feedback
6+
assignees: ''
7+
8+
---
9+
10+
# CLI Feedback
11+
12+
You can use this template to give us structured feedback or just wipe it and leave us a note. Thank you!
13+
14+
## What have you loved?
15+
16+
_eg "the nice colors"_
17+
18+
## What was confusing or gave you pause?
19+
20+
_eg "it did something unexpected"_
21+
22+
## Are there features you'd like to see added?
23+
24+
_eg "gh cli needs mini-games"_
25+
26+
## Anything else?
27+
28+
_eg "have a nice day"_

pkg/cmd/auth/login/login.go

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@ type LoginOptions struct {
2424
IO *iostreams.IOStreams
2525
Config func() (config.Config, error)
2626

27+
Interactive bool
28+
2729
Hostname string
2830
Token string
31+
Web bool
2932
}
3033

3134
func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Command {
@@ -58,6 +61,14 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
5861
# => read token from mytoken.txt and authenticate against a GitHub Enterprise Server instance
5962
`),
6063
RunE: func(cmd *cobra.Command, args []string) error {
64+
if !opts.IO.CanPrompt() && !(tokenStdin || opts.Web) {
65+
return &cmdutil.FlagError{Err: errors.New("--web or --with-token required when not running interactively")}
66+
}
67+
68+
if tokenStdin && opts.Web {
69+
return &cmdutil.FlagError{Err: errors.New("specify only one of --web or --with-token")}
70+
}
71+
6172
if tokenStdin {
6273
defer opts.IO.In.Close()
6374
token, err := ioutil.ReadAll(opts.IO.In)
@@ -67,15 +78,8 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
6778
opts.Token = strings.TrimSpace(string(token))
6879
}
6980

70-
if opts.Token != "" {
71-
// Assume non-interactive if a token is specified
72-
if opts.Hostname == "" {
73-
opts.Hostname = ghinstance.Default()
74-
}
75-
} else {
76-
if !opts.IO.CanPrompt() {
77-
return &cmdutil.FlagError{Err: errors.New("--with-token required when not running interactively")}
78-
}
81+
if opts.IO.CanPrompt() && opts.Token == "" && !opts.Web {
82+
opts.Interactive = true
7983
}
8084

8185
if cmd.Flags().Changed("hostname") {
@@ -84,6 +88,12 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
8488
}
8589
}
8690

91+
if !opts.Interactive {
92+
if opts.Hostname == "" {
93+
opts.Hostname = ghinstance.Default()
94+
}
95+
}
96+
8797
if runF != nil {
8898
return runF(opts)
8999
}
@@ -94,6 +104,7 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
94104

95105
cmd.Flags().StringVarP(&opts.Hostname, "hostname", "h", "", "The hostname of the GitHub instance to authenticate with")
96106
cmd.Flags().BoolVar(&tokenStdin, "with-token", false, "Read token from standard input")
107+
cmd.Flags().BoolVarP(&opts.Web, "web", "w", false, "Open a browser to authenticate")
97108

98109
return cmd
99110
}
@@ -160,7 +171,7 @@ func loginRun(opts *LoginOptions) error {
160171

161172
existingToken, _ := cfg.Get(hostname, "oauth_token")
162173

163-
if existingToken != "" {
174+
if existingToken != "" && opts.Interactive {
164175
err := client.ValidateHostCfg(hostname, cfg)
165176
if err == nil {
166177
apiClient, err := client.ClientFromCfg(hostname, cfg)
@@ -195,15 +206,19 @@ func loginRun(opts *LoginOptions) error {
195206
}
196207

197208
var authMode int
198-
err = prompt.SurveyAskOne(&survey.Select{
199-
Message: "How would you like to authenticate?",
200-
Options: []string{
201-
"Login with a web browser",
202-
"Paste an authentication token",
203-
},
204-
}, &authMode)
205-
if err != nil {
206-
return fmt.Errorf("could not prompt: %w", err)
209+
if opts.Web {
210+
authMode = 0
211+
} else {
212+
err = prompt.SurveyAskOne(&survey.Select{
213+
Message: "How would you like to authenticate?",
214+
Options: []string{
215+
"Login with a web browser",
216+
"Paste an authentication token",
217+
},
218+
}, &authMode)
219+
if err != nil {
220+
return fmt.Errorf("could not prompt: %w", err)
221+
}
207222
}
208223

209224
if authMode == 0 {
@@ -239,27 +254,29 @@ func loginRun(opts *LoginOptions) error {
239254
}
240255
}
241256

242-
var gitProtocol string
243-
err = prompt.SurveyAskOne(&survey.Select{
244-
Message: "Choose default git protocol",
245-
Options: []string{
246-
"HTTPS",
247-
"SSH",
248-
},
249-
}, &gitProtocol)
250-
if err != nil {
251-
return fmt.Errorf("could not prompt: %w", err)
252-
}
257+
gitProtocol := "https"
258+
if opts.Interactive {
259+
err = prompt.SurveyAskOne(&survey.Select{
260+
Message: "Choose default git protocol",
261+
Options: []string{
262+
"HTTPS",
263+
"SSH",
264+
},
265+
}, &gitProtocol)
266+
if err != nil {
267+
return fmt.Errorf("could not prompt: %w", err)
268+
}
253269

254-
gitProtocol = strings.ToLower(gitProtocol)
270+
gitProtocol = strings.ToLower(gitProtocol)
255271

256-
fmt.Fprintf(opts.IO.ErrOut, "- gh config set -h %s git_protocol %s\n", hostname, gitProtocol)
257-
err = cfg.Set(hostname, "git_protocol", gitProtocol)
258-
if err != nil {
259-
return err
260-
}
272+
fmt.Fprintf(opts.IO.ErrOut, "- gh config set -h %s git_protocol %s\n", hostname, gitProtocol)
273+
err = cfg.Set(hostname, "git_protocol", gitProtocol)
274+
if err != nil {
275+
return err
276+
}
261277

262-
fmt.Fprintf(opts.IO.ErrOut, "%s Configured git protocol\n", utils.GreenCheck())
278+
fmt.Fprintf(opts.IO.ErrOut, "%s Configured git protocol\n", utils.GreenCheck())
279+
}
263280

264281
apiClient, err := client.ClientFromCfg(hostname, cfg)
265282
if err != nil {

pkg/cmd/auth/login/login_test.go

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,43 @@ func Test_NewCmdLogin(t *testing.T) {
8181
stdinTTY: true,
8282
cli: "--hostname barry.burton",
8383
wants: LoginOptions{
84-
Hostname: "barry.burton",
85-
Token: "",
84+
Hostname: "barry.burton",
85+
Token: "",
86+
Interactive: true,
8687
},
8788
},
8889
{
8990
name: "tty",
9091
stdinTTY: true,
9192
cli: "",
9293
wants: LoginOptions{
93-
Hostname: "",
94-
Token: "",
94+
Hostname: "",
95+
Token: "",
96+
Interactive: true,
9597
},
9698
},
99+
{
100+
name: "tty web",
101+
stdinTTY: true,
102+
cli: "--web",
103+
wants: LoginOptions{
104+
Hostname: "github.com",
105+
Web: true,
106+
},
107+
},
108+
{
109+
name: "nontty web",
110+
cli: "--web",
111+
wants: LoginOptions{
112+
Hostname: "github.com",
113+
Web: true,
114+
},
115+
},
116+
{
117+
name: "web and with-token",
118+
cli: "--web --with-token",
119+
wantsErr: true,
120+
},
97121
}
98122

99123
for _, tt := range tests {
@@ -134,6 +158,8 @@ func Test_NewCmdLogin(t *testing.T) {
134158

135159
assert.Equal(t, tt.wants.Token, gotOpts.Token)
136160
assert.Equal(t, tt.wants.Hostname, gotOpts.Hostname)
161+
assert.Equal(t, tt.wants.Web, gotOpts.Web)
162+
assert.Equal(t, tt.wants.Interactive, gotOpts.Interactive)
137163
})
138164
}
139165
}
@@ -262,6 +288,9 @@ func Test_loginRun_Survey(t *testing.T) {
262288
}{
263289
{
264290
name: "already authenticated",
291+
opts: &LoginOptions{
292+
Interactive: true,
293+
},
265294
cfg: func(cfg config.Config) {
266295
_ = cfg.Set("github.com", "oauth_token", "ghi789")
267296
},
@@ -280,7 +309,8 @@ func Test_loginRun_Survey(t *testing.T) {
280309
{
281310
name: "hostname set",
282311
opts: &LoginOptions{
283-
Hostname: "rebecca.chambers",
312+
Hostname: "rebecca.chambers",
313+
Interactive: true,
284314
},
285315
wantHosts: "rebecca.chambers:\n oauth_token: def456\n git_protocol: https\n user: jillv\n",
286316
askStubs: func(as *prompt.AskStubber) {
@@ -298,6 +328,9 @@ func Test_loginRun_Survey(t *testing.T) {
298328
{
299329
name: "choose enterprise",
300330
wantHosts: "brad.vickers:\n oauth_token: def456\n git_protocol: https\n user: jillv\n",
331+
opts: &LoginOptions{
332+
Interactive: true,
333+
},
301334
askStubs: func(as *prompt.AskStubber) {
302335
as.StubOne(1) // host type enterprise
303336
as.StubOne("brad.vickers") // hostname
@@ -315,6 +348,9 @@ func Test_loginRun_Survey(t *testing.T) {
315348
{
316349
name: "choose github.com",
317350
wantHosts: "github.com:\n oauth_token: def456\n git_protocol: https\n user: jillv\n",
351+
opts: &LoginOptions{
352+
Interactive: true,
353+
},
318354
askStubs: func(as *prompt.AskStubber) {
319355
as.StubOne(0) // host type github.com
320356
as.StubOne(1) // auth mode: token
@@ -325,6 +361,9 @@ func Test_loginRun_Survey(t *testing.T) {
325361
{
326362
name: "sets git_protocol",
327363
wantHosts: "github.com:\n oauth_token: def456\n git_protocol: ssh\n user: jillv\n",
364+
opts: &LoginOptions{
365+
Interactive: true,
366+
},
328367
askStubs: func(as *prompt.AskStubber) {
329368
as.StubOne(0) // host type github.com
330369
as.StubOne(1) // auth mode: token

pkg/cmd/config/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ func NewCmdConfig(f *cmdutil.Factory) *cobra.Command {
1818
Current respected settings:
1919
- git_protocol: "https" or "ssh". Default is "https".
2020
- editor: if unset, defaults to environment variables.
21+
- prompt: "enabled" or "disabled". Toggles interactive prompting.
2122
`),
2223
}
2324

@@ -72,6 +73,8 @@ func NewCmdConfigSet(f *cmdutil.Factory) *cobra.Command {
7273
Example: heredoc.Doc(`
7374
$ gh config set editor vim
7475
$ gh config set editor "code --wait"
76+
$ gh config set git_protocol ssh
77+
$ gh config set prompt disabled
7578
`),
7679
Args: cobra.ExactArgs(2),
7780
RunE: func(cmd *cobra.Command, args []string) error {

pkg/cmd/factory/http.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func NewHTTPClient(io *iostreams.IOStreams, cfg config.Config, appVersion string
2424
api.AddHeader("User-Agent", fmt.Sprintf("GitHub CLI %s", appVersion)),
2525
api.AddHeaderFunc("Authorization", func(req *http.Request) (string, error) {
2626
hostname := ghinstance.NormalizeHostname(req.URL.Hostname())
27-
if token, err := cfg.Get(hostname, "oauth_token"); err == nil || token != "" {
27+
if token, err := cfg.Get(hostname, "oauth_token"); err == nil && token != "" {
2828
return fmt.Sprintf("token %s", token), nil
2929
}
3030
return "", nil

0 commit comments

Comments
 (0)