طريقة تنفيذ طلب البحث في Bazel

تتناول هذه الصفحة طريقة بدء استخدام لغة طلب البحث في Bazel' لتتبّع المهام التابعة في رمزك.

للاطّلاع على تفاصيل حول اللغة ومزيد من التفاصيل عن العلامة --output، يُرجى الاطّلاع على الأدلّة المرجعية ومرجع طلبات البحث في Bazel ومرجع Bazel cquery. يمكنك الحصول على المساعدة عن طريق كتابة bazel help query أو bazel help cquery في سطر الأوامر.

لتنفيذ طلب بحث مع تجاهل الأخطاء مثل الأهداف المفقودة، استخدِم العلامة --keep_going.

العثور على تبعيات القاعدة

لعرض المهام التابعة لـ //foo، استخدِم الدالة deps في طلب البحث في Bazel:

$ bazel query "deps(//foo)"
//foo:foo
//foo:foo-dep
...

هذه هي مجموعة جميع الأهداف المطلوبة لإنشاء //foo.

تتبُّع سلسلة التبعية بين حزمتَين

المكتبة //third_party/zlib:zlibonly ليست في ملف BUILD لـ //foo، ولكنها اعتمادية غير مباشرة. كيف يمكننا تتبّع مسار الاعتمادية هذا؟ هناك وظيفتان مفيدتان هنا: allpaths وsomepath. يمكنك أيضًا استبعاد تبعيات الأدوات على --notool_deps إذا كنت مهتمًا فقط بالعناصر الواردة في العنصر الذي أنشأته، وليس كل مهمة ممكنة.

لعرض رسم بياني لكل العناصر التابعة، عليك تمرير الناتج عن طلب البحث من خلال أداة سطر الأوامر dot:

$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg

عندما يكون الرسم البياني للاعتمادية كبيرًا ومعقدًا، قد يكون من المفيد بدء مسار واحد:

$ bazel query "somepath(//foo:foo, third_party/zlib:zlibonly)"
//foo:foo
//translations/tools:translator
//translations/base:base
//third_party/py/MySQL:MySQL
//third_party/py/MySQL:_MySQL.so
//third_party/mysql:mysql
//third_party/zlib:zlibonly

إذا لم تُحدِّد --output graph مع allpaths، ستحصل على قائمة مسطّحة من الرسم البياني للاعتمادية.

$ bazel query "allpaths(//foo, third_party/...)"
  ...many errors detected in BUILD files...
//foo:foo
//translations/tools:translator
//translations/tools:aggregator
//translations/base:base
//tools/pkg:pex
//tools/pkg:pex_phase_one
//tools/pkg:pex_lib
//third_party/python:python_lib
//translations/tools:messages
//third_party/py/xml:xml
//third_party/py/xml:utils/boolean.so
//third_party/py/xml:parsers/sgmlop.so
//third_party/py/xml:parsers/pyexpat.so
//third_party/py/MySQL:MySQL
//third_party/py/MySQL:_MySQL.so
//third_party/mysql:mysql
//third_party/openssl:openssl
//third_party/zlib:zlibonly
//third_party/zlib:zlibonly_v1_2_3
//third_party/python:headers
//third_party/openssl:crypto

جانبًا: المهام التابعة الضمنية

لا يشير ملف BUILD الذي يخص //foo مطلقًا إلى //translations/tools:aggregator. إذن، أين تعتمد الاعتمادية المباشرة؟

وتتضمن بعض القواعد تبعيات ضمنية على مكتبات أو أدوات إضافية. على سبيل المثال، لإنشاء قاعدة genproto، عليك أولاً إنشاء مجمِّع البروتوكولات، وبالتالي فإن كل قاعدة genproto تحمل اعتمادًا ضمنيًا على برنامج التجميع. لم يتم ذكر هذه الارتباطات في ملف الإصدار، ولكن تمت إضافتها بواسطة أداة الإصدار. وفي ما يلي المجموعة الكاملة من المهام الضمنية غير الموثَّقة حاليًا. يتيح لك استخدام --noimplicit_deps فلترة هذه الانخفاضات من نتائج طلب البحث. بالنسبة إلى طلب البحث، يشمل ذلك سلاسل الأدوات التي تم حلّها.

عكس المهام التابعة

قد تحتاج إلى معرفة مجموعة الأهداف التي تعتمد على بعض الأهداف. على سبيل المثال، إذا كنت ستغيّر بعض الرموز، قد تحتاج إلى معرفة الرمز الآخر الذي ستخقره. يمكنك استخدام rdeps(u, x) للبحث عن المهام التابعة العكسية للأهداف في x خلال الإغلاق المؤقت لـ u.

Bazel's Sky Query يتيح وظيفة allrdeps التي تتيح لك طلب بحث تبعيات عكسية في الكون الذي تحدّده.

استخدامات متنوعة

يمكنك استخدام bazel query لتحليل العديد من العلاقات التابعة.

ما موجود ...

ما هي الحِزم المتوفّرة تحت foo؟

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

ما هي القواعد التي يتم تعريفها في حزمة foo؟

bazel query 'kind(rule, foo:*)' --output label_kind

ما هي الملفات التي يتم إنشاؤها من خلال القواعد في حزمة foo؟

bazel query 'kind("generated file", //foo:*)'

ما هي الأهداف التي يتم إنشاؤها من خلال وحدة ماكرو نجمية foo؟

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

ما هي مجموعة ملفات BUILD اللازمة لإنشاء //foo؟

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

ما هي الاختبارات الفردية التي يتم توسيع test_suite إليها؟

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

