bazel-contrib / bazel-contrib/buildtools
Buildozer does not parse expressions in `set` command
- Dominant language
- Go
- Stars
- 1.2k
- Forks
- 471
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 13
Description
Consider this setup:
```
$ mkdir x
$ touch x/BUILD
```
Now run `buildozer -f` with this file:
```
new some_rule some_name|x/BUILD
new_load somewhere foo|x/BUILD
set some_attr foo("some_arg")|x/BUILD:some_name
fix unusedLoads|x/BUILD
```
The result is:
```bazel
some_rule(
name = "some_name",
some_attr = foo("some_arg"),
)
```
i.e. `fix unusedLoads` removed the actually-used `load("somewhere", "foo")` statement.
---
Manually running the commands above (i.e. one `buildozer` invocation per command) produces the correct result, because the file gets properly parsed again after every modification. Batching the commands into a single `buildozer` invocation as above doesn't work because the entire right-hand side of the `set` command gets parsed as an identifier:
https://github.com/bazelbuild/buildtools/blob/62b9413b08bb4d1bbac0869eaff8fa8962c46744/edit/buildozer.go#L604-L605
Now [`UsedSymbols()`](https://github.com/bazelbuild/buildtools/blob/62b9413b08bb4d1bbac0869eaff8fa8962c46744/edit/edit.go#L993-L1019) will mark an identifier named `foo("some_arg")` (**not** `foo`) as used, and the load statement for `foo` will be deleted.
Contributor guide
Research direction
Start in edit/buildozer.go at the cited set-command parsing lines, then read edit/edit.go around UsedSymbols(). Reproduce the batched commands from the issue and verify that the expression is tracked by its function name, so fix unusedLoads retains the load for foo while preserving the generated some_attr expression.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- build-system, cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100