@@ -30,7 +30,6 @@ type sshOptions struct {
3030 debug bool
3131 debugFile string
3232 stdio bool
33- config bool
3433 scpArgs []string // scp arguments, for 'cs cp' (nil for 'cs ssh')
3534}
3635
@@ -43,7 +42,6 @@ func newSSHCmd(app *App) *cobra.Command {
4342 PreRunE : func (c * cobra.Command , args []string ) error {
4443 f := c .Flags ()
4544 codespaceFlag := f .Lookup ("codespace" )
46- configFlag := f .Lookup ("config" )
4745 portFlag := f .Lookup ("server-port" )
4846 profileFlag := f .Lookup ("profile" )
4947 stdioFlag := f .Lookup ("stdio" )
@@ -52,32 +50,17 @@ func newSSHCmd(app *App) *cobra.Command {
5250 if ! codespaceFlag .Changed {
5351 return errors .New ("`--stdio` requires explicit `--codespace`" )
5452 }
55- if configFlag .Changed {
56- return errors .New ("cannot use `--stdio` with `--config`" )
57- }
5853 if portFlag .Changed {
5954 return errors .New ("cannot use `--stdio` with `--server-port`" )
6055 }
6156 if profileFlag .Changed {
6257 return errors .New ("cannot use `--stdio` with `--profile`" )
6358 }
6459 }
65- if configFlag .Changed {
66- if profileFlag .Changed {
67- return errors .New ("cannot use `--config` with `--profile`" )
68- }
69- if portFlag .Changed {
70- return errors .New ("cannot use `--config` with `--server-port`" )
71- }
72- }
7360 return nil
7461 },
7562 RunE : func (cmd * cobra.Command , args []string ) error {
76- if opts .config {
77- return app .ListOpensshConfig (cmd .Context (), opts )
78- } else {
79- return app .SSH (cmd .Context (), args , opts )
80- }
63+ return app .SSH (cmd .Context (), args , opts )
8164 },
8265 DisableFlagsInUseLine : true ,
8366 }
@@ -88,7 +71,8 @@ func newSSHCmd(app *App) *cobra.Command {
8871 sshCmd .Flags ().BoolVarP (& opts .debug , "debug" , "d" , false , "Log debug data to a file" )
8972 sshCmd .Flags ().StringVarP (& opts .debugFile , "debug-file" , "" , "" , "Path of the file log to" )
9073 sshCmd .Flags ().BoolVarP (& opts .stdio , "stdio" , "" , false , "Proxy sshd connection to stdio" )
91- sshCmd .Flags ().BoolVarP (& opts .config , "config" , "" , false , "Write OpenSSH configuration to stdout" )
74+
75+ sshCmd .AddCommand (newConfigCmd (app ))
9276
9377 return sshCmd
9478}
@@ -177,7 +161,7 @@ func (a *App) SSH(ctx context.Context, sshArgs []string, opts sshOptions) (err e
177161 }
178162}
179163
180- func (a * App ) ListOpensshConfig (ctx context.Context , opts sshOptions ) error {
164+ func (a * App ) ListOpensshConfig (ctx context.Context , opts configOptions ) error {
181165 // Ensure all child tasks (e.g. port forwarding) terminate before return.
182166 ctx , cancel := context .WithCancel (ctx )
183167 defer cancel ()
@@ -391,6 +375,37 @@ func (a *App) Copy(ctx context.Context, args []string, opts cpOptions) error {
391375 return a .SSH (ctx , nil , opts .sshOptions )
392376}
393377
378+ type configOptions struct {
379+ codespace string
380+ }
381+
382+ func newConfigCmd (app * App ) * cobra.Command {
383+ var opts configOptions
384+
385+ configCmd := & cobra.Command {
386+ Use : "config [-c codespace]" ,
387+ Short : "Write OpenSSH configuration to stdout" ,
388+ Long : heredoc .Docf (`
389+ The config command generates ssh connection configuration in OpenSSH format.
390+
391+ If -c/--codespace is specified, configuration is generated for that codespace
392+ only. Otherwise configuration is emitted for all available codespaces.
393+ ` , "`" ),
394+ Example : heredoc .Doc (`
395+ $ gh codespace config > ~/.ssh/codespaces
396+ $ echo 'include ~/.ssh/codespaces' >> ~/.ssh/config'
397+ ` ),
398+ RunE : func (cmd * cobra.Command , args []string ) error {
399+ return app .ListOpensshConfig (cmd .Context (), opts )
400+ },
401+ DisableFlagsInUseLine : true ,
402+ }
403+
404+ configCmd .Flags ().StringVarP (& opts .codespace , "codespace" , "c" , "" , "Name of the codespace" )
405+
406+ return configCmd
407+ }
408+
394409// fileLogger is a wrapper around an log.Logger configured to write
395410// to a file. It exports two additional methods to get the log file name
396411// and close the file handle when the operation is finished.
0 commit comments