Fix HCL2 code generation for slices within another slice (#8669)

This commit is contained in:
Sylvia Moss 2020-02-03 17:03:28 +01:00 committed by GitHub
parent df18187032
commit 08b0bd1d2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 213 additions and 85 deletions

View File

@ -120,7 +120,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
"chroot_mounts": &hcldec.BlockListSpec{TypeName: "chroot_mounts", Nested: &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.String), Required: false}},
"chroot_mounts": &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.List(cty.String)), Required: false},
"command_wrapper": &hcldec.AttrSpec{Name: "command_wrapper", Type: cty.String, Required: false},
"copy_files": &hcldec.AttrSpec{Name: "copy_files", Type: cty.List(cty.String), Required: false},
"device_path": &hcldec.AttrSpec{Name: "device_path", Type: cty.String, Required: false},

View File

@ -78,7 +78,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"mount_partition": &hcldec.AttrSpec{Name: "mount_partition", Type: cty.String, Required: false},
"mount_path": &hcldec.AttrSpec{Name: "mount_path", Type: cty.String, Required: false},
"post_mount_commands": &hcldec.AttrSpec{Name: "post_mount_commands", Type: cty.List(cty.String), Required: false},
"chroot_mounts": &hcldec.BlockListSpec{TypeName: "chroot_mounts", Nested: &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.String), Required: false}},
"chroot_mounts": &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.List(cty.String)), Required: false},
"copy_files": &hcldec.AttrSpec{Name: "copy_files", Type: cty.List(cty.String), Required: false},
"temporary_os_disk_name": &hcldec.AttrSpec{Name: "temporary_os_disk_name", Type: cty.String, Required: false},
"os_disk_size_gb": &hcldec.AttrSpec{Name: "os_disk_size_gb", Type: cty.Number, Required: false},

View File

@ -174,7 +174,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"chroot_disk_size": &hcldec.AttrSpec{Name: "chroot_disk_size", Type: cty.Number, Required: false},
"chroot_disk_type": &hcldec.AttrSpec{Name: "chroot_disk_type", Type: cty.String, Required: false},
"chroot_mount_path": &hcldec.AttrSpec{Name: "chroot_mount_path", Type: cty.String, Required: false},
"chroot_mounts": &hcldec.BlockListSpec{TypeName: "chroot_mounts", Nested: &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.String), Required: false}},
"chroot_mounts": &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.List(cty.String)), Required: false},
"chroot_copy_files": &hcldec.AttrSpec{Name: "chroot_copy_files", Type: cty.List(cty.String), Required: false},
"chroot_command_wrapper": &hcldec.AttrSpec{Name: "chroot_command_wrapper", Type: cty.String, Required: false},
"mount_options": &hcldec.AttrSpec{Name: "mount_options", Type: cty.List(cty.String), Required: false},

View File

@ -103,7 +103,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"chroot_mounts": &hcldec.BlockListSpec{TypeName: "chroot_mounts", Nested: &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.String), Required: false}},
"chroot_mounts": &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.List(cty.String)), Required: false},
"command_wrapper": &hcldec.AttrSpec{Name: "command_wrapper", Type: cty.String, Required: false},
"copy_files": &hcldec.AttrSpec{Name: "copy_files", Type: cty.List(cty.String), Required: false},
"device_path": &hcldec.AttrSpec{Name: "device_path", Type: cty.String, Required: false},

View File

