Halaman ini membahas cara mulai menggunakan bahasa kueri Bazel untuk melacak dependensi dalam kode Anda.
Untuk mengetahui detail bahasa dan detail tanda --output
, lihat
manual referensi, referensi kueri Bazel
dan referensi cquery Bazel. Anda bisa mendapatkan bantuan dengan
mengetik bazel help query
atau bazel help cquery
di
command line.
Untuk menjalankan kueri sambil mengabaikan error seperti target yang tidak ada, gunakan flag
--keep_going
.
Menemukan dependensi aturan
Untuk melihat dependensi //foo
, gunakan
fungsi deps
dalam kueri bazel:
$ bazel query "deps(//foo)" //foo:foo //foo:foo-dep ...
Ini adalah kumpulan semua target yang diperlukan untuk membangun //foo
.
Melacak rantai dependensi antara dua paket
Library //third_party/zlib:zlibonly
tidak ada dalam file BUILD untuk
//foo
, tetapi merupakan dependensi tidak langsung. Bagaimana cara melacak jalur dependensi ini? Ada dua fungsi berguna di sini:
allpaths
dan somepath
. Anda juga dapat mengecualikan
dependensi alat dengan --notool_deps
jika Anda hanya ingin
menyertakan apa yang ada dalam artefak yang Anda buat, dan bukan setiap kemungkinan tugas.
Untuk memvisualisasikan grafik semua dependensi, teruskan output kueri bazel melalui
alat command line dot
:
$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg
Jika grafik dependensi besar dan rumit, sebaiknya mulai dengan satu jalur:
$ 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
Jika Anda tidak menentukan --output graph
dengan allpaths
,
Anda akan mendapatkan daftar grafik dependensi yang diratakan.
$ 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
Sampingan: dependensi implisit
File BUILD untuk //foo
tidak pernah mereferensikan
//translations/tools:aggregator
. Jadi, di mana dependensi langsungnya?
Aturan tertentu mencakup dependensi implisit pada library atau alat tambahan.
Misalnya, untuk membuat aturan genproto
, Anda harus membuat Compiler Protokol terlebih dahulu, sehingga setiap aturan genproto
memiliki dependensi implisit pada compiler protokol. Dependensi ini tidak disebutkan dalam file build,
tetapi ditambahkan oleh alat build. Kumpulan lengkap dependensi implisit saat ini tidak didokumentasikan. Dengan --noimplicit_deps
, Anda dapat memfilter
dependensi ini dari hasil kueri. Untuk cquery, ini akan mencakup toolchain yang telah diselesaikan.
Dependensi terbalik
Anda mungkin ingin mengetahui kumpulan target yang bergantung pada beberapa target. Misalnya, jika Anda akan mengubah beberapa kode, Anda mungkin ingin mengetahui kode lain yang akan Anda rusak. Anda dapat menggunakan rdeps(u, x)
untuk menemukan dependensi
terbalik dari target di x
dalam penutupan transitif u
.
Sky Query Bazel
mendukung fungsi allrdeps
yang memungkinkan Anda mengkueri dependensi terbalik
di semesta yang Anda tentukan.
Penggunaan lain-lain
Anda dapat menggunakan bazel query
untuk menganalisis banyak hubungan dependensi.
Yang ada ...
Paket apa yang ada di bawah foo
?
bazel query 'foo/...' --output package
Aturan apa yang ditentukan dalam paket foo
?
bazel query 'kind(rule, foo:*)' --output label_kind
File apa yang dihasilkan oleh aturan dalam paket foo
?
bazel query 'kind("generated file", //foo:*)'
Target apa yang dihasilkan oleh makro starlark foo
?
bazel query 'attr(generator_function, foo, //path/to/search/...)'
Apa saja kumpulan file BUILD yang diperlukan untuk membangun //foo
?
bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:
Apa saja pengujian individual yang diperluas oleh test_suite
?
bazel query 'tests(//foo:smoke_tests)'
Manakah yang merupakan pengujian C++?
bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'
Mana yang kecil? Sedang? Besar?
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))'
Apa saja pengujian di bawah foo
yang cocok dengan pola?
bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'
Pola adalah regex dan diterapkan ke nama lengkap aturan. Hal ini mirip dengan melakukan
bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'
Paket mana yang berisi file path/to/file/bar.java
?
bazel query path/to/file/bar.java --output=package
Apa label build untuk path/to/file/bar.java?
bazel query path/to/file/bar.java
Target aturan mana yang berisi file path/to/file/bar.java
sebagai sumber?
fullname=$(bazel query path/to/file/bar.java) bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"
Dependensi paket apa yang ada ...
Paket apa yang menjadi dependensi foo
? (Apa yang perlu saya periksa untuk membuat foo
)
bazel query 'buildfiles(deps(//foo:foo))' --output package
Paket apa yang bergantung pada hierarki foo
, tidak termasuk foo/contrib
?
bazel query 'deps(foo/... except foo/contrib/...)' --output package
Dependensi aturan yang ada ...
Aturan genproto apa yang bergantung pada bar?
bazel query 'kind(genproto, deps(bar/...))'
Temukan definisi beberapa library JNI (C++) yang bergantung secara transitif pada aturan biner Java di hierarki servlet.
bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...Sekarang temukan definisi semua biner Java yang bergantung padanya
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)'
Dependensi file apa yang ada ...
Apa saja kumpulan lengkap file sumber Java yang diperlukan untuk mem-build foo?
File sumber:
bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$
File yang dihasilkan:
bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$
Apa saja kumpulan lengkap file sumber Java yang diperlukan untuk membuat pengujian QUX?
File sumber:
bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
File yang dihasilkan:
bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
Perbedaan dependensi antara X dan Y yang ada ...
Target apa yang bergantung pada //foo
, tetapi tidak bergantung pada //foo:foolib
?
bazel query 'deps(//foo) except deps(//foo:foolib)'
Library C++ apa yang bergantung pada pengujian foo
yang tidak bergantung pada biner produksi //foo
?
bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'
Mengapa dependensi ini ada ...
Mengapa bar
bergantung pada groups2
?
bazel query 'somepath(bar/...,groups2/...:*)'
Setelah mendapatkan hasil kueri ini, Anda akan sering menemukan bahwa satu
target menonjol sebagai dependensi bar
yang tidak terduga atau sangat tidak diinginkan. Kueri kemudian dapat disaring lebih lanjut menjadi:
Tunjukkan jalur dari docker/updater:updater_systest
(py_test
) ke beberapa cc_library
yang bergantung padanya:
bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in somepath(docker/updater:updater_systest, $cc)'
Mengapa library //photos/frontend:lib
bergantung pada dua varian dari library //third_party/jpeglib
dan //third_party/jpeg
yang sama?
Kueri ini pada dasarnya adalah: "tampilkan subgrafik //photos/frontend:lib
yang bergantung pada kedua library". Jika ditampilkan dalam urutan topologi, elemen terakhir
dari hasil adalah penyebab yang paling mungkin.
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
Apa yang bergantung pada ...
Aturan apa di bawah batang yang bergantung pada Y?
bazel query 'bar/... intersect allpaths(bar/..., Y)'
Target mana yang bergantung langsung pada T, dalam paket T?
bazel query 'same_pkg_direct_rdeps(T)'
Bagaimana cara memutus dependensi ...
Jalur dependensi apa yang harus saya putuskan agar bar
tidak lagi bergantung pada X?
Untuk menampilkan grafik ke file svg
:
bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg
Lain-lain
Berapa banyak langkah berurutan dalam pembuatan //foo-tests
?
Sayangnya, bahasa kueri saat ini tidak dapat memberikan jalur terpanjang dari x ke y, tetapi dapat menemukan node terjauh (atau lebih tepatnya satu) dari titik awal, atau menunjukkan panjang jalur terpanjang dari x ke setiap y yang bergantung padanya. Gunakan maxrank
:
bazel query 'deps(//foo-tests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.c
Hasilnya menunjukkan bahwa ada jalur dengan panjang 85 yang harus terjadi secara berurutan dalam build ini.