Esta página explica como criar regras de repositório e fornece exemplos para mais detalhes.
Um repositório externo é uma regra que só pode ser usada
no arquivo WORKSPACE
e permite operações não herméticas na fase de carregamento
do Bazel. Cada regra de repositório externo cria o próprio espaço de trabalho, com os
próprios arquivos e artefatos BUILD
. Eles podem ser usados para depender de bibliotecas
de terceiros (como bibliotecas empacotadas do Maven), mas também para gerar arquivos BUILD
específicos para o host em que o Bazel está sendo executado.
Criação de regras de repositório
Em um arquivo .bzl
, use a função repository_rule para criar uma nova regra de repositório e armazená-la em uma variável global.
Uma regra de repositório personalizada pode ser usada da mesma forma que uma regra de repositório nativo. Ele
tem um atributo name
obrigatório, e cada destino presente nos arquivos de build
pode ser referido como @<name>//package:target
, em que <name>
é o valor do
atributo name
.
A regra é carregada quando você a cria explicitamente ou se ela é uma dependência do
build. Nesse caso, o Bazel vai executar a função implementation
. Essa
função descreve como criar o repositório, o conteúdo e os arquivos BUILD
.
Atributos
Um atributo é um argumento de regra, como url
ou sha256
. É necessário listar
os atributos e os tipos deles ao definir uma regra de repositório.
local_repository = repository_rule(
implementation=_impl,
local=True,
attrs={"path": attr.string(mandatory=True)})
Para acessar um atributo, use repository_ctx.attr.<attribute_name>
.
Todos os repository_rule
s têm atributos definidos implicitamente (assim como as regras
de build). Os dois atributos implícitos são name
(assim como nas regras de build) e
repo_mapping
. O nome de uma regra de repositório pode ser acessado com
repository_ctx.name
. O significado de repo_mapping
é o mesmo das
regras de repositório nativo
local_repository
e
new_local_repository
.
Se o nome de um atributo começar com _
, ele será privado e os usuários não poderão defini-lo.
Função de implementação
Cada regra de repositório requer uma função implementation
. Ele contém a
lógica real da regra e é executado estritamente na fase de carregamento.
A função tem exatamente um parâmetro de entrada, repository_ctx
. A função
retorna None
para indicar que a regra é reproduzível com os
parâmetros especificados ou um dicionário com um conjunto de parâmetros para essa regra que
transformaria essa regra em uma regra reproduzível que gera o mesmo repositório. Por
exemplo, para uma regra que rastreia um repositório do Git, isso significaria retornar um
identificador de confirmação específico em vez de uma ramificação flutuante que foi especificada
originalmente.
O parâmetro de entrada repository_ctx
pode ser usado para
acessar valores de atributos e funções não herméticas (encontrar um binário,
executar um binário, criar um arquivo no repositório ou fazer o download de um arquivo
da Internet). Consulte a biblioteca para mais
informações. Exemplo:
def _impl(repository_ctx):
repository_ctx.symlink(repository_ctx.attr.path, "")
local_repository = repository_rule(
implementation=_impl,
...)
Quando a função de implementação é executada?
Se o repositório for declarado como local
, a mudança em uma dependência
no gráfico de dependências (incluindo o próprio arquivo WORKSPACE
) vai
causar a execução da função de implementação.
A função de implementação pode ser reiniciada se uma dependência solicitada estiver ausente. O início da função de implementação será executado novamente após a dependência ser resolvida. Para evitar reiniciamentos desnecessários (que são caros, já que o acesso à rede pode precisar ser repetido), os argumentos de rótulo são pré-buscados, desde que todos os argumentos de rótulo possam ser resolvidos em um arquivo existente. A resolução de um caminho de uma string ou de um rótulo que foi criado apenas durante a execução da função ainda pode causar uma reinicialização.
Por fim, para repositórios que não são local
, apenas uma mudança nas seguintes
dependências pode causar uma reinicialização:
- arquivos
.bzl
necessários para definir a regra do repositório. - Declaração da regra do repositório no arquivo
WORKSPACE
. - Valor de qualquer variável de ambiente declarada com o atributo
environ
da funçãorepository_rule
. O valor dessa variável de ambiente pode ser aplicado na linha de comando com a flag--action_env
(mas essa flag invalida todas as ações do build). - Conteúdo de qualquer arquivo usado e referenciado por um rótulo (por exemplo,
//mypkg:label.txt
, nãomypkg/label.txt
).
Como forçar a nova busca de repositórios externos
Às vezes, um repositório externo pode ficar desatualizado sem nenhuma mudança na
definição ou nas dependências. Por exemplo, um repositório que busca fontes pode
seguir uma ramificação específica de um repositório de terceiros, e novos commits estão
disponíveis nessa ramificação. Nesse caso, é possível pedir ao Bazel para buscar novamente todos
os repositórios externos de forma incondicional chamando bazel sync
.
Além disso, algumas regras inspecionam a máquina local e podem ficar
desatualizadas se a máquina local for atualizada. Aqui, você pode pedir ao Bazel para
buscar novamente apenas os repositórios externos em que a
definição repository_rule
tem o atributo configure
definido. Use bazel sync --configure
.
Exemplos
Conjunto de ferramentas C++ configurado automaticamente: usa uma regra de repositório para criar automaticamente os arquivos de configuração do C++ para o Bazel procurando o compilador C++ local, o ambiente e as flags com suporte do compilador C++.
Os repositórios do Go usam vários
repository_rule
para definir a lista de dependências necessárias para usar as regras do Go.rules_jvm_external cria um repositório externo chamado
@maven
por padrão, que gera destinos de build para cada artefato do Maven na árvore de dependências transitivas.