Skip to content

Latest commit

 

History

History
165 lines (108 loc) · 6.69 KB

README.md

File metadata and controls

165 lines (108 loc) · 6.69 KB

Hello World

Looking around

In the Maven world, a typical project setup consists of a top level pom.xml file with multiple modules in subdirectories. Each module produces a Maven Artifact (typically a jar or a pom.xml).

The pomgen terminology for a top level project with modules is a "library". Subdirectories of the library (the modules) are Bazel Packages that each produce a Maven Artifact (jar or pom). pomgen processes all modules that are part of a library together.

This example has 3 libraries. A library is defined by the presence of a LIBRARY.root marker file.

A Bazel Package that produces a Maven Artifact must have a BUILD.pom file that defines Maven specific metadata. Note that the java_library target that builds the jar Maven Artifact must be the default target, ie it must have the same name as the directory its BUILD file lives in.

The libraries in this example are, and reference each other in this order:

Before running pomgen

Make sure you have installed the required external dependencies.

Make sure the pomgen tests pass. From the root of the repository:

bazel test //...

pomgen query

The metadata query script provides information about Libraries and Maven Artifacts in the repository. It also shows information on whether a Library needs to be released or not.

From the root of the repository:

bazel run @pomgen//:query -- --package examples/hello-world/juicer --library_release_plan_tree

The output looks similar to this:

examples/hello-world/juicer ++ 3.0.0-SNAPSHOT
  examples/hello-world/healthyfoods ++ 1.0.0-SNAPSHOT
  examples/hello-world/wintervegetables ++ 2.0.0-SNAPSHOT
    examples/hello-world/healthyfoods ++ 1.0.0-SNAPSHOT

The output shows:

  • juicer references wintervegetables, which references healthyfoods
    • juicer also references healthyfoods directly
  • The version of each library
  • Whether the library needs to be released or not
    • In this case they all need to be released because pomgen is not aware of any previous release

Generating poms

pomgen can be run directly (bazel run @pomgen//:pomgen -- --help), however, there's a convenient wrapper script that we'll use instead: it defaults some pomgen flags. Before running, make sure you have the required external dependencies.

bazel run @pomgen//maven -- -a pomgen -l examples/hello-world/juicer

The command above specifies:

  • The action to run, pomgen in this case (to generate poms)
  • The library to generate poms for: examples/hello-world/juicer

pomgen follows refernces between libraries; since juicer depends on 2 other libraries healthyfoods and wintervegerables, pomgen generated pom.xml files for all 3 libraries, ie for all modules that are part of those libraries. Usually this is the right behavior, but if there a lot of upstream libraries, it may be desirable in some cases to not follow library references. This can be accomplished by setting -i (ignore references) flag:

bazel run @pomgen//maven -- -a pomgen -l examples/hello-world/juicer -i

Installing Maven Artifacts into the local Maven Repository

The Maven Artifacts generated by pomgen can be installed into ~/.m2/repository so that they are consumable by a local Maven project. Use the install action:

bazel run @pomgen//maven -- -a install -l examples/hello-world/juicer

If you see this type of error:

ERROR: did not find jar artifact at /Users/stoens/Code/pomgen/bazel-bin/examples/hello-world/juicer/juicer.jar

This error means that pomgen did not find the jar file for the juicer module - this happens when bazel build did not run. There are 2 solutions:

  • Run bazel build examples/hello-world/...
  • If there are many upstream libraries in a large repository, it may be helpful to ask pomgen to build all upstream libraries - use the build action: bazel run @pomgen//maven -- -a build -l examples/hello-world/juicer

Using pomgen libraries in a Maven projects

Once the install action ran successfully for examples/hello-world/juicer, you can use the juicer artifact in a Maven project. Try this pom.xml:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>g1</groupId>
    <artifactId>a1</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>com.pomgen.example</groupId>
            <artifactId>juicer</artifactId>
            <version>10.0.0-qual1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

Then run mvn dependency:tree:

[INFO] g1:a1:jar:1.0.0-SNAPSHOT
[INFO] \- com.pomgen.example:juicer:jar:10.0.0-qual1-SNAPSHOT:compile
[INFO]    +- com.pomgen.example:fruit-api:jar:1.0.0-SNAPSHOT:compile
[INFO]    |  +- org.antlr:ST4:jar:4.0.7:compile
[INFO]    |  +- org.antlr:antlr-runtime:jar:3.5:compile
[INFO]    |  +- org.antlr:stringtemplate:jar:3.2.1:compile
[INFO]    |  \- antlr:antlr:jar:2.7.6:compile
[INFO]    +- com.pomgen.example:vegetable-api:jar:1.0.0-SNAPSHOT:compile
[INFO]    +- com.pomgen.example:wintervegetables:jar:20200416.1-SNAPSHOT:compile
[INFO]    \- com.google.guava:guava:jar:23.0:compile

Advanced use-cases

Templates for pom-only artifacts

pomgen supports custom pom templates for the purpose of generating pom-only artifacts (<packaging>pom</packaging>). This is typically needed when migrating a Maven project to Bazel that has a parent pom, meant to be inherited from: the parent pom still needs to be generated because existing Maven projects may depend on it.

See this example pom template - note that the corresponding BUILD.pom file must specify that the pom_generation_mode is template.

Template Features

Referencing values from the BUILD.pom file

artifact_id, group_id and version from the BUILD.pom file can be referenced in the pom template using the syntax

#{group_id}
#{articat_id}
#{version}

See the example pom template.

Referencing versions

The version of known artifacts, both external (maven_install) and internal (BUILD.pom) can be referenced in the pom template using the following syntax:

  • For external artifacts: #{maven_install_label.version} for example:
    • #{@com_google//:com_google_guava_guava.version}
  • For interal artifacts: #{group_id:artifact_id:version}

See the example pom template.