My coworker Carmi just published a blog post on the Bazel blog about how Java tracks dependencies. Bazel has some nice facilities built in to let you know when you need to add dependencies:
ERROR: /home/kchodorow/test/a/BUILD:24:1: Building libA.jar (1 source file) failed: Worker process sent response with exit code: 1. A.java:6: error: [strict] Using type C from an indirect dependency (TOOL_INFO: "//:C"). See command below ** C getC() { ^ ** Please add the following dependencies: //:C to //:A
He mentioned unused_deps
, a great tool to go the other way: what if your BUILD file declares dependencies you’re not using? unused_deps
lets you quickly clean up your BUILD files.
To get unused_deps
, clone the buildtools
repository and build it:
$ git clone git@github.com:bazelbuild/buildtools.git $ cd buildtools $ bazel build //unused_deps
Now go to your project and run it:
$ cd ~/my-project $ ~/gitroot/buildtools/bazel-bin/unused_deps/unused_deps //... > buildozer-cmds.sh
This will print a bunch of info to stderr as it runs but, when it’s done, you should have a list of buildozer commands in buildozer-cmds.sh
. For example, running this on the Bazel codebase yields:
buildozer 'remove deps //src/main/java/com/google/devtools/build/lib:auth_and_tls_options' //src/tools/remote_worker/src/main/java/com/google/devtools/build/remote:remote buildozer 'remove deps //src/main/java/com/google/devtools/build/lib:build-base' //src/tools/remote_worker/src/main/java/com/google/devtools/build/remote:remote buildozer 'remove deps //src/main/java/com/google/devtools/build/lib:concurrent' //src/tools/remote_worker/src/main/java/com/google/devtools/build/remote:remote buildozer 'remove deps //src/main/java/com/google/devtools/build/lib:events' //src/tools/remote_worker/src/main/java/com/google/devtools/build/remote:remote ...
This is a list of shell commands, so now you need to execute this file. The buildozer
tool also lives in the buildtools
repository, so you just have to build that and then add it to your path:
$ cd ~/gitroot/buildtools $ bazel build //buildozer $ cd ~/my-project $ chmod +x buildozer-cmds.sh $ PATH=$HOME/gitroot/buildtools/bazel-bin/buildozer:$PATH ./buildozer-cmds.sh
This will run all of the buildozer commands and then you can commit the changes, e.g.,
$ git diff diff --git a/src/tools/benchmark/javatests/com/google/devtools/build/benchmark/codegenerator/BUILD b/src/tools/benchmark/javatests/com/google/devtools/build/benchmark/codegenerator/BUILD index 022a4037d..5d5cdf8d0 100644 --- a/src/tools/benchmark/javatests/com/google/devtools/build/benchmark/codegenerator/BUILD +++ b/src/tools/benchmark/javatests/com/google/devtools/build/benchmark/codegenerator/BUILD @@ -6,7 +6,6 @@ java_test( deps = [ "//src/tools/benchmark/java/com/google/devtools/build/benchmark/codegenerator:codegenerator_lib", "//third_party:guava", - "//third_party:junit4", "//third_party:truth", ], ) @@ -17,7 +16,6 @@ java_test( deps = [ "//src/tools/benchmark/java/com/google/devtools/build/benchmark/codegenerator:codegenerator_lib", "//third_party:guava", - "//third_party:junit4", "//third_party:truth", ], ) @@ -39,7 +37,6 @@ java_test( deps = [ "//src/tools/benchmark/java/com/google/devtools/build/benchmark/codegenerator:codegenerator_lib", "//third_party:guava", - "//third_party:junit4", "//third_party:truth", ], ) @@ -50,7 +47,6 @@ java_test( deps = [ "//src/main/java/com/google/devtools/common/options", "//src/tools/benchmark/java/com/google/devtools/build/benchmark/codegenerator:codegenerator_lib", - "//third_party:junit4", "//third_party:truth", ], ) ...
It’s a good idea to run unused_deps
regularly to keep things tidy. For example, the Bazel project does not run it automatically and has nearly 1000 unneeded deps (oops). You might want to add a git hook or something to your CI to run for every change.

Thanks! On a different (but related) note are there any differences between buildozer in the buildtools repo and the one in the buildifer repo?
Scratch that. I didn’t know the buildifier repo was renamed to buildtools 🙂
LikeLike
Wasn’t the buildifier repo renamed “buildtools”?
LikeLike
It was. I updated my comment right after when I saw 🙂
LikeLike
🙂
LikeLike
Great article. Thanks for sharing. I always enjoy your blogs. Apologies for not giving more consistent feedback.
LikeLike