github.com/jamescostian/go-swagger@v0.30.4-0.20221130163922-68364d6b567b/generator/templates/cli/cli.gotmpl (about) 1 // Code generated by go-swagger; DO NOT EDIT. 2 3 4 {{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} 5 6 7 package {{ .GenOpts.CliPackage }} 8 9 // This file was generated by the swagger tool. 10 // Editing this file might prove futile when you re-run the swagger generate command 11 12 import ( 13 {{ imports .DefaultImports }} 14 {{ imports .Imports }} 15 16 "github.com/spf13/cobra" 17 "github.com/spf13/viper" 18 "github.com/go-openapi/runtime" 19 "github.com/go-openapi/swag" 20 httptransport "github.com/go-openapi/runtime/client" 21 homedir "github.com/mitchellh/go-homedir" 22 ) 23 24 // debug flag indicating that cli should output debug logs 25 var debug bool 26 // config file location 27 var configFile string 28 // dry run flag 29 var dryRun bool 30 31 // name of the executable 32 var exeName string = filepath.Base(os.Args[0]) 33 34 // logDebugf writes debug log to stdout 35 func logDebugf(format string, v ...interface{}) { 36 if !debug{ 37 return 38 } 39 log.Printf(format, v...) 40 } 41 42 {{/*TODO: make this a swagger cli option*/}} 43 // depth of recursion to construct model flags 44 var maxDepth int = 5 45 46 // makeClient constructs a client object 47 func makeClient(cmd *cobra.Command, args []string) (*client.{{ pascalize .Name }}, error) { 48 hostname := viper.GetString("hostname") 49 viper.SetDefault("base_path", client.DefaultBasePath) 50 basePath := viper.GetString("base_path") 51 scheme := viper.GetString("scheme") 52 53 r := httptransport.New(hostname, basePath, []string{scheme}) 54 r.SetDebug(debug) 55 56 {{- /* user might define custom mediatype xxx/json and there is no registered ones to handle. */}} 57 // set custom producer and consumer to use the default ones 58 {{ range .Consumes }} 59 {{ range .AllSerializers }} 60 {{- if stringContains .MediaType "json" }} 61 r.Consumers["{{ .MediaType }}"] = runtime.JSONConsumer() 62 {{- else }} 63 // warning: consumes {{ .MediaType }} is not supported by go-swagger cli yet 64 {{- end }} 65 {{- end }} 66 {{ end }} 67 {{ range .Produces }} 68 {{- range .AllSerializers }} 69 {{- if stringContains .MediaType "json" }} 70 r.Producers["{{ .MediaType }}"] = runtime.JSONProducer() 71 {{- else }} 72 // warning: produces {{ .MediaType }} is not supported by go-swagger cli yet 73 {{- end }} 74 {{- end }} 75 {{ end }} 76 77 {{- if .SecurityDefinitions }} 78 auth, err := makeAuthInfoWriter(cmd) 79 if err != nil { 80 return nil, err 81 } 82 r.DefaultAuthentication = auth 83 {{ end }} 84 appCli := client.New(r, strfmt.Default) 85 logDebugf("Server url: %v://%v", scheme, hostname) 86 return appCli, nil 87 } 88 89 // MakeRootCmd returns the root cmd 90 func MakeRootCmd() (*cobra.Command, error) { 91 cobra.OnInitialize(initViperConfigs) 92 93 // Use executable name as the command name 94 rootCmd := &cobra.Command{ 95 Use: exeName, 96 } 97 {{/*note: viper binded flag value must be retrieved from viper rather than cmd*/}} 98 // register basic flags 99 rootCmd.PersistentFlags().String("hostname", client.DefaultHost, "hostname of the service") 100 viper.BindPFlag("hostname", rootCmd.PersistentFlags().Lookup("hostname")) 101 rootCmd.PersistentFlags().String("scheme", client.DefaultSchemes[0], fmt.Sprintf("Choose from: %v", client.DefaultSchemes)) 102 viper.BindPFlag("scheme", rootCmd.PersistentFlags().Lookup("scheme")) 103 rootCmd.PersistentFlags().String("base-path", client.DefaultBasePath, fmt.Sprintf("For example: %v", client.DefaultBasePath)) 104 viper.BindPFlag("base_path", rootCmd.PersistentFlags().Lookup("base-path")) 105 106 // configure debug flag 107 rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "output debug logs") 108 // configure config location 109 rootCmd.PersistentFlags().StringVar(&configFile, "config", "", "config file path") 110 // configure dry run flag 111 rootCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "do not send the request to server") 112 113 // register security flags 114 {{- if .SecurityDefinitions }} 115 if err := registerAuthInoWriterFlags(rootCmd); err != nil{ 116 return nil, err 117 } 118 {{- end }} 119 // add all operation groups 120 {{- range .OperationGroups -}} 121 {{- $operationGroupCmdVarName := printf "operationGroup%vCmd" (pascalize .Name) }} 122 {{ $operationGroupCmdVarName }}, err := makeOperationGroup{{ pascalize .Name }}Cmd() 123 if err != nil { 124 return nil, err 125 } 126 rootCmd.AddCommand({{ $operationGroupCmdVarName }}) 127 {{ end }} 128 129 // add cobra completion 130 rootCmd.AddCommand(makeGenCompletionCmd()) 131 132 return rootCmd, nil 133 } 134 135 // initViperConfigs initialize viper config using config file in '$HOME/.config/<cli name>/config.<json|yaml...>' 136 // currently hostname, scheme and auth tokens can be specified in this config file. 137 func initViperConfigs() { 138 if configFile != "" { 139 // use user specified config file location 140 viper.SetConfigFile(configFile) 141 }else{ 142 // look for default config 143 // Find home directory. 144 home, err := homedir.Dir() 145 cobra.CheckErr(err) 146 147 // Search config in home directory with name ".cobra" (without extension). 148 viper.AddConfigPath(path.Join(home, ".config", exeName)) 149 viper.SetConfigName("config") 150 } 151 152 if err := viper.ReadInConfig(); err != nil { 153 logDebugf("Error: loading config file: %v", err) 154 return 155 } 156 logDebugf("Using config file: %v", viper.ConfigFileUsed()) 157 } 158 159 {{- if .SecurityDefinitions }} 160 {{- /*youyuan: rework this since spec may define multiple auth schemes. 161 cli needs to detect which one user passed rather than add all of them.*/}} 162 // registerAuthInoWriterFlags registers all flags needed to perform authentication 163 func registerAuthInoWriterFlags(cmd *cobra.Command) error { 164 {{- range .SecurityDefinitions }} 165 /*{{.Name}} {{.Description}}*/ 166 {{- if .IsBasicAuth }} 167 cmd.PersistentFlags().String("username", "", "username for basic auth") 168 viper.BindPFlag("username", cmd.PersistentFlags().Lookup("username")) 169 cmd.PersistentFlags().String("password", "", "password for basic auth") 170 viper.BindPFlag("password", cmd.PersistentFlags().Lookup("password")) 171 {{- end }} 172 {{- if .IsAPIKeyAuth }} 173 cmd.PersistentFlags().String("{{.Name}}", "", `{{.Description}}`) 174 viper.BindPFlag("{{.Name}}", cmd.PersistentFlags().Lookup("{{.Name}}")) 175 {{- end }} 176 {{- if .IsOAuth2 }} 177 // oauth2: let user provide the token in a flag, rather than implement the logic to fetch the token. 178 cmd.PersistentFlags().String("oauth2-token", "", `{{.Description}}`) 179 viper.BindPFlag("oauth2-token", cmd.PersistentFlags().Lookup("oauth2-token")) 180 {{- end }} 181 {{- end }} 182 return nil 183 } 184 185 // makeAuthInfoWriter retrieves cmd flags and construct an auth info writer 186 func makeAuthInfoWriter(cmd *cobra.Command) (runtime.ClientAuthInfoWriter, error) { 187 auths := []runtime.ClientAuthInfoWriter{} 188 {{- range .SecurityDefinitions }} 189 /*{{.Name}} {{.Description}}*/ 190 {{- if .IsBasicAuth }} 191 if viper.IsSet("username") { 192 usr := viper.GetString("username") 193 if !viper.IsSet("password"){ 194 return nil, fmt.Errorf("Basic Auth password for user [%v] is not provided.", usr) 195 } 196 pwd := viper.GetString("password") 197 auths = append(auths, httptransport.BasicAuth(usr,pwd)) 198 } 199 {{- end }} 200 {{- if .IsAPIKeyAuth }} 201 if viper.IsSet("{{.Name}}") { 202 {{ pascalize .Name }}Key := viper.GetString("{{.Name}}") 203 auths = append(auths, httptransport.APIKeyAuth("{{.Name}}", "{{.In}}", {{ pascalize .Name }}Key)) 204 } 205 {{- end }} 206 {{- if .IsOAuth2 }} 207 if viper.IsSet("oauth2-token") { 208 // oauth2 workflow for generated CLI is not ideal. 209 // If you have suggestions on how to support it, raise an issue here: https://github.com/go-swagger/go-swagger/issues 210 // This will be added to header: "Authorization: Bearer {oauth2-token value}" 211 token := viper.GetString("oauth2-token") 212 auths = append(auths, httptransport.BearerToken(token)) 213 } 214 {{- end }} 215 {{- end }} 216 if len(auths) == 0 { 217 logDebugf("Warning: No auth params detected.") 218 return nil, nil 219 } 220 // compose all auths together 221 return httptransport.Compose(auths...), nil 222 } 223 {{- end }} 224 225 {{ range .OperationGroups -}} 226 func makeOperationGroup{{ pascalize .Name }}Cmd() (*cobra.Command, error) { 227 {{- $operationGroupCmdVarName := printf "operationGroup%vCmd" (pascalize .Name) }} 228 {{ $operationGroupCmdVarName }} := &cobra.Command{ 229 Use: "{{ .Name }}", 230 Long: `{{ .Description }}`, 231 } 232 {{ range .Operations }} 233 {{- $operationCmdVarName := printf "operation%vCmd" (pascalize .Name) }} 234 {{ $operationCmdVarName }}, err := makeOperation{{pascalize .Package}}{{ pascalize .Name }}Cmd() 235 if err != nil { 236 return nil, err 237 } 238 {{ $operationGroupCmdVarName }}.AddCommand({{ $operationCmdVarName }}) 239 {{ end }} 240 return {{ $operationGroupCmdVarName }}, nil 241 } 242 {{ end }} {{/*operation group*/}}