Merge "Allow soong config value variables to set nested properties" into main
This commit is contained in:
commit
c7a806a657
2 changed files with 91 additions and 5 deletions
|
@ -681,6 +681,14 @@ func (s *valueVariable) PropertiesToApply(config SoongConfig, values reflect.Val
|
||||||
if !propStruct.IsValid() {
|
if !propStruct.IsValid() {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
if err := s.printfIntoPropertyRecursive(nil, propStruct, configValue); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return values.Interface(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *valueVariable) printfIntoPropertyRecursive(fieldName []string, propStruct reflect.Value, configValue string) error {
|
||||||
for i := 0; i < propStruct.NumField(); i++ {
|
for i := 0; i < propStruct.NumField(); i++ {
|
||||||
field := propStruct.Field(i)
|
field := propStruct.Field(i)
|
||||||
kind := field.Kind()
|
kind := field.Kind()
|
||||||
|
@ -695,23 +703,31 @@ func (s *valueVariable) PropertiesToApply(config SoongConfig, values reflect.Val
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
err := printfIntoProperty(field, configValue)
|
err := printfIntoProperty(field, configValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, propStruct.Type().Field(i).Name, err)
|
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
|
||||||
|
return fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, strings.Join(fieldName, "."), err)
|
||||||
}
|
}
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
for j := 0; j < field.Len(); j++ {
|
for j := 0; j < field.Len(); j++ {
|
||||||
err := printfIntoProperty(field.Index(j), configValue)
|
err := printfIntoProperty(field.Index(j), configValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, propStruct.Type().Field(i).Name, err)
|
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
|
||||||
|
return fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, strings.Join(fieldName, "."), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
|
case reflect.Struct:
|
||||||
|
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
|
||||||
|
if err := s.printfIntoPropertyRecursive(fieldName, field, configValue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fieldName = fieldName[:len(fieldName)-1]
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("soong_config_variables.%s.%s: unsupported property type %q", s.variable, propStruct.Type().Field(i).Name, kind)
|
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
|
||||||
|
return fmt.Errorf("soong_config_variables.%s.%s: unsupported property type %q", s.variable, strings.Join(fieldName, "."), kind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
return values.Interface(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func printfIntoProperty(propertyValue reflect.Value, configValue string) error {
|
func printfIntoProperty(propertyValue reflect.Value, configValue string) error {
|
||||||
|
|
|
@ -429,6 +429,76 @@ func Test_PropertiesToApply_Value(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_PropertiesToApply_Value_Nested(t *testing.T) {
|
||||||
|
mt, _ := newModuleType(&ModuleTypeProperties{
|
||||||
|
Module_type: "foo",
|
||||||
|
Config_namespace: "bar",
|
||||||
|
Value_variables: []string{"my_value_var"},
|
||||||
|
Properties: []string{"a.b"},
|
||||||
|
})
|
||||||
|
type properties struct {
|
||||||
|
A struct {
|
||||||
|
B string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conditionsDefault := &properties{
|
||||||
|
A: struct{ B string }{
|
||||||
|
B: "default",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
type valueVarProps struct {
|
||||||
|
A struct {
|
||||||
|
B string
|
||||||
|
}
|
||||||
|
Conditions_default *properties
|
||||||
|
}
|
||||||
|
actualProps := &struct {
|
||||||
|
Soong_config_variables valueSoongConfigVars
|
||||||
|
}{
|
||||||
|
Soong_config_variables: valueSoongConfigVars{
|
||||||
|
My_value_var: &valueVarProps{
|
||||||
|
A: struct{ B string }{
|
||||||
|
B: "A.B=%s",
|
||||||
|
},
|
||||||
|
Conditions_default: conditionsDefault,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
props := reflect.ValueOf(actualProps)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
config SoongConfig
|
||||||
|
wantProps []interface{}
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no_vendor_config",
|
||||||
|
config: Config(map[string]string{}),
|
||||||
|
wantProps: []interface{}{conditionsDefault},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "value_var_set",
|
||||||
|
config: Config(map[string]string{"my_value_var": "Hello"}),
|
||||||
|
wantProps: []interface{}{&properties{
|
||||||
|
A: struct{ B string }{
|
||||||
|
B: "A.B=Hello",
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
gotProps, err := PropertiesToApply(mt, props, tc.config)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: Unexpected error in PropertiesToApply: %s", tc.name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(gotProps, tc.wantProps) {
|
||||||
|
t.Errorf("%s: Expected %s, got %s", tc.name, tc.wantProps, gotProps)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Test_PropertiesToApply_String_Error(t *testing.T) {
|
func Test_PropertiesToApply_String_Error(t *testing.T) {
|
||||||
mt, _ := newModuleType(&ModuleTypeProperties{
|
mt, _ := newModuleType(&ModuleTypeProperties{
|
||||||
Module_type: "foo",
|
Module_type: "foo",
|
||||||
|
|
Loading…
Reference in a new issue