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
This commit is contained in:
parent
5ef7b6608c
commit
b1abbada6a
2 changed files with 100 additions and 28 deletions
|
@ -30,6 +30,8 @@ var (
|
||||||
targetedProperty = new(qualifiedProperty)
|
targetedProperty = new(qualifiedProperty)
|
||||||
addIdents = new(identSet)
|
addIdents = new(identSet)
|
||||||
removeIdents = new(identSet)
|
removeIdents = new(identSet)
|
||||||
|
|
||||||
|
setString *string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -38,6 +40,7 @@ func init() {
|
||||||
flag.Var(targetedProperty, "property", "fully qualified `name` of property to modify (default \"deps\")")
|
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(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(removeIdents, "r", "comma or whitespace separated list of identifiers to remove")
|
||||||
|
flag.Var(stringPtrFlag{&setString}, "str", "set a string property")
|
||||||
flag.Usage = usage
|
flag.Usage = usage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,14 +150,18 @@ func processModule(module *parser.Module, moduleName string,
|
||||||
return false, []error{err}
|
return false, []error{err}
|
||||||
}
|
}
|
||||||
if prop == nil {
|
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,
|
// 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 we must be removing something from a non-existing prop,
|
||||||
// which means this is a noop.
|
// which means this is a noop.
|
||||||
return false, nil
|
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 {
|
if err != nil {
|
||||||
// Here should be unreachable, but still handle it for completeness.
|
// Here should be unreachable, but still handle it for completeness.
|
||||||
return false, []error{err}
|
return false, []error{err}
|
||||||
|
@ -166,16 +173,18 @@ func processModule(module *parser.Module, moduleName string,
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRecursiveProperty(module *parser.Module, name string, prefixes []string) (prop *parser.Property, err error) {
|
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
|
return prop, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func createRecursiveProperty(module *parser.Module, name string, prefixes []string) (prop *parser.Property, modified bool, err error) {
|
func createRecursiveProperty(module *parser.Module, name string, prefixes []string,
|
||||||
return getOrCreateRecursiveProperty(module, name, prefixes, true)
|
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,
|
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
|
m := &module.Map
|
||||||
for i, prefix := range prefixes {
|
for i, prefix := range prefixes {
|
||||||
if prop, found := m.GetProperty(prefix); found {
|
if prop, found := m.GetProperty(prefix); found {
|
||||||
|
@ -187,7 +196,7 @@ func getOrCreateRecursiveProperty(module *parser.Module, name string, prefixes [
|
||||||
return nil, false, fmt.Errorf("Expected property %q to be a map, found %s",
|
return nil, false, fmt.Errorf("Expected property %q to be a map, found %s",
|
||||||
strings.Join(prefixes[:i+1], "."), prop.Value.Type())
|
strings.Join(prefixes[:i+1], "."), prop.Value.Type())
|
||||||
}
|
}
|
||||||
} else if createIfNotFound {
|
} else if empty != nil {
|
||||||
mm := &parser.Map{}
|
mm := &parser.Map{}
|
||||||
m.Properties = append(m.Properties, &parser.Property{Name: prefix, Value: mm})
|
m.Properties = append(m.Properties, &parser.Property{Name: prefix, Value: mm})
|
||||||
m = mm
|
m = mm
|
||||||
|
@ -201,8 +210,8 @@ func getOrCreateRecursiveProperty(module *parser.Module, name string, prefixes [
|
||||||
if prop, found := m.GetProperty(name); found {
|
if prop, found := m.GetProperty(name); found {
|
||||||
// We've found a property in the AST, which must mean we didn't modify the AST.
|
// We've found a property in the AST, which must mean we didn't modify the AST.
|
||||||
return prop, false, nil
|
return prop, false, nil
|
||||||
} else if createIfNotFound {
|
} else if empty != nil {
|
||||||
prop = &parser.Property{Name: name, Value: &parser.List{}}
|
prop = &parser.Property{Name: name, Value: empty}
|
||||||
m.Properties = append(m.Properties, prop)
|
m.Properties = append(m.Properties, prop)
|
||||||
return prop, true, nil
|
return prop, true, nil
|
||||||
} else {
|
} else {
|
||||||
|
@ -222,26 +231,37 @@ func processParameter(value parser.Expression, paramName, moduleName string,
|
||||||
paramName, moduleName)}
|
paramName, moduleName)}
|
||||||
}
|
}
|
||||||
|
|
||||||
list, ok := value.(*parser.List)
|
if len(addIdents.idents) > 0 || len(removeIdents.idents) > 0 {
|
||||||
if !ok {
|
list, ok := value.(*parser.List)
|
||||||
return false, []error{fmt.Errorf("expected parameter %s in module %s to be list, found %s",
|
if !ok {
|
||||||
paramName, moduleName, value.Type().String())}
|
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 {
|
for _, a := range addIdents.idents {
|
||||||
m := parser.AddStringToList(list, a)
|
m := parser.AddStringToList(list, a)
|
||||||
modified = modified || m
|
modified = modified || m
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range removeIdents.idents {
|
for _, r := range removeIdents.idents {
|
||||||
m := parser.RemoveStringFromList(list, r)
|
m := parser.RemoveStringFromList(list, r)
|
||||||
modified = modified || m
|
modified = modified || m
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wasSorted || *sortLists) && modified {
|
if (wasSorted || *sortLists) && modified {
|
||||||
parser.SortList(file, list)
|
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
|
return modified, nil
|
||||||
|
@ -304,8 +324,8 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(addIdents.idents) == 0 && len(removeIdents.idents) == 0 {
|
if len(addIdents.idents) == 0 && len(removeIdents.idents) == 0 && setString == nil {
|
||||||
report(fmt.Errorf("-a or -r parameter is required"))
|
report(fmt.Errorf("-a, -r or -str parameter is required"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,6 +372,22 @@ func diff(b1, b2 []byte) (data []byte, err error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
type identSet struct {
|
||||||
idents []string
|
idents []string
|
||||||
all bool
|
all bool
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/blueprint/parser"
|
"github.com/google/blueprint/parser"
|
||||||
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testCases = []struct {
|
var testCases = []struct {
|
||||||
|
@ -28,6 +29,7 @@ var testCases = []struct {
|
||||||
property string
|
property string
|
||||||
addSet string
|
addSet string
|
||||||
removeSet string
|
removeSet string
|
||||||
|
setString *string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "add",
|
name: "add",
|
||||||
|
@ -249,6 +251,39 @@ var testCases = []struct {
|
||||||
property: "deps",
|
property: "deps",
|
||||||
addSet: "bar-v10-bar",
|
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 {
|
func simplifyModuleDefinition(def string) string {
|
||||||
|
@ -265,6 +300,7 @@ func TestProcessModule(t *testing.T) {
|
||||||
targetedProperty.Set(testCase.property)
|
targetedProperty.Set(testCase.property)
|
||||||
addIdents.Set(testCase.addSet)
|
addIdents.Set(testCase.addSet)
|
||||||
removeIdents.Set(testCase.removeSet)
|
removeIdents.Set(testCase.removeSet)
|
||||||
|
setString = testCase.setString
|
||||||
|
|
||||||
inAst, errs := parser.ParseAndEval("", strings.NewReader(testCase.input), parser.NewScope(nil))
|
inAst, errs := parser.ParseAndEval("", strings.NewReader(testCase.input), parser.NewScope(nil))
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
|
|
Loading…
Reference in a new issue