@ -135,8 +135,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"memory": &hcldec.AttrSpec{Name: "memory", Type: cty.Number, Required: false},
"sound": &hcldec.AttrSpec{Name: "sound", Type: cty.Bool, Required: false},
"usb": &hcldec.AttrSpec{Name: "usb", Type: cty.Bool, Required: false},
"prlctl": &hcldec.BlockListSpec{TypeName: "prlctl", Nested: &hcldec.AttrSpec{Name: "prlctl", Type: cty.List(cty.String), Required: false}},
"prlctl_post": &hcldec.BlockListSpec{TypeName: "prlctl_post", Nested: &hcldec.AttrSpec{Name: "prlctl_post", Type: cty.List(cty.String), Required: false}},
"prlctl": &hcldec.AttrSpec{Name: "prlctl", Type: cty.List(cty.List(cty.String)), Required: false},
"prlctl_post": &hcldec.AttrSpec{Name: "prlctl_post", Type: cty.List(cty.List(cty.String)), Required: false},
"prlctl_version_file": &hcldec.AttrSpec{Name: "prlctl_version_file", Type: cty.String, Required: false},
"shutdown_command": &hcldec.AttrSpec{Name: "shutdown_command", Type: cty.String, Required: false},
"shutdown_timeout": &hcldec.AttrSpec{Name: "shutdown_timeout", Type: cty.String, Required: false},

View File

@ -101,8 +101,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"floppy_dirs": &hcldec.AttrSpec{Name: "floppy_dirs", Type: cty.List(cty.String), Required: false},
"floppy_label": &hcldec.AttrSpec{Name: "floppy_label", Type: cty.String, Required: false},
"output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false},
"prlctl": &hcldec.BlockListSpec{TypeName: "prlctl", Nested: &hcldec.AttrSpec{Name: "prlctl", Type: cty.List(cty.String), Required: false}},
"prlctl_post": &hcldec.BlockListSpec{TypeName: "prlctl_post", Nested: &hcldec.AttrSpec{Name: "prlctl_post", Type: cty.List(cty.String), Required: false}},
"prlctl": &hcldec.AttrSpec{Name: "prlctl", Type: cty.List(cty.List(cty.String)), Required: false},
"prlctl_post": &hcldec.AttrSpec{Name: "prlctl_post", Type: cty.List(cty.List(cty.String)), Required: false},
"prlctl_version_file": &hcldec.AttrSpec{Name: "prlctl_version_file", Type: cty.String, Required: false},
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},

View File

@ -210,7 +210,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"memory": &hcldec.AttrSpec{Name: "memory", Type: cty.Number, Required: false},
"net_device": &hcldec.AttrSpec{Name: "net_device", Type: cty.String, Required: false},
"output_directory": &hcldec.AttrSpec{Name: "output_directory", Type: cty.String, Required: false},
"qemuargs": &hcldec.BlockListSpec{TypeName: "qemuargs", Nested: &hcldec.AttrSpec{Name: "qemuargs", Type: cty.List(cty.String), Required: false}},
"qemuargs": &hcldec.AttrSpec{Name: "qemuargs", Type: cty.List(cty.List(cty.String)), Required: false},
"qemu_binary": &hcldec.AttrSpec{Name: "qemu_binary", Type: cty.String, Required: false},
"qmp_enable": &hcldec.AttrSpec{Name: "qmp_enable", Type: cty.Bool, Required: false},
"qmp_socket_path": &hcldec.AttrSpec{Name: "qmp_socket_path", Type: cty.String, Required: false},

View File

@ -215,8 +215,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"memory": &hcldec.AttrSpec{Name: "memory", Type: cty.Number, Required: false},
"sound": &hcldec.AttrSpec{Name: "sound", Type: cty.String, Required: false},
"usb": &hcldec.AttrSpec{Name: "usb", Type: cty.Bool, Required: false},
"vboxmanage": &hcldec.BlockListSpec{TypeName: "vboxmanage", Nested: &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.String), Required: false}},
"vboxmanage_post": &hcldec.BlockListSpec{TypeName: "vboxmanage_post", Nested: &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.String), Required: false}},
"vboxmanage": &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.List(cty.String)), Required: false},
"vboxmanage_post": &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.List(cty.String)), Required: false},
"virtualbox_version_file": &hcldec.AttrSpec{Name: "virtualbox_version_file", Type: cty.String, Required: false},
"bundle_iso": &hcldec.AttrSpec{Name: "bundle_iso", Type: cty.Bool, Required: false},
"guest_additions_mode": &hcldec.AttrSpec{Name: "guest_additions_mode", Type: cty.String, Required: false},

