Esta página aborda como definir regras de repositório e fornece exemplos para mais detalhes.
Um repositório externo é uma árvore de diretórios,
que contém arquivos de origem utilizáveis em um build do Bazel, gerado sob demanda pela
execução da regra de repositório correspondente. Os repositórios podem ser definidos de várias maneiras, mas, em última análise, cada um é definido invocando uma regra de repositório, assim como os destinos de build são definidos invocando regras de 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.
Definição da regra de repositório
Em um arquivo .bzl, use a função
repository_rule para definir uma nova regra de repositório
e armazená-la em uma variável global. Depois que uma regra de repositório é definida, ela pode ser invocada como uma função para definir repositórios. Essa invocação geralmente é
realizada de dentro de uma extensão de módulo implementação
função.
Os dois principais componentes de uma definição de regra de repositório são o esquema de atributo e a função de implementação. O esquema de atributo determina os nomes e tipos de atributos transmitidos a uma invocação de regra de repositório, e a função de implementação é executada quando o repositório precisa ser buscado.
Atributos
Os atributos são argumentos transmitidos à invocação da regra de repositório. O esquema de atributos aceitos por uma regra de repositório é especificado usando o argumento attrs quando a regra de repositório é definida com uma chamada para repository_rule. Um exemplo que define os atributos url e sha256 como strings:
http_archive = repository_rule(
implementation=_impl,
attrs={
"url": attr.string(mandatory=True),
"sha256": attr.string(mandatory=True),
}
)
Para acessar um atributo na função de implementação, use
repository_ctx.attr.<attribute_name>:
def _impl(repository_ctx):
url = repository_ctx.attr.url
checksum = repository_ctx.attr.sha256
Todos os repository_rule têm o atributo name definido implicitamente. Esse é um atributo de string que se comporta de maneira um pouco mágica: quando especificado como entrada para uma invocação de regra de repositório, ele recebe um nome de repositório aparente, mas, quando lido na função de implementação da regra de repositório usando repository_ctx.attr.name, ele retorna o nome canônico do repositório.
Função de implementação
Cada 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 é reproduzível, considerando os parâmetros especificados, ou um dicionário com um conjunto de parâmetros para essa regra que a transformaria em uma regra reproduzível, gerando o mesmo repositório. Por exemplo, para uma regra que acompanha um repositório Git, isso significa retornar um identificador de commit 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 documentação da API
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?
A função de implementação de uma regra de repositório é executada quando o Bazel precisa de um destino desse repositório, por exemplo, quando outro destino (em outro repositório) depende dele ou se ele é mencionado na linha de comando. A função de implementação precisa criar o repositório no sistema de arquivos. Isso é chamado de "busca" do repositório.
Ao contrário dos destinos normais, os repositórios não são necessariamente buscados novamente quando algo muda e faz com que o repositório seja diferente. Isso ocorre porque há coisas que o Bazel não consegue detectar mudanças ou que causariam muita sobrecarga em cada build (por exemplo, coisas buscadas na rede). Portanto, os repositórios são buscados novamente apenas se uma das seguintes situações mudar:
- Os atributos transmitidos à invocação da regra de repositório.
- O código Starlark que compreende a implementação da regra de repositório.
- O valor de qualquer variável de ambiente transmitida ao
repository_ctx'sgetenv()método ou declarada com oenvironatributo dorepository_rule. Os valores de essas variáveis de ambiente podem ser fixados na linha de comando com a--repo_envflag. - A existência, o conteúdo e o tipo de qualquer caminho que esteja sendo
watched na função de implementação da regra de repositório.- Outros métodos de
repository_ctxcom um parâmetrowatch, comoread(),execute()eextract(), também podem fazer com que os caminhos sejam observados. - Da mesma forma,
repository_ctx.watch_treeepath.readdirpodem fazer com que os caminhos sejam observados de outras maneiras.
- Outros métodos de
- Quando
bazel fetch --forceé executado.
Há dois parâmetros de repository_rule que controlam quando os repositórios são buscados novamente:
- Se a flag
configureestiver definida, o repositório será buscado novamente embazel fetch --force --configure(repositórios nãoconfigurenão serão buscados novamente). - Se a flag
localestiver definida, além dos casos acima, o repositório também será buscado novamente quando o servidor do Bazel for reiniciado.
Forçar a 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, você pode pedir ao Bazel para buscar novamente todos os repositórios externos incondicionalmente chamando bazel fetch --force --all.
Além disso, algumas regras de repositório 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 repository_rule
definição tem o configure atributo definido, use bazel fetch --force
--configure.
Exemplos
C++ autoconfigurada conjunto de ferramentas: ela usa uma regra de repo para criar automaticamente os arquivos de configuração do C++ para o Bazel, procurando o compilador local do C++, o ambiente e as flags que o compilador do C++ oferece suporte.
Os repositórios Go usam vários
repository_rulepara definir a lista de dependências necessárias para usar as regras do Go.rules_jvm_external cria um repositório externo chamado
@mavenpor padrão que gera destinos de build para cada artefato do Maven na árvore de dependências transitivas.