หน้านี้จะอธิบายวิธีเริ่มต้นใช้งานภาษาการค้นหาของ Bazel เพื่อติดตามทรัพยากร Dependency ในโค้ด
โปรดดูรายละเอียดภาษาและรายละเอียดแฟล็ก --output ใน
คู่มืออ้างอิง คู่มืออ้างอิงการค้นหาของ Bazel
และ คู่มืออ้างอิงการค้นหาของ Bazel คุณขอความช่วยเหลือได้โดยพิมพ์ bazel help query หรือ bazel help cquery ในบรรทัดคำสั่ง
หากต้องการเรียกใช้การค้นหาขณะที่ละเว้นข้อผิดพลาด เช่น เป้าหมายที่ขาดหายไป ให้ใช้แฟล็ก --keep_going
การค้นหาทรัพยากร Dependency ของกฎ
หากต้องการดูทรัพยากร Dependency ของ //foo ให้ใช้ฟังก์ชัน deps ในการค้นหาของ Bazel
$ bazel query "deps(//foo)" //foo:foo //foo:foo-dep ...
นี่คือชุดเป้าหมายทั้งหมดที่จำเป็นสำหรับการสร้าง //foo
การติดตามเชนทรัพยากร Dependency ระหว่าง 2 แพ็กเกจ
ไลบรารี //third_party/zlib:zlibonly ไม่ได้อยู่ในไฟล์ BUILD สำหรับ //foo แต่เป็นทรัพยากร Dependency ทางอ้อม เราจะติดตามเส้นทางทรัพยากร Dependency นี้ได้อย่างไร ฟังก์ชันที่มีประโยชน์ 2 ฟังก์ชันในที่นี้คือ allpaths และ somepath นอกจากนี้ คุณยังอาจต้องการยกเว้นทรัพยากร Dependency ของเครื่องมือด้วย --notool_deps หากคุณสนใจเฉพาะสิ่งที่รวมอยู่ในอาร์ติแฟกต์ที่คุณสร้างขึ้น และไม่ใช่ทุกงานที่เป็นไปได้
หากต้องการแสดงกราฟทรัพยากร Dependency ทั้งหมด ให้ส่งเอาต์พุตการค้นหาของ Bazel ผ่าน
เครื่องมือบรรทัดคำสั่ง dot ดังนี้
$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg
เมื่อกราฟทรัพยากร Dependency มีขนาดใหญ่และซับซ้อน การเริ่มต้นด้วยเส้นทางเดียวอาจเป็นประโยชน์
$ 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 คุณจะได้รับรายการกราฟทรัพยากร Dependency แบบแบน
$ 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
หมายเหตุ: ทรัพยากร Dependency โดยนัย
ไฟล์ BUILD สำหรับ //foo ไม่เคยอ้างอิง //translations/tools:aggregator แล้วทรัพยากร Dependency โดยตรงอยู่ที่ไหน
กฎบางข้อมีทรัพยากร Dependency โดยนัยในไลบรารีหรือเครื่องมือเพิ่มเติม
ตัวอย่างเช่น หากต้องการสร้างกฎ genproto คุณต้องสร้างคอมไพเลอร์โปรโตคอลก่อน ดังนั้นกฎ genproto ทุกข้อจึงมีทรัพยากร Dependency โดยนัยในคอมไพเลอร์โปรโตคอล ทรัพยากร Dependency เหล่านี้ไม่ได้ระบุไว้ในไฟล์บิลด์ แต่เครื่องมือบิลด์จะเพิ่มเข้าไป ปัจจุบันยังไม่มีเอกสารอธิบายชุดทรัพยากร Dependency โดยนัยทั้งหมด
การใช้ --noimplicit_deps จะช่วยให้คุณกรองทรัพยากร Dependency เหล่านี้ออกจากผลการค้นหาได้
สำหรับ cquery การดำเนินการนี้จะรวมถึงชุดเครื่องมือที่แก้ไขแล้ว
ทรัพยากร Dependency แบบย้อนกลับ
คุณอาจต้องการทราบชุดเป้าหมายที่ขึ้นอยู่กับเป้าหมายบางอย่าง เช่น หากคุณกำลังจะเปลี่ยนโค้ดบางส่วน คุณอาจต้องการทราบโค้ดอื่นๆ ที่คุณกำลังจะทำให้เกิดข้อผิดพลาด คุณสามารถใช้ rdeps(u, x) เพื่อค้นหาทรัพยากร Dependency แบบย้อนกลับ
ของเป้าหมายใน x ภายในทรานซิทีฟโคลเชอร์ของ u
Sky Query ของ Bazel รองรับฟังก์ชัน allrdeps ซึ่งช่วยให้คุณค้นหาทรัพยากร Dependency แบบย้อนกลับ
ในจักรวาลที่คุณระบุได้
การใช้งานอื่นๆ
คุณสามารถใช้ bazel query เพื่อวิเคราะห์ความสัมพันธ์ของทรัพยากร Dependency ได้มากมาย
สิ่งที่อยู่ ...
แพ็กเกจใดบ้างที่อยู่ใต้ 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
ป้ายกำกับบิลด์สำหรับ 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//:*/}:*)"
ทรัพยากร Dependency ของแพ็กเกจใดบ้างที่อยู่ ...
foo ขึ้นอยู่กับแพ็กเกจใดบ้าง (ฉันต้องเช็คเอาต์อะไรบ้างเพื่อสร้าง foo)
bazel query 'buildfiles(deps(//foo:foo))' --output package
ทรี foo ขึ้นอยู่กับแพ็กเกจใดบ้าง โดยไม่รวม foo/contrib
bazel query 'deps(foo/... except foo/contrib/...)' --output package
ทรัพยากร Dependency ของกฎใดบ้างที่อยู่ ...
กฎ genproto ใดบ้างที่ bar ขึ้นอยู่กับ
bazel query 'kind(genproto, deps(bar/...))'
ค้นหาคำจำกัดความของไลบรารี JNI (C++) บางรายการที่กฎไบนารี Java ในทรี Servlet ขึ้นอยู่กับแบบทรานซิทีฟ
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)'
ทรัพยากร Dependency ของไฟล์ใดบ้างที่อยู่ ...
ชุดไฟล์ต้นฉบับ 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$ความแตกต่างของทรัพยากร Dependency ระหว่าง 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))'ทำไมทรัพยากร Dependency นี้จึงอยู่ ...
ทำไม bar จึงขึ้นอยู่กับ groups2
bazel query 'somepath(bar/...,groups2/...:*)'
เมื่อได้ผลการค้นหานี้แล้ว คุณมักจะพบว่าเป้าหมายเดียวโดดเด่นในฐานะทรัพยากร Dependency ที่ไม่คาดคิดหรือร้ายแรงและไม่พึงประสงค์ของ 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 ซึ่งเป็นไลบรารีเดียวกัน 2 รูปแบบ
การค้นหานี้สรุปได้ว่า "แสดงกราฟย่อยของ //photos/frontend:lib ที่ขึ้นอยู่กับไลบรารีทั้ง 2 รายการ" เมื่อแสดงตามลำดับโทโพโลยี องค์ประกอบสุดท้ายของผลลัพธ์คือสาเหตุที่เป็นไปได้มากที่สุด
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
สิ่งที่ขึ้นอยู่กับ ...
กฎใดบ้างภายใต้ bar ที่ขึ้นอยู่กับ Y
bazel query 'bar/... intersect allpaths(bar/..., Y)'
เป้าหมายใดบ้างที่ขึ้นอยู่กับ T โดยตรงในแพ็กเกจของ T
bazel query 'same_pkg_direct_rdeps(T)'
ฉันจะแยกทรัพยากร Dependency ได้อย่างไร ...
ฉันต้องแยกเส้นทางทรัพยากร Dependency ใดบ้างเพื่อให้ bar ไม่ขึ้นอยู่กับ X อีกต่อไป
หากต้องการส่งออกกราฟไปยังไฟล์ svg ให้ทำดังนี้
bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg
อื่นๆ
บิลด์ //foo-tests มีขั้นตอนต่อเนื่องกันกี่ขั้นตอน
น่าเสียดายที่ปัจจุบันภาษาการค้นหาไม่สามารถแสดงเส้นทางที่ยาวที่สุดจาก x ไปยัง y ได้ แต่จะค้นหาโหนดที่อยู่ไกลที่สุด (หรือค่อนข้างจะ โหนดหนึ่ง) จากจุดเริ่มต้น หรือแสดง ความยาว ของเส้นทางที่ยาวที่สุดจาก x ไปยัง y ทุกรายการที่ขึ้นอยู่ด้วย ใช้ maxrank ดังนี้
bazel query 'deps(//foo-tests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.c
ผลลัพธ์ระบุว่ามีเส้นทางที่มีความยาว 85 เส้นทางที่ต้องเกิดขึ้นตามลำดับในบิลด์นี้