Bazel support

Detailed information on how the Moderne CLI interacts with the Bazel build tool.

Moderne CLI interacts with the Bazel build tool to parse repositories into the Lossless Semantic Tree (LST). Bazel build files are discovered automatically by mod build in the same way other build tools like Maven or Gradle are discovered.

Moderne CLI will execute Bazel with a bazelisk wrapper if present, otherwise falling back on a PATH installed Bazel executable.

The CLI executes bazel query to find Bazel rules of type java_library or kt_jvm_library, followed by a bazel build for each rule matched by that query. The build step applies an aspect that extracts information about the rule's source sets and classpath which is then forwarded on to the OpenRewrite parser to produce LSTs.

Partitioning Bazel repositories

To control the scope of the bazel query step, you can customize the CLI's build steps. For Bazel repositories, generally you will want to go one step further and introduce build partitions to carve up the repository into business functional units, with an LST being produced for each unit.

The bazel build step type has a configurable targetExpression configuration (that defaults to //:all). Any Bazel query expression is valid here, allowing a wide range of options for how to partition the repository. For example:

  • Rules with a particular attribute

  • Fixed words which correspond to fixed named targets or wildcard patterns of them

  • Rules with a particular label

build:
  partitions:
    - name: bookings
      steps:
        - type: bazel
          targetExpression: //:bookings
    - name: payments
      steps:
        - type: bazel
          targetExpression: //:payments

Example Bazel repository

Moderne maintains a public example Bazel repository.

  1. Clone https://github.com/moderneinc/bazel-examples and cd into the directory containing the cloned repository.

  2. Execute mod build .

  3. Examine the .moderne/build/<DATE_TIME_HASH>/manifest.csv file to see that the CLI correctly identified Java source files as such and parsed them into J.CompilationUnit.

n,sourcePath,sourceFileType,buildTool,buildToolVersion,checksum,lineCount
1,"LICENSE",Quark,mod,3.6.2,86d3f3a95c324c9479bd8986968f4327,0
2,"README.md",PlainText,mod,3.6.2,9806770b48fee4ff1a0eb2bce1c66176,2
3,"bazel-java-maven/.gitignore",PlainText,mod,3.6.2,a8edf8bbdab71497f7cd11360a582a86,5
...
10,"bazel-java-maven/src/main/java/com/example/myproject/App.java",,mod,3.6.2,4b01908c328578022630cccdb1719d04,0
11,"bazel-java-maven/src/test/java/com/example/myproject/TestApp.java",,mod,3.6.2,b8b7619c3321903bd9549b4f0b8bfd88,0

Troubleshooting: Repositories that have both Bazel build files and another build tool like Gradle configured at the same folder level

The default build steps used by the CLI give precedence to Maven or Gradle if they are also present. You can customize the default build steps to give precedence to Bazel as described in build steps.

Troubleshooting: What Bazel command did the Moderne CLI execute to produce the LST?

The Bazel command that the Moderne CLI is executing is logged at this path relative to the root of the repository being parsed.

.moderne/build/<DATA_TIME_HASH>/build.log

Troubleshooting: Why were Java files not parsed as Java LSTs?

At the end of build, a manifest is created that itemizes each file that is contained in the LST and how it was parsed. A sure sign that the Bazel rule configuration is not correctly identfying Java source sets is a series of Java file entries in the manifest that are listed as "Quarks", as seen in the image below.

A quark is an LST type that simply indicates the presence of a file, but does not keep its contents. Java-specific recipes will not operate on Quarks to make changes.

The Moderne CLI augments the build with an Aspect that emits information on matching rules into a file in bazel-out/<ARCH>/bin/<RULE>.compilation_info.json.

The JSON structure is easily human readable, and gives insight into the Moderne CLI's understanding of the Java source files that the rule is responsible for and the classpath that should be used to parse those source files.

Last updated