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ências 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
À parte: 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 adicionadas pela ferramenta de build. O conjunto completo de dependências implícitas ainda não está documentado. 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 alterar algum código, pode querer saber que 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 estã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 das alternativas abaixo são testes de C++?
bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'
Quais destes são pequenos? 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 de path/to/file/bar.java?
bazel query path/to/file/bar.java
Quais metas 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 preciso conferir para criar 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 dependências de regras existem ...
De quais regras de genproto a barra depende?
bazel query 'kind(genproto, deps(bar/...))'
Encontre a definição de alguma biblioteca JNI (C++) que depende transitivamente de uma regra binária do Java na árvore de servlet.
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 testes 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/...:*)'
Com os resultados dessa consulta, você geralmente vai descobrir que um único
destino se destaca como uma dependência inesperada, grave e indesejável
de bar
. A consulta pode então 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: "mostrar 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 abaixo da 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.