Esta página contém o manual de referência da Linguagem de consulta do Bazel usada.
quando você usa bazel query
para analisar dependências de build. Ela também
descreve os formatos de saída compatíveis com o bazel query
.
Para casos de uso práticos, consulte as Instruções de consulta do Bazel.
Referência de consulta adicional
Além de query
, que é executado no gráfico de destino da fase de pós-carregamento,
O Bazel inclui uma consulta do gráfico de ações e uma consulta configurável.
Consulta do gráfico de ações
A consulta do gráfico de ações (aquery
) opera na configuração de pós-análise
Gráfico de destino e expõe informações sobre Ações, Artefatos e
e as relações entre dados. aquery
é útil quando você está interessado nos
das ações/artefatos gerados pelo gráfico de destino configurado.
Por exemplo, os comandos reais são executados e as entradas, saídas e recursos mnemônicos deles.
Para mais detalhes, consulte a referência do subconsulta.
Consulta configurável
A consulta tradicional do Bazel é executada no gráfico de destino da fase pós-carregamento e
portanto, não tem o conceito de configurações nem os conceitos relacionados. É importante notar que
ele não resolve corretamente instruções SELECT
em vez disso, retorna todas as resoluções possíveis de seleções. No entanto,
ambiente de consulta configurável, cquery
, processa as configurações corretamente, mas
não fornece toda a funcionalidade da consulta original.
Para mais detalhes, consulte a referência do cquery.
Exemplos
Como as pessoas usam o bazel query
? Veja alguns exemplos:
Por que a árvore //foo
depende de //bar/baz
?
Mostrar um caminho:
somepath(foo/..., //bar/baz:all)
Quais bibliotecas C++ fazem todos os testes foo
dependem disso
o destino foo_bin
não tem?
kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo:foo_bin))
Tokens: a sintaxe léxica
As expressões na linguagem de consulta são compostas pelos seguintes elementos: tokens:
Palavras-chave, como
let
. Palavras-chave são as palavras reservadas do e cada uma delas é descrita abaixo. O conjunto completo de palavras-chave é:Palavras, como "
foo/...
" ou ".*test rule
" ou "//bar/baz:all
". Se um a sequência de caracteres está "entre aspas" (começa e termina com aspas simples ' ou começa e termina com aspas duplas "), é uma palavra. Se uma sequência de caracteres não for citado, ele ainda poderá ser analisado como uma palavra. Palavras sem aspas são sequências de caracteres retirados dos caracteres do alfabeto A-Za-z, os numerais de 0 a 9, e os caracteres especiais*/@.-_:$~[]
(asterisco, barra, a, ponto, hífen, sublinhado, dois-pontos, cifrão, til, chave quadrada esquerda, quadrado à direita chave. No entanto, as palavras sem aspas não podem começar com hífen-
ou asterisco*
mesmo que os [nomes de destino][(/concepts/labels#target-names) possam começar com esses caracteres.As palavras sem aspas também não podem incluir os caracteres de adição
+
ou de igual=
, mesmo que esses caracteres sejam permitidos em nomes de alvo. Quando escrever o código que gera expressões de consulta, os nomes dos destinos devem estar entre aspas.É necessário usar aspas para escrever scripts que criam uma consulta do Bazel expressões de valores fornecidos pelo usuário.
//foo:bar+wiz # WRONG: scanned as //foo:bar + wiz. //foo:bar=wiz # WRONG: scanned as //foo:bar = wiz. "//foo:bar+wiz" # OK. "//foo:bar=wiz" # OK.
Esta citação é feita em adição a qualquer outra que possa ser exigida pelo do shell, por exemplo:
bazel query ' "//foo:bar=wiz" ' # single-quotes for shell, double-quotes for Bazel.
Quando citadas, as palavras-chave são tratadas como palavras comuns. Por exemplo,
some
é uma palavra-chave, mas "algumas" é uma palavra.foo
e "foo" são palavras.No entanto, tenha cuidado ao usar aspas simples ou duplas em nomes de destino. Quando citando um ou mais nomes de alvos, use somente um tipo de aspas (todas aspas simples ou todas as duplas).
Confira abaixo exemplos de como será a string de consulta Java:
'a"'a' # WRONG: Error message: unclosed quotation. "a'"a" # WRONG: Error message: unclosed quotation. '"a" + 'a'' # WRONG: Error message: unexpected token 'a' after query expression '"a" + ' "'a' + "a"" # WRONG: Error message: unexpected token 'a' after query expression ''a' + ' "a'a" # OK. 'a"a' # OK. '"a" + "a"' # OK "'a' + 'a'" # OK
Escolhemos essa sintaxe para que aspas não sejam necessárias na maioria dos casos. O (incomum)
".*test rule"
exemplo precisa de aspas: começa com um ponto e contém um espaço. Citar"cc_library"
é desnecessário, mas inofensivo.Pontuação, como parênteses
()
, ponto.
e vírgula,
. Palavras que contenham pontuação (exceto as exceções listadas acima) precisam estar entre aspas.
Os caracteres de espaço em branco fora de uma palavra entre aspas são ignorados.
Conceitos da linguagem de consulta do Bazel
A linguagem de consulta do Bazel é uma linguagem de expressões. Todas é avaliada como um conjunto parcialmente ordenado de destinos. ou equivalente, um gráfico (DAG) de alvos. Esta é a única tipo de dados.
Conjunto e gráfico se referem ao mesmo tipo de dados, mas enfatizam diferentes aspectos dele, por exemplo:
- Definir:a ordem parcial das segmentações não é interessante.
- Gráfico:a ordem parcial das metas é significativa.
Ciclos no gráfico de dependências
Os gráficos de dependência de build precisam ser acíclicos.
Os algoritmos utilizados pela linguagem da consulta são destinados ao uso em gráficos acíclicos, mas que são robustos contra ciclos. Os detalhes de como são tratados não são especificados e não devem ser considerados confiáveis.
Dependências implícitas
Além de criar dependências que são definidas explicitamente em arquivos BUILD
,
O Bazel adiciona outras dependências implícitas às regras. Por exemplo
toda regra Java depende implicitamente do JavaBuilder. Dependências implícitas
são definidas usando atributos que começam com $
e
não pode ser substituído em arquivos BUILD
.
Por padrão, bazel query
considera dependências implícitas em consideração.
ao calcular o resultado da consulta. Esse comportamento pode ser alterado
a opção --[no]implicit_deps
. Como a consulta não considera
possíveis, os conjuntos de ferramentas nunca serão considerados.
Solidez
As expressões da linguagem de consulta do Bazel operam na versão
gráfico de dependências, que é o gráfico definido implicitamente por todos os
declarações de regra em todos os arquivos BUILD
. É importante entender
que o gráfico é um pouco abstrato e não constitui um
descrição completa de como executar todas as etapas de um build. Em
Para executar um build, também é necessária uma configuração.
consulte as configurações
do Guia do Usuário para obter mais detalhes.
O resultado da avaliação de uma expressão na linguagem de consulta do Bazel for verdadeiro para todas as configurações, o que significa que ele pode ser uma superaproximação conservadora, e não é exatamente precisa. Se você usar a ferramenta de consulta para calcular o conjunto de todos os arquivos de origem necessários durante a criação, eles podem relatar mais do que o necessário porque, por exemplo, a ferramenta de consulta incluirá todos os arquivos necessário para oferecer suporte à tradução de mensagens, mesmo que você não pretenda de usar esse recurso no seu build.
Sobre a preservação da ordem do gráfico
As operações preservam qualquer ordem
e restrições herdadas das subexpressões delas. Você pode pensar
isso é chamado de "a lei da conservação da ordem parcial". Considere um
exemplo: se você emitir uma consulta para determinar o fechamento transitivo de
dependências de um destino específico, o conjunto resultante é ordenado
de acordo com o gráfico de dependência. Se você filtrar esse conjunto
incluir apenas os destinos do tipo file
, o mesmo
relação de ordenação parcial transitiva é mantida entre cada
par de destinos no subconjunto resultante, mesmo que nenhum
esses pares estão diretamente conectados no gráfico original.
Não há bordas de arquivo no gráfico de dependência de build.
No entanto, enquanto todos os operadores preservam a ordem, alguns operações, como as operações de conjunto não introduzem restrições de ordenação próprias. Considere esta expressão:
deps(x) union y
A ordem do conjunto de resultados final garante a preservação de todas as
restrições de ordenação das subexpressões, ou seja, que todas as
dependências transitivas de x
sejam ordenadas corretamente com
e se relacionam entre si. No entanto, a consulta não garante nada sobre
a ordem dos destinos em y
, nem sobre os
ordem dos destinos em deps(x)
em relação àqueles em
y
(exceto as segmentações em
y
que também estão em deps(x)
).
Os operadores que introduzem restrições de ordenação incluem:
allpaths
, deps
, rdeps
, somepath
e os caracteres curinga do padrão de destino
package:*
, dir/...
etc.
Consulta Sky
Sky Query é um modo de consulta que opera em um determinado escopo universal.
Funções especiais disponíveis apenas no SkyQuery
O modo Sky Query tem as funções de consulta adicionais allrdeps
e
rbuildfiles
. Essas funções operam em toda
escopo universal (por isso, não fazem sentido em consultas normais).
Como especificar um escopo de universo
O modo Sky Query é ativado passando as duas flags a seguir:
(--universe_scope
ou --infer_universe_scope
) e
--order_output=no
--universe_scope=<target_pattern1>,...,<target_patternN>
instrui a consulta a
pré-carregam o fechamento transitivo do padrão de destino especificado pelos padrões de destino, o que pode
ser tanto aditivo quanto subtrativo. Em seguida, todas as consultas são avaliadas nesse "escopo". Especificamente,
os objetos allrdeps
e
Os operadores rbuildfiles
só retornam resultados desse escopo.
--infer_universe_scope
diz ao Bazel para inferir um valor para --universe_scope
.
da expressão de consulta. Esse valor inferido é a lista de padrões de segmentação exclusivos no
expressão de consulta, mas talvez não seja o ideal para você. Exemplo:
bazel query --infer_universe_scope --order_output=no "allrdeps(//my:target)"
A lista de padrões de destino exclusivos nessa expressão de consulta é ["//my:target"]
. Portanto,
O Bazel trata isso da mesma forma que a invocação:
bazel query --universe_scope=//my:target --order_output=no "allrdeps(//my:target)"
Mas o resultado dessa consulta com --universe_scope
é apenas //my:target
.
nenhuma das dependências inversas de //my:target
está no universo,
construção! Por outro lado, considere:
bazel query --infer_universe_scope --order_output=no "tests(//a/... + b/...) intersect allrdeps(siblings(rbuildfiles(my/starlark/file.bzl)))"
Esta é uma invocação de consulta significativa que está tentando computar os destinos de teste na
tests
(link em inglês) dos destinos em alguns diretórios que
dependem transitivamente de destinos cuja definição usa um determinado arquivo .bzl
. Aqui,
--infer_universe_scope
é uma conveniência, especialmente no caso em que a escolha de
Caso contrário, --universe_scope
exigiria que você analisasse a expressão de consulta por conta própria.
Portanto, para expressões de consulta que usam operadores com escopo universal, como
allrdeps
e
rbuildfiles
use
--infer_universe_scope
somente se o comportamento for o que você quer.
O Sky Query tem algumas vantagens e desvantagens em comparação com a consulta padrão. O principal
A desvantagem é que ela não pode ordenar sua saída de acordo com a ordem do grafo e, assim, certas
formatos de saída são proibidos. As vantagens são que ele fornece
dois operadores (allrdeps
e
rbuildfiles
) que não estão disponíveis na consulta padrão.
Além disso, a Sky Query faz seu trabalho introspectivamente
gráfico Skyframe, em vez de criar um novo
gráfico, que é o que a implementação padrão faz. Portanto, há algumas circunstâncias em que
ele é mais rápido e usa menos memória.
Expressões: sintaxe e semântica da gramática
Essa é a gramática da linguagem de consulta do Bazel, expressa na notação EBNF:
expr ::= word
| let name = expr in expr
| (expr)
| expr intersect expr
| expr ^ expr
| expr union expr
| expr + expr
| expr except expr
| expr - expr
| set(word *)
| word '(' int | word | expr ... ')'
As seções a seguir descrevem cada uma das produções dessa gramática em ordem.
Padrões de destino
expr ::= word
Sintática, um padrão de destino é apenas uma palavra. Ela é interpretada como uma
(não ordenadas) de segmentações. O padrão de destino mais simples é um rótulo,
identifica um único destino (arquivo ou regra). Por exemplo, o padrão de destino
//foo:bar
retorna um conjunto que contém um elemento, o destino, o bar
regra de firewall.
Os padrões de destino generalizam rótulos para incluir caracteres curinga em pacotes e
de destino. Por exemplo, foo/...:all
(ou apenas foo/...
) é um padrão de destino.
que retorna um conjunto contendo todas as rules em cada pacote de forma recursiva
abaixo do diretório foo
. bar/baz:all
é um padrão de destino que avalia
como um conjunto que contém todas as regras no pacote bar/baz
, mas não seu
subpacotes.
Da mesma forma, foo/...:*
é um padrão de destino avaliado como um conjunto que contém
todos os destinos (regras e arquivos) em cada pacote, recursivamente abaixo da
foo
diretório; bar/baz:*
retorna um conjunto que contém todos os destinos em
o pacote bar/baz
, mas não os subpacotes dele.
Como o caractere curinga :*
corresponde a arquivos e regras, muitas vezes é mais
útil que :all
para consultas. Por outro lado, o caractere curinga :all
(implícito em
padrões de destino como foo/...
) costuma ser mais útil para builds.
Os padrões de destino bazel query
funcionam da mesma forma que os destinos de build bazel build
.
Para mais detalhes, consulte Padrões de destino ou
digite bazel help target-syntax
.
Os padrões de destino podem ser avaliados como um conjunto singleton (no caso de um identificador) e
que contém muitos elementos (como no caso de foo/...
, que tem milhares
de elementos) ou para o conjunto vazio, se o padrão de destino não corresponder a nenhum destino.
Todos os nós no resultado de uma expressão de padrão de destino estão ordenados corretamente
estão relacionados entre si de acordo com a relação de dependência. Então, o resultado
foo:*
não é apenas o conjunto de destinos no pacote foo
, é também o
gráfico acima dessas metas. (Nenhuma garantia é feita sobre a ordem relativa
dos nós de resultados em relação a outros nós. Para mais detalhes, consulte a
seção Ordem do gráfico.
Variáveis
expr ::= let name = expr1 in expr2
| $name
A linguagem de consulta do Bazel permite definições e referências a
variáveis. O resultado da avaliação de uma expressão let
é o mesmo que
a de expr2, com todas as ocorrências livres
da variável name substituída pelo valor de
expr1.
Por exemplo, let v = foo/... in allpaths($v, //common) intersect $v
é
equivalente ao allpaths(foo/...,//common) intersect foo/...
.
Uma ocorrência de uma referência de variável name
diferente de
uma expressão let name = ...
delimitada é uma
erro. Em outras palavras, as expressões de consulta de nível superior não podem ter
variáveis.
Nas produções gramaticais acima, name
é como word, mas com a
restrição adicional de que ele é um identificador legal na programação C
idioma de destino. As referências à variável precisam ser precedidas pelo "$" caractere.
Cada expressão let
define apenas uma única variável, mas é possível aninhá-las.
Tanto os padrões de destino quanto as referências de variáveis consistem em um único token, uma palavra, criando uma ambiguidade sintática. No entanto, não há sem ambiguidade semântica, porque o subconjunto de palavras que são variáveis jurídicas nomes são separados do subconjunto de palavras que são padrões de segmentação legal.
Tecnicamente falando, as expressões let
não aumentam
a expressividade da linguagem de consulta: qualquer consulta expressa em
o idioma também pode ser expresso sem elas. No entanto, eles
melhorar a concisão de muitas consultas, e pode resultar em
avaliação eficiente de consultas.
Expressões entre parênteses
expr ::= (expr)
Os parênteses associam subexpressões para forçar uma ordem de avaliação. Uma expressão entre parênteses avalia o valor do seu argumento.
Operações de conjuntos algébricos: interseção, união, diferença definida
expr ::= expr intersect expr
| expr ^ expr
| expr union expr
| expr + expr
| expr except expr
| expr - expr
Esses três operadores calculam as operações normais de set sobre seus argumentos.
Cada operador tem duas formas, uma nominal, como intersect
, e uma
forma simbólica, como ^
. As duas formas são equivalentes; as formas simbólicas
digitar rapidamente. Para fins de esclarecimento, o restante desta página usa as formas nominais.
Por exemplo,
foo/... except foo/bar/...
avalia o conjunto de destinos que correspondem a foo/...
, mas não a foo/bar/...
.
Você pode escrever a mesma consulta como:
foo/... - foo/bar/...
As operações intersect
(^
) e union
(+
) são comutativas (simétricas).
except
(-
) é assimétrico. O analisador trata os três operadores como
associativa à esquerda e de mesma precedência, então use parênteses. Para
exemplo, as duas primeiras expressões são equivalentes, mas a terceira não é:
x intersect y union z
(x intersect y) union z
x intersect (y union z)
Ler destinos de uma fonte externa: definir
expr ::= set(word *)
O set(a b c ...)
operador calcula a união de um conjunto de zero ou mais
padrões de segmentação, separados por espaços em branco (sem vírgulas).
Em conjunto com o recurso $(...)
do shell Bourne, o set()
fornece uma
significa salvar os resultados de uma consulta em um arquivo de texto normal, manipular
esse arquivo de texto usando outros programas (como ferramentas de shell padrão do UNIX) e, em seguida,
introduzir o resultado de volta na ferramenta de consulta como um valor para
processamento. Exemplo:
bazel query deps(//my:target) --output=label | grep ... | sed ... | awk ... > foo
bazel query "kind(cc_binary, set($(<foo)))"
No próximo exemplo,kind(cc_library, deps(//some_dir/foo:main, 5))
é
calculado filtrando os valores de maxrank
usando um programa awk
.
bazel query 'deps(//some_dir/foo:main)' --output maxrank | awk '($1 < 5) { print $2;} ' > foo
bazel query "kind(cc_library, set($(<foo)))"
Nesses exemplos, $(<foo)
é uma abreviação de $(cat foo)
, mas o shell
comandos diferentes de cat
também podem ser usados, como o comando awk
anterior.
Funções
expr ::= word '(' int | word | expr ... ')'
A linguagem de consulta define várias funções. O nome da função determina o número e o tipo de argumentos necessários. O seguinte estão disponíveis:
allpaths
attr
buildfiles
rbuildfiles
deps
filter
kind
labels
loadfiles
rdeps
allrdeps
same_pkg_direct_rdeps
siblings
some
somepath
tests
visible
Fechamento transitivo de dependências: dependências
expr ::= deps(expr)
| deps(expr, depth)
O operador deps(x)
avalia o gráfico formado
pelo fechamento transitivo de dependências do conjunto de argumentos
x. Por exemplo, o valor de deps(//foo)
é
gráfico de dependência com raízes no nó único foo
, incluindo todos os seus
dependências. O valor de deps(foo/...)
são os gráficos de dependência cujas raízes
são regras em todos os pacotes abaixo do diretório foo
. Nesse contexto,
"dependências" significa apenas regras e destinos de arquivo, portanto, os BUILD
e
Os arquivos do Starlark necessários para criar esses destinos não estão incluídos aqui. Para isso
use o operador buildfiles
.
O gráfico resultante é ordenado de acordo com a relação de dependência. Para mais detalhes, consulte a seção sobre ordem do gráfico.
O operador deps
aceita um segundo argumento opcional, que é um número inteiro.
que especifica um limite superior na profundidade da pesquisa. Então,
deps(foo:*, 0)
retorna todos os destinos no pacote foo
, enquanto
deps(foo:*, 1)
inclui ainda mais os pré-requisitos diretos de qualquer destino no
pacote foo
, e deps(foo:*, 2)
inclui ainda mais os nós diretamente
acessíveis pelos nós em deps(foo:*, 1)
e assim por diante. (Esses números
correspondem às classificações mostradas no formato de saída minrank
.
Se o parâmetro depth for omitido, a pesquisa será
ilimitada: calcula o fechamento transitivo reflexivo de pré-requisitos.
Fechamento transitivo de dependências reversas: rdeps
expr ::= rdeps(expr, expr)
| rdeps(expr, expr, depth)
O rdeps(u, x)
operador avalia as dependências inversas do argumento set
x no fechamento transitivo do universo
u
O gráfico resultante é ordenado de acordo com a relação de dependência. Consulte a sobre ordem do gráfico para mais detalhes.
O operador rdeps
aceita um terceiro argumento opcional, que é um número inteiro.
que especifica um limite superior na profundidade da pesquisa. O resultado
gráfico inclui apenas nós a uma distância da profundidade especificada de qualquer
no argumento definido. Portanto, rdeps(//foo, //common, 1)
é avaliada para todos os nós.
no fechamento transitivo de //foo
que dependem diretamente de //common
. (Esses
os números correspondem às classificações mostradas na saída de minrank
format.) Se o parâmetro depth for omitido, a
a pesquisa é ilimitada.
Fechamento transitivo de todas as dependências reversas: allrdeps
expr ::= allrdeps(expr)
| allrdeps(expr, depth)
O operador allrdeps
se comporta da mesma forma que o rdeps
.
operador, exceto que "universe set" seja qual for a sinalização --universe_scope
são avaliados, em vez de serem especificados separadamente. Assim, se
--universe_scope=//foo/...
foi transmitido, depois allrdeps(//bar)
é
equivalente a rdeps(//foo/..., //bar)
.
Dependências reversas diretas no mesmo pacote: same_pkg_direct_rdeps
expr ::= same_pkg_direct_rdeps(expr)
O operador same_pkg_direct_rdeps(x)
avalia o conjunto completo de destinos.
que estejam no mesmo pacote que um alvo no conjunto de argumentos e que dependam diretamente dele.
Como lidar com o pacote de um destino: irmãos
expr ::= siblings(expr)
O operador siblings(x)
avalia o conjunto completo de destinos que estão em
mesmo pacote que um destino no argumento definido.
Escolha arbitrária: algumas
expr ::= some(expr)
| some(expr, count )
O operador some(x, k)
seleciona no máximo k destinos arbitrariamente de seu
definido como x e é avaliado como um conjunto contendo
apenas essas metas. O parâmetro k é opcional. se
ausente, o resultado será um conjunto Singleton contendo apenas um destino
selecionados arbitrariamente. Se o tamanho do conjunto de argumentos x for
menor que k, todo o conjunto de argumentos
x será retornado.
Por exemplo, a expressão some(//foo:main union //bar:baz)
é avaliada como uma
um conjunto Singleton que contém //foo:main
ou //bar:baz
, embora qual
se um deles não estiver definido. A expressão some(//foo:main union //bar:baz, 2)
ou
some(//foo:main union //bar:baz, 3)
retorna //foo:main
e
//bar:baz
.
Se o argumento for um Singleton, então some
calcula a função de identidade: some(//foo:main)
é
equivalente a //foo:main
.
Será um erro se o conjunto de argumentos especificado estiver vazio, como no
expressão some(//foo:main intersect //bar:baz)
.
Operadores de caminho: somepath, allpaths
expr ::= somepath(expr, expr)
| allpaths(expr, expr)
Os métodos somepath(S, E)
e
Operadores allpaths(S, E)
computam
entre dois conjuntos de destinos. Ambas as consultas aceitam duas
argumentos, um conjunto S de pontos de partida e um conjunto
E de pontos finais. somepath
retorna o
gráfico de nós em algum caminho arbitrário de um destino na
S para uma meta em E allpaths
retorna o gráfico de nós em todos os caminhos de qualquer destino no
S para qualquer destino em E.
Os gráficos resultantes são ordenados de acordo com a relação de dependência. Consulte a seção sobre ordem do gráfico para mais detalhes.
somepath(S1 + S2, E) , um resultado possível. |
somepath(S1 + S2, E) , outro resultado possível. |
allpaths(S1 + S2, E) |
Filtragem de tipo de destino: tipo
expr ::= kind(word, expr)
O kind(pattern, input)
aplica um filtro a um conjunto de destinos e os descarta.
que não são do tipo esperado. O pattern
especifica o tipo de destino a ser correspondido.
Por exemplo, os tipos dos quatro destinos definidos pelo arquivo BUILD
.
(para o pacote p
) mostradas abaixo estão ilustradas na tabela:
Código | Destino | Tipo |
---|---|---|
genrule( name = "a", srcs = ["a.in"], outs = ["a.out"], cmd = "...", ) |
//p:a |
regra geral |
//p:a.in |
arquivo de origem | |
//p:a.out |
arquivo gerado | |
//p:BUILD |
arquivo de origem |
Assim, kind("cc_.* rule", foo/...)
avalia para o conjunto
de todos os cc_library
, cc_binary
etc,
segmentações por regra abaixo de foo
e kind("source file", deps(//foo))
avalia o conjunto de todos os arquivos de origem no fechamento transitivo
de dependências do destino //foo
.
Muitas vezes, é necessário usar uma aspa do argumento pattern
porque, sem ele, muitas expressões regulares, como source
file
e .*_test
, não são consideradas palavras pelo analisador.
Ao fazer a correspondência para package group
, as segmentações que terminam em
É possível que :all
não tenha resultados. Em vez disso, use :all-targets
.
Filtragem de nome de destino: filtro
expr ::= filter(word, expr)
O filter(pattern, input)
aplica um filtro a um conjunto de destinos e descarta destinos cujos
rótulos (em forma absoluta) não correspondem ao padrão;
avalia para um subconjunto da entrada.
O primeiro argumento, pattern, é uma palavra que contém
expressão regular sobre nomes de destino. Uma expressão filter
avalia para o conjunto que contém todos os destinos x, de modo que
x é um membro do conjunto input, e o
rótulo (em forma absoluta, como //foo:bar
)
de x contém uma correspondência (não ancorada)
para a expressão regular pattern. Como todos os
nomes de destino começam com //
, ele pode ser usado como
à âncora de expressão regular ^
.
Em geral, esse operador oferece uma alternativa muito mais rápida e robusta
Operador intersect
. Por exemplo, para ver todas
bar
dependências do destino //foo:foo
, é possível
avaliar
deps(//foo) intersect //bar/...
Essa instrução, no entanto, exigirá a análise de todos os arquivos BUILD
na
bar
, que será lenta e propensa a erros em
arquivos BUILD
irrelevantes. Uma alternativa seria:
filter(//bar, deps(//foo))
que primeiro calcularia o conjunto de dependências de //foo
e
filtraria apenas os destinos que correspondem ao padrão fornecido. Em outras
palavras, destinos com nomes que contêm //bar
como uma substring.
Outro uso comum do operador filter(pattern,
expr)
é filtrar arquivos específicos pelo
nome de usuário ou extensão. Por exemplo,
filter("\.cc$", deps(//foo))
fornecerá uma lista de todos os arquivos .cc
usados para criar o //foo
.
Filtragem de atributos de regra: attr
expr ::= attr(word, word, expr)
O
attr(name, pattern, input)
aplica um filtro a um conjunto de destinos e descarta aqueles que não estão
regras, regras de destino que não têm o atributo name
definido ou por regras em que o valor do atributo não corresponde ao
expressão regular pattern; ele avalia
a um subconjunto da entrada.
O primeiro argumento, name, é o nome da regra
que deve corresponder ao atributo
padrão de expressão regular. O segundo argumento,
pattern é uma expressão regular sobre o atributo.
valores. Uma expressão attr
é avaliada para o conjunto que contém todos os destinos
x, de forma que x seja um
membro do conjunto input, é uma regra com o valor
atributo name, e o valor do atributo contiver um
(não ancorada) para a expressão regular
pattern. Se name for um
atributo opcional e regra não o especifica explicitamente, então o padrão
será usado para comparação. Por exemplo,
attr(linkshared, 0, deps(//foo))
vai selecionar todas as //foo
dependências que têm permissão para
atributo linkshared (como a regra cc_binary
) e definir
explicitamente definido como 0 ou não o defina, mas o valor padrão é 0 (como no
cc_binary
).
Os atributos do tipo lista (como srcs
, data
etc.) têm
convertida em strings no formato [value<sub>1</sub>, ..., value<sub>n</sub>]
,
começando com um colchete [
, terminando com um colchete ]
e usando ",
" (vírgula, espaço) para delimitar diversos valores.
Os rótulos são convertidos em strings usando a forma absoluta da
rótulo. Por exemplo, um atributo deps=[":foo",
"//otherpkg:bar", "wiz"]
seria convertido no
string [//thispkg:foo, //otherpkg:bar, //thispkg:wiz]
.
Os colchetes estão sempre presentes, então a lista vazia usaria o valor de string []
para fins de correspondência. Por exemplo,
attr("srcs", "\[\]", deps(//foo))
selecionará todas as regras entre as dependências de //foo
que tenham um
atributo srcs
vazio, enquanto
attr("data", ".{3,}", deps(//foo))
selecionará todas as regras entre as dependências de //foo
que especificarem
pelo menos um valor no atributo data
(cada rótulo tem pelo menos
3 caracteres devido a //
e :
).
Para selecionar todas as regras entre dependências de //foo
com um value
específico em um
atributo de tipo de lista, use
attr("tags", "[\[ ]value[,\]]", deps(//foo))
Isso funciona porque o caractere antes de value
será [
ou um espaço, e o
após value
será uma vírgula ou ]
.
Filtragem de visibilidade da regra: visível
expr ::= visible(expr, expr)
O operador visible(predicate, input)
aplica um filtro a um conjunto de destinos e descarta os destinos sem o
visibilidade necessária.
O primeiro argumento, predicate, é um conjunto de destinos que todos na saída precisam ser visíveis. Uma expressão visible avalia para o conjunto que contém todos os destinos x, de modo que x é um membro do conjunto input e, para todos os destinos y em predicate x está visível para y. Exemplo:
visible(//foo, //bar:*)
vai selecionar todos os destinos no pacote //bar
que //foo
podem depender sem violar as restrições de visibilidade.
Avaliação de atributos de regra do rótulo de tipo: rótulos
expr ::= labels(word, expr)
O labels(attr_name, inputs)
operador retorna o conjunto de destinos especificados no
atributo attr_name do tipo "label" ou "lista de marcadores" no
alguma regra no conjunto inputs.
Por exemplo, labels(srcs, //foo)
retorna o conjunto de
destinos que aparecem no atributo srcs
do
a regra //foo
. Se houver várias regras
com os atributos srcs
no conjunto inputs, o
a união da srcs
é retornada.
Expandir e filtrar test_suites: testes
expr ::= tests(expr)
O operador tests(x)
retorna o conjunto de todos os valores
regras no conjunto x, expandindo regras test_suite
para
conjunto de testes individuais aos quais eles se referem e aplicando a filtragem
tag
e size
.
Por padrão, a avaliação de consultas
ignora todos os destinos que não sejam de teste em todas as regras test_suite
. Isso pode ser
mudou para erros com a opção --strict_test_suite
.
Por exemplo, a consulta kind(test, foo:*)
lista todos
as regras *_test
e test_suite
no pacote foo
. Todos os resultados (por
definição) do pacote foo
. Por outro lado,
a consulta tests(foo:*)
retornará todos os
Testes individuais que vão ser executados por bazel test
foo:*
: isso pode incluir testes que pertencem a outros pacotes,
referenciados direta ou indiretamente
usando regras test_suite
.
Arquivos de definição de pacote: buildfiles
expr ::= buildfiles(expr)
O operador buildfiles(x)
retorna o conjunto
de arquivos que definem os pacotes de cada destino no
definir x; Em outras palavras, para cada pacote, o arquivo BUILD
correspondente,
além de todos os arquivos .bzl aos quais ela faz referência via load
. Observe que este
também retorna os arquivos BUILD
dos pacotes que contêm essas
load
.
Esse operador normalmente é usado para determinar quais arquivos ou
pacotes são necessários para construir um alvo especificado, muitas vezes em conjunto com
a opção --output package
abaixo). Por exemplo,
bazel query 'buildfiles(deps(//foo))' --output package
retorna o conjunto de todos os pacotes dos quais //foo
depende transitivamente.
Arquivos de definição de pacote: rbuildfiles
expr ::= rbuildfiles(word, ...)
O operador rbuildfiles
usa uma lista separada por vírgulas de fragmentos de caminho e retorna.
o conjunto de arquivos BUILD
que dependem transitivamente desses fragmentos de caminho. Por exemplo, se
//foo
é um pacote, então rbuildfiles(foo/BUILD)
retornará o
Meta de //foo:BUILD
. Se o arquivo foo/BUILD
tiver
load('//bar:file.bzl'...
nela, então rbuildfiles(bar/file.bzl)
vai
retornar o destino //foo:BUILD
, bem como os destinos de qualquer outro arquivo BUILD
que
carregar //bar:file.bzl
O escopo do operador --universe_scope
. Arquivos que não correspondem diretamente a arquivos BUILD
e .bzl
não afetam os resultados. Por exemplo, os arquivos de origem (como foo.cc
) são ignorados,
mesmo que elas sejam explicitamente mencionadas no arquivo BUILD
. Os links simbólicos, no entanto, são respeitados, para que
se foo/BUILD
for um link simbólico para bar/BUILD
,
rbuildfiles(bar/BUILD)
vai incluir //foo:BUILD
nos resultados.
O operador rbuildfiles
é quase moralmente o inverso do
Operador buildfiles
. No entanto, essa inversão moral
tem mais fortemente em uma direção: as saídas de rbuildfiles
são exatamente
entradas de buildfiles
o primeiro terá apenas BUILD
destinos de arquivo em pacotes,
e o último pode conter esses destinos. Na outra direção, a correspondência é mais fraca. O
As saídas do operador buildfiles
são destinos correspondentes a todos os pacotes e .bzl
necessários para uma determinada entrada. No entanto, as entradas do operador rbuildfiles
são
não esses destinos, mas sim os fragmentos de caminho que correspondem a esses destinos.
Arquivos de definição de pacote: loadfiles
expr ::= loadfiles(expr)
O operador loadfiles(x)
retorna o conjunto de
Arquivos do Starlark necessários para carregar os pacotes de cada destino no
defina x. Em outras palavras, para cada pacote, ele retorna o
Arquivos .bzl referenciados nos arquivos BUILD
.
Formatos de saída
bazel query
gera um gráfico.
Você especifica o conteúdo, o formato e a ordem pelos quais
bazel query
apresenta este gráfico
usando a opção de linha de comando --output
.
Ao executar com Sky Query, somente formatos de saída compatíveis com
desordenadas são permitidas. Especificamente, graph
, minrank
e
maxrank
formatos de saída são proibidos.
Alguns dos formatos de saída aceitam opções adicionais. O nome
cada opção de saída tem como prefixo o formato de saída
então --graph:factored
se aplica somente
quando --output=graph
estiver sendo usado; não terá efeito se
é usado um formato de saída diferente de graph
. Da mesma forma,
--xml:line_numbers
só é válido quando --output=xml
está sendo usado.
Na ordem dos resultados
Embora as expressões de consulta sempre sigam a "lei da
conservação da ordem do gráfico", apresentar os resultados pode ser feito
de maneira desordenada ou desordenada. Isso não
influenciam os objetivos no conjunto de resultados ou como a consulta é calculada. Ele só
afeta como os resultados são impressos em stdout. Além disso, os nós
equivalentes na ordem das dependências podem ou não estar em ordem alfabética.
A flag --order_output
pode ser usada para controlar esse comportamento.
A flag --[no]order_results
tem um subconjunto da funcionalidade
da sinalização --order_output
e foi descontinuada.
O valor padrão desta sinalização é auto
, que imprime resultados lexicográficos
ordem. No entanto, quando somepath(a,b)
é usado, os resultados são mostrados
deps
pedido.
Quando essa flag é no
e --output
é uma das
build
, label
, label_kind
, location
, package
, proto
ou
xml
, as saídas serão impressas em ordem arbitrária. Isto é
geralmente a opção mais rápida. No entanto, não há suporte quando
--output
é graph
, minrank
ou
maxrank
: com esses formatos, o Bazel sempre imprime os resultados.
ordenadas pela ordem de dependência ou classificação.
Quando essa flag é deps
, o Bazel imprime os resultados em alguma ordem topológica, ou seja,
dependências primeiro. No entanto, os nós que não estão ordenados pela ordem das dependências
(porque não há caminho de um para o outro) pode ser impresso em qualquer ordem.
Quando essa flag é full
, o Bazel imprime os nós em uma ordem (total) totalmente determinista.
Primeiro, todos os nós são classificados em ordem alfabética. Em seguida, cada nó da lista é usado como o início
pesquisa em profundidade pós-pedido, em que as arestas de saída para nós não visitados são atravessadas
ordem alfabética dos nós sucessores. Finalmente, os nós são impressos na ordem inversa
em que foram visitados.
A impressão de nós nessa ordem pode ser mais lenta, por isso use-a somente quando o determinismo é muito importante.
Mostre o formulário de origem dos destinos como eles apareceriam em BUILD
--output build
Com essa opção, a representação de cada destino é como se fosse
escritos à mão na linguagem BUILD. Todas as variáveis e chamadas de função
(como glob, macros) são expandidos, o que é útil para ver o efeito
de macros Starlark. Além disso, cada regra em vigor informa uma
generator_name
e/ou generator_function
).
fornecendo o nome da macro que foi avaliada para produzir a regra efetiva.
Embora a saída use a mesma sintaxe dos arquivos BUILD
, ela não é
com a garantia de produzir um arquivo BUILD
válido.
Imprimir a etiqueta de cada destino
--output label
Com essa opção, o conjunto de nomes (ou rótulos) de cada destino
no gráfico resultante é impresso, um rótulo por linha,
ordem topológica (a menos que --noorder_results
seja especificado, consulte
observações sobre a ordem dos resultados).
(Uma ordem topológica é aquela em que um gráfico
aparece antes de todos os sucessores. Claro que há
existem muitas ordens topológicas possíveis de um gráfico (reverso
postorder é apenas um); qual foi escolhido, não é especificado.
Ao exibir a saída de uma consulta somepath
, a ordem
na qual os nós são impressos é a ordem do caminho.
Advertência: em alguns casos específicos, pode haver dois alvos distintos com
o mesmo rótulo; por exemplo, uma regra sh_binary
e
o arquivo srcs
único (implícito) podem ser chamados
foo.sh
Se o resultado de uma consulta contiver
esses destinos, a saída (no formato label
) será exibida.
para conter uma cópia. Ao usar o label_kind
(consulte
abaixo), a distinção fica clara: os dois objetivos têm
o mesmo nome, mas uma delas tem o tipo sh_binary rule
, e o
outro tipo source file
.
Imprima o rótulo e o tipo de cada destino
--output label_kind
Como label
, esse formato de saída imprime os rótulos de
cada destino no gráfico resultante, em ordem topológica, mas isso
também precede o rótulo pelo tipo do destino.
Imprimir o rótulo de cada destino, em ordem de classificação
--output minrank --output maxrank
Assim como a label
, a minrank
e maxrank
exibem os rótulos de cada
de destino no gráfico resultante, mas em vez de aparecer
topológica, eles aparecem em ordem de classificação, precedidos por seus
o número da classificação. Eles não são afetados pela ordem dos resultados
Sinalização --[no]order_results
(consulte as observações sobre
a ordem dos resultados).
Há duas variantes desse formato: classificações minrank
cada nó pelo tamanho do caminho mais curto de um nó raiz até ele.
"Raiz" nós (que não têm arestas de entrada) têm classificação 0,
seus sucessores são de classificação 1 etc. (Como sempre, as arestas apontam de um
aos pré-requisitos: os destinos dos quais ele depende.
maxrank
classifica cada nó pelo comprimento do maior
caminho de um nó raiz até ela. Mais uma vez, "raízes" têm classificação 0, todas as outras
nós têm uma classificação maior do que a classificação máxima de todos
seus antecessores.
Todos os nós em um ciclo são considerados com a mesma classificação. (A maioria dos gráficos é
acíclico, mas ciclos existem
simplesmente porque os arquivos BUILD
contêm ciclos incorretos.)
Esses formatos de saída são úteis para descobrir a profundidade de um gráfico.
Se usado para o resultado de um deps(x)
, rdeps(x)
,
ou allpaths
, o número da classificação será igual ao
comprimento do mais curto (com minrank
) ou mais longo
(com maxrank
) de x
para um nó em
nessa classificação. maxrank
pode ser usada para determinar
sequência mais longa de etapas de build necessária para criar um destino.
Por exemplo, o gráfico à esquerda gera as saídas à direita
quando --output minrank
e --output maxrank
forem especificados, respectivamente.
minrank 0 //c:c 1 //b:b 1 //a:a 2 //b:b.cc 2 //a:a.cc |
maxrank 0 //c:c 1 //b:b 2 //a:a 2 //b:b.cc 3 //a:a.cc |
Imprimir o local de cada destino
--output location
Como em label_kind
, essa opção mostra, para cada
destino no resultado, o tipo e rótulo do destino, mas não
tem como prefixo uma string que descreve a localização desse alvo, como
nome do arquivo e número da linha. O formato é semelhante à saída
grep
: Assim, as ferramentas que podem analisar essa última (como o Emacs)
ou vi) também podem usar a saída da consulta para percorrer uma série de
permitindo que a ferramenta de consulta do Bazel seja usada como
"grep para arquivos BUILD" com reconhecimento de gráfico de dependência.
As informações de localização variam de acordo com o tipo de segmentação (consulte o operador kind). Para as regras, a
o local da declaração da regra no arquivo BUILD
é mostrado.
Para arquivos de origem, a localização da linha 1 do arquivo real é
impresso. Para um arquivo gerado, o local da regra que
gera, é impresso. A ferramenta de consulta não tem informações
informações para encontrar a localização real do arquivo gerado; e
de qualquer forma, ele pode não existir se um build ainda não tiver sido executado.)
Imprimir o conjunto de pacotes
--output package
Essa opção imprime o nome de todos os pacotes aos quais ou destino no conjunto de resultados pertence. Os nomes são impressos ordem lexicográfica as duplicatas são excluídas. Formalmente, isso é uma projeção do conjunto de rótulos (pacote, destino) para pacotes.
Os pacotes em repositórios externos são formatados como
@repo//foo/bar
enquanto os pacotes no repositório principal estão
formatado como foo/bar
.
Em conjunto com a consulta deps(...)
, esta saída
pode ser usada para encontrar o conjunto de pacotes que deve ser verificado
para criar um determinado conjunto de destinos.
Exibir um gráfico do resultado
--output graph
Esta opção faz com que o resultado da consulta seja impresso como uma chamada
gráfico no conhecido formato GraphViz da AT&T. Normalmente, o
resultado é salvo em um arquivo, como .png
ou .svg
.
Se o programa dot
não estiver instalado na estação de trabalho,
pode instalá-lo usando o comando sudo apt-get install graphviz
.
Consulte a seção de exemplo abaixo para conferir um exemplo de invocação.
Esse formato de saída é útil principalmente para allpaths
,
deps
ou rdeps
, em que o resultado
inclui um conjunto de caminhos que não podem ser visualizados facilmente quando
renderizados de forma linear, como com --output label
.
Por padrão, o gráfico é renderizado em uma forma fatoração. Ou seja,
nós topologicamente equivalentes são mesclados em um único
nó com vários rótulos. Isso torna o gráfico mais compacto
e legível, porque os gráficos de resultados típicos contêm
e repetitivos. Por exemplo, uma regra java_library
pode depender de centenas de arquivos de origem Java, todos gerados pelo
mesmo genrule
; no gráfico fatorado, todos esses arquivos
são representados por um único nó. Esse comportamento pode ser desativado
com a opção --nograph:factored
.
--graph:node_limit n
A opção especifica o comprimento máximo da string de rótulo para um
nó de gráfico na saída. Rótulos mais longos serão truncados. -1
desativa o truncamento. Devido à forma fatorada em que os gráficos são
geralmente impressos, os rótulos do nó podem ser muito longos. O GraphViz não consegue
identificadores com mais de 1.024 caracteres, que é o valor padrão
dessa opção. Essa opção não tem efeito, a menos que
--output=graph
está sendo usado.
--[no]graph:factored
Por padrão, os gráficos são exibidos na forma fatorada, conforme explicado
acima.
Quando --nograph:factored
é especificado, os gráficos são
impressos sem fatoração. Isso facilita a visualização com o GraphViz
impraticável, mas o formato mais simples pode facilitar o processamento de outros
(como grep). Essa opção não tem efeito
a menos que --output=graph
esteja sendo usado.
XML
--output xml
Essa opção faz com que os destinos resultantes sejam impressos em um XML forma A saída começa com um cabeçalho XML como este
<?xml version="1.0" encoding="UTF-8"?>
<query version="2">
e continua com um elemento XML para cada segmento no gráfico do resultado, em ordem topológica (a menos que resultados não ordenados são solicitados), e, em seguida, termina com uma
</query>
Entradas simples são emitidas para destinos do tipo file
:
<source-file name='//foo:foo_main.cc' .../>
<generated-file name='//foo:libfoo.so' .../>
Mas, para as regras, o XML é estruturado e contém definições de todos
os atributos da regra, incluindo aqueles cujo valor não foi
explicitamente especificado no arquivo BUILD
da regra.
Além disso, o resultado inclui rule-input
e
elementos rule-output
para que a topologia da
o gráfico de dependência pode ser reconstruído sem precisar saber isso,
Por exemplo, os elementos do atributo srcs
são
as dependências (pré-requisitos) e o conteúdo da
outs
são dependências de versões anteriores (consumidores).
Os elementos rule-input
para dependências implícitas serão suprimidos se
--noimplicit_deps
é especificado.
<rule class='cc_binary rule' name='//foo:foo' ...>
<list name='srcs'>
<label value='//foo:foo_main.cc'/>
<label value='//foo:bar.cc'/>
...
</list>
<list name='deps'>
<label value='//common:common'/>
<label value='//collections:collections'/>
...
</list>
<list name='data'>
...
</list>
<int name='linkstatic' value='0'/>
<int name='linkshared' value='0'/>
<list name='licenses'/>
<list name='distribs'>
<distribution value="INTERNAL" />
</list>
<rule-input name="//common:common" />
<rule-input name="//collections:collections" />
<rule-input name="//foo:foo_main.cc" />
<rule-input name="//foo:bar.cc" />
...
</rule>
Todo elemento XML de um destino contém um name
.
atributo, cujo valor é o rótulo do destino, e
um atributo location
, cujo valor é o atributo
local conforme impresso pela --output location
.
--[no]xml:line_numbers
Por padrão, os locais exibidos na saída XML contêm números de linha.
Quando --noxml:line_numbers
é especificado, os números de linha não são impressos.
--[no]xml:default_values
Por padrão, a saída XML não inclui um atributo de regra cujo valor
é o valor padrão desse tipo de atributo (por exemplo, se
não foram especificados no arquivo BUILD
, ou o valor padrão era
fornecidas explicitamente). Essa opção faz com que esses valores de atributo
ser incluído na saída XML.
Expressões regulares
Expressões regulares na linguagem de consulta usam a biblioteca regex Java, para que você possa usar a
sintaxe completa para
java.util.regex.Pattern
Como consultar repositórios externos
Se o build depender de regras de repositórios externos (definidos no
WORKSPACE), os resultados da consulta incluirão essas dependências. Para
exemplo, se //foo:bar
depender de //external:some-lib
e //external:some-lib
estiver vinculado a @other-repo//baz:lib
, então
bazel query 'deps(//foo:bar)'
listará @other-repo//baz:lib
e
//external:some-lib
como dependências.
Os repositórios externos em si não são dependências de um build. Ou seja, em
no exemplo acima, //external:other-repo
não é uma dependência. Ela
pode ser consultado como membro do pacote //external
.
Por exemplo:
# Querying over all members of //external returns the repository.
bazel query 'kind(http_archive, //external:*)'
//external:other-repo
# ...but the repository is not a dependency.
bazel query 'kind(http_archive, deps(//foo:bar))'
INFO: Empty results