หน้านี้จะพูดถึงวิธีเริ่มต้นใช้งานภาษาการค้นหาของ Bazel เพื่อติดตามการขึ้นต่อกันในโค้ดของคุณ
โปรดดูรายละเอียดเกี่ยวกับภาษาและรายละเอียดแฟล็ก --output
ในคู่มืออ้างอิง ข้อมูลอ้างอิงข้อความค้นหาแบบเบเซลและข้อมูลอ้างอิงการค้นหาด้วยโค้ดบาเซล คุณรับความช่วยเหลือได้โดยพิมพ์ bazel help query
หรือ bazel help cquery
ในบรรทัดคำสั่ง
หากต้องการดำเนินการค้นหาโดยไม่สนใจข้อผิดพลาด เช่น เป้าหมายขาดหายไป ให้ใช้แฟล็ก --keep_going
การค้นหาทรัพยากร Dependency ของกฎ
หากต้องการดูทรัพยากร Dependency ของ //foo
ให้ใช้ฟังก์ชัน deps
ในการค้นหาแบบเบเซล ดังนี้
$ 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 ทั้งหมด ให้เชื่อมต่อเอาต์พุตการค้นหาแบบเบลิซผ่านเครื่องมือบรรทัดคำสั่ง 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
คุณจะเห็นรายการที่แยกเป็นกราฟทรัพยากร 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 โดยนัยทั้งหมด การใช้ --noimplicit_deps
จะช่วยให้คุณกรอง
การจัดส่งเหล่านี้ออกจากผลการค้นหาได้ สำหรับ cquery จะรวมเครื่องมือที่ได้รับการแก้ไขแล้วด้วย
ทรัพยากร Dependency แบบย้อนกลับ
คุณอาจต้องการทราบชุดเป้าหมายที่สอดคล้องกับเป้าหมายบางรายการ เช่น หากคุณจะเปลี่ยนโค้ด คุณอาจต้องการทราบว่า
โค้ดอื่นๆ ที่คุณกำลังจะทำให้ใช้งานไม่ได้คืออะไร คุณใช้ rdeps(u, x)
เพื่อดูการขึ้นต่อกันแบบย้อนกลับของเป้าหมายใน 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 ใดบ้าง
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)'
ทรัพยากร Dependency ของไฟล์ใดที่มีอยู่ ...
ข้อใดคือชุดไฟล์ต้นฉบับของ Java ที่ต้องใช้ในการสร้างไฟล์
ไฟล์ต้นฉบับ:
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))'
เหตุใดจึงต้องมีทรัพยากร Dependency นี้ ...
ทำไม 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
จึงใช้ตัวแปร 2 ตัวของไลบรารี //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
ขึ้นอยู่กับ ...
กฎใดในแถบที่ขึ้นอยู่กับ 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
อื่นๆ
มีขั้นตอนตามลำดับกี่ขั้นตอนในบิลด์ //foo-tests
ขออภัย ภาษาในการค้นหาไม่สามารถให้เส้นทางที่ยาวที่สุดจาก x ถึง y ได้ในขณะนี้ แต่สามารถค้นหาโหนดที่อยู่ไกลที่สุด (หรือ a) จากจุดเริ่มต้น หรือแสดงความยาวของเส้นทางที่ยาวที่สุดจาก x ถึง y ทั้งหมดที่เกี่ยวข้อง ใช้ maxrank
:
bazel query 'deps(//foo-tests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.c
ผลลัพธ์แสดงให้เห็นว่ามีเส้นทางที่มีความยาว 85 ซึ่งต้องเกิดขึ้นตามลำดับในบิวด์นี้