【问题标题】:Standalone Shell script working fine but when used is srcs of sh_binary its not working独立 Shell 脚本工作正常,但使用时 sh_binary 的 srcs 无法正常工作
【发布时间】:2021-05-21 08:24:41
【问题描述】:

我的项目结构如下- PROJECT_STRUCTURE

现在 my_shbin.sh 如下 -

#!/bin/bash
find ../../ \( -name "*.java" -o -name "*.xml" -o -name "*.html" -o -name "*.js" -o -name "*.css" \) | grep -vE "/node_modules/|/target/|/dist/" >> temp-scan-files.txt

# scan project files for offensive terms
IFS=$'\n'
for file in $(cat temp-scan-files.txt); do
    grep -iF -f temp-scan-regex.txt $file >> its-scan-report.txt
done

这个脚本在单独调用时工作得很好并给出了所需的结果。但是当我在我的 BUILD 文件中添加下面的 sh_binary 时,我在 temp-scan-files.txt 文件中看不到任何内容,因此它的扫描报告中没有任何内容.txt 文件

sh_binary(
    name = "findFiles",
    srcs = ["src/test/resources/my_shbin.sh"],
    data = glob(["temp-scan-files.txt", "temp-scan-regex.txt", "its-scan-report.txt"]),
)

我使用播放图标从 intellij 运行 sh_binary,还尝试使用 bazel run :findFiles 从终端运行它。没有显示错误,但我看不到 temp-scan-files.txt 中的数据。 关于这个问题的任何帮助。bazel 的文档非常有限,除了用例之外几乎没有任何信息。

【问题讨论】:

标签: sh bazel bazel-rules bazel-java


【解决方案1】:

当使用bazel run 运行二进制文件时,它会从该二进制文件的“运行文件树”运行。运行文件树是 bazel 创建的目录树,其中包含指向二进制输入的符号链接。尝试将pwdtree 放在shell 脚本的开头,看看它是什么样子的。运行文件树不包含 src/main 中的任何文件的原因是它们没有被声明为 sh_binary 的输入(例如,使用 data 属性)。见https://docs.bazel.build/versions/master/user-manual.html#run

另外需要注意的是data = glob(["temp-scan-files.txt", "temp-scan-regex.txt", "its-scan-report.txt"]), 中的 glob 不会匹配任何内容,因为这些文件在 src/test/resources 中相对于 BUILD 文件。但是,脚本会尝试修改这些文件,并且通常不可能修改输入文件(如果此 sh_binary 作为构建操作运行,则输入实际上是只读的。这仅适用于 bazel run 类似在 bazel 之外自行运行最终的二进制文件,例如 bazel build //target && bazel-bin/target)

最直接的方法可能是这样的:

genrule(
  name = "gen_report",
  srcs = [
    # This must be the first element of srcs so that
    # the regex file gets passed to the "-f" of grep in cmd below.
    "src/test/resources/temp-scan-regex.txt",
  ] + glob([
    "src/main/**/*.java",
    "src/main/**/*.xml",
    "src/main/**/*.html",
    "src/main/**/*.js",
    "src/main/**/*.css",
  ],
  exclude = [
    "**/node_modules/**",
    "**/target/**",
    "**/dist/**",
  ]),
  outs = ["its-scan-report.txt"],
  # The first element of $(SRCS) will be the regex file, passed to -f.
  cmd = "grep -iF -f $(SRCS) > $@",
)

$(SRCS)srcs 中由空格分隔的文件,$@ 表示“输出文件,如果只有一个”。 $(SRCS) 将包含 temp-scan-regex.txt 文件,您可能不希望将其作为扫描的一部分包含在内,但如果它是第一个元素,那么它将是 -f 的参数。这可能有点老套而且有点脆弱,但是尝试将文件分离出来也有点烦人(例如,使用 grep 或 sed 或数组切片)。

然后bazel build //project/root/myPackage:its-scan-report.txt

【讨论】:

  • 我按照上面的 genrule 方法做了 bazel build :all (我现在的工作目录是 myProject)。构建成功,但我在 its-scan-report.txt 中没有看到任何内容。看起来cmd中有一些遗漏。有什么帮助吗??
  • 您可以使用--subcommands 查看bazel 运行的最终命令(您可能需要先执行bazel clean,因为--subcommands 只打印bazel 实际运行的内容,所以如果所有内容都已缓存,什么都不会打印)。这应该显示 glob 匹配的内容。您还可以将echo $(SRCS); 放在 grep 前面以打印出 glob 匹配的文件。如果找到了所有预期的文件,则可能与正则表达式文件中的正则表达式有关。
猜你喜欢
  • 1970-01-01
  • 2021-05-17
  • 2012-03-10
  • 2013-07-10
  • 2016-09-01
  • 1970-01-01
  • 2014-12-07
  • 2015-04-04
  • 1970-01-01
相关资源
最近更新 更多