Regras de repositório

Nesta página, explicamos como criar regras de repositório e fornecemos 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 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 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 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 nativo. 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 é uma dependência do build. Nesse caso, o Bazel 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. É 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>.

Todos os repository_rules têm atributos definidos implicitamente (assim como as regras de criação). Os dois atributos implícitos são name (assim como para as regras de criação) 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.

Caso um nome de atributo comece com _, ele é particular e não pode ser definido pelos usuários.

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 de acordo com os parâmetros especificados ou um dict 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, uma regra que rastreia um repositório git significaria retornar um identificador de confirmação específico em vez de uma ramificação flutuante 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. Exemplos

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ências (incluindo o próprio arquivo WORKSPACE) 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, porque o acesso à rede pode precisar ser repetido), os argumentos de rótulo são pré-buscados, desde que todos os argumentos possam ser resolvidos para um arquivo atual. Resolver um caminho de uma string ou 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 alteração nas seguintes dependências 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ção repository_rule. O valor dessa variável 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ão mypkg/label.txt).

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

Às vezes, um repositório externo pode ficar desatualizado sem nenhuma alteração na definição ou nas dependências. Por exemplo, as origens de busca de um repositório podem 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, é 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 poderão ficar desatualizadas se for feito upgrade da máquina local. Aqui é possível pedir ao Bazel para buscar novamente apenas os repositórios externos em que a definição repository_rule tem o atributo configure definido e 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 procurando o compilador C++ local, o ambiente e as sinalizações compatíveis com o compilador do 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.