Add support for setting string property in bpmodify
Add a -str argument to set a property to a string value.
Bug: 186723288
Test: bpmodify_test.go
Change-Id: I490e3be182693c8720020814da579e6e788b3d9f
diff --git a/bpmodify/bpmodify.go b/bpmodify/bpmodify.go
index 0190f19..29d28f0 100644
--- a/bpmodify/bpmodify.go
+++ b/bpmodify/bpmodify.go
@@ -30,6 +30,8 @@
targetedProperty = new(qualifiedProperty)
addIdents = new(identSet)
removeIdents = new(identSet)
+
+ setString *string
)
func init() {
@@ -38,6 +40,7 @@
flag.Var(targetedProperty, "property", "fully qualified `name` of property to modify (default \"deps\")")
flag.Var(addIdents, "a", "comma or whitespace separated list of identifiers to add")
flag.Var(removeIdents, "r", "comma or whitespace separated list of identifiers to remove")
+ flag.Var(stringPtrFlag{&setString}, "str", "set a string property")
flag.Usage = usage
}
@@ -147,14 +150,18 @@
return false, []error{err}
}
if prop == nil {
- if len(addIdents.idents) == 0 {
+ if len(addIdents.idents) > 0 {
+ // We are adding something to a non-existing list prop, so we need to create it first.
+ prop, modified, err = createRecursiveProperty(module, targetedProperty.name(), targetedProperty.prefixes(), &parser.List{})
+ } else if setString != nil {
+ // We setting a non-existent string property, so we need to create it first.
+ prop, modified, err = createRecursiveProperty(module, targetedProperty.name(), targetedProperty.prefixes(), &parser.String{})
+ } else {
// We cannot find an existing prop, and we aren't adding anything to the prop,
// which means we must be removing something from a non-existing prop,
// which means this is a noop.
return false, nil
}
- // Else we are adding something to a non-existing prop, so we need to create it first.
- prop, modified, err = createRecursiveProperty(module, targetedProperty.name(), targetedProperty.prefixes())
if err != nil {
// Here should be unreachable, but still handle it for completeness.
return false, []error{err}
@@ -166,16 +173,18 @@
}
func getRecursiveProperty(module *parser.Module, name string, prefixes []string) (prop *parser.Property, err error) {
- prop, _, err = getOrCreateRecursiveProperty(module, name, prefixes, false)
+ prop, _, err = getOrCreateRecursiveProperty(module, name, prefixes, nil)
return prop, err
}
-func createRecursiveProperty(module *parser.Module, name string, prefixes []string) (prop *parser.Property, modified bool, err error) {
- return getOrCreateRecursiveProperty(module, name, prefixes, true)
+func createRecursiveProperty(module *parser.Module, name string, prefixes []string,
+ empty parser.Expression) (prop *parser.Property, modified bool, err error) {
+
+ return getOrCreateRecursiveProperty(module, name, prefixes, empty)
}
func getOrCreateRecursiveProperty(module *parser.Module, name string, prefixes []string,
- createIfNotFound bool) (prop *parser.Property, modified bool, err error) {
+ empty parser.Expression) (prop *parser.Property, modified bool, err error) {
m := &module.Map
for i, prefix := range prefixes {
if prop, found := m.GetProperty(prefix); found {
@@ -187,7 +196,7 @@
return nil, false, fmt.Errorf("Expected property %q to be a map, found %s",
strings.Join(prefixes[:i+1], "."), prop.Value.Type())
}
- } else if createIfNotFound {
+ } else if empty != nil {
mm := &parser.Map{}
m.Properties = append(m.Properties, &parser.Property{Name: prefix, Value: mm})
m = mm
@@ -201,8 +210,8 @@
if prop, found := m.GetProperty(name); found {
// We've found a property in the AST, which must mean we didn't modify the AST.
return prop, false, nil
- } else if createIfNotFound {
- prop = &parser.Property{Name: name, Value: &parser.List{}}
+ } else if empty != nil {
+ prop = &parser.Property{Name: name, Value: empty}
m.Properties = append(m.Properties, prop)
return prop, true, nil
} else {
@@ -222,26 +231,37 @@
paramName, moduleName)}
}
- list, ok := value.(*parser.List)
- if !ok {
- return false, []error{fmt.Errorf("expected parameter %s in module %s to be list, found %s",
- paramName, moduleName, value.Type().String())}
- }
+ if len(addIdents.idents) > 0 || len(removeIdents.idents) > 0 {
+ list, ok := value.(*parser.List)
+ if !ok {
+ return false, []error{fmt.Errorf("expected parameter %s in module %s to be list, found %s",
+ paramName, moduleName, value.Type().String())}
+ }
- wasSorted := parser.ListIsSorted(list)
+ wasSorted := parser.ListIsSorted(list)
- for _, a := range addIdents.idents {
- m := parser.AddStringToList(list, a)
- modified = modified || m
- }
+ for _, a := range addIdents.idents {
+ m := parser.AddStringToList(list, a)
+ modified = modified || m
+ }
- for _, r := range removeIdents.idents {
- m := parser.RemoveStringFromList(list, r)
- modified = modified || m
- }
+ for _, r := range removeIdents.idents {
+ m := parser.RemoveStringFromList(list, r)
+ modified = modified || m
+ }
- if (wasSorted || *sortLists) && modified {
- parser.SortList(file, list)
+ if (wasSorted || *sortLists) && modified {
+ parser.SortList(file, list)
+ }
+ } else if setString != nil {
+ str, ok := value.(*parser.String)
+ if !ok {
+ return false, []error{fmt.Errorf("expected parameter %s in module %s to be string, found %s",
+ paramName, moduleName, value.Type().String())}
+ }
+
+ str.Value = *setString
+ modified = true
}
return modified, nil
@@ -304,8 +324,8 @@
return
}
- if len(addIdents.idents) == 0 && len(removeIdents.idents) == 0 {
- report(fmt.Errorf("-a or -r parameter is required"))
+ if len(addIdents.idents) == 0 && len(removeIdents.idents) == 0 && setString == nil {
+ report(fmt.Errorf("-a, -r or -str parameter is required"))
return
}
@@ -352,6 +372,22 @@
}
+type stringPtrFlag struct {
+ s **string
+}
+
+func (f stringPtrFlag) Set(s string) error {
+ *f.s = &s
+ return nil
+}
+
+func (f stringPtrFlag) String() string {
+ if f.s == nil || *f.s == nil {
+ return ""
+ }
+ return **f.s
+}
+
type identSet struct {
idents []string
all bool
diff --git a/bpmodify/bpmodify_test.go b/bpmodify/bpmodify_test.go
index 7ccd06e..a92d439 100644
--- a/bpmodify/bpmodify_test.go
+++ b/bpmodify/bpmodify_test.go
@@ -19,6 +19,7 @@
"testing"
"github.com/google/blueprint/parser"
+ "github.com/google/blueprint/proptools"
)
var testCases = []struct {
@@ -28,6 +29,7 @@
property string
addSet string
removeSet string
+ setString *string
}{
{
name: "add",
@@ -249,6 +251,39 @@
property: "deps",
addSet: "bar-v10-bar",
},
+ {
+ name: "set string",
+ input: `
+ cc_foo {
+ name: "foo",
+ }
+ `,
+ output: `
+ cc_foo {
+ name: "foo",
+ foo: "bar",
+ }
+ `,
+ property: "foo",
+ setString: proptools.StringPtr("bar"),
+ },
+ {
+ name: "set existing string",
+ input: `
+ cc_foo {
+ name: "foo",
+ foo: "baz",
+ }
+ `,
+ output: `
+ cc_foo {
+ name: "foo",
+ foo: "bar",
+ }
+ `,
+ property: "foo",
+ setString: proptools.StringPtr("bar"),
+ },
}
func simplifyModuleDefinition(def string) string {
@@ -265,6 +300,7 @@
targetedProperty.Set(testCase.property)
addIdents.Set(testCase.addSet)
removeIdents.Set(testCase.removeSet)
+ setString = testCase.setString
inAst, errs := parser.ParseAndEval("", strings.NewReader(testCase.input), parser.NewScope(nil))
if len(errs) > 0 {