Как включить имя текущей рабочей области в значение аргумента правила по умолчанию?

Допустим, у меня есть правило:

blah = rule(
    attrs = {
        "foo": attr.string(default = "@HELP@"),
    },
)

Я хочу, чтобы значение по умолчанию foo содержало имя рабочей области, которая вызывает правило. Как я могу это сделать?

(Примечание: приемлемый подход — оставить заполнитель в значении и заменить его, когда правило использует атрибут, но я также не могу понять, как получить там текущую рабочую область. Самое близкое, что я могу найти, это ctx.label.workspace_root, но это пусто для «основного» рабочего пространства и, например, external/foo для других вещей.)

ctx.workspace_name не дает правильных ответов. Например, если я print("'%s' -> '%s'", (ctx.label.workspace_root, ctx.workspace_name)), я получаю такие результаты, как:

'externals/foo' -> 'main'
'externals/bar' -> 'main'

... что неправильно; это должны быть «foo» и «bar», а не «main» («main» — это мое основное/корневое рабочее пространство). Обратите внимание, что метки из этих контекстов, например. '@foo//:foo', так что Bazel, по-видимому, знает правильное имя рабочей области.


person Matthew    schedule 21.06.2017    source источник


Ответы (2)


Вы можете использовать атрибут-заполнитель, а затем использовать ctx.workspace_name. в реализации.

def _impl(ctx):
  print("ws: %s" % ctx.workspace_name)

blah = rule(
    implementation = _impl,
)
person kristina    schedule 22.06.2017
comment
Нет, это дает неверный ответ не в основной рабочей области. (См. обновленный вопрос.) - person Matthew; 22.06.2017
comment
О, хороший момент. На самом деле это должно дать правильный результат в будущем (как только github.com/bazelbuild/bazel/issues/ 1262 есть), но до тех пор вы застряли с хакерским скриптом (извините). - person kristina; 22.06.2017

Что касается получения имени рабочей области, это кажется неоптимальным, но также работает:

def _workspace(ctx):
    """Compute name of current workspace."""

    # Check for meaningful workspace_root
    workspace = ctx.label.workspace_root.split("/")[-1]
    if len(workspace):
        return workspace

    # If workspace_root is empty, assume we are the root workspace
    return ctx.workspace_name

Согласно ответу и комментарию Кристины в исходном вопросе, это можно использовать для замены заполнителя в значении параметра.

person Matthew    schedule 22.06.2017