Esta página aborda como começar a usar a linguagem de consulta do Bazel para rastrear dependências no código.
Para saber mais sobre a linguagem e a flag --output
, consulte os
manuais de referência Referência da consulta do Bazel
e Referência da cquery do Bazel. Para receber ajuda,
digite bazel help query
ou bazel help cquery
na
linha de comando.
Para executar uma consulta ignorando erros, como alvos ausentes, use a flag --keep_going
.
Como encontrar as dependências de uma regra
Para conferir as dependências de //foo
, use a
função deps
na consulta do Bazel:
$ bazel query "deps(//foo)" //foo:foo //foo:foo-dep ...
Esse é 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
. Você também pode excluir
dependências de ferramentas com --notool_deps
se estiver interessado apenas no
que está incluído no artefato criado, e não em todos os jobs possíveis.
Para visualizar o gráfico de todas as dependências, canalize a saída da consulta do Bazel pela
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
,
uma lista simplificada do gráfico de dependência será gerada.
$ 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
Observação: dependências implícitas
O arquivo BUILD de //foo
nunca faz referência a
//translations/tools:aggregator
. Onde está a dependência direta?
Algumas regras incluem dependências implícitas de outras bibliotecas ou ferramentas.
Por exemplo, para criar uma regra genproto
, primeiro é necessário criar o compilador de protocolo.
Portanto, cada regra genproto
tem 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. O conjunto completo de dependências implícitas não está
documentado no momento. O uso de --noimplicit_deps
permite filtrar
essas dependências dos resultados da consulta. Para cquery, isso inclui toolchains resolvidos.
Dependências reversas
Talvez você queira saber o conjunto de destinos que depende de algum destino. Por exemplo,
se você for mudar algum código, talvez seja necessário saber qual outro código
você está prestes a quebrar. É possível usar rdeps(u, x)
para encontrar as dependências
inversas das metas em x
dentro do fechamento transitivo de u
.
A Sky Query do Bazel
oferece suporte à função allrdeps
, que permite consultar dependências reversas
em um universo especificado.
Usos diversos
É possível usar bazel query
para analisar muitas relações de dependência.
O que existe ...
Quais pacotes existem 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 por regras no pacote foo
?
bazel query 'kind("generated file", //foo:*)'
Quais são os destinos gerados pelo macro foo
do Starlark?
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:
Quais são os testes individuais que um test_suite
expande?
bazel query 'tests(//foo:smoke_tests)'
Quais destes são testes em C++?
bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'
Quais delas 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 é uma regex e é aplicado ao nome completo da regra. É semelhante a
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 de build para path/to/file/bar.java?
bazel query path/to/file/bar.java
Quais alvos 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? (What do I need to check out to build foo
)
bazel query 'buildfiles(deps(//foo:foo))' --output package
De quais pacotes a árvore foo
depende, excluindo foo/contrib
?
bazel query 'deps(foo/... except foo/contrib/...)' --output package
Quais regras têm dependências?
De quais regras do genproto o bar depende?
bazel query 'kind(genproto, deps(bar/...))'
Encontre a definição de alguma biblioteca JNI (C++) que depende transitivamente de uma regra binária Java na árvore de servlets.
bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...Agora encontre 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 os testes do 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 nas dependências entre X e Y?
De quais destinos //foo
depende que //foo:foolib
não depende?
bazel query 'deps(//foo) except deps(//foo:foolib)'
De quais bibliotecas C++ os testes foo
dependem que 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/...:*)'
Depois de receber os resultados dessa consulta, você vai notar que um único
alvo se destaca como uma dependência inesperada ou grave e indesejável
de bar
. A consulta pode ser refinada para:
Mostre um caminho de docker/updater:updater_systest
(um py_test
) para algumas 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 o subgrafo 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 de T?
bazel query 'same_pkg_direct_rdeps(T)'
Como faço para interromper uma dependência ...
Quais caminhos de dependência preciso interromper para que bar
não dependa mais de 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 há no build //foo-tests
?
No momento, a linguagem de consulta não pode mostrar o caminho mais longo de x para y, mas pode encontrar o nó mais distante (ou seja, a) do ponto de partida ou mostrar os comprimentos do caminho mais longo de x para cada y de que ele depende. Use maxrank
:
bazel query 'deps(//foo-tests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.c
O resultado indica que existem caminhos de comprimento 85 que precisam ocorrer em ordem neste build.