bazelizer
TL;DR
This is your last chance if you really need some maven plugin inside your Bazel build, and you cannot rewrite or adapt it to Bazel.
Long Version
There is a wide variety of maven plugins already written. Moreover, some plugins have no ports to other build systems. So, if
- you use Bazel as main build tool, your CI use bazel and all 99% teams and all infra are using Bazel
- and there is a maven plugin that you need;
Then, you need bazelizer. Someone can call it a dirty hack, but we know the truths ;)
This tool represents overall maven project as one Bazel's target. In this way you can isolate all your maven stuff as one unit (if desired, put everything that is not specific to the maven into Bazel) and integrate it into Bazel environment. Use bazel deps, depends on bazel target and event doing it efficiently.
here
Take a look on example project![Alt text](assets/ci.png?raw=true | width=350)
Usage
#
# in your WORKSPACE
RULES_TAG = "0.2.3"
RULES_TAG_SHA = "e1ff5910ac034aed69e682e9e5cfb52450c27396a85edac8cdec79f50679ad6b"
NAME = "wix_incubator_bazelizer"
http_archive(
name = NAME,
url = "https://github.com/wix-incubator/bazelizer/archive/%s.zip" % RULES_TAG,
type = "zip",
strip_prefix = "bazelizer-%s" % RULES_TAG,
sha256 = RULES_TAG_SHA,
)
load("@wix_incubator_bazelizer//:bazelizer.bzl", "bazelizer")
bazelizer()
load("@wix_incubator_bazelizer//maven:defs.bzl", "maven_repository_registry")
maven_repository_registry(
name = "bazelizer",
modules = [
"//my/module-parent:maven",
"//my/another_module:maven",
],
)
#
# in your BUILD files
load("@wix_incubator_bazelizer//maven:defs.bzl", "maven_project")
maven_project(
name = "maven",
pom_file = ":pom.xml",
)
load("@bazelizer//:execute_build.bzl","execute_build")
execute_build(
name = "maven_build",
srcs = [":source"],
project = ":maven",
....
)
Design
This tools assume that pom.xml (e.g. build configurations) will be updated rarely. So, tool will fetch all dependencies, not related to bazel targets, once and cached by bazel mechanics as maven repository tar archive. All builds rely on this repository 'image' with ability to inject bazel deps dynamical during build.
Rules
maven_repository_registry
This is repository rule that generate and register all declared "maven" targets. This allows to fetch all deps from maven world only once and cache them.
Usage
# ./WORKSPACE
maven_repository_registry_v2(
name = "maven_repo",
modules = [
"//tests/e2e/mvn-lib-a:module",
"//tests/e2e/mvn-lib-parent:module",
"//tests/e2e/mvn-build-lib-one:module",
"//tests/e2e/mvn-lib-b:module",
"//tests/e2e/mvn-lib-G:module",
"//tests/e2e/mvn-lib-G/mvn-lib-G-a:module",
"//tests/e2e/mvn-lib-G/mvn-lib-G-b:module",
]
)
attr name | description |
---|---|
name | Name; required. A unique name for this target. |
modules | list of labels; Labels of declared maven targets via declare_module |
NOTE 1 This rule execute dry run of a build by empty project directory + given pom. This is done to eagerly fetch all plugin's and there dependencies and reuse for any build. In this case pom file have to be ready to be executed with empty workspace directory. Any change in pom file will trigger rebuilding a tarball. Also rule fetches all deps via
NOTE 2 Rule fetches all also by de.qaware.maven:go-offline-maven-plugin:resolve-dependencies
plugin.
This allows to overcome a problem that some plugin can dynamically fetch additional deps only at runtime. Please, read more about it here.
maven_project
Represent a maven target that represented as pom.xml file and optional reference to parent target.
Usage
maven_project(
name = "module",
pom_file = ":pom.xml",
parent = "//tests/e2e/mvn-lib-parent:module"
)
attr name | description |
---|---|
name | Name; required. A unique name for this target. |
pom_file | Actual pom file. |
parent | Label; Reference to parent module; |
flags | List of special flags; |
NOTE: For supported flags please find section below
Usage
load("@maven_repo//:execute_build.bzl", "execute_build")
filegroup(
name = "sources",
srcs = glob(["src/**/*"])
)
execute_build(
name = "mvn-lib-G-b",
pom_def = ":module",
deps = [ "@com_sun_xml_bind_jaxb_impl" ],
srcs = [":sources"],
visibility = ["//visibility:public"]
)
attr name | description |
---|---|
name | Name; required. A unique name for this target. |
pom_def | Label for module declaration; |
deps | Deps; Supported any dep with JavaInfo provider; Support only direct deps; |
srcs | Files; Link maven workspace into bazel sandbox; |
Important notes
This tool not support transitive dependencies. Only direct compile dependencies as full_compile_jars will be used.
Special flags
--deps-drop-all Delete all dependencies that declared in pom file
before tool execution;
--deps-drop-exclude=<coors> Dependencies that satisfy an expression won't be
deleted. Expected a pattern in format '<groupId>:<artifactId>'.
Also accept wildcard expressions. Examples:
'com.google.*:*', '*:guava', 'com.google.guava:failureaccess';
--mvn-active-profiles=<p> Maven active profiles
--mvn-extra-args=<p> Maven extra commands
--mvn-override-artifact-id=<artifactId> Change artifact id for maven project