หน้านี้จะพูดถึงวิธีเริ่มต้นใช้งานภาษาการค้นหาของ Bazel เพื่อติดตามการขึ้นต่อกันในโค้ด
ดูรายละเอียดภาษาและรายละเอียด Flag --output
ได้ที่คู่มืออ้างอิง ข้อมูลอ้างอิงสำหรับคําค้นหาของ Bazel และข้อมูลอ้างอิงสำหรับ cquery ของ Bazel คุณรับความช่วยเหลือได้โดยพิมพ์ bazel help query
หรือ bazel help cquery
ในบรรทัดคำสั่ง
หากต้องการเรียกใช้การค้นหาโดยไม่สนใจข้อผิดพลาด เช่น ไม่มีเป้าหมาย ให้ใช้แฟล็ก --keep_going
การค้นหาทรัพยากร Dependency ของกฎ
หากต้องการดูรายการที่ //foo
อ้างอิง ให้ใช้ฟังก์ชัน
deps
ใน Bazel Query ดังนี้
$ bazel query "deps(//foo)" //foo:foo //foo:foo-dep ...
นี่คือชุดเป้าหมายทั้งหมดที่จําเป็นสําหรับการสร้าง //foo
การติดตามเชนการพึ่งพาระหว่าง 2 แพ็กเกจ
ไลบรารี //third_party/zlib:zlibonly
ไม่ได้อยู่ในไฟล์ BUILD สำหรับ //foo
แต่เป็นทรัพยากร Dependency โดยอ้อม เราติดตามเส้นทางการพึ่งพานี้ได้อย่างไร ฟังก์ชันที่มีประโยชน์ 2 รายการ ได้แก่
allpaths
และ somepath
นอกจากนี้ คุณอาจต้องยกเว้นการพึ่งพาเครื่องมือด้วย --notool_deps
หากสนใจเฉพาะสิ่งที่รวมอยู่ในอาร์ติแฟกต์ที่คุณสร้าง ไม่ใช่งานทั้งหมดที่เป็นไปได้
หากต้องการแสดงภาพกราฟของทรัพยากร Dependency ทั้งหมด ให้แมปเอาต์พุตของการค้นหา Bazel ผ่านเครื่องมือบรรทัดคำสั่ง 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
หมายเหตุ: ทรัพยากร Dependency โดยนัย
ไฟล์ BUILD สำหรับ //foo
ไม่เคยอ้างอิง
//translations/tools:aggregator
Dependency โดยตรงอยู่ที่ไหน
กฎบางข้อมีการขึ้นต่อกันโดยนัยในไลบรารีหรือเครื่องมือเพิ่มเติม
เช่น หากต้องการสร้างกฎ genproto
คุณต้องสร้างคอมไพเลอร์โปรโตคอลก่อน เพื่อให้กฎ genproto
ทั้งหมดมี Dependency ที่ไม่ชัดแจ้งกับคอมไพเลอร์โปรโตคอล ไฟล์บิลด์ไม่ได้กล่าวถึงการพึ่งพาเหล่านี้ แต่เครื่องมือสร้างจะเพิ่มเข้ามา ขณะนี้ยังไม่มีการบันทึกทรัพยากร Dependency โดยนัยทั้งชุด การใช้ --noimplicit_deps
ช่วยให้คุณกรอง deps เหล่านี้ออกจากผลการค้นหาได้ สำหรับ cquery ข้อมูลนี้จะรวมเครื่องมือทางเทคนิคที่แก้ไขแล้ว
ทรัพยากร Dependency แบบย้อนกลับ
คุณอาจต้องทราบชุดเป้าหมายที่ขึ้นอยู่กับเป้าหมายบางรายการ ตัวอย่างเช่น หากคุณกำลังจะเปลี่ยนแปลงโค้ดบางอย่าง คุณอาจต้องการทราบโค้ดอื่นๆ ที่คุณ
กำลังจะเสียหาย คุณสามารถใช้ rdeps(u, x)
เพื่อค้นหาความสัมพันธ์แบบย้อนกลับของเป้าหมายใน x
ภายในการปิดเชิงสื่อกลางของ u
Sky Query ของ Bazel รองรับฟังก์ชัน allrdeps
ซึ่งช่วยให้คุณค้นหาความสัมพันธ์แบบย้อนกลับในจักรวาลที่ระบุได้
การใช้งานเบ็ดเตล็ด
คุณใช้ 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//:*/}:*)"
แพ็กเกจใดบ้างที่ต้องใช้ร่วมกัน ...
foo
ขึ้นอยู่กับแพ็กเกจใด (What do I need to check out to build foo
)
bazel query 'buildfiles(deps(//foo:foo))' --output package
แผนผัง foo
อ้างอิงแพ็กเกจใด ยกเว้น foo/contrib
bazel query 'deps(foo/... except foo/contrib/...)' --output package
What rule dependencies exist ...
bar ขึ้นอยู่กับกฎ 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 คืออะไร
ไฟล์ต้นฉบับ
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)'
การทดสอบ foo
ต้องใช้ไลบรารี C++ ใดที่ //foo
เวอร์ชันที่ใช้จริงไม่ใช้
bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'
Why does this dependency exist ...
Why does bar
depend on groups2
?
bazel query 'somepath(bar/...,groups2/...:*)'
เมื่อได้รับผลการค้นหานี้ คุณมักจะพบว่าเป้าหมายหนึ่งๆ โดดเด่นขึ้นมาในฐานะทรัพยากร bar
ที่ไม่คาดคิด รุนแรง และไม่พึงประสงค์ จากนั้นปรับแต่งการค้นหาเพิ่มเติมเป็น
แสดงเส้นทางจาก docker/updater:updater_systest
(py_test
) ไปยัง cc_library
บางรายการที่ docker/updater:updater_systest
นั้นพึ่งพา
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
สิ่งที่ขึ้นอยู่กับ ...
กฎใดภายใต้แถบขึ้นอยู่กับ Y
bazel query 'bar/... intersect allpaths(bar/..., Y)'
เป้าหมายใดที่ขึ้นอยู่กับ T โดยตรงในแพ็กเกจของ T
bazel query 'same_pkg_direct_rdeps(T)'
ฉันจะยกเลิกการพึ่งพา ... ได้ยังไง
ฉันต้องแยกเส้นทางทรัพยากร 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 ที่ต้องปรากฏตามลําดับในบิลด์นี้