Closed promiseofcake closed 7 years ago
Hey @promiseofcake thanks for asking. So, when you initially write the rule, you don't manually type in the transitive_deps
yourself, you just type in the roots for the transitive search (in this example just com.google.inject:guice:4.1.0
.
What will happen is that a new external workspace will be generated as @guice
(the name
of the maven_repository rule) with a new file called rules.bzl
. That file contains generated maven_jar
definitions for all the transitive dependencies. It also contains a guice_${configuration}
rule that loads the transitive maven jars foreach gradle "configuration". The most common configuration is "compile", but there are a bunch of other ones.
In the next line of your WORKSPACE
, tell bazel to load that file for the configuration you want, and then invoke it.
load("@guice//:rules.bzl", "guice_compile")
guice_compile()
The second file that is generated is @guice//:BUILD
. This contains generated java_library
, java_import
rules (which aggregate the transitive set of jars) that you actually depend on in your own java_library
or java_binary
rules. So, to actually use that set, depend on it:
java_binary(
name = "foo",
srcs = [...],
deps = ["@guice//:compile"] # name of configuration matches the one you loaded
)
Since bazel is super lazy, nothing happens until you do something that actually requires the upstream deps to get evaluated. So when you bazel build src/main/java:foo
, bazel will go back and actually generate the @guice
workspace etc.
When that occurs, rules_maven
compares the maven_repository
rule you wrote to the one where all the transitive deps are included. If there is a discrepancy, it will print out the "closed-form" rule with all the transitive_deps listed for you.
You then have to manually copy-paste the text from your terminal back into your WORKSPACE
file. Assuming there is congruence of expected / actual values of the transitive_deps, the rule will be silent and no output will be printed to the console. (this is the paragraph that actually answers your question).
Hope that made sense! Maybe I should put together a short video on how to do it.
FYI this two-stage loading pattern is similar to how it works in bazelbuild/rules_python.
They may have explained it better, so if you understand one you understand both. cc @mattmoor
@davidstanke FYI
Thank you for the thorough explanation, I was able to get that working!
Good to hear it. FYI it's always useful to inspect the generated files:
$ less $(bazel info output_base)/external/guice/rules.bzl
$ less $(bazel info output_base)/external/guice/BUILD
$ less $(bazel info output_base)/external/guice/build.gradle
And a way to see all the available external workspaces:
$ bazel query //external:*
Forgive me is this is apparent, but how does one generate the WORKSPACE output as described in 2a?
Here is a sample repo (using example from the README.md): https://github.com/promiseofcake/rules_maven_example
How do I convert the
guice
dependency:into:
It seems to differ from the
rules_protobuf
paradigms in that I am not specifying a specific skylark macro such asjava_proto_library
in my BUILD file which can then be triggered.