我在这个拉取请求mvn_package
中有一个规则原型。你提出的观点很关键;在 Bazel 更严格的动作执行环境中驯服 Maven 的约定和期望需要一点时间。
Maven 期望从包含 pom.xml 的目录中执行
您可以使用该-f
标志来指定pom.xml
.
例如mvn package -f %s -DskipTests -DbazelOutputDir=%s -Pbazel" % (ctx.file.pom_xml.dirname,output_jar.dirname)
Maven 将输出写入输入文件树的子目录
我在pom.xml
to 中为自定义 Maven 定义创建了一个自定义配置文件,并通过了上面的命令行定义:
<profiles>
<profile>
<id>bazel</id>
<build>
<directory>${bazelOutputDir}</directory>
</build>
</profile>
</profiles>
当 settings.xml 包含绝对路径时,Maven 是最快乐的(到 .war 的本地 maven 存储库,存储在 git 中)
这很不幸,您必须找到解决方法或禁用沙盒:(
Maven 使用 $HOME/.m2 进行缓存
只要在 Starlark 规则中正确声明了 Bazel 操作输入和输出,您就不需要与 Maven 的 .m2 缓存目录进行交互,因为 Bazel 有自己的操作缓存。
为了完整起见,这里是一个 Starlark 规则的概念证明来打包一个 .jar,所以你可能需要为一个 .war 调整它:
def _mvn_package_impl(ctx):
inputs = []
inputs.extend(ctx.files.srcs)
inputs.append(ctx.file.pom_xml)
output_jar = ctx.actions.declare_file("target/%s-%s.jar" % (ctx.attr.artifact_id, ctx.attr.version))
target_dir = ctx.actions.declare_directory("target")
outputs = [output_jar, target_dir]
# -Djar.finalName=custom-jar-name
ctx.actions.run_shell(
inputs = inputs,
outputs = outputs,
mnemonic = "MvnPackage",
progress_message = "Running 'mvn package' for %s" % output_jar.short_path,
command = "mvn package -f %s -DskipTests -DbazelOutputDir=%s -Pbazel" % (ctx.file.pom_xml.dirname,output_jar.dirname),
)
return [
DefaultInfo(
files = depset(outputs),
),
JavaInfo(
output_jar = output_jar,
compile_jar = output_jar,
),
]
mvn_package = rule(
implementation = _mvn_package_impl,
attrs = {
"srcs": attr.label_list(allow_files = True, allow_empty = False),
"pom_xml": attr.label(allow_single_file = True, mandatory = True),
"artifact_id": attr.string(mandatory = True),
"group_id": attr.string(mandatory = True),
"version": attr.string(mandatory = True),
},
)
并在 BUILD 文件中使用上述规则:
load("@rules_jvm_external//:mvn.bzl", "mvn_package")
mvn_package(
name = "hello_maven",
srcs = [
"//src/main/java/hello:srcs",
],
pom_xml = "//:pom.xml",
group_id = "org.springframework",
artifact_id = "gs-spring-boot",
version = "0.1.0",
)
java_binary(
name = "hello_maven_app",
runtime_deps = [":hello_maven"],
main_class = "hello.Application",
)