View File

@ -190,8 +190,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"post_shutdown_delay": &hcldec.AttrSpec{Name: "post_shutdown_delay", Type: cty.String, Required: false},
"disable_shutdown": &hcldec.AttrSpec{Name: "disable_shutdown", Type: cty.Bool, Required: false},
"acpi_shutdown": &hcldec.AttrSpec{Name: "acpi_shutdown", Type: cty.Bool, Required: false},
"vboxmanage": &hcldec.BlockListSpec{TypeName: "vboxmanage", Nested: &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.String), Required: false}},
"vboxmanage_post": &hcldec.BlockListSpec{TypeName: "vboxmanage_post", Nested: &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.String), Required: false}},
"vboxmanage": &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.List(cty.String)), Required: false},
"vboxmanage_post": &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.List(cty.String)), Required: false},
"virtualbox_version_file": &hcldec.AttrSpec{Name: "virtualbox_version_file", Type: cty.String, Required: false},
"guest_additions_mode": &hcldec.AttrSpec{Name: "guest_additions_mode", Type: cty.String, Required: false},
"checksum": &hcldec.AttrSpec{Name: "checksum", Type: cty.String, Required: false},

View File

@ -186,8 +186,8 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"post_shutdown_delay": &hcldec.AttrSpec{Name: "post_shutdown_delay", Type: cty.String, Required: false},
"disable_shutdown": &hcldec.AttrSpec{Name: "disable_shutdown", Type: cty.Bool, Required: false},
"acpi_shutdown": &hcldec.AttrSpec{Name: "acpi_shutdown", Type: cty.Bool, Required: false},
"vboxmanage": &hcldec.BlockListSpec{TypeName: "vboxmanage", Nested: &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.String), Required: false}},
"vboxmanage_post": &hcldec.BlockListSpec{TypeName: "vboxmanage_post", Nested: &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.String), Required: false}},
"vboxmanage": &hcldec.AttrSpec{Name: "vboxmanage", Type: cty.List(cty.List(cty.String)), Required: false},
"vboxmanage_post": &hcldec.AttrSpec{Name: "vboxmanage_post", Type: cty.List(cty.List(cty.String)), Required: false},
"virtualbox_version_file": &hcldec.AttrSpec{Name: "virtualbox_version_file", Type: cty.String, Required: false},
"guest_additions_mode": &hcldec.AttrSpec{Name: "guest_additions_mode", Type: cty.String, Required: false},
"guest_additions_path": &hcldec.AttrSpec{Name: "guest_additions_path", Type: cty.String, Required: false},

View File

