Автономный сценарий оболочки работает нормально, но при использовании srcs sh_binary он не работает

У меня следующая структура проекта: 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

Этот сценарий отлично работает при индивидуальном вызове и дает требуемые результаты, но когда я добавляю приведенный ниже sh_binary в свой файл BUILD, я не вижу ничего в файле temp-scan-files.txt и, следовательно, ничего в файле its-scan-report.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"]),
)

Я запустил sh_binary из intellij, используя значок воспроизведения, а также попытался запустить его из терминала, используя bazel run:findFiles. Ошибка не отображается, но я не вижу данных в temp-scan-files.txt. Любая помощь по этому вопросу. Документация по bazel очень ограничена примерно никакой информацией, кроме варианта использования.

1 ответ

Когда двоичный файл запускается с использованием, он запускается из «дерева исполняемых файлов» для этого двоичного файла. Дерево runfiles - это дерево каталогов, которое создает bazel, которое содержит символические ссылки на входы двоичного файла. Попробуйте поставить pwd а также treeв начале сценария оболочки, чтобы увидеть, как это выглядит. Причина, по которой дерево runfiles не содержит ни одного из файлов в 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"]), ничего не будет соответствовать, потому что эти файлы находятся в 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) будет содержать файл temp-scan-regex.txt, который вы, вероятно, не хотите включать в сканирование, но если это первый элемент, то он будет параметром для -f. Это может быть немного хакерским и немного хрупким, но также немного раздражает попытка отделить файл (например, с помощью grep или sed или нарезки массива).

потом bazel build //project/root/myPackage:its-scan-report.txt

Другие вопросы по тегам