gpt4 book ai didi

java - 从 Bazel 中调用 Checkstyle 的最佳方式是什么?

转载 作者:行者123 更新时间:2023-11-30 06:45:22 27 4
gpt4 key购买 nike

我正在尝试添加对调用 Checkstyle 的支持,作为我们 Bazel 构建的一部分。我已经看到一些代码使用额外操作来实现这一点,但我希望避免这种方法并使其与纯 Skylark 代码一起使用。我设法使用以下(糟糕的)genrule 来让 JVM 在一组源文件上执行 Checkstyle,但我意识到这是令人难以置信的 hacky:

native.genrule(
name = name,
srcs = srcs,
outs = ["src_output.txt"],
cmd = "$(JAVA) -Dconfig_loc=<full-config-loc-path> -classpath <path>/checkstyle-8.4-all.jar com.puppycrawl.tools.checkstyle.Main -c <config-file-path> -o $@ $(SRCS)",
**kwargs
)

关于如何正确执行此操作有什么建议吗?我已经在我们的 dependency.bzl 文件中拥有所有必需的 JAR 依赖项,因此我很乐意引用这些依赖项而不是 checkstyle-all JAR。

最佳答案

正如 IRC 上所讨论的,这是我一直在使用的规则(在本文末尾)。我有一个目录 config/,其中包含我的 checkstyle 配置、抑制和许可证文件,此处引用了默认参数。在您的工作空间中,您可以使用宏引入所有部门:

load("//tools:checkstyle.bzl", "checkstyle_repositories")
checkstyle_repositories()

在您的构建文件中导入并使用规则:

load("//tools:checkstyle.bzl", "checkstyle_test")

filegroup(
name = "java-srcs",
srcs = glob(["src/main/java/**/*.java"]),
)

checkstyle_test(
name = "check",
srcs = [
":java-srcs",
],
)

然后你可以使用bazel test//path/to/dir:check运行它。

此规则确实有一个限制,即它在命令行上接受参数,因此对于较大的模块,您将需要拆分文件组以停止达到命令行长度限制,例如

load("//tools:checkstyle.bzl", "checkstyle_test")

filegroup(
name = "java-foo-srcs",
srcs = glob(["src/main/java/foo/**/*.java"]),
)
filegroup(
name = "java-bar-srcs",
srcs = glob(["src/main/java/bar/**/*.java"]),
)

checkstyle_test(
name = "check-foo",
srcs = [
":java-foo-srcs",
],
)
checkstyle_test(
name = "check-bar",
srcs = [
":java-bar-srcs",
],
)
test_suite(
name = "check",
tests = [
":check-bar",
":check-foo",
],
)

如果每个包都有一个 BUILD 文件,这可能是不必要的,但如果您要转换大型 Maven 模块并在 bazel 构建文件中保留类似的结构,这会是一个更大的问题。

工具/checkstyle.bzl

load("//tools/gerrit:maven_jar.bzl", "maven_jar")

