Skip to content

Commit 5f7ce59

Browse files
authored
fix: properly handle maps in unmarshaller (#697)
1 parent f8af118 commit 5f7ce59

File tree

4 files changed

+70
-6
lines changed

4 files changed

+70
-6
lines changed

internal/args/args_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ type Enum struct {
8181
Size Size
8282
}
8383

84+
type RecursiveWithMapOfRecursive struct {
85+
ID int
86+
Name string
87+
Short string
88+
Elements map[string]*RecursiveWithMapOfRecursive
89+
}
90+
8491
func (c *CustomStruct) UnmarshalArgs(value string) error {
8592
c.value = strings.ToUpper(value)
8693
return nil

internal/args/unmarshal.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,17 @@ func set(dest reflect.Value, argNameWords []string, value string) error {
213213
if len(argNameWords) == 0 {
214214
return &MissingMapKeyError{}
215215
}
216-
// Create a new value call set and add result in the map
217-
newValue := reflect.New(dest.Type().Elem())
218-
err := set(newValue.Elem(), argNameWords[1:], value)
219-
dest.SetMapIndex(reflect.ValueOf(argNameWords[0]), newValue.Elem())
216+
217+
// Create a new value if it does not exist, then call set and add result in the map
218+
mapKey := reflect.ValueOf(argNameWords[0])
219+
mapValue := dest.MapIndex(mapKey)
220+
221+
if !mapValue.IsValid() {
222+
mapValue = reflect.New(dest.Type().Elem()).Elem()
223+
}
224+
err := set(mapValue, argNameWords[1:], value)
225+
dest.SetMapIndex(mapKey, mapValue)
226+
220227
return err
221228

222229
case reflect.Struct:

internal/args/unmarshal_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,52 @@ func TestUnmarshalStruct(t *testing.T) {
331331
All: "all",
332332
},
333333
}))
334+
335+
t.Run("recursive-with-map-of-recursive-with-one-field-set", run(TestCase{
336+
args: []string{
337+
"name=coucou",
338+
"elements.0.name=bob",
339+
"elements.0.elements.plop.name=world",
340+
},
341+
expected: &RecursiveWithMapOfRecursive{
342+
Name: "coucou",
343+
Elements: map[string]*RecursiveWithMapOfRecursive{
344+
"0": {
345+
Name: "bob",
346+
Elements: map[string]*RecursiveWithMapOfRecursive{
347+
"plop": {
348+
Name: "world",
349+
},
350+
},
351+
},
352+
},
353+
},
354+
}))
355+
356+
t.Run("recursive-with-map-of-recursive-with-multiple-fields-set", run(TestCase{
357+
args: []string{
358+
"name=coucou",
359+
"elements.0.id=1453",
360+
"elements.0.name=bob",
361+
"elements.0.elements.plop.name=world",
362+
"elements.0.elements.plop.short=long",
363+
},
364+
expected: &RecursiveWithMapOfRecursive{
365+
Name: "coucou",
366+
Elements: map[string]*RecursiveWithMapOfRecursive{
367+
"0": {
368+
ID: 1453,
369+
Name: "bob",
370+
Elements: map[string]*RecursiveWithMapOfRecursive{
371+
"plop": {
372+
Name: "world",
373+
Short: "long",
374+
},
375+
},
376+
},
377+
},
378+
},
379+
}))
334380
}
335381

336382
func TestIsUmarshalableValue(t *testing.T) {

internal/namespaces/instance/v1/custom_server_create.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,12 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
259259
}
260260

261261
// Validate root volume type and size.
262-
if err := validateRootVolume(getImageResponse.Image.RootVolume.Size, volumes["0"]); err != nil {
263-
return nil, err
262+
if getImageResponse != nil {
263+
if err := validateRootVolume(getImageResponse.Image.RootVolume.Size, volumes["0"]); err != nil {
264+
return nil, err
265+
}
266+
} else {
267+
logger.Warningf("skipping root volume validation")
264268
}
265269

266270
// Validate total local volume sizes.

0 commit comments

Comments
 (0)