Como implantar regras

Esta página é destinada a autores de regras que planejam disponibilizar as regras para outras pessoas.

Regras de hospedagem e nomenclatura

As novas regras precisam estar no próprio repositório do GitHub na sua organização. Entre em contato com a lista de e-mails bazel-dev se achar que suas regras pertencem à organização bazelbuild.

Os nomes dos repositórios para regras do Bazel são padronizados no seguinte formato: $ORGANIZATION/rules_$NAME. Confira exemplos no GitHub. Para manter a consistência, siga o mesmo formato ao publicar suas regras do Bazel.

Use uma descrição do repositório do GitHub e um título README.md descritivos. Exemplo:

  • Nome do repositório: bazelbuild/rules_go
  • Descrição do repositório: Regras do Go para o Bazel
  • Tags do repositório: golang, bazel
  • README.md cabeçalho: Regras do Go para o Bazel (observe o link para https://bazel.build, que orienta os usuários que não conhecem o Bazel ao lugar certo)

As regras podem ser agrupadas por linguagem (como Scala) ou plataforma (como Android).

Conteúdo do repositório

Cada repositório de regras precisa ter um layout específico para que os usuários possam entender rapidamente as novas regras.

Por exemplo, ao escrever novas regras para a linguagem mockascript (fictícia), o repositório de regras teria a seguinte estrutura:

/
  LICENSE
  README
  WORKSPACE
  mockascript/
    constraints/
      BUILD
    runfiles/
      BUILD
      runfiles.mocs
    BUILD
    defs.bzl
  tests/
    BUILD
    some_test.sh
    another_test.py
  examples/
    BUILD
    bin.mocs
    lib.mocs
    test.mocs

WORKSPACE

No WORKSPACE do projeto, defina o nome que os usuários vão usar para referenciar suas regras. Se as regras pertencerem à bazelbuild organização, use rules_<lang> (como rules_mockascript). Caso contrário, nomeie seu repositório <org>_rules_<lang> (como build_stack_rules_proto). Entre em contato com a lista de e-mails bazel-dev se achar que suas regras precisam seguir a convenção de regras na bazelbuild organização.

Nas seções a seguir, suponha que o repositório pertença à bazelbuild organização.

workspace(name = "rules_mockascript")

README

No nível superior, precisa haver um README que contenha (pelo menos) o que os usuários precisam copiar e colar no arquivo WORKSPACE para usar sua regra. Em geral, esse será um http_archive que aponta para a versão do GitHub e uma chamada de macro que faz o download/configura todas as ferramentas necessárias para a regra. Por exemplo, para as regras do Go, isso é assim:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "rules_go",
    urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.18.5/rules_go-0.18.5.tar.gz"],
    sha256 = "a82a352bffae6bee4e95f68a8d80a70e87f42c4741e6a448bec11998fcc82329",
)
load("@rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()

Se as regras dependem de regras de outro repositório, especifique isso na documentação das regras (por exemplo, consulte as regras do Skydoc, que dependem das regras do Sass) e forneça uma WORKSPACE macro que faça o download de todas as dependências (consulte rules_go acima).

Regras

Muitas vezes, o repositório vai fornecer várias regras. Crie um diretório nomeado pela linguagem e forneça um ponto de entrada: arquivo defs.bzl que exporta todas as regras (inclua também um arquivo BUILD para que o diretório seja um pacote). Para rules_mockascript, isso significa que haverá um diretório chamado mockascript, e um arquivo BUILD e um arquivo defs.bzl dentro dele:

/
  mockascript/
    BUILD
    defs.bzl

Restrições

Se a regra definir regras de conjunto de ferramentas, talvez seja necessário definir constraint_settings e/ou constraint_values personalizados. Coloque-os em um pacote //<LANG>/constraints. A estrutura de diretórios será assim:

/
  mockascript/
    constraints/
      BUILD
    BUILD
    defs.bzl

Leia github.com/bazelbuild/platforms para conferir as práticas recomendadas e ver quais restrições já estão presentes. Considere contribuir com suas restrições se elas forem independentes da linguagem. Esteja ciente da introdução de restrições personalizadas. Todos os usuários das suas regras vão usá-las para realizar uma lógica específica da plataforma nos arquivos BUILD (por exemplo, usando seleções). Com restrições personalizadas, você define um idioma que todo o ecossistema do Bazel vai usar.

Biblioteca de arquivos de execução

Se a regra fornecer uma biblioteca padrão para acessar arquivos de execução, ela precisa estar na forma de um destino de biblioteca localizado em //<LANG>/runfiles (uma abreviação de //<LANG>/runfiles:runfiles). Os destinos do usuário que precisam acessar as dependências de dados normalmente adicionam esse destino ao atributo deps.

Regras do repositório

Dependências

Suas regras podem ter dependências externas. Para simplificar a dependência das regras, forneça uma macro WORKSPACE que declare dependências dessas dependências externas. Não declare dependências de testes, apenas dependências que as regras precisam para funcionar. Coloque as dependências de desenvolvimento no arquivo WORKSPACE.

Crie um arquivo chamado <LANG>/repositories.bzl e forneça uma única macro de ponto de entrada chamada rules_<LANG>_dependencies. Nosso diretório será assim:

/
  mockascript/
    constraints/
      BUILD
    BUILD
    defs.bzl
    repositories.bzl

Como registrar conjuntos de ferramentas

Suas regras também podem registrar conjuntos de ferramentas. Forneça uma macro WORKSPACE separada que registre esses conjuntos de ferramentas. Dessa forma, os usuários podem omitir a macro anterior e controlar as dependências manualmente, sem deixar de registrar conjuntos de ferramentas.

Portanto, adicione uma macro WORKSPACE chamada rules_<LANG>_toolchains ao <LANG>/repositories.bzl arquivo.

Para resolver conjuntos de ferramentas na fase de análise, o Bazel precisa analisar todos os destinos toolchain registrados. O Bazel não precisará analisar todos os destinos referenciados pelo atributo toolchain.toolchain. Se, para registrar conjuntos de ferramentas, você precisar realizar cálculos complexos no repositório, considere dividir o repositório com toolchain destinos do repositório com <LANG>_toolchain destinos. O primeiro será sempre buscado, e o segundo só será buscado quando o usuário realmente precisar criar o código <LANG>.

Snippet de lançamento

No anúncio de lançamento, forneça um snippet que os usuários possam copiar e colar no arquivo WORKSPACE. Esse snippet geralmente será assim:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "rules_<LANG>",
    urls = ["<url_to_the_release.zip"],
    sha256 = "4242424242",
)
load("@rules_<LANG>//<LANG>:repositories.bzl", "rules_<LANG>_dependencies", "rules_<LANG>_toolchains")
rules_<LANG>_dependencies()
rules_<LANG>_toolchains()

