Referensi Kueri Bazel

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.
Laporkan masalah Lihat sumber

Halaman ini adalah panduan referensi untuk Bahasa Kueri Bazel yang digunakan saat Anda menggunakan bazel query untuk menganalisis dependensi build. Bagian ini juga menjelaskan format output yang didukung bazel query.

Untuk kasus penggunaan praktis, lihat Petunjuk Kueri Bazel.

Referensi kueri tambahan

Selain query, yang berjalan pada grafik target fase pasca-pemuatan, Bazel menyertakan kueri grafik tindakan dan kueri yang dapat dikonfigurasi.

Kueri grafik tindakan

Kueri grafik tindakan (aquery) beroperasi pada Grafik Target yang Dikonfigurasi setelah analisis dan menampilkan informasi tentang Tindakan, Artefak, dan hubungannya. aquery berguna saat Anda tertarik dengan properti Action/Artifact yang dihasilkan dari Grafik Target yang Dikonfigurasi. Misalnya, perintah sebenarnya berjalan beserta input, output, dan mnemoniknya.

Untuk mengetahui detail lebih lanjut, lihat referensi kueri.

Kueri yang dapat dikonfigurasi

Kueri Bazel tradisional berjalan pada grafik target fase pasca-pemuatan, sehingga tidak ada konsep konfigurasi serta konsep terkaitnya. Khususnya, tindakan ini tidak me-resolve pernyataan tertentu dengan benar dan menampilkan semua kemungkinan resolusi pemilihan. Namun, lingkungan kueri yang dapat dikonfigurasi, cquery, menangani konfigurasi dengan benar, tetapi tidak menyediakan semua fungsi kueri asli ini.

Untuk mengetahui detail lebih lanjut, baca referensi kueri.

Contoh

Bagaimana cara orang menggunakan bazel query? Berikut adalah contoh umumnya:

Mengapa hierarki //foo bergantung pada //bar/baz? Tampilkan jalur:

somepath(foo/..., //bar/baz:all)

Library C++ apa yang menjadi dependensi semua pengujian foo dan target foo_bin tidak?

kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo:foo_bin))

Token: Sintaksis leksikal

