My organization is migrating to Bazel and the biggest challenge has been lack of IDE integration. In particular, all we want is decent code completion in Java.
TL;DR: how to generate Eclipse .classpath file from BUILD using Bazel (aspects)?
We came up with the following approach:
1. Bazel is the source of truth. That's what we use to build both in our workstations and in CI environment.
2. We want to use Eclipse as code editor and take advantage of it's code completion, formatting, import organization, etc.
3. We settled in the following code structure:
root/
path1/
BUILD
src/
com/
pkg1/
Source1.java
path2/
BUILD
.project
.classpath
src/
com/
pkg2/
Source2.java
4. The files .project and .classpath are to be generated from BUILD.
We wrote .project and .classpath as if they wore generated by a program. This works quite well: we got two projects named after their packages "com.pkg1" and "com.pkg2". Code completion works just as expected. com.pkg2 depends on com.pkg1 so we added a project-reference which enabled smooth code navigation and refactoring capabilities.
The idea is to add a target like eclipse_files(name="eclipse_files") so I can run:
$ bazel build //root/pkg2:eclipse_files
To get files generated. I played with aspects but I still could not grasp how to write tools.bzl's eclipse_files rule/macro/function in order to aggregate deps from java_* rules.
Here is what root/path2/ files look like:
root/path2/.classpath
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry combineaccessrules="false" kind="src" path="/com.pkg1"/>
<classpathentry kind="lib" path="../../bazel-bin/external/com_google_protobuf/libprotobuf_java.jar"/>
<classpathentry kind="lib" path="../../bazel-bin/external/com_google_protobuf/libprotobuf_java_util.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.acqio.cmdline</name>
<comment></comment>
<projects></projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments></arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
root/path2/BUILD
package(default_visibility = ["//visibility:public"])
java_library(
name = "pkg2",
srcs = glob(
["src/**/*.java"],
exclude = ["src/**/*Test.java"],
),
deps = [
"@com_google_protobuf//:protobuf_java",
"@com_google_protobuf//:protobuf_java_util",
],
)
#load("//tools:tools.bzl", "eclipse_files")
#
#eclipse_files(
# name = 'eclipse_files'
#)