В Skylark - заданная метка - как читать теги исходного правила

В моей реализации правила skylark (bazel) у меня есть depset из файловых объектов из которого я извлекаю набор Label Objects.

В общих атрибутах я обнаружил, что все правила жаворонка могут иметь теги , где я могу указать список свободных строк.

Можно ли как-то добраться до тегов исходного правила?

(моя конечная цель - извлечь из исходного набора файлов файлы, созданные по правилу с тегом "X").


person orshachar    schedule 02.04.2017    source источник


Ответы (1)


Правила распространяют информацию вниз по течению (к зависящим от них правилам) через провайдеров. Провайдеры — это фрагменты информации (структуры), которые правило может либо возвращать, либо нет. Я считаю полезным рассматривать провайдеров как интерфейсы, которые правило может выбрать для реализации. Например, правило Skylark, которое возвращает поставщика cc, можно рассматривать так, как если бы оно реализовало интерфейс правила C++, поэтому мы можем ожидать, что оно будет значимой зависимостью от правил C++ и любого правила, которое считывает поставщики cc. Однако, если правило не реализует поставщика java, мы не можем ожидать, что оно будет работать как зависимость правила Java.

Правило может получить доступ к информации только в своих прямых зависимостях и только через Providers. Следовательно, чтобы получить доступ к tags зависимости, зависимость должна предоставить поставщику эту информацию. Насколько я знаю, нет такого провайдера, который мог бы раскрыть правило, но если зависимые правила (чьи tags вы хотите извлечь) также являются правилами Skylark, и вы можете изменить их реализацию, то просто верните пользовательский провайдер с их tags в нем, и вы сделано.

Однако, если вы хотите, например, зависеть от собственных правил *_test (те, которые обычно используют tags), вам необходимо использовать оболочку.

Основная идея состоит в том, чтобы написать макрос Skylark для переноса таких правил. Вместо того, чтобы писать, например. cc_test(..., tags=...) в файле BUILD вы должны написать my_macro(..., tags=...).

Реализация макроса создаст два правила: native.cc_test и простое правило Skylark (которое вам нужно реализовать), которое имеет только атрибут tags и один атрибут метки для тестового правила. Макрос передает tags обоим правилам (плюс остальные атрибуты cc_test), а правило Skylark зависит от тестового правила, поэтому оно имеет доступ к своему набору файлов и может возвращать пользовательский поставщик с набором зависимостей и помечает данные внутри одной структуры.

person László    schedule 03.04.2017
comment
Спасибо!! Это означает, что если я завишу от собственного правила (например, java_library), я не могу изменить его поставщиков и не могу получить доступ к его тегам. - person orshachar; 03.04.2017
comment
относительно получения информации о косвенных зависимостях: на самом деле это нигде не задокументировано, но я вижу, что rules_scala решила добавить еще одно поле extra_information: github.com/bazelbuild/rules_scala/blob/master/scala/, который собирает поле extra_information из всех прямых зависимостей. Знаете ли вы, ведет ли себя так любое другое предоставленное правило? - person orshachar; 03.04.2017
comment
› если я завишу от собственного правила (например, java_library), я не могу изменить его поставщиков и не могу получить доступ к его тегам. Верный. - person László; 04.04.2017
comment
который собирает поле extra_information из всех прямых зависимостей. Знаете ли вы, ведет ли себя так какое-либо другое предоставленное правило? -- Нет, я не думаю, что какое-либо родное правило имеет такие расширяемые поля произвольной формы. Конечно, многие нативные правила предоставляют информацию, относящуюся к их полному транзитивному закрытию, например правила C++ cc.transitive_files. Ключевая идея заключается в том, что правило может решать, какую информацию о своих собственных зависимостях оно предоставляет нижестоящим, в отличие от того, что родитель отправляет объект-посетитель вниз по графу. - person László; 04.04.2017