Ekspresi dalam bahasa kueri terdiri dari token berikut:

  • Kata kunci, seperti let. Kata kunci adalah kata khusus untuk bahasa ini, dan setiap kata kunci dijelaskan di bawah ini. Kumpulan kata kunci lengkap adalah:

  • Kata, seperti "foo/..." atau ".*test rule" atau "//bar/baz:all". Jika urutan karakter "dikutip" (diawali dan diakhiri dengan tanda kutip tunggal 'atau dimulai dan diakhiri dengan tanda kutip ganda "), ini adalah kata. Jika urutan karakter tidak dikutip, nilai tersebut mungkin masih diuraikan sebagai kata. Kata-kata tanpa tanda kutip adalah urutan karakter yang digambar dari karakter alfabet A-Za-z, angka 0-9, dan karakter khusus */@.-_:$~[] (tanda bintang, garis miring, at, titik, tanda hubung, garis bawah, titik dua, tanda dolar, tanda gelombang, kurung kurawal kiri, kurung siku kanan). Namun, kata-kata tanpa tanda kutip tidak boleh diawali dengan tanda hubung - atau tanda bintang * meskipun [nama target][(/concepts/labels#target-names) relatif dapat dimulai dengan karakter tersebut.

    Kata-kata tanpa tanda kutip juga tidak boleh menyertakan karakter plus tanda + atau sama dengan tanda =, meskipun karakter tersebut diizinkan dalam nama target. Saat menulis kode yang menghasilkan ekspresi kueri, nama target harus dikutip.

    Mengutip diperlukan saat menulis skrip yang membuat ekspresi kueri Bazel dari nilai yang diberikan pengguna.

     //foo:bar+wiz    # WRONG: scanned as //foo:bar + wiz.
     //foo:bar=wiz    # WRONG: scanned as //foo:bar = wiz.
     "//foo:bar+wiz"  # OK.
     "//foo:bar=wiz"  # OK.
    

    Perhatikan bahwa kutipan ini merupakan tambahan dari kutipan apa pun yang mungkin diperlukan oleh shell Anda, seperti:

    bazel query ' "//foo:bar=wiz" '   # single-quotes for shell, double-quotes for Bazel.
    

    Kata kunci dan operator, jika dikutip, diperlakukan sebagai kata-kata biasa. Misalnya, some adalah kata kunci, tetapi "beberapa" adalah sebuah kata. foo dan "foo" adalah kata.

    Namun, berhati-hatilah saat menggunakan tanda kutip tunggal atau ganda dalam nama target. Saat mengutip satu atau beberapa nama target, gunakan hanya satu jenis tanda kutip (semua tanda kutip tunggal atau ganda).

    Berikut adalah contoh string kueri Java:

      'a"'a'         # WRONG: Error message: unclosed quotation.
      "a'"a"         # WRONG: Error message: unclosed quotation.
      '"a" + 'a''    # WRONG: Error message: unexpected token 'a' after query expression '"a" + '
      "'a' + "a""    # WRONG: Error message: unexpected token 'a' after query expression ''a' + '
      "a'a"          # OK.
      'a"a'          # OK.
      '"a" + "a"'    # OK
      "'a' + 'a'"    # OK
    

    Kami memilih sintaksis ini sehingga tanda kutip tidak diperlukan dalam kebanyakan kasus. Contoh (tidak biasa) ".*test rule" memerlukan tanda kutip: dimulai dengan titik dan berisi spasi. Mengutip "cc_library" tidak diperlukan tetapi tidak berbahaya.

  • Tanda baca, seperti tanda kurung (), titik ., dan koma ,. Kata yang berisi tanda baca (selain pengecualian yang tercantum di atas) harus dikutip.

Karakter spasi kosong di luar kata yang dikutip diabaikan.

Konsep bahasa kueri Bazel

Bahasa kueri Bazel adalah bahasa ekspresi. Setiap ekspresi dievaluasi ke kumpulan target yang diurutkan sebagian, atau setara dengan grafik (DAG) target. Ini adalah satu-satunya jenis data.

Set dan grafik merujuk pada jenis data yang sama, tetapi menekankan aspek yang berbeda, misalnya:

  • Kumpulan: Urutan target sebagian tidak menarik.
  • Grafik: Urutan parsial target sangat signifikan.

Siklus dalam grafik dependensi

Grafik dependensi build harus siklik.

Algoritme yang digunakan oleh bahasa kueri ditujukan untuk digunakan dalam grafik asiklik, tetapi kuat terhadap siklus. Detail tentang cara siklus diperlakukan tidak ditentukan dan tidak boleh diandalkan.

Dependensi implisit

Selain dependensi build yang ditentukan secara eksplisit dalam file BUILD, Bazel menambahkan dependensi implisit tambahan ke aturan. Misalnya, setiap aturan Java secara implisit bergantung pada JavaBuilder. Dependensi implisit dibuat menggunakan atribut yang dimulai dengan $ dan tidak dapat diganti dalam file BUILD.

Per default bazel query memperhitungkan dependensi implisit saat menghitung hasil kueri. Perilaku ini dapat diubah dengan opsi --[no]implicit_deps. Perlu diperhatikan bahwa karena kueri tidak mempertimbangkan konfigurasi, potensi toolchain tidak akan pernah dipertimbangkan.

Kesehatan

Ekspresi bahasa kueri Bazel beroperasi melalui grafik dependensi build, yang merupakan grafik yang secara implisit ditentukan oleh semua deklarasi aturan di semua file BUILD. Penting untuk memahami bahwa grafik ini agak abstrak, dan bukan merupakan deskripsi lengkap tentang cara melakukan semua langkah build. Agar dapat melakukan build, konfigurasi juga diperlukan; lihat bagian konfigurasi dalam Panduan Pengguna untuk detail selengkapnya.

Hasil evaluasi ekspresi dalam bahasa kueri Bazel adalah benar untuk semua konfigurasi, yang berarti bahwa ekspresi ini mungkin merupakan perkiraan berlebihan yang konservatif, dan tidak sepenuhnya akurat. Jika Anda menggunakan alat kueri untuk menghitung kumpulan semua file sumber yang diperlukan selama build, alat ini mungkin akan melaporkan lebih banyak dari yang sebenarnya diperlukan karena, misalnya, alat kueri akan menyertakan semua file yang diperlukan untuk mendukung terjemahan pesan, meskipun Anda tidak bermaksud menggunakan fitur tersebut dalam build.

Tentang pemeliharaan urutan grafik

Operasi mempertahankan batasan pengurutan yang diwarisi dari subekspresinya. Anda dapat menganggapnya sebagai "hukum konservasi pesanan sebagian". Pertimbangkan contoh: jika Anda mengeluarkan kueri untuk menentukan penutupan transitif dependensi target tertentu, kumpulan yang dihasilkan akan diurutkan sesuai dengan grafik dependensi. Jika Anda memfilter kumpulan tersebut agar hanya menyertakan target dari jenis file, hubungan pengurutan parsial transitif yang sama akan terjadi di antara setiap pasangan target dalam subset yang dihasilkan, meskipun tidak satu pun dari pasangan ini yang benar-benar terhubung langsung dalam grafik asli. (Tidak ada tepi file-file dalam grafik dependensi build).

Namun, meskipun semua operator mempertahankan pesanan, beberapa operasi, seperti operasi yang ditetapkan, tidak memperkenalkan batasan pengurutannya sendiri. Perhatikan ekspresi ini:

deps(x) union y

Urutan kumpulan hasil akhir dijamin untuk mempertahankan semua batasan urutan subekspresinya, yaitu, bahwa semua dependensi transitif x diurutkan dengan benar dengan saling menghormati. Namun, kueri tersebut tidak menjamin pengurutan target di y, atau pengurutan target di deps(x) jika dibandingkan dengan target di y (kecuali untuk target di y yang juga berada di deps(x)).

Operator yang memperkenalkan batasan pengurutan mencakup: allpaths, deps, rdeps, somepath, dan karakter pengganti pola target package:*, dir/..., dll.

Kueri Sky

Sky Query adalah mode kueri yang beroperasi pada cakupan alam semesta yang ditentukan.

Fungsi khusus hanya tersedia di SkyQuery

Mode Sky Query memiliki fungsi kueri tambahan allrdeps dan rbuildfiles. Fungsi ini beroperasi di seluruh cakupan alam semesta (itulah sebabnya tidak cocok untuk Kueri normal).

Menentukan cakupan alam semesta

Mode Kueri Sky diaktifkan dengan meneruskan dua flag berikut: (--universe_scope atau --infer_universe_scope) dan --order_output=no. --universe_scope=<target_pattern1>,...,<target_patternN> memberi tahu kueri untuk memuat penutupan transitif pola target yang ditentukan oleh pola target, yang dapat menjadi aditif dan subduktif. Semua kueri kemudian dievaluasi dalam "cakupan" ini. Secara khusus, operator allrdeps dan rbuildfiles hanya menampilkan hasil dari cakupan ini. --infer_universe_scope memberi tahu Bazel untuk menyimpulkan nilai untuk --universe_scope dari ekspresi kueri. Inferensi nilai ini adalah daftar pola target unik dalam ekspresi kueri, tetapi ini mungkin bukan yang Anda inginkan. Contoh:

bazel query --infer_universe_scope --order_output=no "allrdeps(//my:target)"

Daftar pola target unik dalam ekspresi kueri ini adalah ["//my:target"], sehingga Bazel memperlakukan hal ini sama seperti pemanggilan:

bazel query --universe_scope=//my:target --order_output=no "allrdeps(//my:target)"

Namun, hasil kueri tersebut dengan --universe_scope hanya //my:target; tidak ada dependensi terbalik dari //my:target yang ada di dunia, melalui konstruksi. Di sisi lain, pertimbangkan:

bazel query --infer_universe_scope --order_output=no "tests(//a/... + b/...) intersect allrdeps(siblings(rbuildfiles(my/starlark/file.bzl)))"

Ini adalah pemanggilan kueri yang bermakna yang mencoba menghitung target pengujian dalam perluasan tests target di beberapa direktori yang secara transitif bergantung pada target yang definisinya menggunakan file .bzl tertentu. Di sini, --infer_universe_scope adalah cara yang praktis, terutama jika pilihan --universe_scope mengharuskan Anda mengurai ekspresi kueri sendiri.

Jadi, untuk ekspresi kueri yang menggunakan operator dengan cakupan universe seperti allrdeps dan rbuildfiles, pastikan untuk menggunakan --infer_universe_scope hanya jika perilakunya sesuai dengan yang Anda inginkan.

Sky Query memiliki beberapa kelebihan dan kekurangan dibandingkan dengan kueri default. Kelemahan utamanya adalah tidak dapat mengurutkan output-nya sesuai urutan grafik, sehingga format output tertentu dilarang. Keuntungannya adalah menyediakan dua operator (allrdeps dan rbuildfiles) yang tidak tersedia dalam kueri default. Selain itu, Sky Query melakukan pekerjaannya dengan memperkenalkan grafik Skyframe, bukan membuat grafik baru, yang dilakukan oleh penerapan default. Oleh karena itu, ada beberapa situasi di mana proses ini lebih cepat dan menggunakan lebih sedikit memori.

Ekspresi: Sintaksis dan semantik tata bahasa

Ini adalah tata bahasa dari bahasa kueri Bazel, yang dinyatakan dalam notasi EBNF:

expr ::= word
       | let name = expr in expr
       | (expr)
       | expr intersect expr
       | expr ^ expr
       | expr union expr
       | expr + expr
       | expr except expr
       | expr - expr
       | set(word *)
       | word '(' int | word | expr ... ')'

Bagian berikut menjelaskan setiap produksi tata bahasa ini secara berurutan.

Pola target

expr ::= word

Secara sintaksis, pola target hanyalah sebuah kata. Hal tersebut ditafsirkan sebagai kumpulan target (yang tidak diurutkan). Pola target yang paling sederhana adalah label, yang mengidentifikasi satu target (file atau aturan). Misalnya, pola target //foo:bar dievaluasi ke kumpulan yang berisi satu elemen, target, aturan bar.

Pola target menggeneralisasi label untuk menyertakan karakter pengganti daripada paket dan target. Misalnya, foo/...:all (atau hanya foo/...) adalah pola target yang mengevaluasi ke kumpulan yang berisi semua aturan di setiap paket secara rekursif di bawah direktori foo; bar/baz:all adalah pola target yang dievaluasi ke kumpulan yang berisi semua aturan dalam paket bar/baz, tetapi bukan sub-paketnya.

Demikian pula, foo/...:* adalah pola target yang dievaluasi ke kumpulan yang berisi semua target (file dan aturan) di setiap paket secara rekursif di bawah direktori foo; bar/baz:* mengevaluasi ke kumpulan yang berisi semua target dalam paket bar/baz, tetapi bukan subpaketnya.

Karena karakter pengganti :* cocok dengan file serta aturan, karakter pengganti sering kali lebih berguna daripada :all untuk kueri. Sebaliknya, karakter pengganti :all (implisit dalam pola target seperti foo/...) biasanya lebih berguna untuk build.

Pola target bazel query berfungsi sama seperti target build bazel build. Untuk detail selengkapnya, lihat Pola Target, atau ketik bazel help target-syntax.

Pola target dapat dievaluasi ke kumpulan tunggal (dalam kasus label), ke kumpulan yang berisi banyak elemen (seperti pada kasus foo/..., yang memiliki ribuan elemen) atau kumpulan kosong, jika pola target tidak cocok dengan target.

Semua node dalam hasil ekspresi pola target diurutkan dengan benar relatif terhadap satu sama lain sesuai dengan hubungan dependensi. Jadi, hasil foo:* tidak hanya berupa kumpulan target dalam paket foo, tetapi juga grafik pada target tersebut. (Tidak ada jaminan atas urutan relatif dari node hasil terhadap node lain.) Untuk mengetahui detail selengkapnya, lihat bagian urutan grafik.

Variabel

expr ::= let name = expr1 in expr2
       | $name

Bahasa kueri Bazel memungkinkan definisi dan referensi ke variabel. Hasil evaluasi ekspresi let sama dengan hasil expr2, dengan semua kemunculan gratis variabel name diganti dengan nilai expr1.

Misalnya, let v = foo/... in allpaths($v, //common) intersect $v setara dengan allpaths(foo/...,//common) intersect foo/....

Kemunculan referensi variabel name selain dalam ekspresi let name = ... yang melingkupi adalah error. Dengan kata lain, ekspresi kueri level teratas tidak boleh memiliki variabel bebas.

Dalam produksi tata bahasa di atas, name mirip dengan kata, tetapi dengan batasan tambahan bahwa kode tersebut merupakan ID hukum dalam bahasa pemrograman C. Referensi ke variabel harus diawali dengan karakter "$".

Setiap ekspresi let hanya menentukan variabel tunggal, tetapi Anda dapat membuatnya bertingkat.

Pola target dan referensi variabel hanya terdiri dari satu token, sebuah kata, yang menciptakan ambiguitas sintaksis. Namun, tidak ada ambiguitas semantik, karena subkumpulan kata yang merupakan nama variabel hukum terpisah dari subkumpulan kata yang merupakan pola target hukum.

Secara teknis, ekspresi let tidak meningkatkan ekspresi bahasa kueri: setiap kueri yang dapat dinyatakan dalam bahasa juga dapat dinyatakan tanpanya. Namun, metode tersebut akan meningkatkan ke ringkasan banyak kueri, dan juga dapat menghasilkan evaluasi kueri yang lebih efisien.

Ekspresi yang diberi tanda kurung

expr ::= (expr)

Tanda kurung mengaitkan subekspresi untuk memaksa urutan evaluasi. Ekspresi yang diberi tanda kurung mengevaluasi nilai argumennya.

Operasi himpunan aljabar: persimpangan, gabungan, perbedaan himpunan

expr ::= expr intersect expr
       | expr ^ expr
       | expr union expr
       | expr + expr
       | expr except expr
       | expr - expr

Ketiga operator ini menghitung operasi yang ditetapkan seperti biasa pada argumennya. Setiap operator memiliki dua bentuk, yaitu bentuk nominal, seperti intersect, dan bentuk simbolis, seperti ^. Kedua formulir setara; bentuk simbolis lebih cepat diketik. (Untuk lebih jelasnya, bagian selanjutnya dari halaman ini menggunakan bentuk nominal.)

Misalnya,

foo/... except foo/bar/...

mengevaluasi kumpulan target yang cocok dengan foo/... tetapi tidak foo/bar/....

Anda dapat menulis kueri yang sama seperti:

foo/... - foo/bar/...

Operasi intersect (^) dan union (+) bersifat komutatif (simetris); except (-) bersifat asimetris. Parser memperlakukan ketiga operator tersebut sebagai asosiasi kiri dan memiliki prioritas yang sama, sehingga Anda mungkin perlu tanda kurung. Misalnya, dua dari dua ekspresi pertama ini setara, tetapi yang ketiga tidak:

x intersect y union z
(x intersect y) union z
x intersect (y union z)

Membaca target dari sumber eksternal: ditetapkan

expr ::= set(word *)

Operator set(a b c ...) menghitung gabungan dari nol atau beberapa pola target, yang dipisahkan oleh spasi kosong (tanpa koma).

Dalam kaitannya dengan fitur $(...) shell Bourne, set() menyediakan cara menyimpan hasil dari satu kueri dalam file teks biasa, memanipulasi file teks tersebut menggunakan program lain (seperti alat shell UNIX standar), lalu memperkenalkan kembali hasilnya ke alat kueri sebagai nilai untuk pemrosesan lebih lanjut. Contoh:

bazel query deps(//my:target) --output=label | grep ... | sed ... | awk ... > foo
bazel query "kind(cc_binary, set($(<foo)))"

Pada contoh berikutnya,kind(cc_library, deps(//some_dir/foo:main, 5)) dihitung dengan memfilter nilai maxrank menggunakan program awk.

bazel query 'deps(//some_dir/foo:main)' --output maxrank | awk '($1 < 5) { print $2;} ' > foo
bazel query "kind(cc_library, set($(<foo)))"

Dalam contoh ini, $(<foo) adalah nama pendek untuk $(cat foo), tetapi perintah shell selain cat juga dapat digunakan—seperti perintah awk sebelumnya.

Functions

expr ::= word '(' int | word | expr ... ')'

Bahasa kueri menentukan beberapa fungsi. Nama fungsi menentukan jumlah dan jenis argumen yang dibutuhkan. Fungsi berikut tersedia:

Penutupan transitif dependensi: dependensi

expr ::= deps(expr)
       | deps(expr, depth)

Operator deps(x) mengevaluasi ke grafik yang dibentuk oleh penutupan transitif dependensi dari kumpulan argumennya x. Misalnya, nilai deps(//foo) adalah grafik dependensi yang di-root pada foo node tunggal, termasuk semua dependensinya. Nilai deps(foo/...) adalah grafik dependensi yang root-nya adalah semua aturan dalam setiap paket di bawah direktori foo. Dalam konteks ini, 'dependensi' hanya berarti aturan dan target file. Oleh karena itu, file BUILD dan Starlark yang diperlukan untuk membuat target ini tidak disertakan di sini. Untuk itu, Anda harus menggunakan operator buildfiles.

Grafik yang dihasilkan diurutkan menurut hubungan dependensi. Untuk detail selengkapnya, lihat bagian tentang urutan grafik.

Operator deps menerima argumen kedua opsional, yang merupakan literal bilangan bulat yang menentukan batas atas pada kedalaman penelusuran. Jadi, deps(foo:*, 0) menampilkan semua target dalam paket foo, sementara deps(foo:*, 1) lebih lanjut menyertakan prasyarat langsung dari setiap target dalam paket foo, dan deps(foo:*, 2) lebih lanjut menyertakan node yang langsung dapat dijangkau dari node di deps(foo:*, 1), dan seterusnya. (Angka ini sesuai dengan peringkat yang ditampilkan dalam format output minrank.) Jika parameter depth dihilangkan, penelusuran tidak terikat: parameter tersebut akan menghitung penutupan transitif prasyarat refleksif.

Penutupan transitif dari dependensi terbalik: rdeps

expr ::= rdeps(expr, expr)
       | rdeps(expr, expr, depth)

Operator rdeps(u, x) mengevaluasi dependensi terbalik dari kumpulan argumen x dalam penutupan transitif kumpulan universal u.

Grafik yang dihasilkan diurutkan menurut hubungan dependensi. Lihat bagian urutan grafik untuk detail selengkapnya.

Operator rdeps menerima argumen ketiga opsional, yang merupakan literal bilangan bulat yang menentukan batas atas pada kedalaman penelusuran. Grafik yang dihasilkan hanya mencakup node dalam jarak kedalaman yang ditentukan dari node mana pun dalam kumpulan argumen. Jadi, rdeps(//foo, //common, 1) mengevaluasi ke semua node dalam penutupan transitif //foo yang secara langsung bergantung pada //common. (Angka ini sesuai dengan peringkat yang ditampilkan dalam format output minrank.) Jika parameter depth dihilangkan, penelusuran tidak terikat.

Penutupan transitif dari semua dependensi terbalik: allrdeps

expr ::= allrdeps(expr)
       | allrdeps(expr, depth)

Operator allrdeps berperilaku seperti operator rdeps, kecuali bahwa "universe set" adalah apa pun yang dievaluasi oleh flag --universe_scope, bukan ditentukan secara terpisah. Jadi, jika --universe_scope=//foo/... diteruskan, allrdeps(//bar) setara dengan rdeps(//foo/..., //bar).

Dependensi terbalik langsung dalam paket yang sama: same_pkg_direct_rdeps

expr ::= same_pkg_direct_rdeps(expr)

Operator same_pkg_direct_rdeps(x) mengevaluasi kumpulan target lengkap yang berada dalam paket yang sama dengan target dalam kumpulan argumen, dan yang bergantung secara langsung padanya.

Berurusan dengan paket target: saudara kandung

expr ::= siblings(expr)

Operator siblings(x) mengevaluasi kumpulan target lengkap yang ada dalam paket yang sama dengan target dalam kumpulan argumen.

Pilihan arbitrer: beberapa

expr ::= some(expr)
       | some(expr, count )

Operator some(x, k) memilih maksimal k target secara acak dari argumennya x, dan mengevaluasi ke kumpulan yang hanya berisi target tersebut. Parameter k bersifat opsional; jika tidak ada, hasilnya akan berupa kumpulan tunggal yang hanya berisi satu target yang dipilih secara arbitrer. Jika ukuran argumen x lebih kecil dari k, seluruh kumpulan argumen x akan ditampilkan.

Misalnya, ekspresi some(//foo:main union //bar:baz) bernilai satu kumpulan tunggal yang berisi //foo:main atau //bar:baz—meskipun yang tidak ditentukan. Ekspresi some(//foo:main union //bar:baz, 2) atau some(//foo:main union //bar:baz, 3) menampilkan //foo:main dan //bar:baz.

Jika argumen berupa singleton, some akan menghitung fungsi identitas: some(//foo:main) setara dengan //foo:main.

Akan terjadi error jika kumpulan argumen yang ditentukan kosong, seperti dalam ekspresi some(//foo:main intersect //bar:baz).

Operator jalur: somepath, allpath

expr ::= somepath(expr, expr)
       | allpaths(expr, expr)

Operator somepath(S, E) dan allpaths(S, E) menghitung jalur antara dua kumpulan target. Kedua kueri menerima dua argumen, satu set S dari titik awal dan satu E titik akhir. somepath menampilkan grafik node pada beberapa jalur arbitrer dari target di S ke target di E; allpaths menampilkan grafik node di semua jalur dari target mana pun di S ke target di E.

Grafik yang dihasilkan diurutkan berdasarkan hubungan dependensi. Lihat bagian tentang urutan grafik untuk detail selengkapnya.

Suatu Jalur
somepath(S1 + S2, E), satu kemungkinan hasil.
Suatu Jalur
somepath(S1 + S2, E), kemungkinan hasil lainnya.
Semua jalur
allpaths(S1 + S2, E)

Pemfilteran jenis target: jenis

expr ::= kind(word, expr)

Operator kind(pattern, input) menerapkan filter ke kumpulan target, dan menghapus target tersebut dari jenis yang tidak diharapkan. Parameter pattern menentukan jenis target yang akan dicocokkan.

Misalnya, jenis untuk empat target yang ditentukan oleh file BUILD (untuk paket p) yang ditampilkan di bawah diilustrasikan dalam tabel:

Kode Target Jenis
        genrule(
            name = "a",
            srcs = ["a.in"],
            outs = ["a.out"],
            cmd = "...",
        )
      
//p:a aturan genrule
//p:a.in file sumber
//p:a.out file yang dihasilkan
//p:BUILD file sumber

Dengan demikian, kind("cc_.* rule", foo/...) mengevaluasi ke kumpulan semua cc_library, cc_binary, dll., target aturan di bawah foo, dan kind("source file", deps(//foo)) mengevaluasi ke kumpulan semua file sumber dalam penutupan transitif dependensi target //foo.

Kutipan argumen pattern sering kali diperlukan karena tanpanya, banyak ekspresi reguler, seperti source file dan .*_test, tidak dianggap sebagai kata oleh parser.

Jika cocok dengan package group, target yang diakhiri dengan :all tidak dapat memberikan hasil apa pun. Gunakan :all-targets sebagai gantinya.

Pemfilteran nama target: filter

expr ::= filter(word, expr)

Operator filter(pattern, input) menerapkan filter ke kumpulan target, dan menghapus target yang labelnya (dalam bentuk absolut) tidak cocok dengan pola; operator akan dievaluasi ke subset inputnya.

Argumen pertama, pattern adalah kata yang berisi ekspresi reguler di atas nama target. Ekspresi filter mengevaluasi kumpulan yang berisi semua target x, sehingga x adalah anggota dari kumpulan input dan label (dalam bentuk absolut, seperti //foo:bar) dari x berisi kecocokan (tanpa anchor) untuk ekspresi reguler pattern. Karena semua nama target dimulai dengan //, nama tersebut dapat digunakan sebagai alternatif untuk anchor ekspresi reguler ^.

Operator ini sering kali menyediakan alternatif yang jauh lebih cepat dan lebih andal untuk operator intersect. Misalnya, untuk melihat semua dependensi bar dari target //foo:foo, seseorang dapat mengevaluasi

deps(//foo) intersect //bar/...

Namun, pernyataan ini akan memerlukan penguraian semua file BUILD di hierarki bar, yang akan lambat dan rentan terhadap error dalam file BUILD yang tidak relevan. Alternatifnya adalah:

filter(//bar, deps(//foo))

yang pertama akan menghitung kumpulan dependensi //foo, lalu memfilter hanya target yang cocok dengan pola yang diberikan—dengan kata lain, target dengan nama yang berisi //bar sebagai substring.

Penggunaan umum lainnya dari operator filter(pattern, expr) adalah memfilter file tertentu berdasarkan nama atau ekstensinya. Misalnya,

filter("\.cc$", deps(//foo))

akan memberikan daftar semua file .cc yang digunakan untuk membuat //foo.

Pemfilteran atribut aturan: atribut

expr ::= attr(word, word, expr)

Operator attr(name, pattern, input) menerapkan filter ke kumpulan target, dan menghapus target yang bukan aturan, target aturan yang tidak memiliki atribut name yang ditentukan atau target aturan dengan nilai atribut yang tidak cocok dengan ekspresi reguler pattern yang disediakan; nilai ini dievaluasi ke subset inputnya.

Argumen pertama, name adalah nama atribut aturan yang harus dicocokkan dengan pola ekspresi reguler yang diberikan. Argumen kedua, pattern adalah ekspresi reguler di atas nilai atribut. Ekspresi attr mengevaluasi set yang berisi semua target x sehingga x adalah anggota input yang ditetapkan, adalah aturan dengan atribut name yang ditentukan dan nilai atribut berisi pencocokan (tanpa anchor) untuk ekspresi reguler pattern. Jika name adalah atribut opsional dan aturan tidak menentukannya secara eksplisit, maka nilai atribut default akan digunakan untuk perbandingan. Misalnya,

attr(linkshared, 0, deps(//foo))

akan memilih semua dependensi //foo yang diizinkan untuk memiliki atribut linkshared (seperti, aturan cc_binary) dan menyetelnya secara eksplisit ke 0 atau tidak menetapkannya sama sekali, tetapi nilai defaultnya adalah 0 (misalnya untuk aturan cc_binary).

Atribut jenis daftar (seperti srcs, data, dll.) dikonversi menjadi string bentuk [value<sub>1</sub>, ..., value<sub>n</sub>], dimulai dengan tanda kurung [, diakhiri dengan tanda kurung ] dan menggunakan "," (koma, spasi) untuk membatasi beberapa nilai. Label dikonversi menjadi string dengan menggunakan bentuk absolut label. Misalnya, atribut deps=[":foo", "//otherpkg:bar", "wiz"] akan dikonversi menjadi string [//thispkg:foo, //otherpkg:bar, //thispkg:wiz]. Kurung selalu ada, sehingga daftar kosong akan menggunakan nilai string [] untuk tujuan pencocokan. Misalnya,

attr("srcs", "\[\]", deps(//foo))

akan memilih semua aturan di antara dependensi //foo yang memiliki atribut srcs kosong, sementara

attr("data", ".{3,}", deps(//foo))

akan memilih semua aturan di antara dependensi //foo yang menentukan setidaknya satu nilai dalam atribut data (setiap label panjangnya minimal 3 karakter karena // dan :).

Untuk memilih semua aturan di antara dependensi //foo dengan value tertentu dalam atribut jenis daftar, gunakan

attr("tags", "[\[ ]value[,\]]", deps(//foo))

Ini berfungsi karena karakter sebelum value akan menjadi [ atau spasi dan karakter setelah value akan menjadi koma atau ].

Pemfilteran visibilitas aturan: terlihat

expr ::= visible(expr, expr)

Operator visible(predicate, input) menerapkan filter ke kumpulan target, dan menghapus target tanpa visibilitas yang diperlukan.

Argumen pertama, predicate, adalah kumpulan target yang harus terlihat oleh semua target dalam output. Ekspresi visible dievaluasi ke kumpulan yang berisi semua target x sehingga x adalah anggota set input, dan untuk semua target y di predicate x dapat dilihat oleh y. Contoh:

visible(//foo, //bar:*)

akan memilih semua target dalam paket //bar yang dapat diandalkan //foo tanpa melanggar pembatasan visibilitas.

Evaluasi atribut aturan label jenis: label

expr ::= labels(word, expr)

Operator labels(attr_name, inputs) menampilkan kumpulan target yang ditentukan dalam atribut attr_name dari jenis "label" atau "daftar label" di beberapa aturan dalam kumpulan inputs.

Misalnya, labels(srcs, //foo) menampilkan kumpulan target yang muncul di atribut srcs dari aturan //foo. Jika ada beberapa aturan dengan atribut srcs dalam kumpulan inputs, gabungan srcs-nya akan ditampilkan.

Luaskan dan filter test_suite: pengujian

expr ::= tests(expr)

Operator tests(x) menampilkan kumpulan semua aturan pengujian dalam kumpulan x, yang memperluas aturan test_suite apa pun ke dalam kumpulan pengujian individual yang direferensikan, dan menerapkan pemfilteran berdasarkan tag dan size.

Secara default, evaluasi kueri mengabaikan target non-pengujian di semua aturan test_suite. Hal ini dapat diubah menjadi error dengan opsi --strict_test_suite.

Misalnya, kind(test, foo:*) kueri mencantumkan semua aturan *_test dan test_suite dalam paket foo. Semua hasilnya adalah (menurut definisi) anggota paket foo. Sebaliknya, kueri tests(foo:*) akan menampilkan semua pengujian individual yang akan dijalankan oleh bazel test foo:*: kueri ini dapat mencakup pengujian milik paket lain, yang direferensikan secara langsung atau tidak langsung melalui aturan test_suite.

File definisi paket: buildfile

expr ::= buildfiles(expr)

Operator buildfiles(x) menampilkan kumpulan file yang menentukan paket setiap target dalam kumpulan x; dengan kata lain, untuk setiap paket, file BUILD, ditambah file .bzl yang direferensikan melalui load. Perhatikan bahwa tindakan ini juga menampilkan file BUILD dari paket yang berisi file load ini.

Operator ini biasanya digunakan saat menentukan file atau paket yang diperlukan untuk membuat target yang ditentukan, sering kali bersama dengan opsi --output package, di bawah). Misalnya,

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

menampilkan kumpulan semua paket yang bergantung pada //foo secara transitif.