هذه الصفحة هي الدليل المرجعي للغة طلب البحث في Bazel المُستخدَمة
عند استخدام bazel query
لتحليل تبعيات الإصدار. وتوضّح أيضًا تنسيقات الإخراج المتوافقة مع bazel query
.
للتعرّف على حالات الاستخدام العمليّة، اطّلِع على طريقة التنفيذ لطلب Bazel.
مرجع إضافي لطلب البحث
بالإضافة إلى query
، الذي يعمل على الرسم البياني المستهدف لمرحلة التحميل بعد التحميل، يتضمّن Bazel طلبًا للرسم البياني للإجراء وطلب بحث قابل للضبط.
طلب الرسم البياني للإجراء
يعمل طلب بحث الرسم البياني للإجراء (aquery
) على "الرسم البياني المستهدف" الذي تم ضبطه بعد التحليل ويعرض معلومات عن الإجراءات وال العناصر وعلاقاتها. يمكنك الاستفادة من aquery
عند الاهتمام
بمواقع "الإجراءات/العناصر" التي يتم إنشاؤها من "الرسم البياني المستهدف" الذي تم ضبطه.
على سبيل المثال، يتم تنفيذ الأوامر الفعلية والإدخالات والمخرجات والتذكّرات.
لمزيد من التفاصيل، يُرجى الاطّلاع على مرجع طلب البحث.
طلب قابل للضبط
يعمل طلب Bazel التقليدي على الرسم البياني المستهدف لمرحلة ما بعد التحميل، وبالتالي
ليس هناك مفهوم لعمليات الضبط والمفاهيم ذات الصلة. وتجدر الإشارة إلى أنّه لا يحلّ عبارات محدّدة بشكل صحيح، بل يعرض جميع درجات الدقة المحتملة بدلاً من ذلك. ومع ذلك، فإن بيئة طلبات البحث القابلة للضبط، cquery
، تعالج عمليات الضبط بشكل صحيح، ولكنها لا توفّر كل وظائف طلب البحث الأصلي هذا.
لمزيد من التفاصيل، يُرجى الاطّلاع على مرجع طلب البحث.
أمثلة
كيف يستخدم الأشخاص bazel query
؟ وفي ما يلي أمثلة نموذجية:
لماذا تعتمد شجرة //foo
على //bar/baz
؟
إظهار مسار:
somepath(foo/..., //bar/baz:all)
ما هي مكتبات 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 إلى Zaz والأرقام من 0 إلى 9 والأحرف الخاصة*/@.-_:$~[]
(النجمة والشرطة المائلة إلى الأمام والنقطة والشرطة والشرطة السفلية والنقطتان وعلامة الدولار والتلدة والقوس المربّع الأيسر والقوس المربّع الأيمن). ومع ذلك، قد لا تبدأ الكلمات غير المُقتبَسة بواصلة-
أو علامة نجمية*
، على الرغم من أن [target names((/concepts/labels#target-names) قد تبدأ بهذه الأحرف.بالإضافة إلى ذلك، لا يمكن أن تتضمّن الكلمات غير المُقتبَسة الأحرف بالإضافة إلى العلامة
+
أو علامة يساوي=
، على الرغم من أنّ هذه الأحرف مسموح بها في الأسماء الهدف. عند كتابة الرمز الذي يُنشئ تعبيرات لطلبات البحث، يجب اقتباس أسماء الأهداف.يُعدّ استخدام الاقتباس ضروريًا عند كتابة النصوص البرمجية التي تنشئ تعبيرات طلبات 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
هي كلمة رئيسية في حين أن "some" كلمة.foo
و&&;;;;foo;quot;; كلمات.ومع ذلك، يجب الانتباه عند استخدام علامات الاقتباس المفردة أو المزدوجة في الأسماء المستهدفة. عند اقتباس اسم هدف واحد أو أكثر، استخدِم نوعًا واحدًا فقط من علامات الاقتباس (إما جميع علامات الاقتباس المفردة أو علامات الاقتباس المزدوجة).
إليك أمثلة على ما ستكون سلسلة طلب بحث 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
(باستثناء تلك الأهداف في y
التي تحدث أيضًا في deps(x)
).
وتشمل عوامل التشغيل التي تفرض قيودًا على الطلب:
allpaths
وdeps
وrdeps
وsomepath
وأحرف البدل للنمط المستهدف
package:*
وdir/...
، وما إلى ذلك.
طلب بحث عن ميزة "السماء"
طلب البحث Sky هو طلب بحث يعمل على نطاق كوني محدّد.
الدوال الخاصة متاحة فقط في SkyQuery
يتضمن وضع "طلب البحث في Sky" وظائف طلبات البحث الإضافية allrdeps
وrbuildfiles
. تعمل هذه الدوال على مستوى الكون بأكمله (لهذا السبب لا تناسب معنى طلب البحث العادي).
تحديد نطاق الكون
يتم تفعيل وضع "طلب البحث في Sky" من خلال تمرير العلامتين التاليتين:
(--universe_scope
أو --infer_universe_scope
) و
--order_output=no
.
توجِّه --universe_scope=<target_pattern1>,...,<target_patternN>
طلب البحث إلى التحميل المسبق للنمط غير المباشر للأنماط المستهدَفة التي تحدّدها الأنماط المستهدَفة، ما يمكن أن يكون مضافًا و طرحيًا في الوقت نفسه. يتم بعد ذلك تقييم كل طلبات البحث في هذا الفاصل الزمني "scope" على وجه الخصوص، لا يعرض عاملا التشغيل 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
فقط إذا كان سلوكها هو ما تريده.
تتميّز خدمة Sky Query ببعض المزايا والعيوب مقارنةً بطلب البحث التلقائي. يتمثل العيب الرئيسي في أنه لا يمكنه ترتيب مخرجاته وفقًا لترتيب الرسم البياني، وبالتالي يُمنع استخدام تنسيقات إخراج معيّنة. وتتمثّل مزاياه في أنّه يقدّم
عاملَي تشغيل (allrdeps
و
rbuildfiles
) لا يتوفّران في طلب البحث التلقائي.
إضافةً إلى ذلك، ينفّذ Sky Sky طلبات البحث عن طريق عرض الرسم البياني 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 ...)
اتحاد مجموعة من الصفر أو أكثر من
الأنماط المستهدفة، مع الفصل بينها بمسافة بيضاء (بدون فواصل).
إلى جانب ميزة $(...)
Bourne Shell’s $(...)
، يوفر set()
وسائل لحفظ نتائج طلب بحث واحد في ملف نصي عادي، ومعالجة هذا الملف النصي باستخدام برامج أخرى (مثل أدوات واجهة UNIX العادية)، ثم إعادة النتيجة إلى أداة طلب البحث كقيمة للمعالجة الإضافية. مثلاً:
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))
من خلال الفلترة على قيم maxrank
باستخدام برنامج awk
.
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)
، ولكن يمكن استخدام أوامر Shell بدلاً من 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
الإغلاق المؤقت للاعتماديات: الانخفاضات
expr ::= deps(expr)
| deps(expr, depth)
يقيّم عامل التشغيل deps(x)
الرسم البياني
الذي تم إنشاؤه من خلال الإغلاق الانتقالي لاعتماديات مجموعة الوسيطات التابعة له
x. على سبيل المثال، قيمة deps(//foo)
هي
الرسم البياني للمهام التابعة الجذر في عقدة واحدة foo
، بما في ذلك
جميع العناصر التابعة لها. قيمة deps(foo/...)
هي الرسوم البيانية للاعتمادية التي تكون جذورها
هي كل القواعد في كل حزمة أسفل الدليل foo
. في هذا السياق،
'dependends' تعني فقط القاعدة المستهدفة والملف، وبالتالي، لا يتم تضمين الملفَين BUILD
وStarlark المطلوبَين لإنشاء هذه الأهداف هنا. ولهذا السبب، عليك استخدام عامل التشغيل buildfiles
.
ويتم ترتيب الرسم البياني الناتج وفقًا لعلاقة الاعتمادية. لمزيد من التفاصيل، يمكنك الاطّلاع على القسم الذي يتناول ترتيب الرسم البياني.
يقبل عامل التشغيل deps
وسيطة ثانية اختيارية، وهي عبارة عن عدد صحيح حرفي يحدد حدًا أعلى لعمق البحث. لذلك، تعرض deps(foo:*, 0)
جميع الأهداف في الحزمة foo
، بينما تتضمن deps(foo:*, 1)
المزيد من المتطلبات الأساسية المباشرة لأي هدف في حزمة foo
، وتتضمّن deps(foo:*, 2)
أيضًا العُقد التي يمكن الوصول إليها مباشرةً من العُقد في deps(foo:*, 1)
، وهكذا. (تتطابق هذه الأرقام مع الترتيبات المعروضة بتنسيق نتيجة minrank
).
وإذا تم حذف المعلَمة depth، تكون عملية البحث غير محدودة: لأنها تحتسب الإغلاق التفاعلي العكسي للمتطلبات الأساسية.
الإغلاق المؤقت للاعتمادية العكسية: مرات الظهور
expr ::= rdeps(expr, expr)
| rdeps(expr, expr, depth)
يقيّم عامل التشغيل rdeps(u, x)
تبعيّات عكسية لمجموعة الوسيطات
x ضمن الإغلاق التفاعلي لمجموعة الكون
u.
ويتم ترتيب الرسم البياني الناتج وفقًا لعلاقة الاعتمادية. يمكنك الاطّلاع على القسم المتعلق بترتيب الرسم البياني للحصول على مزيد من التفاصيل.
يقبل عامل التشغيل rdeps
وسيطة ثالثة اختيارية، وهي عبارة عن عدد صحيح حرفي يحدد حدًا أعلى لعمق البحث. يتضمن الرسم البياني الناتج العُقد التي تقع ضمن مسافة عمق محدّدة فقط من أي عقدة في مجموعة الوسيطات. لذلك، يقيّم rdeps(//foo, //common, 1)
كل العُقد
في الإغلاق العام لـ //foo
الذي يعتمد مباشرةً على //common
. (تتطابق هذه الأرقام مع الترتيبات المعروضة بتنسيق إخراج minrank
.) إذا تم حذف المعلمة depth،
فلا يتم إجراء البحث.
الإغلاق المؤقت لجميع الاعتماديات العكسية: جميع الأجزاء التابعة
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)
على الأكثر k هدفًا بشكل عشوائي من مجموعة الوسيطات x الخاصة به، ويقيّمه على مجموعة تحتوي على هذه الاستهدافات فقط. المعلمة 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)
.
عوامل تشغيل المسار: pathpath و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 |
قاعدة القاعدة العامة |
//p:a.in |
ملف المصدر | |
//p:a.out |
ملف تم إنشاؤه | |
//p:BUILD |
ملف المصدر |
وبالتالي، يتم تقييم kind("cc_.* rule", foo/...)
بناءً على مجموعة
جميع استهدافات cc_library
وcc_binary
وما إلى ذلك،
تحت القاعدة foo
و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 ويحتوي التصنيف (في صيغة مطلقة، مثل //foo:bar
) على مطابقة (غير ثابت) للتعبير العادي pattern. بما أنّ جميع الأسماء المستهدفة تبدأ بـ //
، يمكن استخدامها
بدلاً من علامة الارتساء ^
العادية.
وغالبًا ما يوفّر عامل التشغيل هذا بديلاً أسرع وأكثر فعّالية لعامل التشغيل intersect
. على سبيل المثال، لعرض كل تبعيات
bar
لهدف //foo:foo
، يمكن
إجراء تقييم.
deps(//foo) intersect //bar/...
ومع ذلك، سيتطلب هذا البيان تحليل جميع ملفات BUILD
في
شجرة bar
، والتي ستكون بطيئة وعرضة للأخطاء في ملفات BUILD
غير ذات الصلة. يمكن أن يكون البديل:
filter(//bar, deps(//foo))
التي ستحسب أولاً مجموعة تبعيات //foo
،
ثم تعمل على فلترة الأهداف التي تطابق النمط المُقدَّم فقط، وبعبارة أخرى، الاستهدافات التي تحتوي على أسماء تحتوي على //bar
كسلسلة فرعية.
هناك استخدام شائع آخر لعامل التشغيل filter(pattern,
expr)
وهو فلترة ملفات محدّدة حسب
اسمه أو الإضافة. على سبيل المثال:
filter("\.cc$", deps(//foo))
سيقدم قائمة بجميع الملفات البالغ عددها .cc
والتي تم استخدامها لإنشاء //foo
.
فلترة سمات القاعدة: سمة
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
(يصل طول كل تصنيف إلى 3 أحرف على الأقل بسبب //
و:
).
لاختيار جميع القواعد بين تبعيات //foo
مع سمة value
معيّنة في سمة نوع القائمة، استخدِم
attr("tags", "[\[ ]value[,\]]", deps(//foo))
ويعمل ذلك لأن الحرف قبل value
سيكون [
أو مسافة، وسيكون الحرف بعد value
فاصلة أو ]
.
فلترة حق الوصول إلى القاعدة: مرئية
expr ::= visible(expr, expr)
يطبّق عامل التشغيل visible(predicate, input)
فلترًا على مجموعة من الأهداف، ويتجاهل الأهداف التي لا تتضمّن حق الوصول المطلوب.
الوسيطة الأولى، predicate، هي مجموعة من الأهداف التي يجب أن تكون جميع الاستهدافات في الإخراج مرئية لها. تعبير visible يتم تقييم المجموعة التي تحتوي على جميع الأهداف x بحيث يكون x عضوًا في المجموعة input، وتظهر جميع الأهداف y في predicate x لـ y. مثلاً:
visible(//foo, //bar:*)
سيختار جميع الاستهدافات في الحزمة //bar
التي يمكن أن يعتمد عليها //foo
بدون انتهاك قيود مستوى الرؤية.
تقييم سمات القواعد لنوع التصنيف: التصنيفات
expr ::= labels(word, expr)
يعرض عامل التشغيل labels(attr_name, inputs)
مجموعة الأهداف المحدّدة في
السمة attr_name من النوع "label;quot; أو &&;;list of label" في
القاعدة في المجموعة inputs.
على سبيل المثال، تعرض labels(srcs, //foo)
مجموعة
الأهداف التي تظهر في السمة srcs
لقاعدة //foo
. إذا كانت هناك قواعد متعدّدة مع سمات srcs
في المجموعة inputs، يتم عرض اتحاد srcs
.
توسيع نطاق test_suites وفلترته: الاختبارات
expr ::= tests(expr)
يعرض عامل التشغيل tests(x)
مجموعة من جميع قواعد الاختبار في المجموعة x، مع توسيع أي قواعد test_suite
في مجموعة الاختبارات الفردية التي يشير إليها، وتطبيق الفلترة حسب
tag
وsize
.
يتجاهل تقييم طلب البحث تلقائيًا أي استهدافات غير اختبارية في جميع قواعد test_suite
. ويمكن تغيير ذلك إلى أخطاء في الخيار --strict_test_suite
.
على سبيل المثال، يعرض طلب البحث kind(test, foo:*)
كل
قواعد *_test
وtest_suite
في حزمة foo
. جميع النتائج (حسب التعريف) أعضاء في حزمة foo
. في المقابل،
سيعرض طلب البحث tests(foo:*)
جميع الاختبارات الفردية التي سيتم إجراؤها بواسطة bazel test
foo:*
: قد يشمل ذلك الاختبارات التي تنتمي إلى حزم أخرى، والتي تتم الإشارة إليها بشكل مباشر أو غير مباشر
من خلال قواعد test_suite
.
ملفات تعريف الحزمة: الأفراد
expr ::= buildfiles(expr)
يعرض عامل التشغيل buildfiles(x)
مجموعة
الملفات التي تحدّد حِزم كل هدف في
المجموعة x. وبعبارة أخرى، بالنسبة إلى كل حزمة، يكون ملف BUILD
،
بالإضافة إلى أي ملفات .bzl تشير إليها عبر load
. يُرجى العِلم أنّ هذا الإجراء
يعرض أيضًا ملفات 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
هي تلك الأهداف، بل هي أجزاء المسار التي تتطابق مع تلك الاستهدافات.
ملفات تعريف الحزمة: filesfiles
expr ::= loadfiles(expr)
يعرض عامل التشغيل loadfiles(x)
مجموعة من ملفات Starlark اللازمة لتحميل حِزم كل هدف في المجموعة x. وبعبارة أخرى، سيتم عرض ملفات .bzl التي تمت الإشارة إليها من ملفات BUILD
لكل حزمة.
تنسيقات المخرجات
يُنشئ bazel query
رسمًا بيانيًا.
وما عليك سوى تحديد المحتوى وتنسيقه وترتيبه
وهو ما يقدّم
bazel query
هذا الرسم البياني
من خلال خيار سطر الأوامر --output
.
عند التشغيل باستخدام طلب بحث Sky، لا يُسمح إلا بتنسيقات الإخراج المتوافقة مع الناتج غير المُرتَّب. على وجه التحديد، يتم حظر تنسيقات النتائج 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
وملفها الوحيد (implicit) srcs
باسم
foo.sh
. إذا كانت نتيجة طلب البحث تحتوي على كلا الهدفَين، ستظهر النتائج (بتنسيق label
) وكأنها نسخة طبق الأصل. وعند استخدام التنسيق label_kind
(انظر
أدناه)، يظهر الفرق بوضوح: يحتوي الهدفان على الاسم نفسه، ولكن أحدهما يحمل النوع sh_binary rule
والنوع الآخر source file
.
طباعة التصنيف ونوع كل استهداف
--output label_kind
كما هو الحال في label
، يطبِّق تنسيق الناتج هذا تصنيفات
كل هدف في الرسم البياني الناتج بترتيب تسلسلي، ولكنه يسبق أيضًا التصنيف حسب نوع الهدف.
طباعة تصنيف كل هدف بترتيب مرتب
--output minrank --output maxrank
كما هو الحال في label
، يطبع التنسيقان minrank
وmaxrank
التصنيفات تصنيفات كل هدف في الرسم البياني الناتج، ولكن بدلاً من ظهور الترتيب، علمًا بأنّ الترتيب يظهر في الترتيب بترتيب يسبقه رقم الترتيب. ولن تتأثّر هذه العلامات بعلامة ترتيب النتائج
--[no]order_results
(يمكنك الاطّلاع على ملاحظات حول ترتيب النتائج).
هناك صيغة مختلفة من هذا التنسيق: يرتّب minrank
كل عُقدة حسب طول المسار الأقصر من عقدة جذر إليها.
"Root"العُقد (التي ليس لها حواف واردة) تكون من الترتيب 0،
ووراءها تأتي في الترتيب 1، وما إلى ذلك. (كالعادة، تشير الحواف من هدف إلى متطلباته الأساسية: الاستهدافات التي يعتمد عليها).
ترتِّب maxrank
كل عُقدة حسب طول أطول مسار من عقدة جذر إليها. ونكرِّر مرة أخرى أن "roots" لها ترتيب 0، فجميع العُقد الأخرى لها ترتيب أعلى من الحد الأقصى لترتيبها في الترتيب السابق.
يتم اعتبار جميع العُقد في الدورة ترتيبًا متساويًا. (معظم الرسوم البيانية هي
دورية، ولكن حدوث الدورات
يرجع ببساطة إلى أن ملفات BUILD
تحتوي على دورات خاطئة.)
تعتبر تنسيقات النتائج هذه مفيدة في اكتشاف مدى عمق الرسم البياني.
في حال استخدامها نتيجة لطلب بحث deps(x)
أو rdeps(x)
أو
allpaths
، يكون رقم الترتيب مساويًا لمدة أقصر (مع minrank
) أو أطول مسار (مع maxrank
) من x
إلى عقدة في هذا الترتيب. يمكن استخدام 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 كأداة
مستقلة للرسم البياني وقِسمة &grep لملفات BUILD.
تختلف معلومات الموقع الجغرافي حسب نوع الهدف (اطّلِع على عامل تشغيل النوع). بالنسبة إلى القواعد، تتم طباعة
موقع بيان القاعدة ضمن ملف 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
على المئات من ملفات مصدر Java التي تم إنشاؤها من خلال genrule
نفسها، وفي الرسم البياني المُعامل، يتم تمثيل جميع هذه الملفات بعقدة واحدة. ويمكن إيقاف هذا السلوك باستخدام الخيار --nograph:factored
.
--graph:node_limit n
يحدّد هذا الخيار الحد الأقصى لطول سلسلة التصنيف لعقدة رسم بياني في الإخراج. سيتم اقتطاع التصنيفات الأطول، -1
لإيقاف الاقتطاع. بسبب شكل العوامل التي تتم طباعة الرسومات البيانية فيها عادةً، قد تكون تصنيفات العُقد طويلة جدًا. لا يمكن أن تعالج معالجة الرسومات البيانية التي تتجاوز 1024 حرفًا، وهي القيمة التلقائية لهذا الخيار. لن يكون لهذا الخيار أي تأثير ما لم يتم استخدام --output=graph
.
--[no]graph:factored
يتم عرض الرسومات البيانية تلقائيًا في شكل عوامل، على النحو الموضّح
أعلاه.
عند تحديد --nograph:factored
، تتم طباعة الرسوم البيانية
بدون أخذ العوامل في الاعتبار. يجعل هذا التمثيل البصري باستخدام GraphViz
غير عملي، ولكن التنسيق الأبسط قد يُسهّل المعالجة بواسطة أدوات أخرى (مثل grep). لن يكون لهذا الخيار أي تأثير
ما لم يتم استخدام --output=graph
.
XML
--output xml
يؤدي هذا الخيار إلى طباعة الأهداف الناتجة في شكل XML. يبدأ الناتج برأس XML على النحو التالي
<?xml version="1.0" encoding="UTF-8"?>
<query version="2">
وبعد ذلك، ستستمر مع عنصر XML لكل هدف في الرسم البياني للنتيجة، بترتيب تسلسلي (ما لم يتم طلب النتائج غير المُرتَّبة)، ثم تنتهي بإنهاء.
</query>
تتوفّر إدخالات بسيطة تستهدف النوع file
:
<source-file name='//foo:foo_main.cc' .../>
<generated-file name='//foo:libfoo.so' .../>
وبالنسبة إلى القواعد، يكون تنسيق XML منظّمًا ويحتوي على تعريفات لجميع سمات القاعدة، بما في ذلك السمات التي لم يتم تحديد قيمتها صراحةً في ملف BUILD
.
بالإضافة إلى ذلك، تشتمل النتيجة على عنصرَي rule-input
وrule-output
، وبالتالي يمكن إعادة تصميم هيكلية الرسم البياني للمهام التابعة بدون الحاجة إلى معرفة أنّ عناصر السمة srcs
هي تبعيات للأمام (المتطلبات الأساسية) ومحتويات السمة outs
هي تبعيات للخلف (المستهلكين).
يتم منع عناصر rule-input
للاعتماديات الضمنية في حال تحديد --noimplicit_deps
.
<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>
ويحتوي كل عنصر XML في الاستهداف على سمة name
، حيث تكون قيمتها هي الهدف و39، وسمة location
، حيث تكون قيمتها الموقع الجغرافي المستهدف كما هو مطبوع بواسطة --output location
.
--[no]xml:line_numbers
تحتوي المواقع الجغرافية المعروضة في مخرجات XML تلقائيًا على أرقام أسطر.
عند تحديد --noxml:line_numbers
، لا تتم طباعة أرقام الأسطر.
--[no]xml:default_values
بشكل تلقائي، لا يتضمّن مخرجات XML سمة القاعدة التي تكون قيمتها هي القيمة التلقائية لهذا النوع من السمات (على سبيل المثال، إذا لم يتم تحديدها في ملف BUILD
، أو تم تقديم القيمة التلقائية بشكل صريح). يؤدي هذا الخيار إلى تضمين قيم السمات هذه
في ناتج XML.
التعبيرات العادية
تستخدم التعبيرات العادية في لغة طلب البحث مكتبة regex في 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