У меня есть тестовый инструмент (грубо говоря, разностный инструмент), который принимает два входа и возвращает как выход (разница между двумя входами), так и код возврата (0, если два входа совпадают, 1 в противном случае),Он построен в Kotlin и доступен в моем репозитории на //java/fr/enoent/phosphorus
.
Я хочу написать правило, которое проверяет, что сгенерированный чем-то файл идентичен эталонному файлу, уже присутствующему в репозитории. Я пробовал что-то с ctx.actions.run
, проблема в том, что мое правило, с установленным test = True
, должно возвращать исполняемый файл , построенный по этому правилу (поэтому инструмент не предоставлен правилу). Затем я попытался обернуть его в сценарий оболочки, следуя примеру , например:
def _phosphorus_test_impl(ctx):
output = ctx.actions.declare_file("{name}.phs".format(name = ctx.label.name))
script = phosphorus_compare(
ctx,
reference = ctx.file.reference,
comparison = ctx.file.comparison,
out = output,
)
ctx.actions.write(
output = ctx.outputs.executable,
content = script,
)
runfiles = ctx.runfiles(files = [ctx.executable._phosphorus_tool, ctx.file.reference, ctx.file.comparison])
return [DefaultInfo(runfiles = runfiles)]
phosphorus_test = rule(
_phosphorus_test_impl,
attrs = {
"comparison": attr.label(
allow_single_file = [".phs"],
doc = "File to compare to the reference",
mandatory = True,
),
"reference": attr.label(
allow_single_file = [".phs"],
doc = "Reference file",
mandatory = True,
),
"_phosphorus_tool": attr.label(
default = "//java/fr/enoent/phosphorus",
executable = True,
cfg = "host",
),
},
doc = "Compares two files, and fails if they are different.",
test = True,
)
(phosphorus_compare
- это просто макрос, генерирующий фактическую команду.)
Однако у этого подхода есть две проблемы:
- Выходные данные не могут быть объявлены таким образом. Это не связано с какими-либо действиями (и Базель жалуется на это). Может быть, мне не нужно объявлять вывод для теста? Делает ли Базель что-либо доступное в папке с тестами, если тест не пройден?
- Файлы запуска, необходимые для запуска инструмента, по-видимому, недоступны при выполнении теста:
java/fr/enoent/phosphorus/phosphorus: line 359: /home/kernald/.cache/bazel/_bazel_kernald/58c025fbb926eac6827117ef80f7d2fa/sandbox/linux-sandbox/1979/execroot/fr_enoent/bazel-out/k8-fastbuild/bin/tools/phosphorus/tests/should_pass.runfiles/remotejdk11_linux/bin/java: No such file or directory
В целом, я чувствую, что использование сценария оболочки просто добавляет ненужную косвенность и теряет некоторый контекст (например, файлы запуска инструментов). В идеале я бы просто использовал ctx.actions.run
и полагался на его код возврата, но это, кажется, не вариант, поскольку тесту, очевидно, нужно сгенерировать исполняемый файл. Каков будет правильный подход к написанию такого правила?