@@ -53,148 +53,7 @@ Please remember to run `make generate-docs` after your changes to keep the comma
5353
5454Below is a typical structure of a CLI command:
5555
56- ``` go
57- package bar
58-
59- import (
60- (...)
61- )
62-
63- // Define consts for command flags
64- const (
65- someArg = " MY_ARG"
66- someFlag = " my-flag"
67- )
68-
69- // Struct to model user input (arguments and/or flags)
70- type inputModel struct {
71- *globalflags.GlobalFlagModel
72- MyArg string
73- MyFlag *string
74- }
75-
76- // "bar" command constructor
77- func NewCmd (params *params .CmdParams ) *cobra .Command {
78- cmd := &cobra.Command {
79- Use: " bar" ,
80- Short: " Short description of the command (is shown in the help of parent command)" ,
81- Long: " Long description of the command. Can contain some more information about the command usage. It is shown in the help of the current command." ,
82- Args: args.SingleArg (someArg, utils.ValidateUUID ), // Validate argument, with an optional validation function
83- Example: examples.Build (
84- examples.NewExample (
85- ` Do something with command "bar"` ,
86- " $ stackit foo bar arg-value --my-flag flag-value" ),
87- ...
88- ),
89- RunE: func (cmd *cobra.Command , args []string ) error {
90- ctx := context.Background ()
91- model , err := parseInput (params.Printer , cmd, args)
92- if err != nil {
93- return err
94- }
95-
96- // Configure API client
97- apiClient , err := client.ConfigureClient (params.Printer , cmd)
98- if err != nil {
99- return err
100- }
101-
102- // Call API
103- req := buildRequest (ctx, model, apiClient)
104- resp , err := req.Execute ()
105- if err != nil {
106- return fmt.Errorf (" (...): % w" , err)
107- }
108-
109- projectLabel , err := projectname.GetProjectName (ctx, params.Printer , cmd)
110- if err != nil {
111- projectLabel = model.ProjectId
112- }
113-
114- // Check API response "resp" and output accordingly
115- if resp.Item == nil {
116- params.Printer .Info (" (...)" , projectLabel)
117- return nil
118- }
119- return outputResult (params.Printer , cmd, model.OutputFormat , instances)
120- },
121- }
122-
123- configureFlags (cmd)
124- return cmd
125- }
126-
127- // Configure command flags (type, default value, and description)
128- func configureFlags (cmd *cobra .Command ) {
129- cmd.Flags ().StringP (myFlag, " defaultValue" , " My flag description" )
130- }
131-
132- // Parse user input (arguments and/or flags)
133- func parseInput (p *print .Printer , cmd *cobra .Command , inputArgs []string ) (*inputModel , error ) {
134- myArg := inputArgs[0 ]
135-
136- globalFlags := globalflags.Parse (cmd)
137- if globalFlags.ProjectId == " " {
138- return nil , &errors.ProjectIdError {}
139- }
140-
141- model := inputModel{
142- GlobalFlagModel: globalFlags,
143- MyArg: myArg,
144- MyFlag: flags.FlagToStringPointer (cmd, myFlag),
145- }
146-
147- // Write the input model to the debug logs
148- if p.IsVerbosityDebug () {
149- modelStr , err := print .BuildDebugStrFromInputModel (model)
150- if err != nil {
151- p.Debug (print .ErrorLevel , " convert model to string for debugging: %v " , err)
152- } else {
153- p.Debug (print .DebugLevel , " parsed input values: %s " , modelStr)
154- }
155- }
156-
157- return &model, nil
158- }
159-
160- // Build request to the API
161- func buildRequest (ctx context .Context , model *inputModel , apiClient *foo .APIClient ) foo .ApiListInstancesRequest {
162- req := apiClient.GetBar (ctx, model.ProjectId , model.MyArg , someParam)
163- return req
164- }
165-
166- // Output result based on the configured output format
167- func outputResult (p *print .Printer , cmd *cobra .Command , outputFormat string , resources []foo .Resource ) error {
168- switch outputFormat {
169- case print .JSONOutputFormat :
170- details , err := json.MarshalIndent (resources, " " , " " )
171- if err != nil {
172- return fmt.Errorf (" marshal resource list: % w" , err)
173- }
174- p.Outputln (string (details))
175- return nil
176- case print .YAMLOutputFormat :
177- details , err := yaml.Marshal (resources)
178- if err != nil {
179- return fmt.Errorf (" marshal resource list: % w" , err)
180- }
181- p.Outputln (string (details))
182- return nil
183- default :
184- table := tables.NewTable ()
185- table.SetHeader (" ID" , " NAME" , " STATE" )
186- for i := range resources {
187- resource := resources[i]
188- table.AddRow (*resource.ResourceId , *resource.Name , *resource.State )
189- }
190- err := table.Display (cmd)
191- if err != nil {
192- return fmt.Errorf (" render table: % w" , err)
193- }
194- return nil
195- }
196- }
197- ```
56+ https://github.com/stackitcloud/stackit-cli/blob/chore/refactor-cmd-params/.github/docs/contribution-guide/cmd.go#L1-L200
19857
19958Please remember to always add unit tests for ` parseInput ` , ` buildRequest ` (in ` bar_test.go ` ), and any other util functions used.
20059
@@ -224,39 +83,7 @@ If you want to add a command that uses a STACKIT service `foo` that was not yet
22483 1 . This is done in ` internal/pkg/services/foo/client/client.go `
22584 2 . Below is an example of a typical ` client.go ` file structure:
22685
227- ``` go
228- package client
229-
230- import (
231- (...)
232- " github.com/stackitcloud/stackit-sdk-go/services/foo"
233- )
234-
235- func ConfigureClient (cmd *cobra .Command ) (*foo .APIClient , error ) {
236- var err error
237- var apiClient foo.APIClient
238- var cfgOptions []sdkConfig.ConfigurationOption
239-
240- authCfgOption , err := auth.AuthenticationConfig (cmd, auth.AuthorizeUser )
241- if err != nil {
242- return nil , &errors.AuthError {}
243- }
244- cfgOptions = append (cfgOptions, authCfgOption, sdkConfig.WithRegion (" eu01" )) // Configuring region is needed if "foo" is a regional API
245-
246- customEndpoint := viper.GetString (config.fooCustomEndpointKey )
247-
248- if customEndpoint != " " {
249- cfgOptions = append (cfgOptions, sdkConfig.WithEndpoint (customEndpoint))
250- }
251-
252- apiClient, err = foo.NewAPIClient (cfgOptions...)
253- if err != nil {
254- return nil , &errors.AuthError {}
255- }
256-
257- return apiClient, nil
258- }
259- ```
86+ https://github.com/stackitcloud/stackit-cli/blob/chore/refactor-cmd-params/.github/docs/contribution-guide/client.go#L1-L200
26087
26188### Local development
26289
0 commit comments