BazelCon 2022 akan hadir pada 16-17 November ke New York dan online.
Daftar sekarang.

Petunjuk Kueri Bazel

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Halaman ini membahas cara mulai menggunakan bahasa kueri Bazel untuk melacak dependensi dalam kode Anda.

Untuk mengetahui detail bahasa dan detail flag --output, baca panduan referensi, referensi kueri Bazel dan referensi kueri Bazel. Anda bisa mendapatkan bantuan dengan mengetik bazel help query atau bazel help cquery di command line.

Untuk menjalankan kueri dengan mengabaikan error seperti target yang hilang, 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 memedulikan apa yang disertakan dalam artefak yang Anda build, dan bukan setiap tugas yang memungkinkan.

Untuk memvisualisasikan grafik semua dependensi, pipeline 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 berukuran 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 --output graph tidak ditetapkan 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

Selain: dependensi implisit

File BUILD untuk //foo tidak pernah merujuk ke //translations/tools:aggregator. Jadi, di mana dependensi langsungnya?

Aturan tertentu menyertakan dependensi implisit pada alat atau library tambahan. Misalnya, untuk membuat aturan genproto, Anda harus mem-build Protokol 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 didokumentasikan. Dengan menggunakan --noimplicit_deps, Anda dapat memfilter dependensi ini dari hasil kueri. Untuk cquery, ini akan mencakup toolchain yang diselesaikan.

Dependensi terbalik

Anda mungkin ingin mengetahui kumpulan target yang bergantung pada beberapa target. Misalnya, jika Anda akan mengubah beberapa kode, mungkin Anda ingin mengetahui kode lain yang akan rusak. Anda dapat menggunakan rdeps(u, x) untuk menemukan dependensi terbalik target di x dalam penutupan transitif u.

Sky Query dari Bazel mendukung fungsi allrdeps yang memungkinkan Anda mengkueri dependensi terbalik di dunia yang Anda tentukan.

Penggunaan lain-lain

Anda dapat menggunakan bazel query untuk menganalisis banyak hubungan dependensi.

Yang ada ...

Paket apa saja yang ada di bawah foo?

bazel query 'foo/...' --output package

Apa saja aturan 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 saja yang dihasilkan oleh makro starlark foo?

bazel query 'attr(generator_function, foo, //path/to/search/...)'

Apa yang dimaksud dengan kumpulan file BUILD yang diperlukan untuk mem-build //foo?

bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:

Apa saja pengujian individu yang diperluas oleh test_suite?

bazel query 'tests(//foo:smoke_tests)'

Manakah dari pengujian tersebut yang merupakan pengujian C++?

bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'

Manakah dari hal tersebut 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 pola?

bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'

Polanya adalah ekspresi reguler dan diterapkan ke nama lengkap aturan tersebut. 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 bergantung pada foo? (Apa yang perlu saya lihat untuk membuat foo)

bazel query 'buildfiles(deps(//foo:foo))' --output package

Paket apa yang diandalkan hierarki foo, tidak termasuk foo/contrib?

bazel query 'deps(foo/... except foo/contrib/...)' --output package

Dependensi aturan apa yang ada ...

Aturan genproto apa yang diandalkan batang?

bazel query 'kind(genproto, deps(bar/...))'

Temukan definisi beberapa library JNI (C++) yang bergantung secara transitif oleh aturan biner Java di pohon 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 rangkaian lengkap file sumber Java yang diperlukan untuk membuat 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 rangkaian 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$

Apa perbedaan dependensi antara X dan Y ...

Target apa yang tidak //foo bergantung pada //foo:foolib tersebut?

bazel query 'deps(//foo) except deps(//foo:foolib)'

Library C++ apa yang bergantung pada pengujian foo yang binernya 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 mendapati bahwa satu target terlihat sebagai dependensi bar yang tidak terduga atau berat dan tidak diinginkan. Kueri kemudian dapat lebih dipertajam untuk:

Tampilkan 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 library yang sama //third_party/jpeglib dan //third_party/jpeg?

Kueri ini mencakup: "tampilkan subgrafik //photos/frontend:lib yang bergantung pada kedua library". Jika ditampilkan dalam urutan topologi, elemen terakhir dari hasil tersebut 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

Bergantung pada ...

Aturan apa yang ada di bawah kolom bergantung pada Y?

bazel query 'bar/... intersect allpaths(bar/..., Y)'

Apa target yang bergantung langsung pada T, dalam paket T&#39?

bazel query 'same_pkg_direct_rdeps(T)'

Bagaimana cara menghentikan dependensi ...

Jalur dependensi apa yang harus saya pecahkan 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 yang ada 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 yang paling jauh dari titik awal, atau menampilkan 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 berurutan dalam build ini.