def checkstyle_repositories(
omit = [],
versions = {
"antlr_antlr": "2.7.7",
"org_antlr_antlr4_runtime": "4.5.1-1",
"com_puppycrawl_tools_checkstyle": "8.2",
"commons_beanutils_commons_beanutils": "1.9.3",
"commons_cli_commons_cli": "1.4",
"commons_collections_commons_collections": "3.2.2",
"com_google_guava_guava23": "23.0",
"org_slf4j_slf4j_api": "1.7.7",
"org_slf4j_slf4j_jcl": "1.7.7",
}
):
if not "antlr_antlr" in omit:
maven_jar(
name = "antlr_antlr",
attach_source = False,
artifact = "antlr:antlr:" + versions["antlr_antlr"],
)
if not "org_antlr_antlr4_runtime" in omit:
maven_jar(
name = "org_antlr_antlr4_runtime",
artifact = "org.antlr:antlr4-runtime:" + versions["org_antlr_antlr4_runtime"],
)
if not "com_puppycrawl_tools_checkstyle" in omit:
maven_jar(
name = "com_puppycrawl_tools_checkstyle",
artifact = "com.puppycrawl.tools:checkstyle:" + versions["com_puppycrawl_tools_checkstyle"],
)
if not "commons_beanutils_commons_beanutils" in omit:
maven_jar(
name = "commons_beanutils_commons_beanutils",
artifact = "commons-beanutils:commons-beanutils:" + versions["commons_beanutils_commons_beanutils"],
)
if not "commons_cli_commons_cli" in omit:
maven_jar(
name = "commons_cli_commons_cli",
artifact = "commons-cli:commons-cli:" + versions["commons_cli_commons_cli"],
)
if not "commons_collections_commons_collections" in omit:
maven_jar(
name = "commons_collections_commons_collections",
artifact = "commons-collections:commons-collections:" + versions["commons_collections_commons_collections"],
)
if not "com_google_guava_guava23" in omit:
maven_jar(
name = "com_google_guava_guava23",
artifact = "com.google.guava:guava:" + versions["com_google_guava_guava23"],
)
if not "org_slf4j_slf4j_api" in omit:
maven_jar(
name = "org_slf4j_slf4j_api",
artifact = "org.slf4j:slf4j-api:" + versions["org_slf4j_slf4j_api"],
)
if not "org_slf4j_slf4j_jcl" in omit:
maven_jar(
name = "org_slf4j_slf4j_jcl",
artifact = "org.slf4j:jcl-over-slf4j:" + versions["org_slf4j_slf4j_jcl"],
)



def _checkstyle_test_impl(ctx):
name = ctx.label.name
srcs = ctx.files.srcs
deps = ctx.files.deps
config = ctx.file.config
properties = ctx.file.properties
suppressions = ctx.file.suppressions
opts = ctx.attr.opts
sopts = ctx.attr.string_opts

classpath=""
add=False
for file in ctx.files._classpath:
if add:
classpath += ":"
add=True
classpath += file.path
for file in ctx.files.deps:
classpath += ":" + file.path

args = ""
inputs = []
if config:
args += " -c %s" % config.path
inputs.append(config)
if properties:
args += " -p %s" % properties.path
inputs.append(properties)
if suppressions:
inputs.append(suppressions)

cmd = " ".join(
["java -cp %s com.puppycrawl.tools.checkstyle.Main" % classpath] +
[args] +
["--%s" % x for x in opts] +
["--%s %s" % (k, sopts[k]) for k in sopts] +
[x.path for x in srcs]
)

ctx.file_action(
output = ctx.outputs.executable,
content = cmd,
executable = True,
)
files = [ctx.outputs.executable, ctx.file.license] + srcs + deps + ctx.files._classpath + inputs
runfiles = ctx.runfiles(
files = files,
collect_data = True
)
return struct(
files = depset(files),
runfiles = runfiles,
)

checkstyle_test = rule(
implementation = _checkstyle_test_impl,
test = True,
attrs = {
"_classpath": attr.label_list(default=[
Label("@com_puppycrawl_tools_checkstyle//jar"),
Label("@commons_beanutils_commons_beanutils//jar"),
Label("@commons_cli_commons_cli//jar"),
Label("@commons_collections_commons_collections//jar"),
Label("@org_slf4j_slf4j_api//jar"),
Label("@org_slf4j_slf4j_jcl//jar"),
Label("@antlr_antlr//jar"),
Label("@org_antlr_antlr4_runtime//jar"),
Label("@com_google_guava_guava//jar"),
]),
"config": attr.label(allow_single_file=True, default = "//config:checkstyle"),
"suppressions": attr.label(allow_single_file=True, default = "//config:suppressions"),
"license": attr.label(allow_single_file=True, default = "//config:license"),
"properties": attr.label(allow_single_file=True),
"opts": attr.string_list(),
"string_opts": attr.string_dict(),
"srcs": attr.label_list(allow_files = True),
"deps": attr.label_list(),
},
)
"""Run checkstyle

Args:
config: A checkstyle configuration file
suppressions: A checkstyle suppressions file
license: A license file that can be used with the checkstyle license
target
properties: A properties file to be used
opts: Options to be passed on the command line that have no
argument
string_opts: Options to be passed on the command line that have an
argument
srcs: The files to check
"""

关于java - 从 Bazel 中调用 Checkstyle 的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49074677/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com