यह पेज, Bazel क्वेरी लैंग्वेज का रेफ़रंस मैन्युअल है. इसका इस्तेमाल तब किया जाता है, जब बिल्ड डिपेंडेंसी का विश्लेषण करने के लिए bazel query
का इस्तेमाल किया जाता है. इसमें यह जानकारी भी दी जाती है कि bazel query
किन आउटपुट फ़ॉर्मैट के साथ काम करता है.
काम के उदाहरणों के लिए, Bazu क्वेरी का इस्तेमाल करने का तरीका देखें.
क्वेरी का अन्य रेफ़रंस
पोस्ट-लोडिंग फ़ेज़ के टारगेट ग्राफ़ पर चलने वाले query
के अलावा,
बेज़ल में ऐक्शन ग्राफ़ क्वेरी और कॉन्फ़िगर की जा सकने वाली क्वेरी भी शामिल होती हैं.
ऐक्शन ग्राफ़ क्वेरी
कार्रवाई ग्राफ़ क्वेरी (aquery
), विश्लेषण के बाद कॉन्फ़िगर किए गए टारगेट ग्राफ़ पर काम करती है. इसमें कार्रवाइयां, आर्टफ़ैक्ट, और उनके संबंधों के बारे में जानकारी मिलती है. aquery
का इस्तेमाल करना तब फ़ायदेमंद होता है, जब कॉन्फ़िगर किए गए टारगेट ग्राफ़ से जनरेट की गई कार्रवाइयों/आर्टफ़ैक्ट की प्रॉपर्टी में आपकी दिलचस्पी हो.
उदाहरण के लिए, असल में चलाए जाने वाले निर्देश और उनके इनपुट, आउटपुट, और याद रखने के तरीके.
ज़्यादा जानकारी के लिए, क्वेरी का रेफ़रंस देखें.
कॉन्फ़िगर की जा सकने वाली क्वेरी
ट्रेडिशनल बेज़ल क्वेरी, पोस्ट-लोडिंग फ़ेज़ टारगेट ग्राफ़ पर चलती है. इसलिए, इसमें कॉन्फ़िगरेशन और उनसे जुड़े कॉन्सेप्ट का कोई कॉन्सेप्ट नहीं होता. ध्यान दें, यह चुनिंदा स्टेटमेंट का सही तरीके से समाधान नहीं करता. इसके बजाय, यह चुनने के सभी संभावित रिज़ॉल्यूशन दिखाता है. हालांकि, कॉन्फ़िगर किए जा सकने वाले क्वेरी एनवायरमेंट, cquery
, कॉन्फ़िगरेशन को ठीक से मैनेज करता है, लेकिन यह इस ओरिजनल क्वेरी के सभी फ़ंक्शन उपलब्ध नहीं कराता.
ज़्यादा जानकारी के लिए, cquery रेफ़रंस देखें.
उदाहरण
लोग bazel query
का इस्तेमाल कैसे करते हैं? यहां कुछ सामान्य उदाहरण दिए गए हैं:
//foo
ट्री, //bar/baz
पर क्यों निर्भर करता है?
कोई पाथ दिखाएं:
somepath(foo/..., //bar/baz:all)
सभी foo
टेस्ट किन C++ लाइब्रेरी पर निर्भर करते हैं, जिन पर foo_bin
टारगेट निर्भर नहीं करता?
kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo:foo_bin))
टोकन: लेक्सिकल सिंटैक्स
क्वेरी भाषा में एक्सप्रेशन, इन टोक़न से बने होते हैं:
कीवर्ड, जैसे कि
let
. कीवर्ड, भाषा के रिज़र्व किए गए शब्द होते हैं. इनके बारे में यहां बताया गया है. कीवर्ड का पूरा सेट यह है:शब्द, जैसे कि "
foo/...
", ".*test rule
" या "//bar/baz:all
". अगर किसी वर्ण का क्रम "कोट" किया हुआ है (जो सिंगल-कोट ' से शुरू और खत्म होता है या डबल-कोट " पर खत्म होता है), तो वह एक शब्द होता है. अगर किसी वर्ण क्रम को कोट नहीं किया गया है, तो भी उसे शब्द के तौर पर पार्स किया जा सकता है. बिना कोटेशन वाले शब्द, अंग्रेज़ी के अक्षरों A से Z, अंकों 0 से 9, और*/@.-_:$~[]
(तारांकन, फ़ॉरवर्ड स्लैश, ऐट, पीरियड, हाइफ़न, अंडरस्कोर, कोलन, डॉलर साइन, टाइल्ड, बायां स्क्वेयर ब्रैकेट, और दायां स्क्वेयर ब्रैकेट) जैसे खास वर्णों से बने होते हैं. हालांकि, हो सकता है कि बिना कोटेशन मार्क वाले शब्दों के शुरू में हाइफ़न-
या तारे का निशान*
न हो. हालांकि, मिलते-जुलते टारगेट के नाम उन वर्णों से शुरू हो सकते हैं.बिना कोटेशन मार्क वाले शब्दों में, प्लस का निशान
+
या बराबर=
का निशान भी शामिल नहीं हो सकता. भले ही, टारगेट नामों में उन वर्णों की अनुमति हो. क्वेरी एक्सप्रेशन जनरेट करने वाला कोड लिखते समय, टारगेट के नाम को कोट में लिखना चाहिए.उपयोगकर्ताओं से मिली वैल्यू से बेज़ल क्वेरी एक्सप्रेशन बनाने वाली स्क्रिप्ट लिखते समय, कोट करना ज़रूरी है.
//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
फ़ाइलों में साफ़ तौर पर बताई गई डिपेंडेंसी के साथ-साथ,
Bazu, नियमों में एक और इंप्लिसिट डिपेंडेंसी जोड़ता है. उदाहरण के लिए
हर Java नियम सीधे तौर पर JavaBuilder पर निर्भर करता है. $
से शुरू होने वाले एट्रिब्यूट का इस्तेमाल करके, लागू होने वाली डिपेंडेंसी तय की जाती हैं. साथ ही, BUILD
फ़ाइलों में इन एट्रिब्यूट की वैल्यू को बदला नहीं जा सकता.
क्वेरी के नतीजे की गिनती करते समय, डिफ़ॉल्ट रूप से bazel query
इंप्लिसिट डिपेंडेंसी को ध्यान में रखता है. इस व्यवहार को --[no]implicit_deps
विकल्प से बदला जा सकता है. ध्यान दें कि क्वेरी, कॉन्फ़िगरेशन पर विचार नहीं करती है, इसलिए संभावित टूलचेन पर कभी विचार नहीं किया जाता.
सही होना
बेज़ल क्वेरी लैंग्वेज एक्सप्रेशन, बिल्ड डिपेंडेंसी ग्राफ़ पर ऑपरेट होते हैं. यह ऐसा ग्राफ़ होता है जो सभी BUILD
फ़ाइलों में, सभी नियमों के एलान के ज़रिए सीधे तौर पर तय किया जाता है. यह समझना ज़रूरी है कि यह ग्राफ़ कुछ हद तक अस्पष्ट है. इसमें, किसी बिल्ड के सभी चरणों को पूरा करने का तरीका पूरी तरह से नहीं बताया गया है. बिल्ड करने के लिए, कॉन्फ़िगरेशन की भी ज़रूरत होती है. ज़्यादा जानकारी के लिए, उपयोगकर्ता की गाइड का configurations सेक्शन देखें.
बेज़ेल क्वेरी लैंग्वेज में किसी एक्सप्रेशन का आकलन करने का नतीजा, सभी कॉन्फ़िगरेशन के लिए सही होता है. इसका मतलब है कि यह पूरी तरह से सटीक नहीं होने के बावजूद, काफ़ी हद तक सटीक नहीं हो सकता. अगर आप बिल्ड के दौरान ज़रूरी सभी सोर्स फ़ाइलों के सेट का कंप्यूट करने के लिए क्वेरी टूल का इस्तेमाल करते हैं, तो यह असल में ज़रूरत से ज़्यादा रिपोर्ट कर सकता है क्योंकि, उदाहरण के लिए, क्वेरी टूल में मैसेज का अनुवाद करने के लिए ज़रूरी सभी फ़ाइलें शामिल होंगी, भले ही आप अपने बिल्ड में उस सुविधा का इस्तेमाल नहीं करना चाहते हों.
ग्राफ़ के क्रम को बनाए रखने के बारे में जानकारी
ऑपरेशन अपने सब-एक्सप्रेशन से इनहेरिट की गई
सभी कंस्ट्रेंट को बनाए रखते हैं. इसे "कुछ हद तक ऑर्डर बनाए रखने का नियम" माना जा सकता है. उदाहरण के लिए: अगर किसी टारगेट की डिपेंडेंसी के ट्रांज़िशन क्लोज़र का पता लगाने के लिए क्वेरी जारी की जाती है, तो नतीजे के सेट को डिपेंडेंसी ग्राफ़ के हिसाब से क्रम में लगाया जाता है. अगर उस सेट को फ़िल्टर करके, सिर्फ़ file
टाइप के टारगेट शामिल किए जाते हैं, तो नतीजे के सबसेट में टारगेट के हर जोड़े के बीच, ट्रांसीटिव पार्सल ऑर्डरिंग का वही संबंध होता है - भले ही, इनमें से कोई भी जोड़ा मूल ग्राफ़ में सीधे तौर पर कनेक्ट न हो.
(बिल्ड डिपेंडेंसी ग्राफ़ में, फ़ाइल-फ़ाइल एज नहीं हैं).
हालांकि, सभी ऑपरेटर ऑर्डर को सेव करते हैं, लेकिन कुछ कार्रवाइयां, जैसे कि सेट ऑपरेशन अपने-आप में सेट की गई किसी भी ऑर्डर कंस्ट्रेंट को पेश नहीं करती हैं. इस एक्सप्रेशन का इस्तेमाल करें:
deps(x) union y
इस बात की गारंटी है कि आखिरी नतीजे के सेट का क्रम, इसके सब-एक्सप्रेशन के क्रम में मौजूद सभी कंस्ट्रेंट को बनाए रखेगा. इसका मतलब है कि x
की सभी ट्रांज़िशन डिपेंडेंसी, एक-दूसरे के हिसाब से सही क्रम में लगी हैं. हालांकि, क्वेरी से इस बात की कोई गारंटी नहीं मिलती कि y
में टारगेट के क्रम और y
में मौजूद टारगेट के मुकाबले deps(x)
में टारगेट का क्रम क्या है. हालांकि, y
में मौजूद टारगेट के क्रम, 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 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 ग्राफ़ का विश्लेषण करके अपना काम करती है. डिफ़ॉल्ट तौर पर, ऐसा नहीं किया जाता. इसलिए, कुछ मामलों में यह ज़्यादा तेज़ी से काम करता है और कम मेमोरी का इस्तेमाल करता है.
एक्सप्रेशन: व्याकरण के सिंटैक्स और सिमेंटिक्स
यह बेज़ल क्वेरी लैंग्वेज का व्याकरण है, जिसकी जानकारी ईबीएनएफ़ नोटेशन में दी गई है:
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/...
के बराबर है.
बंद किए गए let name = ...
एक्सप्रेशन के अलावा, किसी दूसरे वैरिएबल रेफ़रंस name
के होने पर गड़बड़ी होती है. दूसरे शब्दों में, टॉप-लेवल क्वेरी एक्सप्रेशन में फ़्री वैरिएबल नहीं हो सकते.
ऊपर दिए गए ग्रामर प्रोडक्शन में name
, शब्द की तरह होता है. हालांकि, इसमें एक अतिरिक्त शर्त होती है कि यह 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)
के बराबर है.
एक ही पैकेज में डायरेक्ट रिवर्स डिपेंडेंसी: समान_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 में मौजूद किसी भी टारगेट तक के सभी पाथ पर मौजूद नोड का ग्राफ़ दिखाता है.
इससे मिलने वाले ग्राफ़, डिपेंडेंसी रिलेशन के हिसाब से क्रम में लगा दिए जाते हैं. ज़्यादा जानकारी के लिए, ग्राफ़ का क्रम वाला सेक्शन देखें.
टारगेट प्रकार फ़िल्टर करना: प्रकार
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 शामिल होते हैं. ऐसा तब होता है, जब x, सेट input का सदस्य हो और x के लेबल (जैसे कि //foo:bar
के सटीक फ़ॉर्म में) में रेगुलर एक्सप्रेशन pattern के लिए, बिना ऐंकर वाला मैच शामिल हो. सभी टारगेट के नाम //
से शुरू होते हैं. इसलिए, इसका इस्तेमाल ^
रेगुलर एक्सप्रेशन ऐंकर के विकल्प के तौर पर किया जा सकता है.
यह ऑपरेटर, अक्सर intersect
ऑपरेटर का ज़्यादा तेज़ और ज़्यादा मज़बूत विकल्प उपलब्ध कराता है. उदाहरण के लिए, //foo:foo
टारगेट की सभी bar
डिपेंडेंसी देखने के लिए,
deps(//foo) intersect //bar/...
हालांकि, इस स्टेटमेंट के लिए, bar
ट्री में मौजूद सभी BUILD
फ़ाइलों को पार्स करना होगा. यह प्रोसेस धीमी होगी और काम की 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
डिपेंडेंसी को चुनेगा जिनके लिए लिंक किया गया एट्रिब्यूट (जैसे, 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 के कुछ नियम के "लेबल" या "लेबल की सूची" टाइप के एट्रिब्यूट attr_name में तय किए गए टारगेट का सेट दिखाता है.
उदाहरण के लिए, labels(srcs, //foo)
, //foo
नियम के srcs
एट्रिब्यूट में दिखने वाले टारगेट का सेट दिखाता है. अगर inputs सेट में srcs
एट्रिब्यूट वाले एक से ज़्यादा नियम हैं, तो उनके srcs
का यूनियन दिखाया जाता है.
Test_suites को बड़ा और फ़िल्टर करें: टेस्ट
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
के नियमों के ज़रिए दिया गया है.
पैकेज की परिभाषा वाली फ़ाइलें: बिल्डफ़ाइलें
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
टारगेट के साथ-साथ, //bar:file.bzl
को लोड करने वाली किसी भी अन्य BUILD
फ़ाइल के टारगेट भी दिखाएगा
--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)
ऑपरेटर, x सेट में हर टारगेट के पैकेज लोड करने के लिए ज़रूरी Starlark फ़ाइलों का सेट दिखाता है. दूसरे शब्दों में, हर पैकेज के लिए, यह ऐसी .bzl फ़ाइलें दिखाता है जो उसकी BUILD
फ़ाइलों से रेफ़र की गई हैं.
आउटपुट फ़ॉर्मैट
bazel query
से ग्राफ़ जनरेट होता है.
कॉन्टेंट, फ़ॉर्मैट, और वह क्रम तय किया जा सकता है जिससे bazel query
इस ग्राफ़ को --output
कमांड लाइन विकल्प की मदद से दिखाता है.
Sky Query का इस्तेमाल करते समय, सिर्फ़ ऐसे आउटपुट फ़ॉर्मैट इस्तेमाल किए जा सकते हैं जो बिना क्रम वाले आउटपुट के साथ काम करते हैं. खास तौर पर, graph
, minrank
, और
maxrank
आउटपुट फ़ॉर्मैट का इस्तेमाल करने की अनुमति नहीं है.
कुछ आउटपुट फ़ॉर्मैट में अन्य विकल्प भी इस्तेमाल किए जा सकते हैं. हर आउटपुट विकल्प का नाम, आउटपुट फ़ॉर्मैट पर लागू होता है. इसलिए, --graph:factored
सिर्फ़ तब लागू होता है, जब --output=graph
का इस्तेमाल किया जा रहा हो. graph
के अलावा किसी दूसरे आउटपुट फ़ॉर्मैट का इस्तेमाल करने पर इसका कोई असर नहीं पड़ता. इसी तरह,
--xml:line_numbers
सिर्फ़ तब लागू होता है, जब --output=xml
का इस्तेमाल किया जा रहा हो.
नतीजों के क्रम के बारे में जानकारी
क्वेरी एक्सप्रेशन हमेशा "ग्राफ़ के क्रम को बनाए रखने के नियम" का पालन करते हैं. हालांकि, नतीजों को प्रज़ेंट करने के लिए, डिपेंडेंसी के क्रम या बिना क्रम के कोई भी तरीका अपनाया जा सकता है. यह नतीजे के सेट में मौजूद टारगेट या क्वेरी को कंप्यूट करने के तरीके पर असर नहीं डालता. इससे सिर्फ़ एसटीडीआउट में नतीजे प्रिंट होने के तरीके पर असर पड़ता है. इसके अलावा, जो नोड डिपेंडेंसी ऑर्डर में मिलते-जुलते हैं वे अंग्रेज़ी वर्णमाला के क्रम में हो सकते हैं और नहीं भी.
इस व्यवहार को कंट्रोल करने के लिए, --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 नोड को पूरी तरह से तय (कुल) क्रम में प्रिंट करता है.
सबसे पहले, सभी नोड वर्णमाला के क्रम में लगाए जाते हैं. इसके बाद, सूची के हर नोड का इस्तेमाल पोस्ट-ऑर्डर डेप्थ-फ़र्स्ट सर्च के शुरुआत के रूप में किया जाता है. इसमें जिन नोड से विज़िट नहीं किए गए नोड को, अगले नोड के वर्णमाला के क्रम में ट्रैवर्सित किया जाता है. आखिर में, नोड उसी क्रम में प्रिंट किए जाते हैं जिस क्रम में उन्हें विज़िट किया गया था.
इस क्रम में नोड प्रिंट करने में ज़्यादा समय लग सकता है. इसलिए, इसका इस्तेमाल सिर्फ़ तब किया जाना चाहिए, जब डिटरमिनिज़्म ज़रूरी हो.
टारगेट के सोर्स फ़ॉर्म को उसी तरह प्रिंट करें जैसा वे बिल्ड में दिखेंगे
--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) तब भी काम किया जा सकता है, जब Baze अब भी आउटपुट दे रहा हो.
टेक्स्ट प्रोटो फ़ॉर्मैट में टारगेट प्रिंट करें
--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) को पार्स करने वाले टूल भी मैच की सीरीज़ में जाने के लिए, क्वेरी आउटपुट का इस्तेमाल कर सकते हैं. इससे बेज़ल क्वेरी टूल को डिपेंडेंसी-ग्राफ़-अवेयर "BUILD फ़ाइलों के लिए ग्रेप" के तौर पर इस्तेमाल किया जा सकता है.
जगह की जानकारी, टारगेट के टाइप के हिसाब से अलग-अलग होती है. kind ऑपरेटर देखें. नियमों के लिए, BUILD
फ़ाइल में नियम के एलान की जगह की जानकारी प्रिंट की जाती है.
सोर्स फ़ाइलों के लिए, असल फ़ाइल की लाइन 1 की जगह प्रिंट की गई होती है. जनरेट की गई फ़ाइल के लिए, उसे जनरेट करने वाले नियम की जगह की जानकारी प्रिंट की जाती है. (जनरेट की गई फ़ाइल की जगह की जानकारी का पता लगाने के लिए, क्वेरी टूल में ज़रूरी जानकारी नहीं है. साथ ही, अगर फ़ाइल अभी तक नहीं बनाई गई है, तो हो सकता है कि यह मौजूद न हो.)
पैकेज के सेट को प्रिंट करें
--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
नियम
एक ही genrule
से जनरेट की जाने वाली सैंकड़ों Java सोर्स फ़ाइलों पर निर्भर कर सकता है;
फ़ैक्टर किए गए ग्राफ़ में, ये सभी फ़ाइलें एक ही नोड से दिखाई जाती हैं. यह व्यवहार --nograph:factored
विकल्प से बंद किया जा सकता है.
--graph:node_limit n
यह विकल्प, आउटपुट में ग्राफ़ नोड के लिए लेबल स्ट्रिंग की ज़्यादा से ज़्यादा लंबाई तय करता है. बड़े लेबल छोटे किए जाएंगे; -1 से
छोटे किए गए लेबल बंद हो जाते हैं. आम तौर पर, ग्राफ़ को फ़ैक्टर वाले फ़ॉर्म में प्रिंट किया जाता है. इस वजह से, नोड के लेबल बहुत लंबे हो सकते हैं. ग्राफ़विज़ 1024 वर्णों से ज़्यादा के लेबल को हैंडल नहीं कर सकता, जो इस विकल्प की डिफ़ॉल्ट वैल्यू है. इस विकल्प का तब तक कोई असर नहीं होता, जब तक --output=graph
का इस्तेमाल न किया जा रहा हो.
--[no]graph:factored
डिफ़ॉल्ट रूप से, ग्राफ़ फ़ैक्टर वाले फ़ॉर्म में दिखाए जाते हैं, जैसा कि ऊपर बताया गया है.
जब --nograph:factored
बताया जाता है, तो ग्राफ़ बिना फ़ैक्टरिंग के प्रिंट किए जाते हैं. इस वजह से, GraphViz का इस्तेमाल करके विज़ुअलाइज़ेशन करना मुश्किल हो जाता है. हालांकि, आसान फ़ॉर्मैट की मदद से, grep जैसे अन्य टूल से प्रोसेसिंग आसानी से की जा सकती है. इस विकल्प का कोई असर तब तक नहीं पड़ता,
जब तक --output=graph
का इस्तेमाल न किया जा रहा हो.
XML
--output 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
डिफ़ॉल्ट रूप से, एक्सएमएल आउटपुट में दिखाई गई जगहों में लाइन नंबर होते हैं.
--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