यह पेज, Bazel Query Language के लिए रेफ़रंस मैन्युअल है. इसका इस्तेमाल, bazel query
का इस्तेमाल करके बिल्ड डिपेंडेंसी का विश्लेषण करते समय किया जाता है. इसमें उन आउटपुट फ़ॉर्मैट के बारे में भी बताया गया है जिनके साथ bazel query
काम करता है.
इस्तेमाल के उदाहरणों के लिए, Bazel Query How-To देखें.
क्वेरी का अतिरिक्त रेफ़रंस
Bazel में query
के अलावा, ऐक्शन ग्राफ़ क्वेरी और कॉन्फ़िगर की जा सकने वाली क्वेरी भी शामिल हैं. query
, पोस्ट-लोडिंग फ़ेज़ के टारगेट ग्राफ़ पर काम करता है.
ऐक्शन ग्राफ़ क्वेरी
ऐक्शन ग्राफ़ क्वेरी (aquery
), विश्लेषण के बाद कॉन्फ़िगर किए गए टारगेट ग्राफ़ पर काम करती है. साथ ही, ऐक्शन, आर्टफ़ैक्ट, और उनके संबंधों के बारे में जानकारी देती है. aquery
का इस्तेमाल तब किया जाता है, जब आपको कॉन्फ़िगर किए गए टारगेट ग्राफ़ से जनरेट किए गए ऐक्शन/आर्टफ़ैक्ट की प्रॉपर्टी के बारे में जानना हो.
उदाहरण के लिए, असल में चलाए गए निर्देश और उनके इनपुट, आउटपुट, और नेमोनिक.
ज़्यादा जानकारी के लिए, aquery रेफ़रंस देखें.
कॉन्फ़िगर की जा सकने वाली क्वेरी
Bazel की पारंपरिक क्वेरी, पोस्ट-लोडिंग फ़ेज़ के टारगेट ग्राफ़ पर चलती है. इसलिए, इसमें कॉन्फ़िगरेशन और उनसे जुड़े कॉन्सेप्ट का कोई कॉन्सेप्ट नहीं होता. खास तौर पर, यह SELECT स्टेटमेंट को सही तरीके से हल नहीं करता है. इसके बजाय, यह SELECT स्टेटमेंट के सभी संभावित समाधान दिखाता है. हालांकि, कॉन्फ़िगर किए जा सकने वाले क्वेरी एनवायरमेंट, cquery
, में कॉन्फ़िगरेशन को सही तरीके से हैंडल किया जाता है. हालांकि, इसमें इस ओरिजनल क्वेरी की सभी सुविधाएं उपलब्ध नहीं होती हैं.
ज़्यादा जानकारी के लिए, cquery का रेफ़रंस देखें.
उदाहरण
लोग bazel query
का इस्तेमाल कैसे करते हैं? यहां कुछ सामान्य उदाहरण दिए गए हैं:
//foo
ट्री, //bar/baz
पर क्यों निर्भर करता है?
पाथ दिखाएं:
somepath(foo/..., //bar/baz:all)
foo
टारगेट में मौजूद कौनसी C++ लाइब्रेरी, foo
टेस्ट में मौजूद नहीं हैं?foo_bin
kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo:foo_bin))
टोकन: लेक्सिकल सिंटैक्स
क्वेरी लैंग्वेज में एक्सप्रेशन, इन टोकन से मिलकर बने होते हैं:
कीवर्ड, जैसे कि
let
. कीवर्ड, भाषा के रिज़र्व किए गए शब्द होते हैं. इनमें से हर एक के बारे में यहां बताया गया है. कीवर्ड का पूरा सेट यह है:शब्द, जैसे कि "
foo/...
" या ".*test rule
" या "//bar/baz:all
". अगर वर्णों के किसी क्रम को "कोट किया गया है" (सिंगल-कोट ' से शुरू और खत्म होता है या डबल-कोट " से शुरू और खत्म होता है), तो यह एक शब्द होता है. अगर किसी वर्ण क्रम को कोट नहीं किया गया है, तो भी उसे शब्द के तौर पर पार्स किया जा सकता है. बिना कोट किए गए शब्द, वर्णों के ऐसे क्रम होते हैं जिनमें A-Za-z वर्णमाला के अक्षर, 0-9 अंक, और*/@.-_:$~[]
(तारांकन, फ़ॉरवर्ड स्लैश, ऐट, फ़ुल स्टॉप, हाइफ़न, अंडरस्कोर, कोलन, डॉलर का निशान, टाइल्ड, बायां स्क्वेयर ब्रेस, दायां स्क्वेयर ब्रेस) जैसे खास वर्ण शामिल होते हैं. हालांकि, कोट नहीं किए गए शब्दों की शुरुआत हाइफ़न-
या तारा चिह्न*
से नहीं हो सकती. भले ही, रिलेटिव टारगेट के नाम इन वर्णों से शुरू हो सकते हों.बिना कोट किए गए शब्दों में, प्लस का निशान
+
या बराबर का निशान=
शामिल नहीं किया जा सकता. भले ही, टारगेट के नामों में इन वर्णों का इस्तेमाल किया जा सकता हो. क्वेरी एक्सप्रेशन जनरेट करने वाला कोड लिखते समय, टारगेट के नामों को कोट किया जाना चाहिए.उपयोगकर्ता की दी गई वैल्यू से Bazel क्वेरी एक्सप्रेशन बनाने वाली स्क्रिप्ट लिखते समय, कोटेशन मार्क का इस्तेमाल करना ज़रूरी है.
//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.
ध्यान दें कि यह कोटेशन, आपके शेल के लिए ज़रूरी किसी भी कोटेशन के अलावा है. जैसे:
bazel query ' "//foo:bar=wiz" ' # single-quotes for shell, double-quotes for Bazel.
कोट किए गए कीवर्ड और ऑपरेटर को सामान्य शब्दों के तौर पर माना जाता है. उदाहरण के लिए,
some
एक कीवर्ड है, लेकिन "कुछ" एक शब्द है.foo
और "foo", दोनों शब्द हैं.हालांकि, टारगेट के नामों में सिंगल या डबल कोट का इस्तेमाल करते समय सावधानी बरतें. एक या उससे ज़्यादा टारगेट के नामों को कोट करते समय, सिर्फ़ एक तरह के कोट का इस्तेमाल करें. जैसे, सभी सिंगल कोट या सभी डबल कोट.
यहां 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
हमने इस सिंटैक्स को इसलिए चुना है, ताकि ज़्यादातर मामलों में कोटेशन मार्क की ज़रूरत न पड़े. (असामान्य)
".*test rule"
उदाहरण में कोटेशन मार्क की ज़रूरत है: यह अवधि से शुरू होता है और इसमें एक स्पेस होता है."cc_library"
को कोट करना ज़रूरी नहीं है, लेकिन इससे कोई नुकसान नहीं होता.विराम चिह्न, जैसे कि ब्रैकेट
()
, फ़ुलस्टॉप.
, और कॉमा,
. विराम चिह्न वाले शब्दों (ऊपर बताए गए शब्दों के अलावा) को कोट किया जाना चाहिए.
कोट किए गए शब्द के बाहर मौजूद खाली सफ़ेद जगह को अनदेखा कर दिया जाता है.
Bazel की क्वेरी लैंग्वेज के कॉन्सेप्ट
Bazel क्वेरी लैंग्वेज, एक्सप्रेशन की एक लैंग्वेज है. हर एक्सप्रेशन, टारगेट का पार्शियल-ऑर्डर सेट या टारगेट का ग्राफ़ (डीएजी) दिखाता है. यह सिर्फ़ एक डेटा टाइप है.
सेट और ग्राफ़, एक ही डेटाटाइप को दिखाते हैं. हालांकि, ये इसके अलग-अलग पहलुओं पर ज़ोर देते हैं. उदाहरण के लिए:
- सेट: टारगेट का पार्शियल ऑर्डर काम का नहीं है.
- ग्राफ़: टारगेट का आंशिक क्रम अहम होता है.
डिपेंडेंसी ग्राफ़ में साइकल
डिपेंडेंसी ग्राफ़ में कोई साइकल नहीं होना चाहिए.
क्वेरी लैंग्वेज में इस्तेमाल किए जाने वाले एल्गोरिदम, असाइकलिक ग्राफ़ में इस्तेमाल किए जाने के लिए बनाए गए हैं. हालांकि, ये साइकल के ख़िलाफ़ मज़बूत होते हैं. इसमें यह जानकारी नहीं दी गई है कि साइकल को कैसे मैनेज किया जाता है. इसलिए, इस पर भरोसा नहीं किया जाना चाहिए.
इंप्लिसिट डिपेंडेंसी
BUILD
फ़ाइलों में साफ़ तौर पर तय की गई बिल्ड डिपेंडेंसी के अलावा, Bazel नियमों में इंप्लिसिट डिपेंडेंसी भी जोड़ता है. उदाहरण के लिए, हर Java नियम, JavaBuilder पर निर्भर करता है. $
से शुरू होने वाले एट्रिब्यूट का इस्तेमाल करके, डिपेंडेंसी तय की जाती हैं. इन्हें BUILD
फ़ाइलों में बदला नहीं जा सकता.
डिफ़ॉल्ट रूप से, bazel query
क्वेरी के नतीजे का हिसाब लगाते समय, छिपी हुई डिपेंडेंसी को ध्यान में रखता है. --[no]implicit_deps
विकल्प का इस्तेमाल करके, इस सुविधा को बंद किया जा सकता है. ध्यान दें कि क्वेरी में कॉन्फ़िगरेशन को ध्यान में नहीं रखा जाता है. इसलिए, संभावित टूलचेन पर कभी विचार नहीं किया जाता.
साउंडनेस
Bazel की क्वेरी लैंग्वेज के एक्सप्रेशन, बिल्ड डिपेंडेंसी ग्राफ़ पर काम करते हैं. यह ग्राफ़, सभी BUILD
फ़ाइलों में सभी नियम के एलान से अपने-आप तय होता है. यह समझना ज़रूरी है कि यह ग्राफ़ कुछ हद तक अमूर्त है. साथ ही, इसमें किसी बिल्ड के सभी चरणों को पूरा करने के तरीके के बारे में पूरी जानकारी नहीं दी गई है. बिल्ड करने के लिए, कॉन्फ़िगरेशन भी ज़रूरी है. ज़्यादा जानकारी के लिए, उपयोगकर्ता गाइड का कॉन्फ़िगरेशन सेक्शन देखें.
Bazel क्वेरी लैंग्वेज में किसी एक्सप्रेशन का आकलन करने पर, सभी कॉन्फ़िगरेशन के लिए नतीजा सही होता है. इसका मतलब है कि यह एक अनुमानित नतीजा हो सकता है और सटीक नहीं हो सकता. अगर आपने क्वेरी टूल का इस्तेमाल करके, बिल्ड के दौरान ज़रूरी सभी सोर्स फ़ाइलों का सेट कंप्यूट किया है, तो हो सकता है कि यह टूल, ज़रूरत से ज़्यादा फ़ाइलों की जानकारी दे. ऐसा इसलिए होता है, क्योंकि क्वेरी टूल उन सभी फ़ाइलों को शामिल करेगा जिनकी ज़रूरत मैसेज का अनुवाद करने के लिए होती है. भले ही, आपको अपने बिल्ड में उस सुविधा का इस्तेमाल न करना हो.
ग्राफ़ के क्रम को बनाए रखने के बारे में
ऑपरेशन, अपने सबएक्सप्रेशन से मिली किसी भी क्रम से जुड़ी शर्त को बनाए रखते हैं. इसे "आंशिक क्रम के संरक्षण का नियम" कहा जा सकता है. उदाहरण के लिए: अगर आपको किसी टारगेट की डिपेंडेंसी का ट्रांज़िटिव क्लोज़र पता करना है, तो क्वेरी जारी करें. इसके बाद, नतीजे के तौर पर मिलने वाले सेट को डिपेंडेंसी ग्राफ़ के हिसाब से क्रम में लगाया जाता है. अगर उस सेट को फ़िल्टर करके, सिर्फ़ file
तरह के टारगेट शामिल किए जाते हैं, तो नतीजे में मिले सबसेट में टारगेट के हर जोड़े के बीच, ट्रांज़िटिव पार्शियल ऑर्डरिंग का वही संबंध होता है. भले ही, मूल ग्राफ़ में इनमें से कोई भी जोड़ा सीधे तौर पर कनेक्ट न हो.
(बिल्ड डिपेंडेंसी ग्राफ़ में, फ़ाइल-फ़ाइल के बीच कोई एज नहीं है).
हालांकि, सभी ऑपरेटर क्रम बनाए रखते हैं. वहीं, कुछ कार्रवाइयां, जैसे कि सेट ऑपरेशंस, क्रम से जुड़ी कोई भी पाबंदी लागू नहीं करती हैं. इस एक्सप्रेशन पर विचार करें:
deps(x) union y
फ़ाइनल नतीजे के सेट का क्रम, इसके सबएक्सप्रेशन के क्रम से जुड़ी सभी शर्तों को पूरा करता है. इसका मतलब है कि x
की सभी ट्रांज़िटिव डिपेंडेंसी, एक-दूसरे के हिसाब से सही क्रम में होती हैं. हालांकि, क्वेरी से इस बात की कोई गारंटी नहीं मिलती कि y
में टारगेट किस क्रम में होंगे. न ही इससे इस बात की गारंटी मिलती है कि deps(x)
में टारगेट किस क्रम में होंगे. y
में मौजूद टारगेट के मुकाबले deps(x)
में मौजूद टारगेट किस क्रम में होंगे, इसकी भी कोई गारंटी नहीं मिलती. हालांकि, y
में मौजूद ऐसे टारगेट के बारे में यह जानकारी मिलती है जो deps(x)
में भी मौजूद हैं.
क्रम से जुड़ी पाबंदियां लागू करने वाले ऑपरेटर में ये शामिल हैं:
allpaths
, deps
, rdeps
, somepath
, और टारगेट पैटर्न वाइल्डकार्ड
package:*
, dir/...
वगैरह.
स्काई क्वेरी
स्काई क्वेरी, क्वेरी का एक ऐसा मोड है जो तय किए गए यूनिवर्स स्कोप पर काम करता है.
सिर्फ़ SkyQuery में उपलब्ध खास फ़ंक्शन
स्काई क्वेरी मोड में, क्वेरी के अतिरिक्त फ़ंक्शन allrdeps
और rbuildfiles
होते हैं. ये फ़ंक्शन, पूरे यूनिवर्स के स्कोप पर काम करते हैं. इसलिए, ये सामान्य क्वेरी के लिए सही नहीं हैं.
यूनिवर्स का स्कोप तय करना
स्काई क्वेरी मोड को चालू करने के लिए, इन दो फ़्लैग को पास करें:
(--universe_scope
या --infer_universe_scope
) और
--order_output=no
.
--universe_scope=<target_pattern1>,...,<target_patternN>
, क्वेरी को टारगेट पैटर्न के ट्रांज़िटिव क्लोज़र को प्रीलोड करने के लिए कहता है. टारगेट पैटर्न, टारगेट पैटर्न से तय होता है. यह ऐडिटिव और सबट्रैक्टिव, दोनों हो सकता है. इसके बाद, सभी क्वेरी का आकलन इस "स्कोप" में किया जाता है. खास तौर पर, allrdeps
और rbuildfiles
ऑपरेटर सिर्फ़ इसी स्कोप से नतीजे दिखाते हैं.
--infer_universe_scope
, Bazel को यह निर्देश देता है कि वह क्वेरी एक्सप्रेशन से --universe_scope
की वैल्यू का अनुमान लगाए. अनुमानित वैल्यू, क्वेरी एक्सप्रेशन में मौजूद यूनीक टारगेट पैटर्न की सूची होती है. हालांकि, ऐसा हो सकता है कि यह आपकी ज़रूरत के मुताबिक न हो. उदाहरण के लिए:
bazel query --infer_universe_scope --order_output=no "allrdeps(//my:target)"
इस क्वेरी एक्सप्रेशन में यूनीक टारगेट पैटर्न की सूची ["//my:target"]
है. इसलिए, Bazel इसे इस इनवोकेशन की तरह ही मानता है:
bazel query --universe_scope=//my:target --order_output=no "allrdeps(//my:target)"
हालांकि, --universe_scope
के साथ उस क्वेरी का नतीजा सिर्फ़ //my:target
है;
बनावट के हिसाब से, //my:target
की कोई भी रिवर्स डिपेंडेंसी यूनिवर्स में नहीं है! वहीं दूसरी ओर, इन बातों पर ध्यान दें:
bazel query --infer_universe_scope --order_output=no "tests(//a/... + b/...) intersect allrdeps(siblings(rbuildfiles(my/starlark/file.bzl)))"
यह क्वेरी, टेस्ट टारगेट को कंप्यूट करने के लिए है. यह क्वेरी, कुछ डायरेक्ट्री के टारगेट के tests
एक्सपैंशन में टेस्ट टारगेट को कंप्यूट करने की कोशिश कर रही है. ये डायरेक्ट्री, उन टारगेट पर ट्रांज़िटिव तरीके से निर्भर करती हैं जिनकी परिभाषा में किसी .bzl
फ़ाइल का इस्तेमाल किया जाता है. यहां, --infer_universe_scope
एक सुविधा है. खास तौर पर, ऐसे मामले में जहां --universe_scope
को चुनने के लिए, आपको क्वेरी एक्सप्रेशन को खुद पार्स करना होगा.
इसलिए, allrdeps
और rbuildfiles
जैसे यूनिवर्स-स्कोप वाले ऑपरेटर का इस्तेमाल करने वाले क्वेरी एक्सप्रेशन के लिए, --infer_universe_scope
का इस्तेमाल सिर्फ़ तब करें, जब आपको इसका व्यवहार पसंद हो.
डिफ़ॉल्ट क्वेरी की तुलना में, स्काई क्वेरी के कुछ फ़ायदे और नुकसान हैं. इसका मुख्य नुकसान यह है कि यह अपने आउटपुट को ग्राफ़ के क्रम के हिसाब से व्यवस्थित नहीं कर सकता. इसलिए, कुछ आउटपुट फ़ॉर्मैट इस्तेमाल नहीं किए जा सकते. इसके फ़ायदे ये हैं: यह दो ऑपरेटर (allrdeps
और rbuildfiles
) उपलब्ध कराता है, जो डिफ़ॉल्ट क्वेरी में उपलब्ध नहीं हैं.
साथ ही, Sky Query, नया ग्राफ़ बनाने के बजाय Skyframe ग्राफ़ की जांच करके काम करता है. डिफ़ॉल्ट तौर पर, नया ग्राफ़ बनाया जाता है. इसलिए, कुछ मामलों में यह ज़्यादा तेज़ होता है और कम मेमोरी का इस्तेमाल करता है.
एक्सप्रेशन: व्याकरण का सिंटैक्स और सिमैंटिक्स
यह Bazel क्वेरी लैंग्वेज की व्याकरण है, जिसे 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 ... ')'
यहां दिए गए सेक्शन में, इस व्याकरण के हर प्रोडक्शन के बारे में क्रम से बताया गया है.
टारगेट पैटर्न
expr ::= word
सिंटैक्टिक तौर पर, टारगेट पैटर्न सिर्फ़ एक शब्द होता है. इसे टारगेट के (बिना क्रम वाला) सेट के तौर पर समझा जाता है. सबसे आसान टारगेट पैटर्न एक लेबल होता है. यह किसी एक टारगेट (फ़ाइल या नियम) की पहचान करता है. उदाहरण के लिए, टारगेट पैटर्न //foo:bar
का आकलन, एक एलिमेंट वाले सेट के तौर पर किया जाता है. इसमें टारगेट, bar
नियम शामिल होता है.
टारगेट पैटर्न, लेबल को सामान्य बनाते हैं, ताकि पैकेज और टारगेट में वाइल्डकार्ड शामिल किए जा सकें. उदाहरण के लिए, foo/...:all
(या सिर्फ़ foo/...
) एक टारगेट पैटर्न है. यह foo
डायरेक्ट्री के नीचे मौजूद हर पैकेज में, सभी नियमों वाले सेट का आकलन करता है. bar/baz:all
एक टारगेट पैटर्न है. यह bar/baz
पैकेज में मौजूद सभी नियमों वाले सेट का आकलन करता है, लेकिन इसके सब-पैकेज का नहीं.
इसी तरह, foo/...:*
एक टारगेट पैटर्न है. यह एक ऐसे सेट का आकलन करता है जिसमें foo
डायरेक्ट्री के नीचे मौजूद हर पैकेज में सभी टारगेट (नियम और फ़ाइलें) शामिल होते हैं. bar/baz:*
, bar/baz
पैकेज में मौजूद सभी टारगेट वाले सेट का आकलन करता है, लेकिन इसके सब-पैकेज का नहीं.
:*
वाइल्डकार्ड, फ़ाइलों के साथ-साथ नियमों से भी मेल खाता है. इसलिए, यह अक्सर क्वेरी के लिए :all
से ज़्यादा काम का होता है. इसके उलट, :all
वाइल्डकार्ड (foo/...
जैसे टारगेट पैटर्न में शामिल) आम तौर पर बिल्ड के लिए ज़्यादा फ़ायदेमंद होता है.
bazel query
टारगेट पैटर्न, bazel build
बिल्ड टारगेट की तरह ही काम करते हैं.
ज़्यादा जानकारी के लिए, टारगेट पैटर्न देखें या
bazel help target-syntax
टाइप करें.
टारगेट पैटर्न का आकलन, सिंगलटन सेट (लेबल के मामले में), कई एलिमेंट वाला सेट (जैसे कि foo/...
के मामले में, जिसमें हज़ारों एलिमेंट होते हैं) या खाली सेट के तौर पर किया जा सकता है. ऐसा तब होता है, जब टारगेट पैटर्न किसी भी टारगेट से मेल नहीं खाता.
टारगेट पैटर्न एक्सप्रेशन के नतीजे में मौजूद सभी नोड, एक-दूसरे के हिसाब से सही क्रम में होते हैं. यह क्रम, निर्भरता के संबंध के हिसाब से तय होता है. इसलिए, foo:*
का नतीजा सिर्फ़ पैकेज foo
में मौजूद टारगेट का सेट नहीं है, बल्कि यह उन टारगेट का ग्राफ़ भी है. (नतीजे के नोड को अन्य नोड के मुकाबले किस क्रम में दिखाया जाएगा, इसकी कोई गारंटी नहीं है.) ज़्यादा जानकारी के लिए, ग्राफ़ का क्रम सेक्शन देखें.
वैरिएबल
expr ::= let name = expr1 in expr2
| $name
Bazel की क्वेरी लैंग्वेज में, वैरिएबल को परिभाषित करने और उनके रेफ़रंस देने की अनुमति होती है. let
एक्सप्रेशन का आकलन करने पर मिलने वाला नतीजा, expr2 के बराबर होता है. इसमें वैरिएबल name के सभी फ़्री इंस्टेंस को expr1 की वैल्यू से बदल दिया जाता है.
उदाहरण के लिए, let v = foo/... in allpaths($v, //common) intersect $v
, allpaths(foo/...,//common) intersect foo/...
के बराबर है.
अगर वैरिएबल रेफ़रंस name
, let name = ...
एक्सप्रेशन में शामिल नहीं है, तो उसे गड़बड़ी माना जाता है. दूसरे शब्दों में, टॉप-लेवल क्वेरी एक्सप्रेशन में फ़्री वैरिएबल नहीं हो सकते.
ऊपर दिए गए व्याकरण के नियमों में, name
, word की तरह है. हालांकि, इसमें यह अतिरिक्त शर्त है कि यह C प्रोग्रामिंग भाषा में एक मान्य आइडेंटिफ़ायर होना चाहिए. वैरिएबल के रेफ़रंस से पहले "$" वर्ण जोड़ना ज़रूरी है.
हर let
एक्सप्रेशन सिर्फ़ एक वैरिएबल तय करता है. हालांकि, इन्हें नेस्ट किया जा सकता है.
टारगेट पैटर्न और वैरिएबल रेफ़रंस, दोनों में सिर्फ़ एक टोकन होता है. यह एक शब्द होता है, जिससे सिंटैक्टिक अस्पष्टता पैदा होती है. हालांकि, इसमें कोई सिमैंटिक अस्पष्टता नहीं है, क्योंकि कानूनी तौर पर मान्य वैरिएबल नामों का सबसेट, कानूनी तौर पर मान्य टारगेट पैटर्न के सबसेट से अलग होता है.
तकनीकी तौर पर, let
एक्सप्रेशन से क्वेरी की भाषा की अभिव्यक्ति क्षमता नहीं बढ़ती है: भाषा में एक्सप्रेस की जा सकने वाली किसी भी क्वेरी को इनके बिना भी एक्सप्रेस किया जा सकता है. हालांकि, इनसे कई क्वेरी के जवाब कम शब्दों में मिलते हैं. साथ ही, क्वेरी का आकलन ज़्यादा असरदार तरीके से किया जा सकता है.
ब्रैकेट में दिए गए एक्सप्रेशन
expr ::= (expr)
ब्रैकेट, सबएक्सप्रेशन को जोड़ते हैं, ताकि इवैलुएशन का क्रम लागू किया जा सके. ब्रैकेट में दिए गए एक्सप्रेशन का आकलन, उसके तर्क की वैल्यू के हिसाब से किया जाता है.
सेट के लिए बीजगणितीय संक्रियाएं: इंटरसेक्शन, यूनियन, सेट डिफरेंस
expr ::= expr intersect expr
| expr ^ expr
| expr union expr
| expr + expr
| expr except expr
| expr - expr
ये तीनों ऑपरेटर, अपने आर्ग्युमेंट पर सामान्य सेट ऑपरेशन करते हैं.
हर ऑपरेटर के दो फ़ॉर्म होते हैं. एक नॉमिनल फ़ॉर्म, जैसे कि intersect
और दूसरा सिंबॉलिक फ़ॉर्म, जैसे कि ^
. दोनों फ़ॉर्म एक जैसे हैं. सिंबल वाले फ़ॉर्म को टाइप करने में कम समय लगता है. (आसानी से समझने के लिए, इस पेज पर बाकी जगहों पर सामान्य फ़ॉर्म का इस्तेमाल किया गया है.)
उदाहरण के लिए,
foo/... except foo/bar/...
इस फ़ंक्शन से, उन टारगेट का सेट मिलता है जो foo/...
से मेल खाते हैं, लेकिन foo/bar/...
से नहीं.
इस क्वेरी को ऐसे भी लिखा जा सकता है:
foo/... - foo/bar/...
intersect
(^
) और union
(+
) ऑपरेशन कम्यूटेटिव (सिमेट्रिक) होते हैं;
except
(-
) असिमेट्रिक होता है. पार्सर, तीनों ऑपरेटर को लेफ्ट-एसोसिएटिव और एक ही प्राथमिकता वाला मानता है. इसलिए, आपको कोष्ठक का इस्तेमाल करना पड़ सकता है. उदाहरण के लिए, इनमें से पहले दो एक्सप्रेशन एक जैसे हैं, लेकिन तीसरा अलग है:
x intersect y union z
(x intersect y) union z
x intersect (y union z)
किसी बाहरी सोर्स से टारगेट पढ़ने की अनुमति: सेट
expr ::= set(word *)
set(a b c ...)
ऑपरेटर, शून्य या उससे ज़्यादा टारगेट पैटर्न के सेट का यूनियन कंप्यूट करता है. इन्हें खाली जगह (कॉमा नहीं) से अलग किया जाता है.
बोर्न शेल की $(...)
सुविधा के साथ मिलकर काम करने वाला set()
, एक क्वेरी के नतीजों को सामान्य टेक्स्ट फ़ाइल में सेव करने का तरीका उपलब्ध कराता है. साथ ही, यह अन्य प्रोग्राम (जैसे कि स्टैंडर्ड यूनिक्स शेल टूल) का इस्तेमाल करके, उस टेक्स्ट फ़ाइल में बदलाव करने और फिर क्वेरी टूल में नतीजे को वैल्यू के तौर पर वापस लाने की सुविधा देता है, ताकि आगे की प्रोसेसिंग की जा सके. उदाहरण के लिए:
bazel query deps(//my:target) --output=label | grep ... | sed ... | awk ... > foo
bazel query "kind(cc_binary, set($(<foo)))"
अगले उदाहरण में, kind(cc_library, deps(//some_dir/foo:main, 5))
की गिनती, awk
प्रोग्राम का इस्तेमाल करके maxrank
वैल्यू को फ़िल्टर करके की जाती है.
bazel query 'deps(//some_dir/foo:main)' --output maxrank | awk '($1 < 5) { print $2;} ' > foo
bazel query "kind(cc_library, set($(<foo)))"
इन उदाहरणों में, $(<foo)
, $(cat foo)
के लिए शॉर्टहैंड है. हालांकि, cat
के अलावा अन्य शेल कमांड का इस्तेमाल भी किया जा सकता है. जैसे, पिछली awk
कमांड.
फ़ंक्शन
expr ::= word '(' int | word | expr ... ')'
क्वेरी लैंग्वेज में कई फ़ंक्शन तय किए गए हैं. फ़ंक्शन के नाम से यह तय होता है कि इसके लिए कितने और किस तरह के आर्ग्युमेंट की ज़रूरत है. ये फ़ंक्शन उपलब्ध हैं:
allpaths
attr
buildfiles
rbuildfiles
deps
filter
kind
labels
loadfiles
rdeps
allrdeps
same_pkg_direct_rdeps
siblings
some
somepath
tests
visible
डिपेंडेंसी का ट्रांज़िटिव क्लोज़र: deps
expr ::= deps(expr)
| deps(expr, depth)
deps(x)
ऑपरेटर, अपने आर्ग्युमेंट सेट x की डिपेंडेंसी के ट्रांज़िटिव क्लोज़र से बने ग्राफ़ का आकलन करता है. उदाहरण के लिए, deps(//foo)
की वैल्यू, foo
नोड पर आधारित डिपेंडेंसी ग्राफ़ है. इसमें इसकी सभी डिपेंडेंसी शामिल हैं. deps(foo/...)
की वैल्यू, डिपेंडेंसी ग्राफ़ होती है. इसके रूट, foo
डायरेक्ट्री के नीचे मौजूद हर पैकेज के सभी नियम होते हैं. इस संदर्भ में, 'डिपेंडेंसी' का मतलब सिर्फ़ नियम और फ़ाइल टारगेट से है. इसलिए, इन टारगेट को बनाने के लिए ज़रूरी BUILD
और Starlark फ़ाइलें यहां शामिल नहीं हैं. इसके लिए, आपको buildfiles
ऑपरेटर का इस्तेमाल करना चाहिए.
नतीजे के तौर पर मिले ग्राफ़ को डिपेंडेंसी के हिसाब से क्रम में लगाया जाता है. ज़्यादा जानकारी के लिए, ग्राफ़ का क्रम सेक्शन देखें.
deps
ऑपरेटर, दूसरे आर्ग्युमेंट को स्वीकार करता है. यह आर्ग्युमेंट ज़रूरी नहीं है. यह एक पूर्णांक लिटरल होता है, जो खोज की गहराई की ऊपरी सीमा तय करता है. इसलिए, deps(foo:*, 0)
, foo
पैकेज में मौजूद सभी टारगेट दिखाता है. वहीं, deps(foo:*, 1)
में foo
पैकेज में मौजूद किसी भी टारगेट की ज़रूरी शर्तें शामिल होती हैं. इसके अलावा, deps(foo:*, 2)
में deps(foo:*, 1)
में मौजूद नोड से सीधे तौर पर पहुंचने वाले नोड शामिल होते हैं. इसी तरह, यह प्रोसेस आगे बढ़ती रहती है. (ये नंबर, minrank
आउटपुट फ़ॉर्मैट में दिखाई गई रैंक के हिसाब से हैं.)
अगर depth पैरामीटर को शामिल नहीं किया जाता है, तो खोज की कोई सीमा नहीं होती: यह ज़रूरी शर्तों के रिफ़्लेक्सिव ट्रांज़िटिव क्लोज़र का हिसाब लगाता है.
रिवर्स डिपेंडेंसी का ट्रांज़िटिव क्लोज़र: rdeps
expr ::= rdeps(expr, expr)
| rdeps(expr, expr, depth)
rdeps(u, x)
ऑपरेटर, यूनिवर्स सेट
u के ट्रांज़िटिव क्लोज़र में, आर्ग्युमेंट सेट
x की रिवर्स डिपेंडेंसी का आकलन करता है.
नतीजे के तौर पर मिले ग्राफ़ को डिपेंडेंसी के हिसाब से क्रम में लगाया जाता है. ज़्यादा जानकारी के लिए, ग्राफ़ का क्रम सेक्शन देखें.
rdeps
ऑपरेटर, तीसरे आर्ग्युमेंट को स्वीकार करता है. यह एक पूर्णांक लिटरल होता है, जो खोज की गहराई की ऊपरी सीमा तय करता है. इस ग्राफ़ में सिर्फ़ वे नोड शामिल होते हैं जो आर्ग्युमेंट सेट में मौजूद किसी भी नोड से तय की गई डेप्थ की दूरी पर होते हैं. इसलिए, rdeps(//foo, //common, 1)
का आकलन, //foo
के ट्रांज़िटिव क्लोज़र में मौजूद उन सभी नोड के तौर पर किया जाता है जो सीधे तौर पर //common
पर निर्भर होते हैं. (ये नंबर, minrank
आउटपुट फ़ॉर्मैट में दिखाई गई रैंक से मेल खाते हैं.) अगर depth पैरामीटर को शामिल नहीं किया जाता है, तो खोज की सीमा तय नहीं की जाती है.
सभी रिवर्स डिपेंडेंसी का ट्रांज़िटिव क्लोज़र: allrdeps
expr ::= allrdeps(expr)
| allrdeps(expr, depth)
allrdeps
ऑपरेटर, rdeps
ऑपरेटर की तरह ही काम करता है. हालांकि, "यूनिवर्स सेट" को अलग से तय करने के बजाय, --universe_scope
फ़्लैग के तौर पर इस्तेमाल किया जाता है. इसलिए, अगर --universe_scope=//foo/...
पास हो गया है, तो allrdeps(//bar)
, rdeps(//foo/..., //bar)
के बराबर है.
एक ही पैकेज में सीधे तौर पर निर्भरता वाले पैकेज: same_pkg_direct_rdeps
expr ::= same_pkg_direct_rdeps(expr)
same_pkg_direct_rdeps(x)
ऑपरेटर, टारगेट के उस पूरे सेट का आकलन करता है जो आर्ग्युमेंट सेट में मौजूद टारगेट के साथ एक ही पैकेज में शामिल हैं और जो सीधे तौर पर उस पर निर्भर करते हैं.
टारगेट के पैकेज से निपटना: भाई-बहन
expr ::= siblings(expr)
siblings(x)
ऑपरेटर, टारगेट के उस पूरे सेट का आकलन करता है जो आर्ग्युमेंट सेट में मौजूद टारगेट के साथ एक ही पैकेज में शामिल है.
कोई भी विकल्प: कुछ
expr ::= some(expr)
| some(expr, count )
some(x, k)
ऑपरेटर, अपने आर्ग्युमेंट सेट x से ज़्यादा से ज़्यादा k टारगेट चुनता है. साथ ही, यह सिर्फ़ उन टारगेट वाले सेट का आकलन करता है. पैरामीटर k ज़रूरी नहीं है. अगर यह मौजूद नहीं है, तो नतीजे के तौर पर एक सिंगलटन सेट मिलेगा. इसमें सिर्फ़ एक टारगेट होगा, जिसे मनमुताबिक चुना जाएगा. अगर आर्ग्युमेंट सेट x का साइज़, k से छोटा है, तो पूरा आर्ग्युमेंट सेट x दिखेगा.
उदाहरण के लिए, एक्सप्रेशन some(//foo:main union //bar:baz)
का आकलन करने पर, एक सिंगलटन सेट मिलता है. इसमें //foo:main
या //bar:baz
में से कोई एक शामिल होता है. हालांकि, यह तय नहीं होता कि इनमें से कौनसी वैल्यू शामिल होगी. एक्सप्रेशन some(//foo:main union //bar:baz, 2)
या some(//foo:main union //bar:baz, 3)
, //foo:main
और //bar:baz
, दोनों वैल्यू दिखाता है.
अगर आर्ग्युमेंट एक सिंगलटन है, तो some
आइडेंटिटी फ़ंक्शन का हिसाब लगाता है: some(//foo:main)
, //foo:main
के बराबर होता है.
अगर तय किया गया आर्ग्युमेंट सेट खाली है, तो यह गड़बड़ी है. जैसे, some(//foo:main intersect //bar:baz)
एक्सप्रेशन में.
पाथ ऑपरेटर: somepath, allpaths
expr ::= somepath(expr, expr)
| allpaths(expr, expr)
somepath(S, E)
और allpaths(S, E)
ऑपरेटर, टारगेट के दो सेट के बीच के पाथ का हिसाब लगाते हैं. दोनों क्वेरी में दो आर्ग्युमेंट स्वीकार किए जाते हैं. पहला, शुरुआती पॉइंट का सेट S और दूसरा, आखिरी पॉइंट का सेट E. somepath
, S में मौजूद किसी टारगेट से E में मौजूद किसी टारगेट तक के कुछ पाथ पर मौजूद नोड का ग्राफ़ दिखाता है; allpaths
, S में मौजूद किसी टारगेट से E में मौजूद किसी टारगेट तक के सभी पाथ पर मौजूद नोड का ग्राफ़ दिखाता है.
नतीजे के तौर पर मिले ग्राफ़ को, डिपेंडेंसी के हिसाब से क्रम में लगाया जाता है. ज़्यादा जानकारी के लिए, ग्राफ़ का क्रम सेक्शन देखें.
somepath(S1 + S2, E) , एक संभावित नतीजा. |
somepath(S1 + S2, E) , यह भी एक संभावित नतीजा है. |
allpaths(S1 + S2, E) |
टारगेट के टाइप के हिसाब से फ़िल्टर करना: kind
expr ::= kind(word, expr)
kind(pattern, input)
ऑपरेटर, टारगेट के सेट पर फ़िल्टर लागू करता है. साथ ही, उन टारगेट को खारिज कर देता है जो उम्मीद के मुताबिक नहीं हैं. pattern
पैरामीटर से पता चलता है कि किस तरह के टारगेट को मैच करना है.
उदाहरण के लिए, यहां दी गई टेबल में BUILD
फ़ाइल में तय किए गए चार टारगेट (पैकेज p
के लिए) के टाइप दिखाए गए हैं:
कोड | टारगेट | टाइप |
---|---|---|
genrule( name = "a", srcs = ["a.in"], outs = ["a.out"], cmd = "...", ) |
//p:a |
genrule नियम |
//p:a.in |
सोर्स फ़ाइल | |
//p:a.out |
जनरेट की गई फ़ाइल | |
//p:BUILD |
सोर्स फ़ाइल |
इसलिए, kind("cc_.* rule", foo/...)
का आकलन, foo
के नीचे मौजूद सभी cc_library
, cc_binary
वगैरह के नियम टारगेट के सेट के तौर पर किया जाता है. साथ ही, kind("source file", deps(//foo))
का आकलन, //foo
टारगेट की डिपेंडेंसी के ट्रांज़िटिव क्लोज़र में मौजूद सभी सोर्स फ़ाइलों के सेट के तौर पर किया जाता है.
patternआर्गुमेंट का कोटेशन अक्सर ज़रूरी होता है
क्योंकि इसके बिना, कई रेगुलर एक्सप्रेशन, जैसे कि source
file
और .*_test
, को पार्सर शब्दों के तौर पर नहीं मानता है.
package group
के लिए मैचिंग करते समय, :all
पर खत्म होने वाले टारगेट से कोई नतीजा नहीं मिल सकता. इसके बजाय, :all-targets
का इस्तेमाल करें.
टारगेट के नाम के हिसाब से फ़िल्टर करना: फ़िल्टर करें
expr ::= filter(word, expr)
filter(pattern, input)
ऑपरेटर, टारगेट के सेट पर फ़िल्टर लागू करता है. साथ ही, उन टारगेट को खारिज कर देता है जिनके लेबल (पूरी जानकारी के साथ) पैटर्न से मेल नहीं खाते. यह अपने इनपुट के सबसेट का आकलन करता है.
पहला आर्ग्युमेंट, pattern एक ऐसा शब्द है जिसमें टारगेट के नामों के लिए रेगुलर एक्सप्रेशन होता है. filter
एक्सप्रेशन, उन सभी टारगेट x का सेट दिखाता है जो input सेट के सदस्य हैं. साथ ही, x के लेबल (जैसे कि //foo:bar
) में रेगुलर एक्सप्रेशन pattern के लिए (अनऐंकर्ड) मैच शामिल है.x सभी टारगेट के नाम //
से शुरू होते हैं. इसलिए, इसका इस्तेमाल ^
रेगुलर एक्सप्रेशन ऐंकर के विकल्प के तौर पर किया जा सकता है.
यह ऑपरेटर, अक्सर intersect
ऑपरेटर के मुकाबले ज़्यादा तेज़ी से और बेहतर तरीके से काम करता है. उदाहरण के लिए, //foo:foo
टारगेट की सभी bar
डिपेंडेंसी देखने के लिए, कोई व्यक्ति
deps(//foo) intersect //bar/...
हालांकि, इस स्टेटमेंट के लिए BUILD
ट्री में मौजूद सभी bar
फ़ाइलों को पार्स करना होगा. इससे प्रोसेस धीमी हो जाएगी और काम की न होने वाली BUILD
फ़ाइलों में गड़बड़ियां होने की आशंका बढ़ जाएगी. इसके अलावा, यह तरीका भी अपनाया जा सकता है:
filter(//bar, deps(//foo))
यह सबसे पहले //foo
डिपेंडेंसी के सेट का हिसाब लगाएगा. इसके बाद, सिर्फ़ उन टारगेट को फ़िल्टर करेगा जो दिए गए पैटर्न से मेल खाते हैं. दूसरे शब्दों में कहें, तो ऐसे टारगेट जिनके नाम में //bar
सबस्ट्रिंग के तौर पर शामिल है.
filter(pattern,
expr)
ऑपरेटर का इस्तेमाल, किसी फ़ाइल को उसके नाम या एक्सटेंशन के हिसाब से फ़िल्टर करने के लिए भी किया जाता है. उदाहरण के लिए,
filter("\.cc$", deps(//foo))
से, //foo
बनाने के लिए इस्तेमाल की गई सभी .cc
फ़ाइलों की सूची मिलेगी.
नियम के एट्रिब्यूट के हिसाब से फ़िल्टर करना: attr
expr ::= attr(word, word, expr)
attr(name, pattern, input)
ऑपरेटर, टारगेट के सेट पर फ़िल्टर लागू करता है. साथ ही, उन टारगेट को खारिज कर देता है जो नियम नहीं हैं, ऐसे नियम टारगेट जिनमें name एट्रिब्यूट तय नहीं किया गया है या ऐसे नियम टारगेट जिनमें एट्रिब्यूट की वैल्यू, दिए गए रेगुलर एक्सप्रेशन से मेल नहीं खाती है pattern; यह अपने इनपुट के सबसेट का आकलन करता है.
पहला आर्ग्युमेंट, name है. यह नियम के उस एट्रिब्यूट का नाम है जिसका मिलान दिए गए रेगुलर एक्सप्रेशन पैटर्न से किया जाना चाहिए. दूसरा आर्ग्युमेंट, pattern एट्रिब्यूट की वैल्यू के लिए रेगुलर एक्सप्रेशन है. attr
एक्सप्रेशन का आकलन, सभी टारगेट x वाले सेट के तौर पर किया जाता है. ऐसा इसलिए, क्योंकि x, सेट input का सदस्य है. साथ ही, यह तय किए गए एट्रिब्यूट name वाला नियम है. इसके अलावा, एट्रिब्यूट वैल्यू में रेगुलर एक्सप्रेशन pattern के लिए (अनऐंकर्ड) मैच शामिल होता है. अगर name एक
ज़रूरी नहीं है और नियम में इसे साफ़ तौर पर नहीं बताया गया है, तो तुलना के लिए एट्रिब्यूट की डिफ़ॉल्ट वैल्यू का इस्तेमाल किया जाएगा. उदाहरण के लिए,
attr(linkshared, 0, deps(//foo))
यह उन सभी //foo
डिपेंडेंसी को चुनेगा जिनके लिए linkshared एट्रिब्यूट की अनुमति है. जैसे, cc_binary
नियम. साथ ही, यह एट्रिब्यूट की वैल्यू को साफ़ तौर पर 0 पर सेट करेगा या इसे सेट नहीं करेगा, लेकिन डिफ़ॉल्ट वैल्यू 0 होगी. जैसे, cc_binary
नियमों के लिए.
सूची वाले एट्रिब्यूट (जैसे कि srcs
, data
वगैरह) को [value<sub>1</sub>, ..., value<sub>n</sub>]
के फ़ॉर्म में स्ट्रिंग में बदल दिया जाता है. यह [
ब्रैकेट से शुरू होता है और ]
ब्रैकेट पर खत्म होता है. साथ ही, इसमें एक से ज़्यादा वैल्यू को अलग करने के लिए ",
" (कॉमा, स्पेस) का इस्तेमाल किया जाता है.
लेबल को स्ट्रिंग में बदलने के लिए, लेबल के ऐब्सलूट फ़ॉर्म का इस्तेमाल किया जाता है. उदाहरण के लिए, एट्रिब्यूट deps=[":foo",
"//otherpkg:bar", "wiz"]
को स्ट्रिंग [//thispkg:foo, //otherpkg:bar, //thispkg:wiz]
में बदल दिया जाएगा.
ब्रैकेट हमेशा मौजूद होते हैं. इसलिए, खाली सूची में मैचिंग के लिए स्ट्रिंग वैल्यू []
का इस्तेमाल किया जाएगा. उदाहरण के लिए,
attr("srcs", "\[\]", deps(//foo))
//foo
डिपेंडेंसी में मौजूद उन सभी नियमों को चुनेगा जिनमें srcs
एट्रिब्यूट की वैल्यू खाली है. वहीं,
attr("data", ".{3,}", deps(//foo))
//foo
डिपेंडेंसी में मौजूद सभी नियमों को चुनेगा. इन नियमों में, data
एट्रिब्यूट की कम से कम एक वैल्यू दी गई है. //
और :
की वजह से, हर लेबल कम से कम तीन वर्णों का होता है.
सूची वाले एट्रिब्यूट में, किसी खास value
के साथ //foo
डिपेंडेंसी वाले सभी नियमों को चुनने के लिए, इसका इस्तेमाल करें
attr("tags", "[\[ ]value[,\]]", deps(//foo))
ऐसा इसलिए होता है, क्योंकि value
से पहले वाला वर्ण [
या स्पेस होगा और value
के बाद वाला वर्ण कॉमा या ]
होगा.
नियम के दिखने से जुड़ी सेटिंग: दिखने की अनुमति है
expr ::= visible(expr, expr)
visible(predicate, input)
ऑपरेटर, टारगेट के सेट पर फ़िल्टर लागू करता है. साथ ही, उन टारगेट को खारिज कर देता है जो ज़रूरी शर्तों को पूरा नहीं करते.
पहला आर्ग्युमेंट, predicate, टारगेट का एक ऐसा सेट होता है जिसमें आउटपुट में मौजूद सभी टारगेट दिखने चाहिए. visible एक्सप्रेशन से, सभी टारगेट x वाला सेट मिलता है. इसमें x, सेट input का सदस्य होता है. साथ ही, predicate में मौजूद सभी टारगेट y के लिए, x दिखता है.y उदाहरण के लिए:
visible(//foo, //bar:*)
यह पैकेज //bar
में मौजूद उन सभी टारगेट को चुनेगा //foo
जिन पर, दिखने से जुड़ी पाबंदियों का उल्लंघन किए बिना भरोसा किया जा सकता है.
लेबल टाइप के नियम एट्रिब्यूट का आकलन: लेबल
expr ::= labels(word, expr)
labels(attr_name, inputs)
ऑपरेटर, उन टारगेट का सेट दिखाता है जिन्हें सेट inputs के किसी नियम में, "label" या "list of label" टाइप वाले एट्रिब्यूट attr_name में तय किया गया है.
उदाहरण के लिए, labels(srcs, //foo)
, //foo
नियम के srcs
एट्रिब्यूट में दिखने वाले टारगेट का सेट दिखाता है. अगर inputs सेट में srcs
एट्रिब्यूट वाले कई नियम हैं, तो उनके srcs
का यूनीयन दिखाया जाता है.
test_suites: tests को बड़ा करें और फ़िल्टर करें
expr ::= tests(expr)
tests(x)
ऑपरेटर, सेट x में मौजूद सभी टेस्ट के नियमों का सेट दिखाता है. साथ ही, test_suite
नियमों को उन अलग-अलग टेस्ट के सेट में बदलता है जिनसे वे जुड़े होते हैं. इसके अलावा, tag
और size
के हिसाब से फ़िल्टर करता है.
डिफ़ॉल्ट रूप से, क्वेरी का आकलन करते समय सभी test_suite
नियमों में, टेस्ट नहीं किए जा सकने वाले टारगेट को अनदेखा किया जाता है. --strict_test_suite
विकल्प का इस्तेमाल करके, इसे गड़बड़ियों में बदला जा सकता है.
उदाहरण के लिए, kind(test, foo:*)
क्वेरी, foo
पैकेज में मौजूद सभी *_test
और test_suite
नियमों को दिखाती है. सभी नतीजे, foo
पैकेज के सदस्य हैं. इसके उलट, tests(foo:*)
क्वेरी, bazel test
foo:*
से लागू किए जाने वाले सभी अलग-अलग टेस्ट दिखाएगी. इनमें ऐसे टेस्ट भी शामिल हो सकते हैं जो दूसरे पैकेज से जुड़े हैं. इन्हें test_suite
नियमों के ज़रिए सीधे या परोक्ष तौर पर रेफ़रंस किया जाता है.
पैकेज की परिभाषा वाली फ़ाइलें: buildfiles
expr ::= buildfiles(expr)
buildfiles(x)
ऑपरेटर, उन फ़ाइलों का सेट दिखाता है जो सेट x में मौजूद हर टारगेट के पैकेज तय करती हैं. दूसरे शब्दों में कहें, तो हर पैकेज के लिए उसकी BUILD
फ़ाइल और load
के ज़रिए रेफ़र की गई कोई भी .bzl फ़ाइल. ध्यान दें कि इससे, उन पैकेज की BUILD
फ़ाइलें भी दिखती हैं जिनमें ये load
की गई फ़ाइलें शामिल हैं.
इस ऑपरेटर का इस्तेमाल आम तौर पर यह तय करने के लिए किया जाता है कि किसी टारगेट को बनाने के लिए किन फ़ाइलों या पैकेज की ज़रूरत है. अक्सर इसका इस्तेमाल, नीचे दिए गए --output package
विकल्प के साथ किया जाता है. उदाहरण के लिए,
bazel query 'buildfiles(deps(//foo))' --output package
यह उन सभी पैकेज का सेट दिखाता है जिन पर //foo
ट्रांज़िटिव तौर पर निर्भर करता है.
पैकेज की परिभाषा वाली फ़ाइलें: rbuildfiles
expr ::= rbuildfiles(word, ...)
rbuildfiles
ऑपरेटर, पाथ फ़्रैगमेंट की कॉमा से अलग की गई सूची लेता है और BUILD
फ़ाइलों का सेट दिखाता है. ये फ़ाइलें, ट्रांज़िटिव तरीके से इन पाथ फ़्रैगमेंट पर निर्भर करती हैं. उदाहरण के लिए, अगर //foo
कोई पैकेज है, तो rbuildfiles(foo/BUILD)
, //foo:BUILD
टारगेट दिखाएगा. अगर foo/BUILD
फ़ाइल में load('//bar:file.bzl'...
मौजूद है, तो rbuildfiles(bar/file.bzl)
, //foo:BUILD
टारगेट के साथ-साथ, BUILD
फ़ाइलों के टारगेट भी दिखाएगा. ये वे फ़ाइलें होंगी जो //bar:file.bzl
लोड करती हैं
--universe_scope
फ़्लैग से तय होता है. BUILD
फ़ाइलों और .bzl
फ़ाइलों से सीधे तौर पर जुड़ी न होने वाली फ़ाइलों से, नतीजों पर कोई असर नहीं पड़ता. उदाहरण के लिए, सोर्स फ़ाइलों (जैसे कि foo.cc
) को अनदेखा कर दिया जाता है. भले ही, उन्हें BUILD
फ़ाइल में साफ़ तौर पर बताया गया हो. हालांकि, सिंबॉलिक लिंक को अनदेखा नहीं किया जाता. इसलिए, अगर foo/BUILD
, bar/BUILD
का सिंबॉलिक लिंक है, तो rbuildfiles(bar/BUILD)
के नतीजों में //foo:BUILD
शामिल होगा.
rbuildfiles
ऑपरेटर, buildfiles
ऑपरेटर के ठीक उलट काम करता है. हालांकि, यह नैतिक सिद्धांत एक दिशा में ज़्यादा लागू होता है: rbuildfiles
के आउटपुट, buildfiles
के इनपुट की तरह होते हैं. पहले वाले में सिर्फ़ पैकेज में मौजूद BUILD
फ़ाइल टारगेट शामिल होंगे. वहीं, दूसरे वाले में ऐसे टारगेट शामिल हो सकते हैं. दूसरी दिशा में, यह समानता कमज़ोर है. buildfiles
ऑपरेटर के आउटपुट, सभी पैकेज और . से जुड़े टारगेट होते हैं.bzl
किसी इनपुट के लिए ज़रूरी फ़ाइलें. हालांकि, rbuildfiles
ऑपरेटर के इनपुट, वे टारगेट नहीं होते. इसके बजाय, वे पाथ फ़्रैगमेंट होते हैं जो उन टारगेट से मेल खाते हैं.
पैकेज की परिभाषा वाली फ़ाइलें: loadfiles
expr ::= loadfiles(expr)
loadfiles(x)
ऑपरेटर, Starlark फ़ाइलों का ऐसा सेट दिखाता है जो loadfiles(x)
सेट में मौजूद हर टारगेट के पैकेज लोड करने के लिए ज़रूरी होती हैं.x दूसरे शब्दों में, यह हर पैकेज के लिए उन .bzl फ़ाइलों को दिखाता है जिन्हें उसकी BUILD
फ़ाइलों से रेफ़र किया गया है.
आउटपुट फ़ॉर्मैट
bazel query
एक ग्राफ़ जनरेट करता है.
bazel query
कमांड-लाइन विकल्प का इस्तेमाल करके, कॉन्टेंट, फ़ॉर्मैट, और क्रम तय किया जाता है. इससे bazel query
इस ग्राफ़ को दिखाता है.--output
Sky Query के साथ इस्तेमाल करने पर, सिर्फ़ ऐसे आउटपुट फ़ॉर्मैट इस्तेमाल किए जा सकते हैं जो बिना क्रम वाले आउटपुट के साथ काम करते हैं. खास तौर पर, graph
, minrank
, और maxrank
आउटपुट फ़ॉर्मैट इस्तेमाल करने की अनुमति नहीं है.
कुछ आउटपुट फ़ॉर्मैट में अतिरिक्त विकल्प इस्तेमाल किए जा सकते हैं. हर आउटपुट विकल्प के नाम के आगे, उस आउटपुट फ़ॉर्मैट का नाम लिखा होता है जिस पर वह विकल्प लागू होता है. इसलिए, --graph:factored
सिर्फ़ तब लागू होता है, जब --output=graph
का इस्तेमाल किया जा रहा हो. अगर graph
के अलावा किसी दूसरे आउटपुट फ़ॉर्मैट का इस्तेमाल किया जाता है, तो इसका कोई असर नहीं होता. इसी तरह, --xml:line_numbers
का इस्तेमाल सिर्फ़ तब किया जा सकता है, जब --output=xml
का इस्तेमाल किया जा रहा हो.
नतीजों को क्रम से लगाने के बारे में जानकारी
क्वेरी एक्सप्रेशन हमेशा "ग्राफ़ के क्रम के संरक्षण के नियम" का पालन करते हैं. हालांकि, नतीजों को पेश करने का तरीका, निर्भरता के क्रम में या बिना क्रम के हो सकता है. इससे, नतीजों के सेट में मौजूद टारगेट या क्वेरी के हिसाब से डेटा का आकलन करने के तरीके पर कोई असर नहीं पड़ता. इससे सिर्फ़ यह तय होता है कि नतीजे stdout में कैसे प्रिंट किए जाएंगे. इसके अलावा, डिपेंडेंसी के क्रम में एक जैसे नोड को वर्णमाला के क्रम में लगाया जा सकता है या नहीं भी लगाया जा सकता.
इस व्यवहार को कंट्रोल करने के लिए, --order_output
फ़्लैग का इस्तेमाल किया जा सकता है.
(--[no]order_results
फ़्लैग में, --order_output
फ़्लैग की कुछ सुविधाएं उपलब्ध हैं. हालांकि, अब इसका इस्तेमाल नहीं किया जाता.)
इस फ़्लैग की डिफ़ॉल्ट वैल्यू auto
होती है. इससे नतीजे, लेक्सिकोग्राफ़िकल क्रम में प्रिंट होते हैं. हालांकि, somepath(a,b)
का इस्तेमाल करने पर, नतीजे deps
क्रम में प्रिंट होंगे.
जब यह फ़्लैग no
पर सेट होता है और --output
, build
, label
, label_kind
, location
, package
, proto
या xml
में से कोई एक होता है, तो आउटपुट किसी भी क्रम में प्रिंट किए जाएंगे. आम तौर पर, यह सबसे तेज़ विकल्प होता है. हालांकि, जब --output
, graph
, minrank
या maxrank
में से कोई एक होता है, तब यह काम नहीं करता: इन फ़ॉर्मैट के साथ, Bazel हमेशा नतीजों को निर्भरता के क्रम या रैंक के हिसाब से प्रिंट करता है.
इस फ़्लैग के deps
होने पर, Bazel कुछ टोपोलॉजिकल क्रम में नतीजे प्रिंट करता है. इसका मतलब है कि सबसे पहले डिपेंडेंसी. हालांकि, जिन नोड को निर्भरता के क्रम के हिसाब से क्रम में नहीं लगाया गया है (क्योंकि एक से दूसरे तक कोई पाथ नहीं है), उन्हें किसी भी क्रम में प्रिंट किया जा सकता है.
अगर इस फ़्लैग को full
पर सेट किया जाता है, तो Bazel नोड को पूरी तरह से तय किए गए (कुल) क्रम में प्रिंट करता है.
सबसे पहले, सभी नोड को वर्णमाला के क्रम में लगाया जाता है. इसके बाद, सूची में मौजूद हर नोड का इस्तेमाल पोस्ट-ऑर्डर डेप्थ-फ़र्स्ट सर्च के शुरुआती नोड के तौर पर किया जाता है. इसमें, जिन नोड पर नहीं जाया गया है उनके आउटगोइंग एज को, सक्सेसर नोड के वर्णमाला क्रम में ट्रैवर्स किया जाता है. आखिर में, नोड को उस क्रम के उलट क्रम में प्रिंट किया जाता है जिस क्रम में उन्हें देखा गया था.
इस क्रम में नोड प्रिंट करने में ज़्यादा समय लग सकता है. इसलिए, इसका इस्तेमाल सिर्फ़ तब किया जाना चाहिए, जब यह ज़रूरी हो कि नोड को एक ही क्रम में प्रिंट किया जाए.
टारगेट के सोर्स फ़ॉर्म को प्रिंट करें. ये फ़ॉर्म, BUILD में दिखते हैं
--output build
इस विकल्प से, हर टारगेट को इस तरह से दिखाया जाता है जैसे उसे BUILD भाषा में हाथ से लिखा गया हो. सभी वैरिएबल और फ़ंक्शन कॉल (जैसे कि glob, मैक्रो) को बड़ा किया जाता है. इससे Starlark मैक्रो का असर देखने में मदद मिलती है. इसके अलावा, हर असरदार नियम, generator_name
और/या generator_function
वैल्यू दिखाता है. इससे उस मैक्रो का नाम पता चलता है जिसका आकलन करके असरदार नियम बनाया गया था.
आउटपुट में BUILD
फ़ाइलों के जैसा ही सिंटैक्स इस्तेमाल किया जाता है. हालांकि, इससे मान्य BUILD
फ़ाइल जनरेट होने की गारंटी नहीं मिलती.
हर टारगेट का लेबल प्रिंट करें
--output label
इस विकल्प की मदद से, नतीजे के तौर पर मिले ग्राफ़ में मौजूद हर टारगेट के नामों (या लेबल) का सेट प्रिंट किया जाता है. हर लाइन में एक लेबल होता है. लेबल, टोपोलॉजिकल क्रम में होते हैं. हालांकि, अगर --noorder_results
विकल्प का इस्तेमाल किया जाता है, तो लेबल टोपोलॉजिकल क्रम में नहीं होते. इस बारे में ज़्यादा जानने के लिए, नतीजों के क्रम के बारे में जानकारी देखें.
(टपॉलॉजिकल ऑर्डरिंग एक ऐसी ऑर्डरिंग होती है जिसमें किसी ग्राफ़ नोड को उसके सभी सक्सेसर से पहले दिखाया जाता है.) किसी ग्राफ़ के कई टोपोलॉजिकल ऑर्डर हो सकते हैं. रिवर्स पोस्टऑर्डर उनमें से सिर्फ़ एक है. यह नहीं बताया गया है कि कौनसे ऑर्डर को चुना गया है.
somepath
क्वेरी का आउटपुट प्रिंट करते समय, नोड को प्रिंट करने का क्रम, पाथ का क्रम होता है.
चेतावनी: कुछ खास मामलों में, एक ही लेबल वाले दो अलग-अलग टारगेट हो सकते हैं. उदाहरण के लिए, sh_binary
नियम और उसकी एकमात्र (इंप्लिसिट) srcs
फ़ाइल, दोनों को foo.sh
कहा जा सकता है. अगर किसी क्वेरी के नतीजे में ये दोनों टारगेट शामिल हैं, तो आउटपुट (label
फ़ॉर्मैट में) में डुप्लीकेट दिखेगा. label_kind
(नीचे देखें) फ़ॉर्मैट का इस्तेमाल करने पर, अंतर साफ़ तौर पर दिखता है: दोनों टारगेट का नाम एक जैसा है, लेकिन एक का टाइप sh_binary rule
है और दूसरे का टाइप source file
है.
हर टारगेट का लेबल और टाइप प्रिंट करें
--output label_kind
label
की तरह, इस आउटपुट फ़ॉर्मैट में टोपोलॉजिकल क्रम में, नतीजे के तौर पर मिले ग्राफ़ में हर टारगेट के लेबल प्रिंट किए जाते हैं. हालांकि, इसमें टारगेट के टाइप के हिसाब से लेबल भी शामिल होते हैं.
प्रोटोकॉल बफ़र फ़ॉर्मैट में प्रिंट टारगेट
--output proto
क्वेरी के आउटपुट को QueryResult
प्रोटोकॉल बफ़र के तौर पर प्रिंट करता है.
लंबाई के हिसाब से तय किए गए प्रोटोकॉल बफ़र फ़ॉर्मैट में प्रिंट टारगेट
--output streamed_proto
यह Target
प्रोटोकॉल बफ़र की लंबाई के हिसाब से तय की गई स्ट्रीम को प्रिंट करता है. यह (i) तब काम आता है, जब एक QueryResult
में फ़िट होने के लिए बहुत ज़्यादा टारगेट होते हैं और प्रोटोकॉल बफ़र के साइज़ की सीमाएं लागू होती हैं या (ii) जब Bazel अब भी आउटपुट दे रहा होता है, तब प्रोसेसिंग शुरू करने के लिए इसका इस्तेमाल किया जाता है.
टेक्स्ट प्रोटो फ़ॉर्मैट में प्रिंट टारगेट
--output textproto
यह --output proto
की तरह ही काम करता है. हालांकि, यह QueryResult
प्रोटोकॉल बफ़र को टेक्स्ट फ़ॉर्मैट में प्रिंट करता है.
ndjson फ़ॉर्मैट में प्रिंट टारगेट
--output streamed_jsonproto
यह --output streamed_proto
की तरह ही, Target
प्रोटोकॉल बफ़र की स्ट्रीम को प्रिंट करता है. हालांकि, यह ndjson फ़ॉर्मैट में होता है.
हर टारगेट के लेबल को रैंक के क्रम में प्रिंट करें
--output minrank --output maxrank
label
की तरह, minrank
और maxrank
आउटपुट फ़ॉर्मैट, नतीजे के तौर पर मिले ग्राफ़ में हर टारगेट के लेबल प्रिंट करते हैं. हालांकि, टोपोलॉजिकल क्रम में दिखने के बजाय, ये रैंक के क्रम में दिखते हैं. इनसे पहले, इनकी रैंक का नंबर दिखता है. इन पर, नतीजों के क्रम को बदलने वाले --[no]order_results
फ़्लैग का कोई असर नहीं पड़ता. नतीजों के क्रम के बारे में जानकारी देखें.
इस फ़ॉर्मैट के दो वैरिएंट हैं: minrank
हर नोड को रूट नोड से उसके सबसे छोटे पाथ की लंबाई के हिसाब से रैंक करता है.
"रूट" नोड (जिनमें कोई इनकमिंग एज नहीं होता) की रैंक 0 होती है. इसके बाद आने वाले नोड की रैंक 1 होती है. इसी तरह, आगे के नोड की रैंक बढ़ती जाती है. (हमेशा की तरह, एज किसी टारगेट से उसकी ज़रूरी शर्तों की ओर इशारा करते हैं: वे टारगेट जिन पर वह निर्भर करता है.)
maxrank
हर नोड को रैंक करता है. यह रैंक, रूट नोड से उस नोड तक के सबसे लंबे पाथ की लंबाई के हिसाब से तय की जाती है. फिर से, "रूट" का रैंक 0 होता है. अन्य सभी नोड का रैंक, उनके सभी पूर्ववर्तियों के ज़्यादा से ज़्यादा रैंक से एक ज़्यादा होता है.
किसी साइकल में मौजूद सभी नोड को एक ही रैंक का माना जाता है. (ज़्यादातर ग्राफ़ में कोई साइकल नहीं होती, लेकिन साइकल होती हैं. ऐसा इसलिए होता है, क्योंकि BUILD
फ़ाइलों में गलत साइकल होती हैं.)
ये आउटपुट फ़ॉर्मैट, यह पता लगाने के लिए काम आते हैं कि कोई ग्राफ़ कितना डीप है.
अगर इनका इस्तेमाल deps(x)
, rdeps(x)
या allpaths
क्वेरी के नतीजे के लिए किया जाता है, तो रैंक नंबर, x
से उस रैंक के नोड तक के सबसे छोटे (minrank
के साथ) या सबसे लंबे (maxrank
के साथ) पाथ की लंबाई के बराबर होता है. maxrank
का इस्तेमाल, टारगेट बनाने के लिए ज़रूरी बिल्ड चरणों के सबसे लंबे क्रम का पता लगाने के लिए किया जा सकता है.
उदाहरण के लिए, बाईं ओर मौजूद ग्राफ़ में, --output minrank
और --output maxrank
को तय करने पर, दाईं ओर मौजूद आउटपुट मिलते हैं.
minrank 0 //c:c 1 //b:b 1 //a:a 2 //b:b.cc 2 //a:a.cc |
maxrank 0 //c:c 1 //b:b 2 //a:a 2 //b:b.cc 3 //a:a.cc |
हर टारगेट की जगह की जानकारी प्रिंट करना
--output location
label_kind
की तरह, यह विकल्प भी नतीजे में मौजूद हर टारगेट के लिए, टारगेट का टाइप और लेबल प्रिंट करता है. हालांकि, इसमें टारगेट की जगह की जानकारी देने वाली स्ट्रिंग पहले से जुड़ी होती है. यह स्ट्रिंग, फ़ाइल के नाम और लाइन नंबर के तौर पर होती है. यह फ़ॉर्मैट, grep
के आउटपुट जैसा होता है. इसलिए, जो टूल बाद वाले को पार्स कर सकते हैं (जैसे कि Emacs या vi), वे क्वेरी के आउटपुट का इस्तेमाल करके, मैच की सीरीज़ में आगे बढ़ सकते हैं. इससे Bazel क्वेरी टूल का इस्तेमाल, डिपेंडेंसी-ग्राफ़ के बारे में जानने वाले "BUILD फ़ाइलों के लिए grep" के तौर पर किया जा सकता है.
जगह की जानकारी, टारगेट के टाइप के हिसाब से अलग-अलग होती है. इसके लिए, kind ऑपरेटर देखें. नियमों के लिए, BUILD
फ़ाइल में नियम के एलान की जगह प्रिंट की जाती है.
सोर्स फ़ाइलों के लिए, असल फ़ाइल की पहली लाइन की जगह की जानकारी प्रिंट की जाती है. जनरेट की गई फ़ाइल के लिए, उसे जनरेट करने वाले नियम की जगह प्रिंट की जाती है. (क्वेरी टूल के पास, जनरेट की गई फ़ाइल की असल जगह का पता लगाने के लिए ज़रूरी जानकारी नहीं है. साथ ही, अगर अब तक कोई बिल्ड नहीं किया गया है, तो हो सकता है कि यह फ़ाइल मौजूद न हो.)
पैकेज का सेट प्रिंट करना
--output package
इस विकल्प से, उन सभी पैकेज के नाम प्रिंट किए जाते हैं जिनमें नतीजे के सेट में मौजूद कुछ टारगेट शामिल हैं. नामों को लेक्सिकोग्राफ़िकल क्रम में प्रिंट किया जाता है. डुप्लीकेट नामों को शामिल नहीं किया जाता. आसान शब्दों में कहें, तो यह लेबल (पैकेज, टारगेट) के सेट से पैकेज पर प्रोजेक्शन होता है.
बाहरी रिपॉज़िटरी में मौजूद पैकेज को @repo//foo/bar
के तौर पर फ़ॉर्मैट किया जाता है, जबकि मुख्य रिपॉज़िटरी में मौजूद पैकेज को foo/bar
के तौर पर फ़ॉर्मैट किया जाता है.
deps(...)
क्वेरी के साथ इस आउटपुट विकल्प का इस्तेमाल करके, उन पैकेज का सेट ढूंढा जा सकता है जिन्हें टारगेट के दिए गए सेट को बनाने के लिए, चेक आउट करना ज़रूरी है.
नतीजे का ग्राफ़ दिखाना
--output graph
इस विकल्प से, क्वेरी के नतीजे को लोकप्रिय AT&T GraphViz फ़ॉर्मैट में डायरेक्टेड ग्राफ़ के तौर पर प्रिंट किया जाता है. आम तौर पर, नतीजे को किसी फ़ाइल में सेव किया जाता है. जैसे, .png
या .svg
.
(अगर आपके वर्कस्टेशन पर dot
प्रोग्राम इंस्टॉल नहीं है, तो sudo apt-get install graphviz
कमांड का इस्तेमाल करके इसे इंस्टॉल किया जा सकता है.)
सैंपल इनवोकेशन के लिए, यहां दिया गया उदाहरण देखें.
यह आउटपुट फ़ॉर्मैट, खास तौर पर allpaths
, deps
या rdeps
क्वेरी के लिए काम का है. इनमें नतीजे में पाथ का एक सेट शामिल होता है. इसे लीनियर फ़ॉर्म में रेंडर करने पर, आसानी से विज़ुअलाइज़ नहीं किया जा सकता. जैसे, --output label
के साथ.
डिफ़ॉल्ट रूप से, ग्राफ़ को फ़ैक्टर्ड फ़ॉर्म में रेंडर किया जाता है. इसका मतलब है कि टोपोलॉजिकल तौर पर एक जैसे नोड को एक ही नोड में मर्ज कर दिया जाता है. इस नोड में कई लेबल होते हैं. इससे ग्राफ़ ज़्यादा कॉम्पैक्ट और पढ़ने में आसान हो जाता है, क्योंकि सामान्य नतीजों वाले ग्राफ़ में एक जैसे पैटर्न बार-बार दिखते हैं. उदाहरण के लिए, java_library
नियम सैकड़ों Java सोर्स फ़ाइलों पर निर्भर हो सकता है. ये सभी फ़ाइलें एक ही genrule
से जनरेट होती हैं. फ़ैक्टर्ड ग्राफ़ में, इन सभी फ़ाइलों को एक नोड से दिखाया जाता है. --nograph:factored
विकल्प का इस्तेमाल करके, इस सुविधा को बंद किया जा सकता है.
--graph:node_limit n
इस विकल्प से, आउटपुट में मौजूद ग्राफ़ नोड के लिए लेबल स्ट्रिंग की ज़्यादा से ज़्यादा लंबाई तय की जाती है. ज़्यादा लंबे लेबल छोटे कर दिए जाएंगे; -1
से लेबल छोटे करने की सुविधा बंद हो जाती है. आम तौर पर, ग्राफ़ को फ़ैक्टर्ड फ़ॉर्म में प्रिंट किया जाता है. इस वजह से, नोड के लेबल बहुत लंबे हो सकते हैं. GraphViz, 1,024 से ज़्यादा वर्णों वाले लेबल को हैंडल नहीं कर सकता. यह इस विकल्प की डिफ़ॉल्ट वैल्यू है. इस विकल्प का कोई असर नहीं होता, जब तक --output=graph
का इस्तेमाल न किया जा रहा हो.
--[no]graph:factored
डिफ़ॉल्ट रूप से, ग्राफ़ को फ़ैक्टर्ड फ़ॉर्म में दिखाया जाता है. इसके बारे में ऊपर बताया गया है.
--nograph:factored
तय किए जाने पर, ग्राफ़ को फ़ैक्टर किए बिना प्रिंट किया जाता है. इस वजह से, GraphViz का इस्तेमाल करके विज़ुअलाइज़ेशन करना मुश्किल हो जाता है. हालांकि, आसान फ़ॉर्मैट की वजह से, अन्य टूल (जैसे कि grep) से प्रोसेस करना आसान हो सकता है. --output=graph
का इस्तेमाल किए बिना, इस विकल्प का कोई असर नहीं होता.
XML
--output xml
इस विकल्प की वजह से, टारगेट को XML फ़ॉर्म में प्रिंट किया जाता है. आउटपुट, इस तरह के एक्सएमएल हेडर से शुरू होता है
<?xml version="1.0" encoding="UTF-8"?>
<query version="2">
इसके बाद, नतीजे के ग्राफ़ में मौजूद हर टारगेट के लिए एक्सएमएल एलिमेंट का इस्तेमाल किया जाता है. इन्हें टोपोलॉजिकल क्रम में रखा जाता है. हालांकि, अगर बिना क्रम वाले नतीजे का अनुरोध किया जाता है, तो इन्हें टोपोलॉजिकल क्रम में नहीं रखा जाता. इसके बाद,
</query>
file
तरह के टारगेट के लिए, सामान्य एंट्री जारी की जाती हैं:
<source-file name='//foo:foo_main.cc' .../>
<generated-file name='//foo:libfoo.so' .../>
हालांकि, नियमों के लिए एक्सएमएल को स्ट्रक्चर किया जाता है. इसमें नियम के सभी एट्रिब्यूट की परिभाषाएं शामिल होती हैं. इनमें वे एट्रिब्यूट भी शामिल होते हैं जिनकी वैल्यू, नियम की BUILD
फ़ाइल में साफ़ तौर पर नहीं बताई गई थी.
इसके अलावा, नतीजे में rule-input
और rule-output
एलिमेंट शामिल होते हैं, ताकि डिपेंडेंसी ग्राफ़ की टोपोलॉजी को फिर से बनाया जा सके. इसके लिए, यह जानने की ज़रूरत नहीं होती कि उदाहरण के लिए, srcs
एट्रिब्यूट के एलिमेंट, फ़ॉरवर्ड डिपेंडेंसी (ज़रूरी शर्तें) हैं और outs
एट्रिब्यूट के कॉन्टेंट, बैकवर्ड डिपेंडेंसी (उपयोगकर्ता) हैं.
अगर --noimplicit_deps
की जानकारी दी गई है, तो इंप्लिसिट डिपेंडेंसी के लिए rule-input
एलिमेंट नहीं दिखते.
<rule class='cc_binary rule' name='//foo:foo' ...>
<list name='srcs'>
<label value='//foo:foo_main.cc'/>
<label value='//foo:bar.cc'/>
...
</list>
<list name='deps'>
<label value='//common:common'/>
<label value='//collections:collections'/>
...
</list>
<list name='data'>
...
</list>
<int name='linkstatic' value='0'/>
<int name='linkshared' value='0'/>
<list name='licenses'/>
<list name='distribs'>
<distribution value="INTERNAL" />
</list>
<rule-input name="//common:common" />
<rule-input name="//collections:collections" />
<rule-input name="//foo:foo_main.cc" />
<rule-input name="//foo:bar.cc" />
...
</rule>
हर टारगेट के लिए एक्सएमएल एलिमेंट में, name
एट्रिब्यूट होता है. इसकी वैल्यू, टारगेट का लेबल होती है. साथ ही, इसमें location
एट्रिब्यूट होता है. इसकी वैल्यू, टारगेट की वह जगह होती है जिसे --output location
ने प्रिंट किया है.
--[no]xml:line_numbers
डिफ़ॉल्ट रूप से, XML आउटपुट में दिखाई गई जगहों में लाइन नंबर शामिल होते हैं.
--noxml:line_numbers
को तय करने पर, लाइन नंबर प्रिंट नहीं किए जाते.
--[no]xml:default_values
डिफ़ॉल्ट रूप से, एक्सएमएल आउटपुट में ऐसे नियम एट्रिब्यूट शामिल नहीं होते जिनकी वैल्यू, उस तरह के एट्रिब्यूट के लिए डिफ़ॉल्ट वैल्यू होती है. उदाहरण के लिए, अगर इसे BUILD
फ़ाइल में नहीं बताया गया है या डिफ़ॉल्ट वैल्यू साफ़ तौर पर दी गई है. इस विकल्प से, एट्रिब्यूट की ऐसी वैल्यू को एक्सएमएल आउटपुट में शामिल किया जाता है.
रेगुलर एक्सप्रेशन
क्वेरी लैंग्वेज में रेगुलर एक्सप्रेशन, Java रेगुलर एक्सप्रेशन लाइब्रेरी का इस्तेमाल करते हैं. इसलिए, java.util.regex.Pattern
के लिए पूरे सिंटैक्स का इस्तेमाल किया जा सकता है.
बाहरी रिपॉज़िटरी से क्वेरी करना
अगर बिल्ड, बाहरी रिपॉज़िटरी (WORKSPACE फ़ाइल में तय की गई) के नियमों पर निर्भर करता है, तो क्वेरी के नतीजों में ये डिपेंडेंसी शामिल होंगी. उदाहरण के लिए, अगर //foo:bar
, //external:some-lib
पर निर्भर है और //external:some-lib
, @other-repo//baz:lib
से जुड़ा है, तो bazel query 'deps(//foo:bar)'
, @other-repo//baz:lib
और //external:some-lib
, दोनों को निर्भरता के तौर पर दिखाएगा.
बाहरी डेटाबेस, बिल्ड की डिपेंडेंसी नहीं होते. इसका मतलब है कि ऊपर दिए गए उदाहरण में, //external:other-repo
कोई डिपेंडेंसी नहीं है. हालांकि, //external
पैकेज के सदस्य के तौर पर इसके बारे में क्वेरी की जा सकती है. उदाहरण के लिए:
# Querying over all members of //external returns the repository.
bazel query 'kind(http_archive, //external:*)'
//external:other-repo
# ...but the repository is not a dependency.
bazel query 'kind(http_archive, deps(//foo:bar))'
INFO: Empty results