@ -201,6 +201,10 @@ type StructDef struct {
Struct *types.Struct
}
// outputStructHCL2SpecBody writes the map[string]hcldec.Spec that defines the HCL spec of a
// struct. Based on the layout of said struct.
// If a field of s is a struct then the HCL2Spec() function of that struct will be called, otherwise a
// cty.Type is outputed.
func outputStructHCL2SpecBody(w io.Writer, s *types.Struct) {
fmt.Fprintf(w, "s := map[string]hcldec.Spec{\n")
@ -217,72 +221,99 @@ func outputStructHCL2SpecBody(w io.Writer, s *types.Struct) {
fmt.Fprintln(w, `return s`)
}
// outputHCL2SpecField is called on each field of a struct.
// outputHCL2SpecField writes the values of the `map[string]hcldec.Spec` map
// supposed to define the HCL spec of a struct.
func outputHCL2SpecField(w io.Writer, accessor string, fieldType types.Type, tag *structtag.Tags) {
if m2h, err := tag.Get(""); err == nil && m2h.HasOption("self-defined") {
fmt.Fprintf(w, `(&%s{}).HCL2Spec()`, fieldType.String())
return
}
spec, _ := writeSpecField(accessor, fieldType)
switch spec := spec.(type) {
case string:
fmt.Fprintf(w, spec)
default:
fmt.Fprintf(w, `%#v`, spec)
}
}
// goFieldToCtyType is a recursive method that returns a cty.Type (or a string) based on the fieldType.
// goFieldToCtyType returns the values of the `map[string]hcldec.Spec` map
// supposed to define the HCL spec of a struct.
// To allow it to be recursive, the method returns two values: an interface that can either be
// a cty.Type or a string. The second argument is used for recursion and is the
// type that will be used by the parent. For example when fieldType is a []string; a
// recursive goFieldToCtyType call will return a cty.String.
func writeSpecField(accessor string, fieldType types.Type) (interface{}, cty.Type) {
switch f := fieldType.(type) {
case *types.Pointer:
outputHCL2SpecField(w, accessor, f.Elem(), tag)
return writeSpecField(accessor, f.Elem())
case *types.Basic:
fmt.Fprintf(w, `%#v`, &hcldec.AttrSpec{
ctyType := basicKindToCtyType(f.Kind())
return &hcldec.AttrSpec{
Name: accessor,
Type: basicKindToCtyType(f.Kind()),
Type: ctyType,
Required: false,
})
}, ctyType
case *types.Map:
fmt.Fprintf(w, `%#v`, &hcldec.BlockAttrsSpec{
return &hcldec.BlockAttrsSpec{
TypeName: accessor,
ElementType: cty.String, // for now everything can be simplified to a map[string]string
Required: false,
})
}, cty.Map(cty.String)
case *types.Named:
// Named is the relative type when of a field with a struct.
// E.g. SourceAmiFilter *common.FlatAmiFilterOptions
// SourceAmiFilter will become a block with nested elements from the struct itself.
underlyingType := f.Underlying()
switch underlyingType.(type) {
case *types.Struct:
// A struct returns NilType because its HCL2Spec is written in the related file
// and we don't need to write it again.
return fmt.Sprintf(`&hcldec.BlockSpec{TypeName: "%s",`+
` Nested: hcldec.ObjectSpec((*%s)(nil).HCL2Spec())}`, accessor, f.String()), cty.NilType
default:
return writeSpecField(accessor, underlyingType)
}
case *types.Slice:
elem := f.Elem()
if ptr, isPtr := elem.(*types.Pointer); isPtr {
elem = ptr.Elem()
}
switch elem := elem.(type) {
case *types.Basic:
fmt.Fprintf(w, `%#v`, &hcldec.AttrSpec{
Name: accessor,
Type: cty.List(basicKindToCtyType(elem.Kind())),
Required: false,
})
case *types.Named:
// A Slice of Named is the relative type of a filed with a slice of structs.
// E.g. LaunchMappings []common.FlatBlockDevice
// LaunchMappings will validate more than one block with nested elements.
b := bytes.NewBuffer(nil)
underlyingType := elem.Underlying()
switch underlyingType.(type) {
case *types.Struct:
fmt.Fprintf(b, `hcldec.ObjectSpec((*%s)(nil).HCL2Spec())`, elem.String())
default:
outputHCL2SpecField(b, accessor, elem, tag)
}
fmt.Fprintf(w, `&hcldec.BlockListSpec{TypeName: "%s", Nested: %s}`, accessor, b.String())
case *types.Slice:
b := bytes.NewBuffer(nil)
outputHCL2SpecField(b, accessor, elem.Underlying(), tag)
fmt.Fprintf(w, `&hcldec.BlockListSpec{TypeName: "%s", Nested: %s}`, accessor, b.String())
return fmt.Sprintf(`&hcldec.BlockListSpec{TypeName: "%s", Nested: %s}`, accessor, b.String()), cty.NilType
default:
outputHCL2SpecField(w, accessor, elem.Underlying(), tag)
_, specType := writeSpecField(accessor, elem)
if specType == cty.NilType {
return writeSpecField(accessor, elem.Underlying())
}
return &hcldec.AttrSpec{
Name: accessor,
Type: cty.List(specType),
Required: false,
}, cty.List(specType)
}
case *types.Named:
underlyingType := f.Underlying()
switch underlyingType.(type) {
case *types.Struct:
fmt.Fprintf(w, `&hcldec.BlockSpec{TypeName: "%s",`+
` Nested: hcldec.ObjectSpec((*%s)(nil).HCL2Spec())}`, accessor, f.String())
default:
outputHCL2SpecField(w, accessor, underlyingType, tag)
}
default:
fmt.Fprintf(w, `%#v`, &hcldec.AttrSpec{
Name: accessor,
Type: basicKindToCtyType(types.Bool),
Required: false,
})
fmt.Fprintf(w, `/* TODO(azr): could not find type */`)
}
b := bytes.NewBuffer(nil)
fmt.Fprintf(b, `%#v`, &hcldec.AttrSpec{
Name: accessor,
Type: basicKindToCtyType(types.Bool),
Required: false,
})
fmt.Fprintf(b, `/* TODO(azr): could not find type */`)
return b.String(), cty.NilType
}
func basicKindToCtyType(kind types.BasicKind) cty.Type {

View File

@ -194,6 +194,10 @@ var (
"b",
"c",
},
SliceSliceString: [][]string{
{"a", "b"},
{"c", "d"},
},
}
basicMockBuilder = &MockBuilder{

View File

@ -20,6 +20,7 @@ type NestedMockConfig struct {
Duration time.Duration `mapstructure:"duration"`
MapStringString map[string]string `mapstructure:"map_string_string"`
SliceString []string `mapstructure:"slice_string"`
SliceSliceString [][]string `mapstructure:"slice_slice_string"`
NamedMapStringString NamedMapStringString `mapstructure:"named_map_string_string"`
NamedString NamedString `mapstructure:"named_string"`
}

View File

@ -17,6 +17,7 @@ type FlatMockConfig struct {
Duration *string `mapstructure:"duration" cty:"duration"`
MapStringString map[string]string `mapstructure:"map_string_string" cty:"map_string_string"`
SliceString []string `mapstructure:"slice_string" cty:"slice_string"`
SliceSliceString [][]string `mapstructure:"slice_slice_string" cty:"slice_slice_string"`
NamedMapStringString NamedMapStringString `mapstructure:"named_map_string_string" cty:"named_map_string_string"`
NamedString *NamedString `mapstructure:"named_string" cty:"named_string"`
Nested *FlatNestedMockConfig `mapstructure:"nested" cty:"nested"`
@ -43,6 +44,7 @@ func (*FlatMockConfig) HCL2Spec() map[string]hcldec.Spec {
"duration": &hcldec.AttrSpec{Name: "duration", Type: cty.String, Required: false},
"map_string_string": &hcldec.BlockAttrsSpec{TypeName: "map_string_string", ElementType: cty.String, Required: false},
"slice_string": &hcldec.AttrSpec{Name: "slice_string", Type: cty.List(cty.String), Required: false},
"slice_slice_string": &hcldec.AttrSpec{Name: "slice_slice_string", Type: cty.List(cty.List(cty.String)), Required: false},
"named_map_string_string": &hcldec.BlockAttrsSpec{TypeName: "named_map_string_string", ElementType: cty.String, Required: false},
"named_string": &hcldec.AttrSpec{Name: "named_string", Type: cty.String, Required: false},
"nested": &hcldec.BlockSpec{TypeName: "nested", Nested: hcldec.ObjectSpec((*FlatNestedMockConfig)(nil).HCL2Spec())},
@ -62,6 +64,7 @@ type FlatNestedMockConfig struct {
Duration *string `mapstructure:"duration" cty:"duration"`
MapStringString map[string]string `mapstructure:"map_string_string" cty:"map_string_string"`
SliceString []string `mapstructure:"slice_string" cty:"slice_string"`
SliceSliceString [][]string `mapstructure:"slice_slice_string" cty:"slice_slice_string"`
NamedMapStringString NamedMapStringString `mapstructure:"named_map_string_string" cty:"named_map_string_string"`
NamedString *NamedString `mapstructure:"named_string" cty:"named_string"`
}
@ -86,6 +89,7 @@ func (*FlatNestedMockConfig) HCL2Spec() map[string]hcldec.Spec {
"duration": &hcldec.AttrSpec{Name: "duration", Type: cty.String, Required: false},
"map_string_string": &hcldec.BlockAttrsSpec{TypeName: "map_string_string", ElementType: cty.String, Required: false},
"slice_string": &hcldec.AttrSpec{Name: "slice_string", Type: cty.List(cty.String), Required: false},
"slice_slice_string": &hcldec.AttrSpec{Name: "slice_slice_string", Type: cty.List(cty.List(cty.String)), Required: false},
"named_map_string_string": &hcldec.BlockAttrsSpec{TypeName: "named_map_string_string", ElementType: cty.String, Required: false},
"named_string": &hcldec.AttrSpec{Name: "named_string", Type: cty.String, Required: false},
}

View File

@ -22,6 +22,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
nested {
string = "string"
@ -39,6 +43,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
nested_slice {
@ -61,6 +69,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
nested {
string = "string"
@ -78,6 +90,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
nested_slice {
@ -100,6 +116,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
nested {
string = "string"
@ -117,6 +137,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
nested_slice {

View File

@ -22,6 +22,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
nested {
string = "string"
@ -39,6 +43,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
nested_slice {
@ -61,6 +69,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
nested {
string = "string"
@ -78,6 +90,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
nested_slice {
@ -101,6 +117,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
nested {
string = "string"
@ -118,6 +138,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
nested_slice {
@ -140,6 +164,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
nested {
string = "string"
@ -157,6 +185,10 @@ build {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
nested_slice {

View File

@ -14,6 +14,10 @@ source "virtualbox-iso" "ubuntu-1204" {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
nested {
string = "string"
@ -31,23 +35,9 @@ source "virtualbox-iso" "ubuntu-1204" {
"b",
"c",
]
}
nested_slice {
string = "string"
int = 42
int64 = 43
bool = true
trilean = true
duration = "10s"
map_string_string {
a = "b"
c = "d"
}
slice_string = [
"a",
"b",
"c",
slice_slice_string = [
["a","b"],
["c","d"]
]
}
@ -67,5 +57,31 @@ source "virtualbox-iso" "ubuntu-1204" {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
nested_slice {
string = "string"
int = 42
int64 = 43
bool = true
trilean = true
duration = "10s"
map_string_string {
a = "b"
c = "d"
}
slice_string = [
"a",
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
}

View File

@ -15,6 +15,10 @@ source "virtualbox-iso" "ubuntu-1204" {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
nested {
string = "string"
@ -32,23 +36,9 @@ source "virtualbox-iso" "ubuntu-1204" {
"b",
"c",
]
}
nested_slice {
string = "string"
int = 42
int64 = 43
bool = true
trilean = true
duration = "10s"
map_string_string {
a = "b"
c = "d"
}
slice_string = [
"a",
"b",
"c",
slice_slice_string = [
["a","b"],
["c","d"]
]
}
@ -68,5 +58,31 @@ source "virtualbox-iso" "ubuntu-1204" {
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
nested_slice {
string = "string"
int = 42
int64 = 43
bool = true
trilean = true
duration = "10s"
map_string_string {
a = "b"
c = "d"
}
slice_string = [
"a",
"b",
"c",
]
slice_slice_string = [
["a","b"],
["c","d"]
]
}
}