Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buildozer new command: copy rule #1078

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions buildozer/README.md
Original file line number Diff line number Diff line change
@@ -117,6 +117,8 @@ Buildozer supports the following commands(`'command args'`):
exists in the `to_rule`, it will be overwritten.
* `copy_no_overwrite <attr> <from_rule>`: Copies the value of `attr` between
rules. If it exists in the `to_rule`, no action is taken.
* `copy_rule <from_rule>`: Copies the value of `from_rule` to the `to_rule`. If
`to_rule` exists, it will be overwritten.
* `dict_add <attr> <(key:value)(s)>`: Sets the value of a key for the dict
attribute `attr`. If the key was already present, it will _not_ be overwritten
* `dict_set <attr> <(key:value)(s)>`: Sets the value of a key for the dict
@@ -185,6 +187,9 @@ buildozer 'new cc_binary new_bin before tests' //:__pkg__
# Copy an attribute from `protolib` to `py_protolib`.
buildozer 'copy testonly protolib' //pkg:py_protolib

# Copy a rule from `protolib` to `py_protolib`.
buildozer 'copy_rule protolib' //pkg:py_protolib

# Set two attributes in the same rule
buildozer 'set compile 1' 'set srcmap 1' //pkg:rule

40 changes: 40 additions & 0 deletions buildozer/buildozer_test.sh
Original file line number Diff line number Diff line change
@@ -866,6 +866,46 @@ go_binary(name = "to")'
assert_err "rule 'from' does not have attribute 'visibility'"
}

function test_copy_rule() {
in='proto_library(name = "from", visibility = ["://foo"] + CONST)
cc_binary(name = "to")'

run "$in" 'copy_rule from' '//pkg:to'
assert_equals 'proto_library(
name = "from",
visibility = ["://foo"] + CONST,
)
cc_binary(
name = "to",
visibility = ["://foo"] + CONST,
)'
}

function test_copy_rule_overwrite() {
in='proto_library(name = "from", testonly = 1)
cc_binary(name = "to", testonly = 2)'

run "$in" 'copy_rule from' '//pkg:to'
assert_equals 'proto_library(
name = "from",
testonly = 1,
)
cc_binary(
name = "to",
testonly = 1,
)'
}

function test_copy_rule_no_from_rule() {
in='go_binary(name = "to")'
ERROR=2 run "$in" 'copy_rule from' '//pkg:to'
assert_err "could not find rule 'from'"
}

function test_set_kind() {
in='cc_library(name = "a")'

23 changes: 23 additions & 0 deletions edit/buildozer.go
Original file line number Diff line number Diff line change
@@ -563,6 +563,28 @@ func cmdCopyNoOverwrite(opts *Options, env CmdEnvironment) (*build.File, error)
return copyAttributeBetweenRules(env, attrName, from)
}

func cmdCopyRule(opts *Options, env CmdEnvironment) (*build.File, error) {
from := env.Args[0]

fromRule := FindRuleByName(env.File, from)
if fromRule == nil {
return nil, fmt.Errorf("could not find rule '%s'", from)
}
for _, key := range env.Rule.AttrKeys() {
if key != "name" {
env.Rule.DelAttr(key)
}
}
for _, key := range fromRule.AttrKeys() {
if key != "name" {
copyAttributeBetweenRules(env, key, from)
}
}

return env.File, nil

}

// cmdDictAdd adds a key to a dict, if that key does _not_ exit already.
func cmdDictAdd(opts *Options, env CmdEnvironment) (*build.File, error) {
attr := env.Args[0]
@@ -727,6 +749,7 @@ var AllCommands = map[string]CommandInfo{
"set_if_absent": {cmdSetIfAbsent, true, 1, -1, "<attr> <value(s)>"},
"copy": {cmdCopy, true, 2, 2, "<attr> <from_rule>"},
"copy_no_overwrite": {cmdCopyNoOverwrite, true, 2, 2, "<attr> <from_rule>"},
"copy_rule": {cmdCopyRule, true, 1, 1, "<from_rule>"},
"dict_add": {cmdDictAdd, true, 2, -1, "<attr> <(key:value)(s)>"},
"dict_set": {cmdDictSet, true, 2, -1, "<attr> <(key:value)(s)>"},
"dict_remove": {cmdDictRemove, true, 2, -1, "<attr> <key(s)>"},