ריכזנו במאמר הזה מידע על תחילת העבודה עם שפת השאילתות של Bazel'. מעקב אחר יחסי תלות בקוד שלכם.
כדי לקבל פרטים על השפה ופרטים על הדגל של --output
, עיינו במדריכים הרלוונטיים, בהפניות לשאילתות ב-Bazel ובהפניות לשאילתות ב-Bazel. כדי לקבל עזרה, מקלידים bazel help query
או bazel help cquery
בשורת הפקודה.
כדי לבצע שאילתה תוך התעלמות משגיאות כמו יעדים חסרים, יש להשתמש בסימון --keep_going
.
מציאת תלויות של כלל
כדי לראות את התלות של //foo
, צריך להשתמש בפונקציה deps
בשדה השאילתה:
$ 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
כולל תלות מרומזת
מהדר הפרוטוקול. יחסי התלות האלה לא מוזכרים בקובץ ה-build, אבל הם נוספים על ידי כלי ה-build. הקבוצה המלאה של יחסי תלות לא משתמעים
לא מתועדת כרגע. אפשר להשתמש ב---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:*)'
אילו יעדים נוצרים על ידי מאקרו Starlark 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
מהי תווית ה-build של 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
מהם יחסי תלות של כלל ...
על אילו כללי ג'נטוטו תלויה עמודה?
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'
קובצי מקור:
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
?
השאילתה הזו מתבססת על: "Show me the subscript of //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
מה תלוי ...
אילו כללים מתחת לרף תלויים ב-Y?
bazel query 'bar/... intersect allpaths(bar/..., Y)'
אילו יעדים תלויים ישירות ב-T, בחבילת T'
bazel query 'same_pkg_direct_rdeps(T)'
איך מבטלים קשרי תלות ...
אילו נתיבי תלות עליי לשבור כדי ש-bar
לא יהיה יותר תלוי ב-X?
כדי לייצא את התרשים לקובץ svg
:
bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg
שונות
כמה שלבים עוקבים יש ב-build של //foo-tests
?
לצערנו, שפת השאילתה לא יכולה לספק לכם את הנתיב הארוך ביותר מ-x עד Y, אבל היא יכולה למצוא את הצומת הארוך ביותר (או a) מנקודת ההתחלה או את הארוכים של האורך של הנתיב הארוך ביותר, מ-x ועד כל שנה, תלוי. שימוש בmaxrank
:
bazel query 'deps(//foo-tests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.c
התוצאה מצביעה על כך שיש נתיבים באורך 85 שחייבים להתרחש בסדר הזה.