-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Feature request: Setting default javacopts for all java_library rules in workspace #3427
Comments
This is similar to #2358, with one major difference: that FR wants the defaults to apply to external repositories' code, whereas I don't want. I haven't experimented with using a custom toolchain to solve this, so I'm not sure if that would be a feasible solution. |
You can use the (somewhat poorly named) |
We ended up using extra actions to run more checks for our java code. Maybe that could be an option? With extra actions you can use --experimental_extra_action_filter=-@ to skip running them on external dependencies. We do this to run checkstyle, ecj and findbugs - and it would obviously be possible to run error prone. Maybe not an optimal solution, but should work :) It's quite annoying that external dependencies will be compiled with the same copts as the local rules as default, which makes it hard to take full advantage of non default error prone checks and javac lint rules. (sorry if you got duplicate notification. Posted with the wrong github user first). |
Discussed with @dslomov a while ago: I wanted to have a similar feature for TypeScript to set compiler default options, and ran into the same issues. Even for a rule written in skylark (not a native rule like java_library) there is no good way to apply defaults just to the local repository. |
There's now another option for setting javacopts based on package specifications. It wasn't created specifically with this issue in mind, but it may be better than some of the existing options. The configuration uses load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "default_java_toolchain")
# this is a convenience macro that inherits values from Bazel's default java_toolchain
default_java_toolchain(
name = "toolchain",
package_configuration = [
":error_prone",
],
visibility = ["//visibility:public"],
)
# this associates a set of javac flags with a set of packages
java_package_configuration(
name = "error_prone",
javacopts = [
"-Xep:MissingOverride:ERROR",
],
packages = ["error_prone_packages"],
)
# this is a regular package_group, which is used to specify a set of packages to apply flags to
package_group(
name = "error_prone_packages",
packages = [
"//foo/...",
"-//foo/bar/...", # this is an exclusion
],
)
|
Thanks @cushon, the setup you describe suits our use case well! Could you point me to the fix you're referring to in your comment?
|
@unlikely-leo I think that was af24688. The example I provided should work without having to set |
Thanks for checking @cushon! FYI in Bazel version 0.14 (build timestamp 1527858416), |
Please do not assign more than one team to an issue. |
This seems to be resolves with |
I'd like to set some javacopts on all java_library rules in my project. In particular, I want to enable certain Error Prone checks that aren't on by default, with the
-Xep
flags. However, I only want these flags to apply to Java targets in my project, not to builds of Java code in external repositories that are included with e.g.http_archive
. That external code may not adhere to our internal standards, so I can't have these additional error checks enabled there---it would cause the build to fail.I've tried several approaches to make this happen (all with Bazel 0.5.2), and each of them has drawbacks that make them infeasible:
1. Set flags in
tools/bazel.rc
Since javacopts can be set both on the java_library rule and via the
--javacopt
flag tobazel build
, I created atools/bazel.rc
like thisPros:
bazel build -s
Cons:
http_archive
s, so external builds fail2. Enforce setting via out-of-band validation
Create
tools/build_rules/java.bzl
defining a list,JAVACOPTS = ['-XepDisableWarningsInGeneratedCode', '-Xep:MissingCasesInEnumSwitch:ERROR', …]
. In each BUILD file, addload("//tools/build_roles/java.bzl", "JAVACOPTS")
and setjavacopts=JAVACOPTS
in the java_library call. Finally, add a check in CI that all BUILD files that contain a java_library rule pass the imported JAVACOPTS.I could put the
load
call in bazel_prelude, but that has its own discoverability problems (see #1612 and #1674).Pros:
Cons:
java_library
rules across dozens of files, each of which needs to have theload
and argument added and maintained3. Wrap
java_library
with a macroSimilarly to 2, create
tools/build_rules/java.bzl
that definesJAVACOPTS
and also amy_java_library
macro, e.g.:In each BUILD file, load and use
my_java_library
in place of the native rule.Pros:
Cons:
4. Shadow
java_library
with a macroLike #3, but name the macro
java_library
so it shadows the built-in, and load it in the prelude so it automatically applies to all targets. The macro can checknative.repository_name
and apply different changes to my project's code vs external code:Pros:
repository_name
check makes this only apply to targets in my project, not external codeCons:
Feature request
None of the above solutions are ideal: (1) causes build failures in external code; (2) and (3) require extra checks and documentation outside of Bazel; and (4) is excessively magical and difficult to discover & maintain.
It would be great if Bazel had a supported, clear way of setting default arguments to rules in a workspace. The defaults should apply only to rules defined in that workspace (not to external repositories loaded at build time). I can't find anything like this that exists now.
That would solve for my need of default javacopts, and support other needs for default arguments (e.g. default global test resources; I'm sure there are others).
Example proposal
For example, this could be implemented via a new workspace rule called
default_arguments
, used like so:At analysis time, these arguments would be mixed in to each target's arguments for a given rule. This could be used for any rule and argument, not just javacopts and java_library.
I'm not sure what the best logic would be for resolving the existing default arguments vs ones set in the workspace vs arguments passed to each rule; that would have to be decided and documented.
The text was updated successfully, but these errors were encountered: