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 que podem ser usados em um build do Bazel, que é gerado sob demanda
executando a regra do repositório correspondente. Os repositórios podem ser definidos de várias
maneiras, mas cada repo é definido invocando uma regra de repositório, assim como
os destinos de build são definidos ao invocar essas regras. 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 do 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 em uma função de implementação de extensão de módulo.
Os dois principais componentes de uma definição de regra de repositório são o esquema de atributos e a função de implementação. O esquema de atributos determina os nomes e tipos de atributos transmitidos para 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 para a invocação da regra do 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
s têm o atributo name
definido implicitamente. Esse é um
atributo de string que se comporta de maneira mágica: quando especificado como uma entrada para
uma invocação de regra de repositório, ele recebe um nome de repositório aparente. No entanto, 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
. 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, considerando 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 os documentos
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 repo é 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. Espera-se que a função de implementação crie o repositório no sistema de arquivos. Isso é chamado de "buscar" o repositório.
Ao contrário dos destinos normais, os repositórios não são necessariamente buscados novamente quando algo muda e causa uma diferença no repositório. 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 que são buscadas da rede). Portanto, os repositórios serão buscados novamente somente se uma das seguintes condições for alterada:
- Os atributos transmitidos para a invocação da regra do repositório.
- O código Starlark que compreende a implementação da regra do repositório.
- O valor de qualquer variável de ambiente transmitida para o método
getenv()
derepository_ctx
ou declarado com o atributoenviron
dorepository_rule
. Os valores dessas variáveis de ambiente podem ser fixados na linha de comando com a flag--repo_env
. - A existência, o conteúdo e o tipo de todos os caminhos que estão sendo
watch
ed na função de implementação da regra do repositório.- Alguns outros métodos de
repository_ctx
com um parâmetrowatch
, comoread()
,execute()
eextract()
, também podem fazer com que os caminhos sejam monitorados. - Da mesma forma,
repository_ctx.watch_tree
epath.readdir
podem fazer com que os caminhos sejam monitorados de outras maneiras.
- Alguns 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
configure
estiver definida, o repositório será buscado novamente embazel fetch --force --configure
. Os repositórios que não sãoconfigure
não são buscados novamente. - Se a flag
local
estiver definida, além dos casos acima, o repositório também será buscado novamente quando o servidor do Bazel for reiniciado.
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 novos commits estão disponíveis nessa
ramificação. Nesse caso, você pode pedir que o Bazel refaça a busca de 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 definição de repository_rule
tem o atributo configure
definido. Use bazel fetch --force
--configure
.
Exemplos
Kit de ferramentas C++ configurado automaticamente: usa uma regra de repositório para criar automaticamente os arquivos de configuração C++ do Bazel procurando o compilador C++ local, o ambiente e as flags com as quais o compilador C++ é compatível.
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 alvos de build para cada artefato do Maven na árvore de dependências transitivas.