Nesta página, você verá como começar a usar a linguagem de consulta do Bazel para rastrear dependências no seu código.
Para detalhes de uma linguagem e da sinalização --output
, consulte os manuais de referência, Referência de consulta do Bazel e Referência de consulta do Bazel. Para receber ajuda,
digite bazel help query
ou bazel help cquery
na
linha de comando.
Para executar uma consulta e ignorar erros, como destinos ausentes, use a
sinalização --keep_going
.
Como encontrar as dependências de uma regra
Para ver as dependências de //foo
, use a
função deps
na consulta do bazel:
$ bazel query "deps(//foo)" //foo:foo //foo:foo-dep ...
Este é o conjunto de todos os destinos necessários para criar //foo
.
Como rastrear a cadeia de dependências entre dois pacotes
A biblioteca //third_party/zlib:zlibonly
não está no arquivo BUILD para //foo
, mas é uma dependência indireta. Como podemos
rastrear esse caminho de dependência? Há duas funções úteis aqui:
allpaths
e somepath
. Também é possível excluir
as dependências de ferramentas com --notool_deps
se você se preocupa apenas com
o que está incluído no artefato criado, e não com todos os jobs possíveis.
Para visualizar o gráfico de todas as dependências, canalize a saída da consulta do bazel por meio da ferramenta de linha de comando dot
:
$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg
Quando um gráfico de dependência é grande e complicado, pode ser útil começar com um único caminho:
$ bazel query "somepath(//foo:foo, third_party/zlib:zlibonly)" //foo:foo //translations/tools:translator //translations/base:base //third_party/py/MySQL:MySQL //third_party/py/MySQL:_MySQL.so //third_party/mysql:mysql //third_party/zlib:zlibonly
Se você não especificar --output graph
com allpaths
,
você verá uma lista nivelada do gráfico de dependências.
$ bazel query "allpaths(//foo, third_party/...)" ...many errors detected in BUILD files... //foo:foo //translations/tools:translator //translations/tools:aggregator //translations/base:base //tools/pkg:pex //tools/pkg:pex_phase_one //tools/pkg:pex_lib //third_party/python:python_lib //translations/tools:messages //third_party/py/xml:xml //third_party/py/xml:utils/boolean.so //third_party/py/xml:parsers/sgmlop.so //third_party/py/xml:parsers/pyexpat.so //third_party/py/MySQL:MySQL //third_party/py/MySQL:_MySQL.so //third_party/mysql:mysql //third_party/openssl:openssl //third_party/zlib:zlibonly //third_party/zlib:zlibonly_v1_2_3 //third_party/python:headers //third_party/openssl:crypto
À parte: dependências implícitas
O arquivo BUILD para //foo
nunca faz referência a
//translations/tools:aggregator
. Mas qual é a dependência direta?
Algumas regras incluem dependências implícitas em outras bibliotecas ou ferramentas.
Por exemplo, para criar uma regra genproto
, primeiro você precisa criar o compilador de protocolo. Portanto, cada regra genproto
carrega uma dependência implícita no compilador de protocolo. Essas dependências não são mencionadas no arquivo de build,
mas são adicionadas pela ferramenta de build. No momento, o conjunto completo de dependências implícitas está
sem documentação. O uso de --noimplicit_deps
permite filtrar
essas dependências dos resultados da consulta. Para o cquery, isso inclui os conjuntos de ferramentas resolvidos.
Reverter dependências
É recomendável saber o conjunto de destinos que depende de algum destino. Por exemplo,
se você precisa mudar algum código, pode querer saber qual outro
código está prestes a violar. É possível usar rdeps(u, x)
para encontrar as dependências
reversas dos destinos em x
dentro do fechamento transitivo de u
.
A Consulta do céu do Bazel é compatível com a função allrdeps
, que permite consultar dependências inversas em um universo especificado.
Usos diversos
Você pode usar o bazel query
para analisar muitas relações de dependência.
O que existe ...
Quais pacotes estão abaixo de foo
?
bazel query 'foo/...' --output package
Quais regras são definidas no pacote foo
?
bazel query 'kind(rule, foo:*)' --output label_kind
Quais arquivos são gerados pelas regras no pacote foo
?
bazel query 'kind("generated file", //foo:*)'
Quais destinos são gerados pela macro Starlark foo
?
bazel query 'attr(generator_function, foo, //path/to/search/...)'
Qual é o conjunto de arquivos BUILD necessário para criar //foo
?
bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:
Para quais testes cada test_suite
se expande?
bazel query 'tests(//foo:smoke_tests)'
Quais destes são testes em C++?
bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'
Quais destas opções são pequenas? Médio? Grande?
bazel query 'attr(size, small, tests(//foo:smoke_tests))' bazel query 'attr(size, medium, tests(//foo:smoke_tests))' bazel query 'attr(size, large, tests(//foo:smoke_tests))'
Quais são os testes abaixo de foo
que correspondem a um padrão?
bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'
O padrão é um regex e é aplicado ao nome completo da regra. É como fazer
bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'
Qual pacote contém o arquivo path/to/file/bar.java
?
bazel query path/to/file/bar.java --output=package
Qual é o rótulo do build para path/to/file/bar.java?
bazel query path/to/file/bar.java
Quais destinos de regra contêm o arquivo path/to/file/bar.java
como origem?
fullname=$(bazel query path/to/file/bar.java) bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"
Quais dependências de pacote existem ...
De quais pacotes foo
depende? (O que eu preciso verificar para criar o foo
)
bazel query 'buildfiles(deps(//foo:foo))' --output package
De quais pacotes a árvore foo
depende, exceto foo/contrib
?
bazel query 'deps(foo/... except foo/contrib/...)' --output package
Quais são as dependências de regras ...
Quais regras genproto dependem da barra?
bazel query 'kind(genproto, deps(bar/...))'
Encontre a definição de uma biblioteca JNI (C++) que depende temporariamente de uma regra binária Java na árvore de servlet.
bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
... encontrar as definições de todos os binários Java que dependem deles.
bazel query 'let jbs = kind(java_binary, //java/com/example/frontend/...) in let cls = kind(cc_.*library, deps($jbs)) in $jbs intersect allpaths($jbs, $cls)'
Quais dependências de arquivo existem ...
Qual é o conjunto completo de arquivos de origem Java necessários para criar o foo?
Arquivos de origem:
bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$
Arquivos gerados:
bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$
Qual é o conjunto completo de arquivos de origem Java necessários para criar testes de QUX?
Arquivos de origem:
bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
Arquivos gerados:
bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
Quais são as diferenças entre as dependências X e Y ...
De quais destinos o //foo
depende e que //foo:foolib
não depende?
bazel query 'deps(//foo) except deps(//foo:foolib)'
De quais bibliotecas C++ os testes foo
dependem? O binário de produção //foo
não depende.
bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'
Por que essa dependência existe ...
Por que bar
depende de groups2
?
bazel query 'somepath(bar/...,groups2/...:*)'
Quando você tiver os resultados dessa consulta, muitas vezes verá que um único
destino se destaca como uma dependência inesperada ou grave e
indesejável de bar
. A consulta pode ser ainda mais refinada para:
Mostre um caminho de docker/updater:updater_systest
(py_test
) para cc_library
, de que ele depende:
bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in somepath(docker/updater:updater_systest, $cc)'
Por que a biblioteca //photos/frontend:lib
depende de duas variantes da mesma biblioteca //third_party/jpeglib
e //third_party/jpeg
?
Essa consulta se resume a: "Mostre-me o subgráfico de //photos/frontend:lib
que
depende das duas bibliotecas". Quando mostrado em ordem topológica, o último elemento
do resultado é o culpado mais provável.
bazel query 'allpaths(//photos/frontend:lib, //third_party/jpeglib) intersect allpaths(//photos/frontend:lib, //third_party/jpeg)' //photos/frontend:lib //photos/frontend:lib_impl //photos/frontend:lib_dispatcher //photos/frontend:icons //photos/frontend/modules/gadgets:gadget_icon //photos/thumbnailer:thumbnail_lib //third_party/jpeg/img:renderer
O que depende de ...
Quais regras na barra dependem de Y?
bazel query 'bar/... intersect allpaths(bar/..., Y)'
Quais destinos dependem diretamente de T no pacote T?
bazel query 'same_pkg_direct_rdeps(T)'
Como quebrar uma dependência ...
Quais caminhos de dependência preciso interromper para que o bar
não dependa mais do X?
Para gerar o gráfico em um arquivo svg
:
bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg
Diversos
Quantas etapas sequenciais existem no build //foo-tests
?
No momento, a linguagem de consulta não fornece o caminho mais longo
de x para y, mas pode encontrar o nó mais distante (ou a) do
ponto de partida ou mostrar os tamanhos do caminho mais longo de x a cada
y de que depende. Use maxrank
:
bazel query 'deps(//foo-tests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.c
O resultado indica que existem caminhos com tamanho 85 que precisam ocorrer em ordem nessa versão.