Skylark中如何获取bazel-out全路径以实现Bazel集成Checkstyle
Bazel集成Checkstyle路径问题解决及优化方案
路径问题解决
你不需要硬编码项目根路径,更不用手动找bazel-out的全路径,原因如下:
- Bazel执行自定义规则的动作时,默认工作目录就是WORKSPACE文件所在的项目根目录,
file.path本身就是相对于该根目录的相对路径,JVM可以直接识别相对路径的classpath,直接拼接file.path即可正常运行,不需要加前缀。 - 如果确实有特殊场景必须使用绝对路径,可在构造执行命令时动态获取根目录,在命令开头加
ROOT=$(pwd),之后classpath拼接$ROOT/${file.path}即可,完全不需要硬编码。
更优实现方案
作为Bazel新手,不需要从零手写Checkstyle集成逻辑,更稳定的方案如下:
- 优先使用Bazel官方维护的JVM生态规则集rules_jvm_external,里面已经内置了开箱即用的Checkstyle规则,只需要简单配置就能直接用,不需要自己维护classpath拼接、动作执行等底层逻辑。
- 如果确实需要自定义规则,可做以下优化:
- 不要手动遍历依赖拼接classpath,通过Bazel内置的
JavaInfoprovider可以直接拿到所有传递依赖的运行时jar列表,不会出现依赖遗漏的问题,取dep[JavaInfo].transitive_runtime_jars即可获取。 - 用Bazel内置的
ctx.actions.args()构造命令参数,它会自动处理路径展开、分隔符转义、长参数拆分等问题,比手动拼接字符串稳定很多,示例如下:
args = ctx.actions.args() # 自动用冒号拼接classpath,不需要手动处理分隔符 args.add("-cp", ctx.files._classpath + ctx.files.deps, join_with = ":") # 追加其他Checkstyle参数 args.add("-c", ctx.file._config.path) args.add_all(ctx.files.srcs) ctx.actions.run( inputs = ctx.files._classpath + ctx.files.deps + ctx.files.srcs + [ctx.file._config], outputs = [ctx.outputs.checkstyle_report], executable = ctx.executable._checkstyle_bin, arguments = [args] )- 不需要主动关心bazel-out的路径,只要你把所有需要的文件都加到action的inputs列表里,Bazel会自动处理路径映射,执行时所有文件都会在预期的路径上,不需要手动拼接bazel-out相关前缀。
- 不要手动遍历依赖拼接classpath,通过Bazel内置的
内容的提问来源于stack exchange,提问作者KeykoYume
相关产品推荐
相关产品推荐