ما هو المقصود باختبارات C++ ؟

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

أيٌّ منها صغير الحجم؟ متوسطة؟ كبيرة؟

bazel query 'attr(size, small, tests(//foo:smoke_tests))'

bazel query 'attr(size, medium, tests(//foo:smoke_tests))'

bazel query 'attr(size, large, tests(//foo:smoke_tests))'

ما هي الاختبارات أسفل foo التي تطابق نمطًا؟

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

النمط هو تعبير عادي ويتم تطبيقه على الاسم الكامل للقاعدة. إنّها مماثلة لأداء

bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'

ما هي الحزمة التي تحتوي على الملف path/to/file/bar.java؟

 bazel query path/to/file/bar.java --output=package

ما هو تصنيف الإصدار لـ path/to/file/bar.java?؟

bazel query path/to/file/bar.java

ما أهداف القاعدة التي تحتوي على الملف path/to/file/bar.java كمصدر؟

fullname=$(bazel query path/to/file/bar.java)
bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"

ما هي اعتماديات الحزمة ...

ما هي الحِزم التي يعتمد عليها foo؟ (ما الذي أحتاج إليه لإتمام الدفع لإنشاء foo؟)

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

ما هي الحِزم التي يعتمد عليها شجرة foo؟ باستثناء foo/contrib.

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

ما هي اعتماديات القاعدة المتاحة ...

ما هي قواعد Genproto التي يعتمد عليها الشريط؟

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

يمكنك العثور على تعريف لبعض مكتبة JNI (C++ ) التي تعتمد عليها بشكل مؤقت من خلال قاعدة Java ثنائية في شجرة الخادم.

bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...يمكنك الآن العثور على تعريفات جميع برامج Java الثنائية التي تعتمد عليها
bazel query 'let jbs = kind(java_binary, //java/com/example/frontend/...) in
  let cls = kind(cc_.*library, deps($jbs)) in
    $jbs intersect allpaths($jbs, $cls)'

ما هي تبعيات الملفات المتاحة ...

ما هي المجموعة الكاملة من ملفات مصدر Java المطلوبة لإنشاء foo؟

ملفات المصدر:

bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$

الملفات التي تم إنشاؤها:

bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$

ما هي المجموعة الكاملة من ملفات مصدر Java المطلوبة لإنشاء اختبارات QUX's؟

ملفات المصدر:

bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$

الملفات التي تم إنشاؤها:

bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$

ما هي الاختلافات في التبعيات بين X وY ...

ما هي الاستهدافات التي يعتمد عليها //foo ولا تعتمد //foo:foolib عليها؟

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

ما هي مكتبات C++ التي تعتمد عليها اختبارات foo؟يعتمد البرنامج الثنائي //foo للإنتاج

bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'

لماذا تنشأ هذه الاعتمادية؟

لماذا يعتمد bar على groups2؟

bazel query 'somepath(bar/...,groups2/...:*)'

وبعد الحصول على نتائج طلب البحث هذا، غالبًا ما تجد أن هدفًا واحدًا يتميز بأنّه مصدر غير متوقّع أو فاضح أو غير مرغوب فيه وهو bar. ويمكن بعد ذلك تنقيح طلب البحث بما يلي:

اعرض لي مسارًا من docker/updater:updater_systest (ال py_test) إلى بعض cc_library استنادًا إلى ما يلي:

bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in
  somepath(docker/updater:updater_systest, $cc)'

لماذا تعتمد المكتبة //photos/frontend:lib على صيغتَين من المكتبة //third_party/jpeglib و//third_party/jpeg نفسها؟

يتلخّص طلب البحث هذا بما يلي: &&;;; بالتألّف من ظهور الترميز الفرعي لـ //photos/frontend:lib الذي يعتمد على كلتا المكتبتَين& يظهر العنصر الأخير في النتيجة بترتيب طوبوغرافي، وهو السبب الأكثر احتمالاً.

bazel query 'allpaths(//photos/frontend:lib, //third_party/jpeglib)
                intersect
               allpaths(//photos/frontend:lib, //third_party/jpeg)'
//photos/frontend:lib
//photos/frontend:lib_impl
//photos/frontend:lib_dispatcher
//photos/frontend:icons
//photos/frontend/modules/gadgets:gadget_icon
//photos/thumbnailer:thumbnail_lib
//third_party/jpeg/img:renderer

يعتمد ذلك على ...

ما هي القواعد التي تقع ضمن الشريط التي تعتمد على "ص"؟

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

ما هي الأهداف التي تعتمد بشكل مباشر على T، في حزمة T's؟

bazel query 'same_pkg_direct_rdeps(T)'

كيف يمكنني الحصول على اعتمادية ...

أي مسارات اعتمادية يجب أن أقطعها لتوقف bar عن الاعتماد على X؟

لإخراج الرسم البياني إلى ملف svg:

bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg

ميزات متنوّعة

ما عدد الخطوات التسلسلية الموجودة في إصدار //foo-tests؟

للأسف، لا يمكن للغة طلب البحث أن ترسل لك في الوقت الحالي أطول مسار من x إلى y، ولكن يمكنها العثور على العقدة البعيدة (أو بدلاً من ذلك a) من نقطة البداية، أو عرض أطوال أطول مسار من x إلى كل y تعتمد عليه. استخدام maxrank:

bazel query 'deps(//foo-tests)' --output maxrank | tail -1
85 //third_party/zlib:zutil.c

تشير النتيجة إلى وجود مسارات بطول 85 يجب أن تكون مرتَّبة بالترتيب في هذا الإصدار.