Skip to content

Commit 1d85aa4

Browse files
authored
fix: Add nil checks for values which are printed to the console (#583)
* add nil checks and wrap output of pointers with utils.PtrString() * fix: linter issues * Add tests cases for outputResult * implement review feedback
1 parent 3a4bf87 commit 1d85aa4

File tree

182 files changed

+1299
-763
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+1299
-763
lines changed

internal/cmd/beta/image/create/create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ func outputResult(p *print.Printer, model *inputModel, resp *iaas.ImageCreateRes
395395

396396
return nil
397397
default:
398-
p.Outputf("Created image %q with id %s\n", model.Name, *model.Id)
398+
p.Outputf("Created image %q with id %s\n", model.Name, utils.PtrString(model.Id))
399399
return nil
400400
}
401401
}

internal/cmd/beta/key-pair/create/create.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func NewCmd(p *print.Printer) *cobra.Command {
8282
return fmt.Errorf("create key pair: %w", err)
8383
}
8484

85-
return outputResult(p, model, resp)
85+
return outputResult(p, model.GlobalFlagModel.OutputFormat, resp)
8686
},
8787
}
8888
configureFlags(cmd)
@@ -141,8 +141,12 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli
141141
return req.CreateKeyPairPayload(payload)
142142
}
143143

144-
func outputResult(p *print.Printer, model *inputModel, item *iaas.Keypair) error {
145-
switch model.OutputFormat {
144+
func outputResult(p *print.Printer, outputFormat string, item *iaas.Keypair) error {
145+
if item == nil {
146+
return fmt.Errorf("no key pair found")
147+
}
148+
149+
switch outputFormat {
146150
case print.JSONOutputFormat:
147151
details, err := json.MarshalIndent(item, "", " ")
148152
if err != nil {
@@ -156,7 +160,10 @@ func outputResult(p *print.Printer, model *inputModel, item *iaas.Keypair) error
156160
}
157161
p.Outputln(string(details))
158162
default:
159-
p.Outputf("Created key pair %q.\nkey pair Fingerprint: %q\n", *item.Name, *item.Fingerprint)
163+
p.Outputf("Created key pair %q.\nkey pair Fingerprint: %q\n",
164+
utils.PtrString(item.Name),
165+
utils.PtrString(item.Fingerprint),
166+
)
160167
}
161168
return nil
162169
}

internal/cmd/beta/key-pair/create/create_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,42 @@ func TestBuildRequest(t *testing.T) {
194194
})
195195
}
196196
}
197+
198+
func Test_outputResult(t *testing.T) {
199+
type args struct {
200+
item *iaas.Keypair
201+
outputFormat string
202+
}
203+
tests := []struct {
204+
name string
205+
args args
206+
wantErr bool
207+
}{
208+
{
209+
name: "empty",
210+
args: args{
211+
item: nil,
212+
outputFormat: "",
213+
},
214+
wantErr: true,
215+
},
216+
{
217+
name: "base",
218+
args: args{
219+
item: &iaas.Keypair{},
220+
outputFormat: "",
221+
},
222+
wantErr: false,
223+
},
224+
}
225+
226+
p := print.NewPrinter()
227+
p.Cmd = NewCmd(p)
228+
for _, tt := range tests {
229+
t.Run(tt.name, func(t *testing.T) {
230+
if err := outputResult(p, tt.args.outputFormat, tt.args.item); (err != nil) != tt.wantErr {
231+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
232+
}
233+
})
234+
}
235+
}

internal/cmd/beta/key-pair/describe/describe.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"fmt"
77
"strings"
88

9+
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
10+
911
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
1012
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
1113
"github.com/stackitcloud/stackit-cli/internal/pkg/flags"
@@ -69,7 +71,11 @@ func NewCmd(p *print.Printer) *cobra.Command {
6971
return fmt.Errorf("read key pair: %w", err)
7072
}
7173

72-
return outputResult(p, model.OutputFormat, model.PublicKey, resp)
74+
if keypair := resp; keypair != nil {
75+
return outputResult(p, model.OutputFormat, model.PublicKey, *keypair)
76+
}
77+
p.Outputln("No keypair found.")
78+
return nil
7379
},
7480
}
7581
configureFlags(cmd)
@@ -107,7 +113,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli
107113
return apiClient.GetKeyPair(ctx, model.KeyPairName)
108114
}
109115

