diff --git a/TODOS.md b/TODOS.md index 2dae97392..c7e1db9da 100644 --- a/TODOS.md +++ b/TODOS.md @@ -20,6 +20,7 @@ - Select entire name, find references => no results - Crashes if maven is not installed - Homebrew users don't have src.zip, detect java version and download the appropriate src.zip +- Temporary files created for Bazel command output are not cleaned up. ## Optimizations - Compilation is very slow in the presence of lots of errors diff --git a/src/main/java/org/javacs/InferConfig.java b/src/main/java/org/javacs/InferConfig.java index 8cc004c55..d30b97075 100644 --- a/src/main/java/org/javacs/InferConfig.java +++ b/src/main/java/org/javacs/InferConfig.java @@ -302,7 +302,7 @@ private Path bazelOutputBase(Path bazelWorkspaceRoot) { String[] command = { "bazel", "info", "output_base", }; - var output = fork(bazelWorkspaceRoot, command); + var output = fork(bazelWorkspaceRoot, command, false); if (output == NOT_FOUND) { return NOT_FOUND; } @@ -319,11 +319,12 @@ private void bazelDryRunBuild(Path bazelWorkspaceRoot, Set targets) { var command = new ArrayList(); command.add("bazel"); command.add("build"); + command.add("--keep_going"); command.add("--nobuild"); command.addAll(targets); String[] c = new String[command.size()]; c = command.toArray(c); - var output = fork(bazelWorkspaceRoot, c); + var output = fork(bazelWorkspaceRoot, c, true); if (output == NOT_FOUND) { return; } @@ -331,8 +332,8 @@ private void bazelDryRunBuild(Path bazelWorkspaceRoot, Set targets) { } private Set bazelQuery(Path bazelWorkspaceRoot, String filterKind) { - String[] command = {"bazel", "query", "kind(" + filterKind + ",//...)"}; - var output = fork(bazelWorkspaceRoot, command); + String[] command = {"bazel", "query", "--keep_going", "kind(" + filterKind + ",//...)"}; + var output = fork(bazelWorkspaceRoot, command, true); if (output == NOT_FOUND) { return Set.of(); } @@ -366,13 +367,14 @@ private Set bazelAQuery( String[] command = { "bazel", "aquery", + "--keep_going", "--output=proto", "--include_aspects", // required for java_proto_library, see // https://stackoverflow.com/questions/63430530/bazel-aquery-returns-no-action-information-for-java-proto-library "--allow_analysis_failures", "mnemonic(" + filterMnemonic + ", " + kindUnion + ")" }; - var output = fork(bazelWorkspaceRoot, command); + var output = fork(bazelWorkspaceRoot, command, true); if (output == NOT_FOUND) { return Set.of(); } @@ -474,7 +476,7 @@ private static String buildPath(List fragments, int id) { throw new RuntimeException(); } - private static Path fork(Path workspaceRoot, String[] command) { + private static Path fork(Path workspaceRoot, String[] command, boolean allowNonZeroExit) { try { LOG.info("Running " + String.join(" ", command) + " ..."); var output = Files.createTempFile("java-language-server-bazel-output", ".proto"); @@ -489,7 +491,9 @@ private static Path fork(Path workspaceRoot, String[] command) { var result = process.waitFor(); if (result != 0) { LOG.severe("`" + String.join(" ", command) + "` returned " + result); - return NOT_FOUND; + if (!allowNonZeroExit) { + return NOT_FOUND; + } } return output; } catch (InterruptedException | IOException e) { diff --git a/src/test/examples/bazel-project-broken/.bazelversion b/src/test/examples/bazel-project-broken/.bazelversion new file mode 100644 index 000000000..74ecad8a3 --- /dev/null +++ b/src/test/examples/bazel-project-broken/.bazelversion @@ -0,0 +1 @@ +4.2.4 \ No newline at end of file diff --git a/src/test/examples/bazel-project-broken/.gitignore b/src/test/examples/bazel-project-broken/.gitignore new file mode 100644 index 000000000..6d8ad95fa --- /dev/null +++ b/src/test/examples/bazel-project-broken/.gitignore @@ -0,0 +1 @@ +bazel-* \ No newline at end of file diff --git a/src/test/examples/bazel-project-broken/WORKSPACE b/src/test/examples/bazel-project-broken/WORKSPACE new file mode 100644 index 000000000..6fc327c5a --- /dev/null +++ b/src/test/examples/bazel-project-broken/WORKSPACE @@ -0,0 +1,32 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +RULES_JVM_EXTERNAL_TAG = "4.2" +RULES_JVM_EXTERNAL_SHA = "cd1a77b7b02e8e008439ca76fd34f5b07aecb8c752961f9640dea15e9e5ba1ca" + +http_archive( + name = "rules_jvm_external", + sha256 = RULES_JVM_EXTERNAL_SHA, + strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG, + url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG, +) + +load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps") + +rules_jvm_external_deps() + +load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup") + +rules_jvm_external_setup() + +load("@rules_jvm_external//:defs.bzl", "maven_install") + +maven_install( + artifacts = [ + "com.google.guava:guava:18.0", + ], + repositories = [ + "https://jcenter.bintray.com/", + "https://repo1.maven.org/maven2", + ], + fetch_sources = True, +) \ No newline at end of file diff --git a/src/test/examples/bazel-project-broken/broken/BUILD b/src/test/examples/bazel-project-broken/broken/BUILD new file mode 100644 index 000000000..52016f0c2 --- /dev/null +++ b/src/test/examples/bazel-project-broken/broken/BUILD @@ -0,0 +1 @@ +fail("intentionally broken") diff --git a/src/test/examples/bazel-project-broken/hello/BUILD b/src/test/examples/bazel-project-broken/hello/BUILD new file mode 100644 index 000000000..6b3070fe9 --- /dev/null +++ b/src/test/examples/bazel-project-broken/hello/BUILD @@ -0,0 +1,9 @@ +java_binary( + name = "main", + srcs = glob(["src/**/*.java"]), + main_class = "Hello", + visibility = ["//visibility:public"], + deps = [ + "@maven//:com_google_guava_guava", + ], +) \ No newline at end of file diff --git a/src/test/examples/bazel-project-broken/hello/src/Hello.java b/src/test/examples/bazel-project-broken/hello/src/Hello.java new file mode 100644 index 000000000..76b62dc8e --- /dev/null +++ b/src/test/examples/bazel-project-broken/hello/src/Hello.java @@ -0,0 +1,5 @@ +class Hello { + public static void main(String[] args) { + System.out.println("Hello, world!"); + } +} \ No newline at end of file diff --git a/src/test/examples/bazel-project/.bazelversion b/src/test/examples/bazel-project/.bazelversion new file mode 100644 index 000000000..74ecad8a3 --- /dev/null +++ b/src/test/examples/bazel-project/.bazelversion @@ -0,0 +1 @@ +4.2.4 \ No newline at end of file diff --git a/src/test/examples/bazel-protos-project/.bazelversion b/src/test/examples/bazel-protos-project/.bazelversion new file mode 100644 index 000000000..74ecad8a3 --- /dev/null +++ b/src/test/examples/bazel-protos-project/.bazelversion @@ -0,0 +1 @@ +4.2.4 \ No newline at end of file diff --git a/src/test/java/org/javacs/InferBazelConfigTest.java b/src/test/java/org/javacs/InferBazelConfigTest.java index a1eaa8369..8010d242f 100644 --- a/src/test/java/org/javacs/InferBazelConfigTest.java +++ b/src/test/java/org/javacs/InferBazelConfigTest.java @@ -25,6 +25,12 @@ public void bazelClassPathWithProtos() { assertThat(bazel.classPath(), hasItem(hasToString(endsWith("libperson_proto-speed.jar")))); } + @Test + public void bazelClassPathBrokenProject() { + var bazel = new InferConfig(Paths.get("src/test/examples/bazel-project-broken")); + assertThat(bazel.classPath(), contains(hasToString(endsWith("guava-18.0.jar")))); + } + @Test public void bazelDocPath() { var bazel = new InferConfig(Paths.get("src/test/examples/bazel-project"));