将mvn作为bazel构建中的工具运行



我的项目中有一个棘手的模块,除了Maven之外,其他任何东西都无法构建它。好的一面是,这个模块在我的项目中没有任何Java依赖项,它只生成一个.war文件,我需要将其移动到输出zip分发中的正确位置。

我想将构建迁移到bazel,但我想在迁移的后期处理棘手的模块。

如何在我的bazel构建中运行mvn作为工具,让它生成.war文件?

  • Maven期望从包含pom.xml的目录中执行
  • Maven将输出写入输入文件树的子目录
  • 当settings.xml包含绝对路径(到.war的本地Maven存储库,存储在git中(时,Maven最开心
  • Maven使用$HOME/.m2进行缓存

我查看了rules_forging_cc,它围绕cmake创建了一个包装脚本。这是要走的路吗?https://github.com/bazelbuild/rules_foreign_cc/blob/8372f383cf7277a88762efe25d8cfee10ad27929/tools/build_defs/framework.bzl#L156

我在这个pull请求中有一个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中为自定义Maven定义创建了一个自定义配置文件,并传递了定义上述命令行的命令:

<profiles>
<profile>
<id>bazel</id>
<build>
<directory>${bazelOutputDir}</directory>
</build>
</profile>
</profiles>

当settings.xml包含绝对路径(到.war的本地Maven存储库,存储在git中(时,Maven最开心

这很不幸,你必须找到一种方法来解决它,或者禁用沙箱:(

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",
)

最新更新