@@ -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
3134func 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 {
0 commit comments