En esta página, se explica cómo comenzar a usar el lenguaje de consulta de Bazel para rastrear las dependencias en tu código.
Para obtener detalles del lenguaje y de la marca --output
, consulta los
manuales de referencia, la referencia de las consultas de Bazel
y la referencia de BigQuery Bazel. Para obtener ayuda, escribe bazel help query
o bazel help cquery
en la línea de comandos.
Para ejecutar una consulta y pasar por alto errores, como destinos faltantes, usa la marca --keep_going
.
Busca las dependencias de una regla
Para ver las dependencias de //foo
, usa la
función deps
en la consulta de Bazel:
$ bazel query "deps(//foo)" //foo:foo //foo:foo-dep ...
Este es el conjunto de todos los destinos necesarios para compilar //foo
.
Haz un seguimiento de la cadena de dependencia entre dos paquetes
La biblioteca //third_party/zlib:zlibonly
no está en el archivo BUILD para //foo
, pero es una dependencia indirecta. ¿Cómo se puede rastrear esta ruta de dependencia? Aquí hay dos funciones útiles: allpaths
y somepath
. También puedes excluir dependencias de herramientas con --notool_deps
si solo te interesa lo que se incluye en el artefacto que compilaste y no en todos los trabajos posibles.
Para visualizar el grafo de todas las dependencias, canaliza el resultado de la consulta de Bazel a través de
la herramienta de línea de comandos de dot
:
$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg
Cuando un gráfico de dependencia es grande y complicado, puede resultar útil comenzar con una sola ruta:
$ 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
Si no especificas --output graph
con allpaths
, obtendrás una lista plana del gráfico de dependencias.
$ 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
Apartado: dependencias implícitas
El archivo BUILD para //foo
nunca hace referencia a //translations/tools:aggregator
. ¿Dónde está la dependencia directa?
Algunas reglas incluyen dependencias implícitas en bibliotecas o herramientas adicionales.
Por ejemplo, para compilar una regla genproto
, primero debes compilar el Compilador de protocolo, por lo que cada regla genproto
lleva una dependencia implícita del compilador de protocolo. Estas dependencias no se mencionan en el archivo de compilación, pero se agregan mediante la herramienta de compilación. Por el momento, el conjunto completo de dependencias implícitas no está documentado. Usar --noimplicit_deps
te permite filtrar estas dependencias en los resultados de consultas. Para cquery, se incluirán los conjuntos de herramientas resueltos.
Revierte las dependencias
Es posible que desee conocer el conjunto de objetivos que depende de algún objetivo. Por ejemplo, si vas a cambiar algún código, es posible que desees saber qué otro código estás a punto de romper. Puedes usar rdeps(u, x)
para encontrar las dependencias inversas de los destinos en x
dentro del cierre transitivo de u
.
Sky Query de Bazel admite la función allrdeps
, que te permite consultar dependencias inversas en un universo que especifiques.
Usos varios
Puedes usar bazel query
para analizar muchas relaciones de dependencia.
Lo que existe ...
¿Qué paquetes existen por debajo de foo
?
bazel query 'foo/...' --output package
¿Qué reglas se definen en el paquete foo
?
bazel query 'kind(rule, foo:*)' --output label_kind
¿Qué archivos se generan con las reglas en el paquete foo
?
bazel query 'kind("generated file", //foo:*)'
¿Qué objetivos genera la macro de Starlark foo
?
bazel query 'attr(generator_function, foo, //path/to/search/...)'
¿Cuál es el conjunto de archivos BUILD necesarios para compilar //foo
?
bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:
¿En qué pruebas individuales se expande un test_suite
?
bazel query 'tests(//foo:smoke_tests)'
¿Cuáles de estas son pruebas de C++?
bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'
¿Cuáles de estas son pequeñas? ¿Es mediano? ¿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))'
¿Cuáles son las pruebas debajo de foo
que coinciden con un patrón?
bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'
El patrón es una regex y se aplica al nombre completo de la regla. Es similar a hacer
bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'
¿Qué paquete contiene el archivo path/to/file/bar.java
?
bazel query path/to/file/bar.java --output=package
¿Cuál es la etiqueta de compilación para path/to/file/bar.java?
?
bazel query path/to/file/bar.java
¿Qué orientaciones de norma contienen el archivo path/to/file/bar.java
como fuente?
fullname=$(bazel query path/to/file/bar.java) bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"
Qué dependencias de paquetes existen ...
¿De qué paquetes depende foo
? (¿Qué necesito revisar para compilar foo
)?
bazel query 'buildfiles(deps(//foo:foo))' --output package
¿De qué paquetes depende el árbol foo
, sin incluir foo/contrib
?
bazel query 'deps(foo/... except foo/contrib/...)' --output package
Qué dependencias de regla existen ...
¿De qué reglas de genproto dependen las barras?
bazel query 'kind(genproto, deps(bar/...))'
Busca la definición de alguna biblioteca JNI (C++) de la que se depende de forma transitiva una regla binaria de Java en el árbol de servlet.
bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...Ahora encuentre las definiciones de todos los objetos binarios de Java que dependen de ellos
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)'
Qué dependencias de archivo existen ...
¿Cuál es el conjunto completo de archivos fuente Java que se necesita para crear foo?
Archivos de origen:
bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$
Archivos generados:
bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$
¿Cuál es el conjunto completo de archivos de origen de Java que se necesita para compilar las pruebas de QUX?
Archivos de origen:
bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
Archivos generados:
bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
Diferencias en las dependencias entre X e Y ...
¿De qué objetivos depende //foo
que //foo:foolib
no?
bazel query 'deps(//foo) except deps(//foo:foolib)'
¿De qué bibliotecas de C++ depende foo
que //foo
el objeto binario de producción no dependa?
bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'
¿Por qué existe esta dependencia?
¿Por qué bar
depende de groups2
?
bazel query 'somepath(bar/...,groups2/...:*)'
Una vez que obtienes los resultados de esta consulta, a menudo, descubres que un único objetivo se destaca por ser una dependencia inesperada, no deseada o no deseada de bar
. Luego, la consulta se puede definir mejor para lo siguiente:
Mostrarme una ruta de acceso de docker/updater:updater_systest
(un py_test
) a un cc_library
del que depende:
bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in somepath(docker/updater:updater_systest, $cc)'
¿Por qué la biblioteca //photos/frontend:lib
depende de dos variantes de la misma biblioteca //third_party/jpeglib
y //third_party/jpeg
?
Esta consulta se resume en: “muéstrame el subgrafo de //photos/frontend:lib
que depende de ambas bibliotecas”. Cuando se muestra en orden topológico, el último elemento del resultado es el culpable más probable.
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
Qué depende de ...
¿Qué reglas de la barra dependen de Y?
bazel query 'bar/... intersect allpaths(bar/..., Y)'
¿Qué objetivos dependen directamente de T, en el paquete de T?
bazel query 'same_pkg_direct_rdeps(T)'
¿Cómo puedo romper una dependencia ...
¿Qué rutas de dependencia debo romper para que bar
ya no dependa de X?
Para generar el grafo en un archivo svg
, haz lo siguiente:
bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg
Varios
¿Cuántos pasos secuenciales hay en la compilación //foo-tests
?
Lamentablemente, el lenguaje de consulta no puede darte la ruta más larga de x a y, pero puede encontrar el nodo (o a) más distante del punto de partida o mostrarte las longitudes de la ruta más larga desde x hasta cada y de la que depende. Usa maxrank
:
bazel query 'deps(//foo-tests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.c
El resultado indica que existen rutas de longitud 85 que deben ocurrir en orden en esta compilación.