-
Notifications
You must be signed in to change notification settings - Fork 854
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
How to run google-java-format from Bazel? #917
Comments
Can you say more about what the desired workflow would be? Would you like to be able to |
@cushon anything that works, really; if there is no good way to do via After staring at Would you welcome a contrib (PR) proposing some (backwards compatible) minor refactoring to I guess it's not even Bazel related, per se... such a test could "dog food" and even run within this project! |
If you want a |
public class GoogleJavaFormatTest {
@Test
public void testGoogleJavaFormat() {
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out, UTF_8));
PrintWriter err = new PrintWriter(new OutputStreamWriter(System.err, UTF_8));
Assert.assertEquals(0, new GoogleJavaFormatToolProvider().run(out, err, "--help"));
}
} works! Now I just need to figure out to... hm, what? I would probably want some Blaze I can't pass an argument to a test. Set a system property? (Not sure if that could run into length limitations...) Probably best to somehow get a file with all Java classes to format written, possibly with a fixed name, and But how do you do that - I don't know how to do the Bazel part... 😭 Will read up and ask around - and welcome any pointers & tips! |
Note that you don't need to instantiate the class directory, you can also use the ToolProvider SPI: Line 42 in 1a00656
For the Bazel part, tests can only see files if they're inputs in the build graph. I don't know a standard way to make all of the |
A proposed solution for porting Spotless to Bazel is to use the third-party https://github.com/apple/apple_rules_lint, so I wanted to let you both know if this possibility in case you hadn't considered it already. :) |
FYI I personally won't be actively pursuing this further, because I've settled on using https://github.com/macisamuele/language-formatters-pre-commit-hooks/ instead of a Bazel integrated approach, for my current project, for now. (I suspect it is more "incremental" than a Bazel-based solution could be; as https://pre-commit.com uses git to check only changed files.) But I'm leaving this issue open just in case this analysis/discussion is ever of any use to others in the future. |
#216 (for bazel-contrib/rules_jvm#23) seems to be related to this... |
I think the main reason to move Say your project started to use GJF 1.7 years ago, and due to it evolution, we are currently on version 1.22 (at the time of writing this comment). Now consider that your project has 42 stable branches (any many of them are still active and continue to become fixes and need to be formatted with the right GJF version used on that stable branch). What branch is re-formatted with which version of GJF? So similarly, how baselisk is using Or alternatively, just use Bazel to fetch and run the right version of GJF on the right branch. In that case the upgrade would only be GJF version bump in some Bazel build file (similarly to # old
maven_jar(
name = "google-java-format",
artifact = "com.google.googlejavaformat:google-java-format:1.7:all-deps",
sha1 = "b6d34a51e579b08db7c624505bdf9af4397f1702",
)
# new
maven_jar(
name = "google-java-format",
artifact = "com.google.googlejavaformat:google-java-format:1.22.0:all-deps",
sha1 = "693d8fd04656886a2287cfe1d7a118c4697c3a57",
)
Actually the both approaches would be great to have. I added the first option in this Gerrit change: [2] and can do something like that (see discussion in bazelbuild/bazel#3325 to understand why
The above invocation could be simplified, if we split it in two steps: 1/ retrieve executable script and 2/ invoke it:
The second option to add a test rule would be more challenging, because one need to provide the sources, see this comment: bazelbuild/bazel#3325 (comment): java_binary(
name = "gjf-binary",
main_class = "com.google.googlejavaformat.java.Main",
visibility = ["//visibility:public"],
runtime_deps = ["@google_java_format//jar"],
)
genrule(
name = "gjf-check-invocation",
srcs = glob(["src/main/java/**/*.java"]),
cmd = "find . -name \"*.java\" | xargs $(location :gjf-binary) --dry-run > $@",
tools = [":gjf-binary"],
outs = ["check-java-format.log"],
)
sh_test(
name = "gjf-check",
srcs = [":gjf-check-invocation"],
tags = ["oauth"],
) This only works, because this gerrit plugin has only one single Bazel package with all java sources located under this root (that wouldn't be the case for any non trivial Bazel project though):
Having said that, I think this issue is more justified for Bazel related projects and not for GJF itself. [1] https://gerrit-review.googlesource.com/c/gerrit/+/428139/6/tools/setup_gjf.sh |
I would like to run
google-java-format
in an (open source) project which uses Bazel as build system.I currently have it set up using https://github.com/dustinsand/pre-commit-jvm (with https://pre-commit.com) but it strikes me as "odd" having to install https://get-coursier.io and relying on
dustinsand/pre-commit-jvm
when it should be possible to "just" have a (Maven) dependency on this in Bazel and "run it" - I'm just not entirely sure HOW one would be run a Java based tool like this one from Bazel...... I have briefly explored something like what this post on
bazel-discuss
may have been after, and started to write my ownGoogleJavaFormatTest
using this project's API, but it doesn't seem to be intended to used like that (UsageException
is package local only, even thoughMain#format(String... args) throws UsageException
) - and integrated this as ab test //...
is perhaps that's the wrong way to go about this anyway?How would one best run google-java-format from Bazel? You would want it "run whenever any *.java changed", and one would want it to fail the build if the formatting was wrong - but re-write (correct) the source files. Is this possible with Bazel? How does one even "run a main() method from a dependency" for something like this?
@cushon perhaps you have some wise guidance?
The text was updated successfully, but these errors were encountered: