Regras de repositório

Reportar um problema Ver a fonte Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Nesta página, você vai aprender a criar regras de repositório e encontrar exemplos para mais detalhes.

Um repositório externo é uma regra que pode ser usada apenas no arquivo WORKSPACE e permite uma operação não hermética na fase de carregamento do Bazel. Cada regra de repositório externo cria um espaço de trabalho próprio, com 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 do 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 como uma regra nativa. Ele tem um atributo name obrigatório, e cada destino presente nos arquivos de build pode ser chamado de @<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 da build. Nesse caso, o Bazel vai executar 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. É 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_rules 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 nativas 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

Cada regra de repositório exige 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 que transformariam a regra em uma regra reproduzível, gerando o mesmo repositório. Por exemplo, para uma regra que rastreia 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 baixar 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, uma mudança em uma dependência no gráfico de dependências (incluindo o próprio arquivo WORKSPACE) vai causar uma 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 depois que a dependência for resolvida. Para evitar reinicializações desnecessárias (que são caras, já que o acesso à rede pode ter que 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. Resolver um caminho de uma string ou um rótulo construído 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ção repository_rule. O valor dessas variáveis 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ão mypkg/label.txt).

Como forçar a nova busca de repositórios externos

Às vezes, um repositório externo pode ficar desatualizado sem que haja mudanças na definição ou nas dependências dele. Por exemplo, um repositório que busca fontes pode seguir uma ramificação específica de um repositório de terceiros, e novos commits ficam disponíveis nessa ramificação. Nesse caso, é possível pedir ao bazel para buscar novamente todos os repositórios externos incondicionalmente chamando bazel sync.

Além disso, algumas regras inspecionam a máquina local e podem ficar desatualizadas se ela 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

  • Cadeia de ferramentas autoconfigurada do C++: usa uma regra de repositório para criar automaticamente os arquivos de configuração do C++ para o Bazel. Para isso, procura o compilador local do C++, o ambiente e as flags compatíveis com o compilador.

  • Os repositórios Go usam vários repository_rule para definir a lista de dependências necessárias para usar as regras do Go.

  • O 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ência transitiva.