Testes

É necessário que haja testes que verifiquem se as regras estão funcionando conforme o esperado. Isso pode estar no local padrão da linguagem para a qual as regras são ou em um diretório tests/ no nível superior.

Exemplos (opcional)

É útil para os usuários ter um diretório examples/ que mostre algumas maneiras básicas de usar as regras.

Teste

Configure o Travis conforme descrito na documentação de primeiros passos Em seguida, adicione um arquivo .travis.yml ao repositório com o seguinte conteúdo:

dist: xenial  # Ubuntu 16.04

# On trusty (or later) images, the Bazel apt repository can be used.
addons:
  apt:
    sources:
    - sourceline: 'deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8'
      key_url: 'https://bazel.build/bazel-release.pub.gpg'
    packages:
    - bazel

script:
  - bazel build //...
  - bazel test //...

Se o repositório estiver na organização bazelbuild, você pode pedir para adicionar a ci.bazel.build.

Documentação

Consulte a documentação do Stardoc para instruções sobre como comentar as regras para que a documentação possa ser gerada automaticamente.

Perguntas frequentes

Por que não podemos adicionar nossa regra ao repositório principal do GitHub do Bazel?

Queremos separar as regras das versões do Bazel o máximo possível. É mais claro quem é o proprietário das regras individuais, reduzindo a carga dos desenvolvedores do Bazel. Para nossos usuários, a separação facilita a modificação, o upgrade, o downgrade e a substituição de regras. A contribuição para regras pode ser mais leve do que a contribuição para o Bazel, dependendo das regras, incluindo acesso total ao repositório do GitHub correspondente. Obter acesso de envio ao Bazel é um processo muito mais complexo.

A desvantagem é um processo de instalação única mais complicado para nossos usuários: eles precisam copiar e colar uma regra no arquivo WORKSPACE, conforme mostrado na seção README.md acima.

Antes, tínhamos todas as regras no repositório do Bazel (em //tools/build_rules ou //tools/build_defs). Ainda temos algumas regras lá, mas estamos trabalhando para remover as regras restantes.