Halaman ini membahas cara mulai menggunakan bahasa kueri Bazel untuk melacak dependensi dalam kode Anda.
Untuk detail bahasa dan detail tanda --output
, lihat
panduan referensi, referensi kueri Bazel,
dan referensi kueri Bazel. Anda bisa mendapatkan bantuan dengan
mengetik bazel help query
atau bazel help cquery
pada
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 membuat //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 yang berguna di sini:
allpaths
dan somepath
. Anda mungkin juga ingin mengecualikan
dependensi alat dengan --notool_deps
jika hanya memerlukan
hal yang disertakan dalam artefak yang Anda build, bukan semua tugas yang memungkinkan.
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, ada baiknya memulai 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 --output graph
tidak ditentukan dengan allpaths
, Anda akan mendapatkan daftar grafik dependensi yang disatukan.
$ 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
Selain: dependensi implisit
File BUILD untuk //foo
tidak pernah mereferensikan
//translations/tools:aggregator
. Jadi, di mana dependensi langsungnya?
Aturan tertentu menyertakan dependensi implisit pada library atau alat tambahan.
Misalnya, untuk membuat aturan genproto
, Anda harus mem-build Protocol
Compiler terlebih dahulu, sehingga setiap aturan genproto
membawa dependensi implisit pada
compiler protokol. Dependensi ini tidak disebutkan dalam file build,
tetapi ditambahkan oleh alat build. Kumpulan lengkap dependensi implisit saat ini
tidak terdokumentasi. Penggunaan --noimplicit_deps
memungkinkan Anda memfilter dependensi ini dari hasil kueri Anda. Untuk cquery, ini akan menyertakan toolchain yang di-resolve.
Membalik dependensi
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 dipecahkan. Anda dapat menggunakan rdeps(u, x)
untuk menemukan dependensi terbalik target di x
dalam penutupan transitif u
.
Sky Query Bazel
mendukung fungsi allrdeps
yang memungkinkan Anda membuat kueri dependensi terbalik
di alam semesta yang Anda tentukan.
Penggunaan lain-lain
Anda dapat menggunakan bazel query
untuk menganalisis banyak hubungan dependensi.
Apa yang ada ...
Paket apa saja 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 dibuat 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 rangkaian file BUILD yang diperlukan untuk membuat //foo
?
bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:
Masing-masing pengujian apa saja yang diperluas test_suite
?
bazel query 'tests(//foo:smoke_tests)'
Manakah yang merupakan pengujian C++?
bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'
Manakah yang berukuran 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 suatu pola?
bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'
Polanya berupa ekspresi reguler dan diterapkan ke nama lengkap aturan. Ini mirip dengan melakukan
bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'
Paket apa 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
Apa target aturan 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 diandalkan foo
? (Apa yang harus saya periksa untuk mem-build foo
)
bazel query 'buildfiles(deps(//foo:foo))' --output package
Paket apa yang diandalkan oleh hierarki foo
, kecuali foo/contrib
?
bazel query 'deps(foo/... except foo/contrib/...)' --output package
Apa saja dependensi aturan yang ada ...
Apa aturan genproto yang diandalkan bar?
bazel query 'kind(genproto, deps(bar/...))'
Temukan definisi beberapa library JNI (C++) yang secara transitif bergantung pada aturan biner Java dalam 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 saja yang ada ...
Apa set 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 set lengkap file sumber Java yang diperlukan untuk membangun 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$
Apa perbedaan dependensi antara X dan Y ...
Target apa yang tidak diandalkan oleh //foo
pada //foo:foolib
?
bazel query 'deps(//foo) except deps(//foo:foolib)'
Library C++ apa yang diandalkan oleh pengujian foo
sehingga biner produksi //foo
tidak bergantung?
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 yang tidak terduga, berat, dan tidak diinginkan dari bar
. Kueri tersebut kemudian dapat disaring lebih lanjut menjadi:
Tampilkan jalur dari docker/updater:updater_systest
(py_test
) ke beberapa cc_library
yang menjadi dependensinya:
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 yang sama //third_party/jpeglib
dan //third_party/jpeg
?
Kueri ini terdiri dari: "tampilkan subgrafik //photos/frontend:lib
yang
bergantung pada kedua library". Ketika ditampilkan dalam urutan topologi, elemen terakhir
dari hasil kemungkinan besar adalah penyebabnya.
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 apa yang secara langsung bergantung pada T, dalam paket T?
bazel query 'same_pkg_direct_rdeps(T)'
Bagaimana cara merusak dependensi ...
Jalur dependensi apa yang harus saya pecahkan agar bar
tidak lagi bergantung pada X?
Untuk menghasilkan grafik ke file svg
:
bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg
Lain-lain
Ada berapa banyak langkah berurutan dalam build //foo-tests
?
Sayangnya, bahasa kueri saat ini tidak dapat memberi Anda jalur terpanjang
dari x ke y, tetapi dapat menemukan (atau lebih tepatnya a) node paling jauh dari
titik awal, atau menunjukkan panjang jalur terpanjang dari x ke
setiap y yang menjadi dependensinya. 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.