Regras de repositório

Informar um problema Mostrar fonte Por noite · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

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

Um repositório externo é uma regra que pode ser usada apenas no arquivo WORKSPACE e permite a operação não hermética 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 e artefatos BUILD. Eles podem ser usados com dependências (como bibliotecas empacotadas Maven), mas também para gerar arquivos BUILD específico para o host em que o Bazel está sendo executado.

Criação de regra de repositório

Em um arquivo .bzl, use o função repository_rule para criar um novo regra de repositório e armazená-la em uma variável global.

Uma regra de repositório personalizada pode ser usada da mesma forma que uma regra de repositório nativa. Ela tem um atributo name obrigatório e todos os destinos presentes nos arquivos de build pode ser chamado de @<name>//package:target, em que <name> é o valor do name.

A regra é carregada quando você a cria explicitamente ou se for uma dependência de o build. Nesse caso, o Bazel executa a função implementation. Isso descreve como criar o repositório, o conteúdo dele e os arquivos BUILD.

Atributos

Os atributos são argumentos de regra transmitidos como um dict para o argumento de regra attrs. Os atributos e os respectivos tipos são listados quando você define um regra de repositório. Um exemplo que define os atributos url e sha256 como strings:

local_repository = repository_rule(
    implementation=_impl,
    local=True,
    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 atributos definidos implicitamente, assim como o build regras). Os dois atributos implícitos são name (assim como as 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 que para o regras de repositório nativo 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

Toda regra de repositório requer 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). Acesse a biblioteca para mais informações 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 um repositório é executada quando o Bazel precisa 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 deverá criar o repositório no arquivo sistema. Isso é chamado de "busca" repositório.

Diferente dos destinos regulares, os repositórios não são necessariamente buscados novamente quando algo mudar que faria com que o repositório fosse 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 parâmetros transmitidos para a declaração do repositório no WORKSPACE.
  • O código Starlark que compreende a implementação do repositório.
  • Valor de qualquer variável de ambiente declarada com o environ do objeto repository_rule. Os valores dessas variáveis de ambiente podem ser fixados no comando com o --action_env (mas vai invalidar todas as ações da compilação).
  • 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 sync é 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 sync 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á buscadas novamente quando o servidor do Bazel é reiniciado ou quando qualquer arquivo que afete a declaração das mudanças do repositório (por exemplo, o arquivo WORKSPACE ou um arquivo for carregado), independentemente de as alterações terem resultado em uma alteração na declaração do repositório ou do código dele.

    Os repositórios não locais não são buscados novamente nesses casos. Isso ocorre porque presume-se que esses repositórios se comuniquem com a rede ou sejam caro.

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 mudança 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 sync.

Além disso, algumas regras inspecionam a máquina local e podem se tornar se o upgrade da máquina local estiver desatualizado. Aqui você pode pedir ao Bazel para apenas rebuscar os repositórios externos em que o repository_rule definição tiver o atributo configure definido, use bazel sync --configure.

Exemplos

  • Conjunto de ferramentas configurado automaticamente para C++: ele usa uma regra de repositório 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.