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*/}}