Regras de repositório

Relatar um problema Conferir código-fonte Por noite · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

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. contendo arquivos de origem utilizáveis em uma versão do Bazel, que é gerada sob demanda pelo executando a regra repo correspondente. Os repositórios podem ser definidos em vários mas, em última análise, cada repo é definido invocando uma regra repo, assim como os destinos de build são definidos invocando regras de build. Elas podem ser usadas para depender bibliotecas de terceiros (como bibliotecas empacotadas pelo Maven), mas também para gerar Arquivos BUILD específicos do host em que o Bazel está sendo executado.

Definição da regra do repositório

Em um arquivo .bzl, use o função repository_rule para definir nova regra de repositório e armazená-la em uma variável global. Depois que uma regra de repositório for definida, ele pode ser invocado como uma função para definir repos. Essa invocação geralmente é realizada dentro de uma implementação de extensão de módulo função.

Os dois principais componentes de uma definição de regra de repositório são o esquema de atributos e função de implementação. O esquema de atributos determina os nomes e tipos passados para uma invocação de regra de repositório, e a função de implementação é executada quando for preciso buscar o repositório.

Atributos

Atributos são argumentos passados para a invocação da regra do repo. O esquema de atributos aceitos por uma regra de repositório são especificados usando o argumento attrs quando a regra de repo é definida com uma chamada para repository_rule. Um exemplo que define 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_rules têm o atributo name definido implicitamente. Esta é uma atributo string que se comporta de maneira mágica: quando especificado como uma entrada para uma invocação de regra de repositório, ele assume um nome de repositório aparente; mas, quando lido na função de implementação da regra repo usando repository_ctx.attr.name, ela retorna o nome do repositório canônico.

Função de implementação

Toda regra de repositório exige uma função implementation. Ele contém 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, considerando o 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. Para exemplo, para uma regra que rastreia um repositório Git, o que significaria retornar um identificador de commit específico em vez de uma ramificação flutuante especificado.

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 repo é executada quando o Bazel precisa de uma destino desse repositório, por exemplo, quando outro destino (em outro repo) depende dele ou se é mencionado na linha de comando. O função de implementação deverá criar o repositório no arquivo sistema. Isso é chamado de "busca" no repositório.

Diferente dos destinos regulares, os repositórios não são necessariamente buscados novamente quando algo mudar que faria o repositório ser diferente. Isso é porque o Bazel não detecta mudanças em algumas coisas ou causar muita sobrecarga em cada compilação (por exemplo, itens buscados da rede). Portanto, os repositórios serão buscados novamente somente se um dos as seguintes mudanças:

  • Os atributos transmitidos para a invocação da regra de repositório.
  • O código Starlark que compreende a implementação da regra repo.
  • O valor de qualquer variável de ambiente passada para o comando repository_ctx método getenv() ou declarado com o atributo environ da repository_rule Os valores dessas variáveis de ambiente podem ser conectadas na linha de comando com o flag --repo_env.
  • O conteúdo de qualquer arquivo transmitido para read(), execute() e similares métodos de repository_ctx, que são referenciados por um rótulo (por exemplo, //mypkg:label.txt, mas não mypkg/label.txt)
  • 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 só vai ser buscado novamente bazel fetch quando o parâmetro --configure for passado a ela (se o atributo não estiver definido, este comando não causará uma nova busca)
  • Se a sinalização local estiver definida, além dos casos acima, o repositório será também buscadas novamente quando o servidor do Bazel é reiniciado.

Como reiniciar a função de implementação

A função de implementação pode ser reiniciada enquanto um repositório está sendo buscado se uma dependência solicitada estiver ausente. Nesse caso, a execução a função de implementação será interrompida, a dependência ausente será resolvida e a função será executada novamente depois que a dependência for resolvida. Para evitar reinicializações desnecessárias (que são caras, pois o acesso à rede pode repetidos), argumentos de rótulo são pré-buscados, contanto que todos de rótulo podem ser resolvidos em um arquivo atual. A resolução Um caminho de uma string ou um rótulo que foi criado somente durante a execução da função ainda pode causar uma reinicialização.

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

Às vezes, um repositório externo pode ficar desatualizado sem qualquer alteração ou dependências. Por exemplo, um repositório que busca origens pode seguem uma ramificação específica de um repositório de terceiros, e novas confirmações são disponíveis na ramificação. Nesse caso, você pode pedir ao Bazel para refazer todas as repositórios externos incondicionalmente chamando bazel fetch --force --all.

Além disso, algumas regras de repo inspecionam a máquina local e podem se tornar desatualizados se a máquina local foi atualizada. Aqui você pode pedir ao Bazel para apenas refazer os repositórios externos em que repository_rule tem o atributo configure definido, use bazel fetch --all --configure.

Exemplos

  • Conjunto de ferramentas configurado automaticamente para C++: ele usa uma regra repo para criar automaticamente arquivos de configuração C++ para Bazel procurando pelo compilador C++ local, o e as sinalizações compatíveis com o compilador C++.

  • Repositórios Go usa 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.