Nesta página, mostramos como começar a usar a linguagem de consulta do Bazel para rastrear dependências no seu código.
Para detalhes de linguagem e da sinalização --output
, consulte os manuais de referência, a referência de consulta do Bazel e a referência de 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 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 ...
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 rastrear esse caminho de dependência? Há duas funções úteis aqui:
allpaths
e somepath
. Também é possível excluir
dependências de ferramentas com --notool_deps
se você se importa 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, direcione 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
,
receberá uma lista nivelada do gráfico de dependência.
$ 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
. Então, onde está 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 Protocol
Compiler. Dessa forma, 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 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 o cquery, isso vai incluir conjuntos de ferramentas resolvidos.
Reverter dependências
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. Você pode usar rdeps(u, x)
para encontrar as dependências
reversas dos destinos em x
dentro do fechamento transitivo de u
.
A Sky Query
do Bazel é compatível com a função allrdeps
, que permite consultar dependências reversas
em um universo especificado por você.
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 destinos são gerados pela macro starlark foo
?
bazel query 'attr(generator_function, foo, //path/to/search/...)'
Qual é o conjunto de arquivos BUILD necessários para criar //foo
?
bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:
Para quais testes individuais uma test_suite
se 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 é um regex e é aplicado ao nome completo da regra. É semelhante a 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 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 de foo
depende, exceto 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 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ário 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$
Que diferenças existem nas dependências entre X e Y ...
Quais metas a //foo
depende de //foo:foolib
não?
bazel query 'deps(//foo) except deps(//foo:foolib)'
De quais bibliotecas C++ os testes foo
dependem do binário de produção //foo
não?
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 alguns 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 quebro uma dependência ...
Quais caminhos de dependência preciso quebrar para fazer com 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
?
Infelizmente, a linguagem de consulta não pode atualmente fornecer o caminho mais longo de x para y, mas pode encontrar o nó (ou a) mais distante do ponto de partida ou mostrar os comprimentos 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 de comprimento 85 que precisam ocorrer em ordem nesse build.