110-
func outputResult(p *print.Printer, outputFormat string, showOnlyPublicKey bool, keyPair *iaas.Keypair) error {
116+
func outputResult(p *print.Printer, outputFormat string, showOnlyPublicKey bool, keyPair iaas.Keypair) error {
111117
switch outputFormat {
112118
case print.JSONOutputFormat:
113119
details, err := json.MarshalIndent(keyPair, "", " ")
@@ -145,10 +151,10 @@ func outputResult(p *print.Printer, outputFormat string, showOnlyPublicKey bool,
145151
return nil
146152
}
147153
table := tables.NewTable()
148-
table.AddRow("KEY PAIR NAME", *keyPair.Name)
154+
table.AddRow("KEY PAIR NAME", utils.PtrString(keyPair.Name))
149155
table.AddSeparator()
150156

151-
if *keyPair.Labels != nil && len(*keyPair.Labels) > 0 {
157+
if keyPair.Labels != nil && len(*keyPair.Labels) > 0 {
152158
var labels []string
153159
for key, value := range *keyPair.Labels {
154160
labels = append(labels, fmt.Sprintf("%s: %s", key, value))
@@ -157,17 +163,21 @@ func outputResult(p *print.Printer, outputFormat string, showOnlyPublicKey bool,
157163
table.AddSeparator()
158164
}
159165

160-
table.AddRow("FINGERPRINT", *keyPair.Fingerprint)
166+
table.AddRow("FINGERPRINT", utils.PtrString(keyPair.Fingerprint))
161167
table.AddSeparator()
162168

163-
truncatedPublicKey := (*keyPair.PublicKey)[:maxLengthPublicKey] + "..."
169+
truncatedPublicKey := ""
170+
if keyPair.PublicKey != nil {
171+
truncatedPublicKey = (*keyPair.PublicKey)[:maxLengthPublicKey] + "..."
172+
}
173+
164174
table.AddRow("PUBLIC KEY", truncatedPublicKey)
165175
table.AddSeparator()
166176

167-
table.AddRow("CREATED AT", *keyPair.CreatedAt)
177+
table.AddRow("CREATED AT", utils.PtrString(keyPair.CreatedAt))
168178
table.AddSeparator()
169179

170-
table.AddRow("UPDATED AT", *keyPair.UpdatedAt)
180+
table.AddRow("UPDATED AT", utils.PtrString(keyPair.UpdatedAt))
171181
table.AddSeparator()
172182

173183
p.Outputln(table.Render())

internal/cmd/beta/key-pair/describe/describe_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,35 @@ func TestBuildRequest(t *testing.T) {
186186
})
187187
}
188188
}
189+
190+
func Test_outputResult(t *testing.T) {
191+
type args struct {
192+
outputFormat string
193+
showOnlyPublicKey bool
194+
keyPair iaas.Keypair
195+
}
196+
tests := []struct {
197+
name string
198+
args args
199+
wantErr bool
200+
}{
201+
{
202+
name: "base",
203+
args: args{
204+
outputFormat: "",
205+
showOnlyPublicKey: false,
206+
keyPair: iaas.Keypair{},
207+
},
208+
wantErr: false,
209+
},
210+
}
211+
p := print.NewPrinter()
212+
p.Cmd = NewCmd(p)
213+
for _, tt := range tests {
214+
t.Run(tt.name, func(t *testing.T) {
215+
if err := outputResult(p, tt.args.outputFormat, tt.args.showOnlyPublicKey, tt.args.keyPair); (err != nil) != tt.wantErr {
216+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
217+
}
218+
})
219+
}
220+
}

internal/cmd/beta/key-pair/list/list.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"fmt"
77
"strings"
88

9+
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
10+
911
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
1012
"github.com/stackitcloud/stackit-cli/internal/pkg/errors"
1113
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
@@ -158,11 +160,19 @@ func outputResult(p *print.Printer, outputFormat string, keyPairs []iaas.Keypair
158160
keyPair := keyPairs[idx]
159161

160162
var labels []string
161-
for key, value := range *keyPair.Labels {
162-
labels = append(labels, fmt.Sprintf("%s: %s", key, value))
163+
if keyPair.Labels != nil {
164+
for key, value := range *keyPair.Labels {
165+
labels = append(labels, fmt.Sprintf("%s: %s", key, value))
166+
}
163167
}
164168

165-
table.AddRow(*keyPair.Name, strings.Join(labels, ", "), *keyPair.Fingerprint, *keyPair.CreatedAt, *keyPair.UpdatedAt)
169+
table.AddRow(
170+
utils.PtrString(keyPair.Name),
171+
strings.Join(labels, ", "),
172+
utils.PtrString(keyPair.Fingerprint),
173+
utils.PtrString(keyPair.CreatedAt),
174+
utils.PtrString(keyPair.UpdatedAt),
175+
)
166176
}
167177

168178
p.Outputln(table.Render())

internal/cmd/beta/key-pair/list/list_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,37 @@ func TestBuildRequest(t *testing.T) {
186186
})
187187
}
188188
}
189+
190+
func Test_outputResult(t *testing.T) {
191+
type args struct {
192+
outputFormat string
193+
keyPairs []iaas.Keypair
194+
}
195+
tests := []struct {
196+
name string
197+
args args
198+
wantErr bool
199+
}{
200+
{
201+
name: "empty",
202+
args: args{
203+
outputFormat: "",
204+
keyPairs: []iaas.Keypair{
205+
{},
206+
},
207+
},
208+
wantErr: false,
209+
},
210+
}
211+
212+
for _, tt := range tests {
213+
t.Run(tt.name, func(t *testing.T) {
214+
p := print.NewPrinter()
215+
p.Cmd = NewCmd(p)
216+
217+
if err := outputResult(p, tt.args.outputFormat, tt.args.keyPairs); (err != nil) != tt.wantErr {
218+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
219+
}
220+
})
221+
}
222+
}

internal/cmd/beta/key-pair/update/update.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@ func NewCmd(p *print.Printer) *cobra.Command {
4343
),
4444
RunE: func(cmd *cobra.Command, args []string) error {
4545
ctx := context.Background()
46-
model, err := parseInput(p, cmd, args)
47-
if err != nil {
48-
return err
49-
}
46+
model := parseInput(p, cmd, args)
5047

5148
// Configure API client
5249
apiClient, err := client.ConfigureClient(p)
@@ -63,13 +60,16 @@ func NewCmd(p *print.Printer) *cobra.Command {
6360
}
6461

6562
// Call API
66-
req := buildRequest(ctx, model, apiClient)
63+
req := buildRequest(ctx, &model, apiClient)
6764
resp, err := req.Execute()
6865
if err != nil {
6966
return fmt.Errorf("update key pair: %w", err)
7067
}
68+
if resp == nil {
69+
return fmt.Errorf("response is nil")
70+
}
7171

72-
return outputResult(p, model, resp)
72+
return outputResult(p, model, *resp)
7373
},
7474
}
7575
configureFlags(cmd)
@@ -100,7 +100,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli
100100
return req.UpdateKeyPairPayload(payload)
101101
}
102102

