Esta página aborda as diretrizes básicas de estilo do Starlark e também inclui informações sobre macros e regras.
Starlark é um linguagem que define como o software é construído e, assim, é uma programação e uma linguagem de configuração.
Você usará o Starlark para gravar arquivos BUILD
, macros e regras de build. Macros e
são essencialmente metalinguagens. Elas definem como os arquivos BUILD
são escritos.
Os arquivos BUILD
precisam ser simples e repetitivos.
Todo software é lido com mais frequência do que escrito. Isso é especialmente verdade
Starlark, enquanto os engenheiros leem arquivos BUILD
para entender as dependências
destinos e detalhes dos builds. Essa leitura muitas vezes acontecerá de passagem,
com pressa ou em paralelo à realização de outra tarefa. Consequentemente,
simplicidade e legibilidade são muito importantes para que os usuários possam analisar e
compreenda arquivos BUILD
rapidamente.
Quando um usuário abre um arquivo BUILD
, ele quer saber rapidamente a lista de destinos no
o arquivo. ou analise a lista de fontes dessa biblioteca C++; ou remover um
desse binário Java. Cada vez que você adiciona uma camada de abstração,
dificultam a realização dessas tarefas por parte do usuário.
Os arquivos BUILD
também são analisados e atualizados por muitas ferramentas diferentes. As ferramentas não podem
poderá editar seu arquivo BUILD
se ele usar abstrações. A BUILD
vai ser mantida
arquivos simples permitirão ferramentas melhores. À medida que a base de código cresce, ela
se torna cada vez mais frequente fazer alterações em muitos arquivos BUILD
, a fim de
atualizar uma biblioteca ou fazer uma limpeza.
Recomendações gerais
- Usar o Buildifier como formatador e linter.
- Siga as diretrizes de teste.
Estilo
Estilo Python
Em caso de dúvida, siga as Use o Guia de estilo PEP 8 quando possível. Em particular, use quatro em vez de dois espaços para que o recuo siga a convenção do Python.
Como
O Starlark não é Python,
alguns aspectos do estilo Python não se aplicam. Por exemplo, a PEP 8 recomenda que
as comparações com Singletons sejam feitas com is
, que não é um operador em
Starlark.
String de documento
Documente arquivos e funções usando docstrings.
Use um docstring na parte superior de cada arquivo .bzl
e um docstring para cada arquivo público.
função.
Documentar regras e aspectos
Regras e aspectos, juntamente com seus atributos, assim como provedores e seus
campos, precisam ser documentados usando o argumento doc
.
Convenção de nomenclatura
- As variáveis e os nomes de funções usam letras minúsculas com palavras separadas por
sublinhados (
[a-z][a-z0-9_]*
), comocc_library
. - Valores particulares de nível superior começam com um sublinhado. O Bazel aplica que os valores particulares não podem ser usados em outros arquivos. As variáveis locais não devem use o prefixo sublinhado.
Comprimento da linha
Como nos arquivos BUILD
, não há um limite rígido de comprimento de linha, já que os rótulos podem ser longos.
Quando possível, tente usar no máximo 79 caracteres por linha (seguindo
guia de estilo, PEP 8). Esta diretriz
não devem ser aplicadas estritamente: os editores devem exibir mais de 80 colunas,
as mudanças automáticas costumam gerar filas mais longas, e os humanos não devem
passe tempo dividindo as linhas que já estão legíveis.
Argumentos de palavra-chave
Em argumentos de palavra-chave, é preferível usar espaços em torno do sinal de igual:
def fct(name, srcs):
filtered_srcs = my_filter(source = srcs)
native.cc_library(
name = name,
srcs = filtered_srcs,
testonly = True,
)
Valores booleanos
Prefere valores True
e False
(em vez de 1
e 0
) para valores booleanos
(como ao usar um atributo booleano em uma regra).
Usar somente impressão para depuração
Não use a função print()
no código de produção. ele é destinado apenas a
depuração e vai enviar spam para todos os usuários diretos e indiretos de seu arquivo .bzl
. O
A única exceção é que você pode enviar um código que use print()
se ele estiver desativado
por padrão e só podem ser ativados ao editar a fonte. Por exemplo, se todos
os usos de print()
são protegidos por if DEBUG:
, em que DEBUG
é fixado no código para
False
. Saiba se essas declarações são úteis o suficiente para justificar
o impacto na legibilidade.
Macros
Uma macro é uma função que instancia uma ou mais regras durante o carregamento fase de testes. Em geral, use regras sempre que possível em vez de macros. O build gráfico visto pelo usuário não é o mesmo usado pelo Bazel durante a build: as macros são expandidas antes de o Bazel fazer qualquer análise de gráfico de build.
Por isso, quando algo dá errado, o usuário precisa entender
a implementação da macro para resolver
problemas de build. Além disso, os resultados de bazel
query
podem ser difíceis de interpretar porque os destinos mostrados nos resultados
vêm da expansão macro. Por fim, os aspectos não reconhecem as macros, então as ferramentas
dependendo de aspectos (IDEs e outros), pode falhar.
Um uso seguro das macros é definir destinos adicionais para serem referenciados diretamente na CLI do Bazel ou nos arquivos BUILD: nesse caso, apenas o Os usuários finais desses destinos precisam conhecê-los e quaisquer problemas de compilação. introduzidos por macros nunca estão longe de seu uso.
Para macros que definem destinos gerados (detalhes de implementação da macro que não devem ser referenciados na CLI nem dependentes dos destinos não instanciada por essa macro), siga estas práticas recomendadas:
- Uma macro precisa usar um argumento
name
e definir um destino com esse nome. Esse destino se torna o principal alvo dessa macro. - Os destinos gerados, ou seja, todos os outros destinos definidos por uma macro, precisam:
- Ter os nomes com o prefixo
<name>
ou_<name>
. Por exemplo, usarname = '%s_bar' % (name)
: - têm visibilidade restrita (
//visibility:private
); - Tenha uma tag
manual
para evitar a expansão em destinos com caracteres curinga (:all
,...
,:*
etc.).
- Ter os nomes com o prefixo
- O
name
só pode ser usado para derivar nomes de destinos definidos pelo e não para mais nada. Por exemplo, não use o nome para obter uma dependência ou arquivo de entrada que não é gerado pela própria macro. - Todos os destinos criados na macro devem ser acoplados de alguma forma ao alvo principal.
- Convencionalmente,
name
precisa ser o primeiro argumento ao definir uma macro. - Mantenha os nomes dos parâmetros na macro consistentes. Se um parâmetro for passado
como um valor de atributo para o destino principal, mantenha seu nome igual. Se uma macro
tem a mesma finalidade de um atributo de regra comum, como
deps
, como seria o atributo (veja abaixo). - Ao chamar uma macro, use apenas argumentos de palavra-chave. Isso é consistente com e melhora muito a legibilidade.
Os engenheiros geralmente escrevem macros quando a API Starlark de regras relevantes é insuficientes para o caso de uso específico, independentemente de a regra ser definidos no Bazel em código nativo ou no Starlark. Se você está enfrentando esse problema problema, pergunte ao autor da regra se ele pode estender a API para realizar seu metas.
Como regra geral, quanto mais macros se assemelham às regras, melhor.
Consulte também macros.
Regras
- Regras, aspectos e seus atributos devem usar nomes em minúsculas ("snake", em inglês) caso).
- Os nomes de regras são substantivos que descrevem o tipo principal de artefato produzido pelo
do ponto de vista das dependências (ou para regras de folha, a
usuário). Não é necessariamente um sufixo de arquivo. Por exemplo, uma regra que
produz artefatos C++ para serem usados, já que extensões Python podem ser chamadas
py_extension
: Para a maioria das linguagens, as regras típicas incluem:*_library
: uma unidade de compilação ou "módulo".*_binary
: um destino que produz um executável ou uma unidade de implantação.*_test
: um destino de teste. Isso pode incluir vários testes. Espere todos em um destino*_test
como variações do mesmo tema, para por exemplo, testar uma única biblioteca.*_import
: um destino que encapsula um artefato pré-compilado, como um.jar
ou uma.dll
usada durante a compilação.
- Use nomes e tipos consistentes para os atributos. Algumas configurações
incluem:
srcs
:label_list
, permitindo arquivos: arquivos de origem, normalmente de autoria humana.deps
:label_list
, normalmente não permite arquivos: compilação dependências.data
:label_list
, permitindo arquivos: arquivos de dados, como dados de teste etc.runtime_deps
:label_list
: dependências de ambiente de execução que não são necessárias. para compilação.
- Para atributos com comportamento não óbvio (por exemplo, modelos de string)
com substituições especiais ou ferramentas que são invocadas com comandos
requisitos), forneça a documentação usando o argumento de palavra-chave
doc
para o declaração do atributo (attr.label_list()
ou similar). - As funções de implementação de regras devem ser quase sempre funções privadas
(nomeado com um sublinhado no início). Um estilo comum é dar
função de implementação de
myrule
com o nome_myrule_impl
. - Transmita informações entre suas regras usando um provider. Declarar e documentar o provedor campos.
- Crie sua regra com a extensibilidade em mente. Considere que outras regras podem interagir com a regra, acessar os provedores e reutilizar os as ações criadas por você.
- Siga as diretrizes de desempenho nas suas regras.