bpmodify: remove-property

`r` option removes only item(s) in a list, so add `remove-property`
option to remove a property itself.

Bug: 146436251
Test: unittest
Change-Id: I0c838d31e72358f094cfb5fa9468dce07018e061
This commit is contained in:
Jeongik Cha 2022-02-09 06:25:39 +00:00
parent 451dd63611
commit 5860caea33
2 changed files with 85 additions and 25 deletions

View file

@ -30,9 +30,9 @@ var (
targetedProperty = new(qualifiedProperty) targetedProperty = new(qualifiedProperty)
addIdents = new(identSet) addIdents = new(identSet)
removeIdents = new(identSet) removeIdents = new(identSet)
removeProperty = flag.Bool("remove-property", false, "remove the property")
setString *string setString *string
addLiteral *string addLiteral *string
) )
func init() { func init() {
@ -147,7 +147,7 @@ func findModules(file *parser.File) (modified bool, errs []error) {
func processModule(module *parser.Module, moduleName string, func processModule(module *parser.Module, moduleName string,
file *parser.File) (modified bool, errs []error) { file *parser.File) (modified bool, errs []error) {
prop, err := getRecursiveProperty(module, targetedProperty.name(), targetedProperty.prefixes()) prop, parent, err := getRecursiveProperty(module, targetedProperty.name(), targetedProperty.prefixes())
if err != nil { if err != nil {
return false, []error{err} return false, []error{err}
} }
@ -168,25 +168,28 @@ func processModule(module *parser.Module, moduleName string,
// 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}
} }
} else if *removeProperty {
// remove-property is used solely, so return here.
return parent.RemoveProperty(prop.Name), nil
} }
m, errs := processParameter(prop.Value, targetedProperty.String(), moduleName, file) m, errs := processParameter(prop.Value, targetedProperty.String(), moduleName, file)
modified = modified || m modified = modified || m
return modified, errs return modified, errs
} }
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, parent *parser.Map, err error) {
prop, _, err = getOrCreateRecursiveProperty(module, name, prefixes, nil) prop, parent, _, err = getOrCreateRecursiveProperty(module, name, prefixes, nil)
return prop, err return prop, parent, err
} }
func createRecursiveProperty(module *parser.Module, name string, prefixes []string, func createRecursiveProperty(module *parser.Module, name string, prefixes []string,
empty parser.Expression) (prop *parser.Property, modified bool, err error) { empty parser.Expression) (prop *parser.Property, modified bool, err error) {
prop, _, modified, err = getOrCreateRecursiveProperty(module, name, prefixes, empty)
return getOrCreateRecursiveProperty(module, name, prefixes, empty) return prop, modified, err
} }
func getOrCreateRecursiveProperty(module *parser.Module, name string, prefixes []string, func getOrCreateRecursiveProperty(module *parser.Module, name string, prefixes []string,
empty parser.Expression) (prop *parser.Property, modified bool, err error) { empty parser.Expression) (prop *parser.Property, parent *parser.Map, 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 {
@ -195,7 +198,7 @@ func getOrCreateRecursiveProperty(module *parser.Module, name string, prefixes [
} else { } else {
// We've found a property in the AST and such property is not of type // We've found a property in the AST and such property is not of type
// *parser.Map, which must mean we didn't modify the AST. // *parser.Map, which must mean we didn't modify the AST.
return nil, false, fmt.Errorf("Expected property %q to be a map, found %s", return nil, 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 empty != nil { } else if empty != nil {
@ -206,18 +209,18 @@ func getOrCreateRecursiveProperty(module *parser.Module, name string, prefixes [
// check after this for loop must fail, because the node we inserted is an // check after this for loop must fail, because the node we inserted is an
// empty parser.Map, thus this function will return |modified| is true. // empty parser.Map, thus this function will return |modified| is true.
} else { } else {
return nil, false, nil return nil, nil, false, nil
} }
} }
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, m, false, nil
} else if empty != nil { } else if empty != nil {
prop = &parser.Property{Name: name, Value: empty} 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, m, true, nil
} else { } else {
return nil, false, nil return nil, nil, false, nil
} }
} }
@ -341,8 +344,13 @@ func main() {
return return
} }
if len(addIdents.idents) == 0 && len(removeIdents.idents) == 0 && setString == nil && addLiteral == nil { if len(addIdents.idents) == 0 && len(removeIdents.idents) == 0 && setString == nil && addLiteral == nil && !*removeProperty {
report(fmt.Errorf("-a, -add-literal, -r or -str parameter is required")) report(fmt.Errorf("-a, -add-literal, -r, -remove-property or -str parameter is required"))
return
}
if *removeProperty && (len(addIdents.idents) > 0 || len(removeIdents.idents) > 0 || setString != nil || addLiteral != nil) {
report(fmt.Errorf("-remove-property cannot be used with other parameter(s)"))
return return
} }

View file

@ -23,14 +23,15 @@ import (
) )
var testCases = []struct { var testCases = []struct {
name string name string
input string input string
output string output string
property string property string
addSet string addSet string
removeSet string removeSet string
addLiteral *string addLiteral *string
setString *string setString *string
removeProperty bool
}{ }{
{ {
name: "add", name: "add",
@ -304,6 +305,56 @@ var testCases = []struct {
property: "foo", property: "foo",
setString: proptools.StringPtr("bar"), setString: proptools.StringPtr("bar"),
}, },
{
name: "remove existing property",
input: `
cc_foo {
name: "foo",
foo: "baz",
}
`,
output: `
cc_foo {
name: "foo",
}
`,
property: "foo",
removeProperty: true,
}, {
name: "remove nested property",
input: `
cc_foo {
name: "foo",
foo: {
bar: "baz",
},
}
`,
output: `
cc_foo {
name: "foo",
foo: {},
}
`,
property: "foo.bar",
removeProperty: true,
}, {
name: "remove non-existing property",
input: `
cc_foo {
name: "foo",
foo: "baz",
}
`,
output: `
cc_foo {
name: "foo",
foo: "baz",
}
`,
property: "bar",
removeProperty: true,
},
} }
func simplifyModuleDefinition(def string) string { func simplifyModuleDefinition(def string) string {
@ -320,6 +371,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)
removeProperty = &testCase.removeProperty
setString = testCase.setString setString = testCase.setString
addLiteral = testCase.addLiteral addLiteral = testCase.addLiteral