Я был именно там, где вы есть, и я пошел по пути, который вы начали исследовать.Я генерирую описание JSON, которое также включает в себя информацию, собранную из git для упаковки с результатом, и в итоге я сделал что-то вроде этого:
def _build_mft_impl(ctx):
args = ctx.actions.args()
args.add('-f')
args.add(ctx.info_file)
args.add('-i')
args.add(ctx.files.src)
args.add('-o')
args.add(ctx.outputs.out)
ctx.actions.run(
outputs = [ctx.outputs.out],
inputs = ctx.files.src + [ctx.info_file],
arguments = [args],
progress_message = "Generating manifest: " + ctx.label.name,
executable = ctx.executable._expand_template,
)
def _get_mft_outputs(src):
return {"out": src.name[:-len(".tmpl")]}
build_manifest = rule(
implementation = _build_mft_impl,
attrs = {
"src": attr.label(mandatory=True,
allow_single_file=[".json.tmpl", ".json_tmpl"]),
"_expand_template": attr.label(default=Label("//:expand_template"),
executable=True,
cfg="host"),
},
outputs = _get_mft_outputs,
)
//:expand_template
- это метка в моем случае, указывающая на py_binary
выполняя само преобразование.Я был бы счастлив узнать о лучшем (более родном, меньшем количестве прыжков) способе сделать это, но (пока) я пошел: это работает.Несколько комментариев о подходе и ваших проблемах:
- AFAIK, который вы не можете прочитать (файл и выполнить операции в жаворонке) сам ...
- ... говоря о том, что этовероятно, неплохо было бы разделить преобразование (инструмент) и описание сборки (bazel) в любом случае.
- Можно обсудить, что составляет официальную документацию, но
ctx.info_file
может не появиться в справочном руководстве, этозадокументировано в исходном дереве.:) Это относится и к другим областям (и я надеюсь, что это не потому, что эти интерфейсы тоже пока не приняты).
Ради полноты в src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java
есть:
@SkylarkCallable(
name = "info_file",
structField = true,
documented = false,
doc =
"Returns the file that is used to hold the non-volatile workspace status for the "
+ "current build request."
)
public FileApi getStableWorkspaceStatus() throws InterruptedException, EvalException;
РЕДАКТИРОВАТЬ: несколько дополнительных деталей, как указано в комментарии.
В моем workspace_status.sh
у меня будет, например, следующая строка:
echo STABLE_GIT_REF $(git log -1 --pretty=format:%H)
В моем файле .json.tmpl
у меня было бы:
"ref": "${STABLE_GIT_REF}",
Я выбрал замену текста, похожую на оболочку, поскольку он интуитивно понятен для многих пользователей, а также прост в сопоставлении.
Что касается замены, соответствующая (CLI исключается из этого) часть фактического кода будет:
def get_map(val_file):
"""
Return dictionary of key/value pairs from ``val_file`.
"""
value_map = {}
for line in val_file:
(key, value) = line.split(' ', 1)
value_map.update(((key, value.rstrip('\n')),))
return value_map
def expand_template(val_file, in_file, out_file):
"""
Read each line from ``in_file`` and write it to ``out_file`` replacing all
${KEY} references with values from ``val_file``.
"""
def _substitue_variable(mobj):
return value_map[mobj.group('var')]
re_pat = re.compile(r'\${(?P<var>[^} ]+)}')
value_map = get_map(val_file)
for line in in_file:
out_file.write(re_pat.subn(_substitue_variable, line)[0])
EDIT2: Вот как скрипт Python выглядит так, как явыставить скрипт python остальным базелам.
py_binary(
name = "expand_template",
main = "expand_template.py",
srcs = ["expand_template.py"],
visibility = ["//visibility:public"],
)