103-
func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) {
103+
func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) inputModel {
104104
keyPairName := inputArgs[0]
105105
globalFlags := globalflags.Parse(p, cmd)
106106

@@ -119,11 +119,15 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu
119119
}
120120
}
121121

122-
return &model, nil
122+
return model
123123
}
124124

125-
func outputResult(p *print.Printer, model *inputModel, keyPair *iaas.Keypair) error {
126-
switch model.OutputFormat {
125+
func outputResult(p *print.Printer, model inputModel, keyPair iaas.Keypair) error {
126+
var outputFormat string
127+
if model.GlobalFlagModel != nil {
128+
outputFormat = model.GlobalFlagModel.OutputFormat
129+
}
130+
switch outputFormat {
127131
case print.JSONOutputFormat:
128132
details, err := json.MarshalIndent(keyPair, "", " ")
129133
if err != nil {
@@ -137,7 +141,7 @@ func outputResult(p *print.Printer, model *inputModel, keyPair *iaas.Keypair) er
137141
}
138142
p.Outputln(string(details))
139143
default:
140-
p.Outputf("Updated labels of key pair %q\n", *model.KeyPairName)
144+
p.Outputf("Updated labels of key pair %q\n", utils.PtrString(model.KeyPairName))
141145
}
142146
return nil
143147
}

internal/cmd/beta/key-pair/update/update_test.go

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,18 +141,12 @@ func TestParseInput(t *testing.T) {
141141
t.Fatalf("error validating args: %v", err)
142142
}
143143

144-
model, err := parseInput(p, cmd, tt.argValues)
145-
if err != nil {
146-
if !tt.isValid {
147-
return
148-
}
149-
t.Fatalf("error parsing flags: %v", err)
150-
}
144+
model := parseInput(p, cmd, tt.argValues)
151145

152146
if !tt.isValid {
153147
t.Fatalf("did not fail on invalid input")
154148
}
155-
diff := cmp.Diff(model, tt.expectedModel)
149+
diff := cmp.Diff(&model, tt.expectedModel)
156150
if diff != "" {
157151
t.Fatalf("Data does not match: %s", diff)
158152
}
@@ -188,3 +182,38 @@ func TestBuildRequest(t *testing.T) {
188182
})
189183
}
190184
}
185+
186+
func Test_outputResult(t *testing.T) {
187+
type args struct {
188+
model inputModel
189+
keyPair iaas.Keypair
190+
}
191+
tests := []struct {
192+
name string
193+
args args
194+
wantErr bool
195+
}{
196+
{
197+
name: "empty",
198+
args: args{},
199+
wantErr: false,
200+
},
201+
{
202+
name: "base",
203+
args: args{
204+
model: inputModel{},
205+
keyPair: iaas.Keypair{},
206+
},
207+
wantErr: false,
208+
},
209+
}
210+
p := print.NewPrinter()
211+
p.Cmd = NewCmd(p)
212+
for _, tt := range tests {
213+
t.Run(tt.name, func(t *testing.T) {
214+
if err := outputResult(p, tt.args.model, tt.args.keyPair); (err != nil) != tt.wantErr {
215+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
216+
}
217+
})
218+
}
219+
}

0 commit comments

Comments
 (0)