Nesta página, explicamos como criar regras de repositório e fornecemos exemplos para mais detalhes.
Um repositório externo é uma regra que pode ser usada apenas
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 BUILD
e artefatos. Eles podem ser usados para depender de bibliotecas
de terceiros, como bibliotecas empacotadas Maven, mas também para gerar arquivos BUILD
específicos do host em que o Bazel está sendo executado.
Criação de regra de repositório
Em um arquivo .bzl
, use a função repository_rule para criar uma nova regra de repositório e armazene-a em uma variável global.
Uma regra de repositório personalizada pode ser usada da mesma forma que uma regra de repositório nativa. Ele
tem um atributo name
obrigatório, e todos os destinos presentes nos arquivos de build
podem ser chamados de @<name>//package:target
, em que <name>
é o valor do
atributo name
.
A regra é carregada quando você a cria explicitamente ou se é uma dependência do
build. Nesse caso, o Bazel executa a função implementation
. Essa
função descreve como criar o repositório, o conteúdo dele e os arquivos BUILD
.
Atributos
Um atributo é um argumento de regra, como url
ou sha256
. É preciso 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>
.
Todas as repository_rule
s têm atributos definidos implicitamente, assim como as regras de
build. Os dois atributos implícitos são name
(assim como para 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 um nome de atributo começar com _
, ele será particular e não poderá ser definido pelos usuários.
Função de implementação
Toda regra de repositório requer uma função implementation
. Ela contém a lógica real da regra e é executada 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 pode ser reproduzida com base nos parâmetros especificados, ou um dict com um conjunto de parâmetros para essa regra que a transformaria em uma regra reproduzível que gera o mesmo repositório. Por
exemplo, uma regra que rastreia um repositório Git significa 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
contexto. 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 alteração em uma dependência
no gráfico de dependência (incluindo o próprio arquivo WORKSPACE
)
vai causar a execução da função de implementação.
A função de implementação poderá ser reiniciada se uma dependência solicitada estiver ausente. O início da função de implementação será executado novamente após a resolução da dependência. Para evitar reinicializações desnecessárias (que são caras porque o acesso à rede pode precisar ser repetido), os argumentos de rótulo são pré-buscados, desde que todos eles possam ser resolvidos em um arquivo atual. Observe que resolver um caminho de uma string ou um rótulo criado apenas durante a execução da função ainda pode causar uma reinicialização.
Por fim, para repositórios não local
, apenas uma mudança nas dependências
a seguir pode causar uma reinicialização:
- Arquivos
.bzl
necessários para definir a regra de repositório. - Declaração da regra de repositório no arquivo
WORKSPACE
. - Valor de qualquer variável de ambiente declarada com o atributo
environ
da funçãorepository_rule
. O valor dessas variáveis de ambiente pode ser aplicado a partir da linha de comando com a sinalização--action_env
, mas essa sinalização invalidará todas as ações do build. - Conteúdo de qualquer arquivo usado e referenciado por um rótulo (por exemplo,
//mypkg:label.txt
e nãomypkg/label.txt
).
Como forçar uma nova busca de repositórios externos
Às vezes, um repositório externo pode ficar desatualizado sem qualquer mudança na definição ou nas dependências dele. Por exemplo, um repositório que busca origens pode
seguir uma ramificação específica de um repositório de terceiros, e novas confirmações estão
disponíveis nessa ramificação. Nesse caso, você pode solicitar que o Bazel refaça a busca de todos
os repositórios externos incondicionalmente chamando bazel sync
.
Além disso, algumas regras inspecionam a máquina local e podem ficar desatualizadas se a máquina local tiver sido atualizada. Aqui, você pode pedir que o Bazel
refaça apenas os repositórios externos em que a definição
repository_rule
tem o conjunto de atributos configure
. Use bazel sync --configure
.
Exemplos
Conjunto de ferramentas configurado automaticamente para C++: ele usa uma regra de repositório para criar automaticamente os arquivos de configuração C++ para o Bazel. Para isso, ele procura o compilador C++ local, o ambiente e as sinalizações compatíveis com o 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 Maven na árvore de dependências transitiva.