คำสั่ง aquery
ช่วยให้คุณค้นหาการดำเนินการในกราฟบิลด์ได้
โดยจะทำงานในกราฟเป้าหมายที่กำหนดค่าไว้หลังการวิเคราะห์และแสดงข้อมูลเกี่ยวกับการดำเนินการ อาร์ติแฟกต์ และความสัมพันธ์ของอาร์ติแฟกต์
aquery
มีประโยชน์เมื่อคุณสนใจพร็อพเพอร์ตี้ของการดำเนินการ/อาร์ติแฟกต์
ที่สร้างจากกราฟเป้าหมายที่กำหนดค่าไว้ เช่น คำสั่งจริงที่เรียกใช้
และอินพุต/เอาต์พุต/คำช่วยจำ
เครื่องมือนี้ยอมรับตัวเลือกบรรทัดคำสั่งหลายรายการ โดยเฉพาะอย่างยิ่ง คำสั่ง aquery จะทำงานอยู่เหนือบิลด์ Bazel ปกติและรับช่วงชุดตัวเลือกที่ใช้ได้ในระหว่างบิลด์
โดยรองรับฟังก์ชันชุดเดียวกันกับที่ใช้ได้ใน query
แบบเดิม แต่ siblings
, buildfiles
และ tests
ตัวอย่างaquery
เอาต์พุต (ไม่มีรายละเอียดที่เฉพาะเจาะจง)
$ bazel aquery 'deps(//some:label)' action 'Writing file some_file_name' Mnemonic: ... Target: ... Configuration: ... ActionKey: ... Inputs: [...] Outputs: [...]
ไวยากรณ์พื้นฐาน
ตัวอย่างไวยากรณ์แบบง่ายสำหรับ aquery
มีดังนี้
bazel aquery "aquery_function(function(//target))"
นิพจน์การค้นหา (ในเครื่องหมายคำพูด) ประกอบด้วยข้อมูลต่อไปนี้
aquery_function(...)
: ฟังก์ชันที่เฉพาะเจาะจงสำหรับaquery
ดูรายละเอียดเพิ่มเติมได้ด้านล่างfunction(...)
: ฟังก์ชันมาตรฐาน เหมือนกับquery
แบบเดิม//target
คือป้ายกำกับของเป้าหมายที่สนใจ
# aquery examples: # Get the action graph generated while building //src/target_a $ bazel aquery '//src/target_a' # Get the action graph generated while building all dependencies of //src/target_a $ bazel aquery 'deps(//src/target_a)' # Get the action graph generated while building all dependencies of //src/target_a # whose inputs filenames match the regex ".*cpp". $ bazel aquery 'inputs(".*cpp", deps(//src/target_a))'
การใช้ฟังก์ชัน aquery
aquery
ฟังก์ชันมี 3 อย่างดังนี้
inputs
: กรองการดำเนินการตามอินพุตoutputs
: กรองการทำงานตามเอาต์พุตmnemonic
: กรองการดำเนินการตามนิวมอนิกโค้ด
expr ::= inputs(word, expr)
โอเปอเรเตอร์ inputs
จะแสดงผลการดำเนินการที่สร้างขึ้นจากการสร้าง expr
ซึ่งชื่อไฟล์อินพุตตรงกับนิพจน์ทั่วไปที่ word
ระบุ
$ bazel aquery 'inputs(".*cpp", deps(//src/target_a))'
ฟังก์ชัน outputs
และ mnemonic
มีไวยากรณ์คล้ายกัน
นอกจากนี้ คุณยังรวมฟังก์ชันต่างๆ เพื่อดำเนินการแบบ AND ได้ด้วย เช่น
$ bazel aquery 'mnemonic("Cpp.*", (inputs(".*cpp", inputs("foo.*", //src/target_a))))'
คำสั่งข้างต้นจะค้นหาการดำเนินการทั้งหมดที่เกี่ยวข้องกับการสร้าง //src/target_a
ซึ่งมีคำช่วยจำตรงกับ "Cpp.*"
และอินพุตตรงกับรูปแบบ
".*cpp"
และ "foo.*"
ตัวอย่างข้อผิดพลาดด้านไวยากรณ์ที่เกิดขึ้น
$ bazel aquery 'deps(inputs(".*cpp", //src/target_a))' ERROR: aquery filter functions (inputs, outputs, mnemonic) produce actions, and therefore can't be the input of other function types: deps deps(inputs(".*cpp", //src/target_a))
ตัวเลือก
ตัวเลือกการสร้าง
aquery
ทำงานอยู่บนการบิลด์ Bazel ปกติ จึงรับช่วงชุดตัวเลือก
ที่ใช้ได้ในระหว่างการบิลด์
ตัวเลือก Aquery
--output=(text|summary|proto|jsonproto|textproto), default=text
รูปแบบเอาต์พุตเริ่มต้น (text
) เป็นรูปแบบที่มนุษย์อ่านได้
ใช้ proto
, textproto
หรือ jsonproto
สำหรับรูปแบบที่เครื่องอ่านได้
ข้อความ Proto คือ analysis.ActionGraphContainer
--include_commandline, default=true
รวมเนื้อหาของบรรทัดคำสั่งการดำเนินการในเอาต์พุต (อาจมีขนาดใหญ่)
--include_artifacts, default=true
รวมชื่อของอินพุตและเอาต์พุตของการดำเนินการในเอาต์พุต (อาจมีขนาดใหญ่)
--include_aspects, default=true
จะรวมการดำเนินการที่สร้างโดย Aspect ไว้ในเอาต์พุตหรือไม่
--include_param_files, default=false
รวมเนื้อหาของไฟล์พารามิเตอร์ที่ใช้ในคำสั่ง (อาจมีขนาดใหญ่)
--include_file_write_contents, default=false
รวมเนื้อหาไฟล์สำหรับการดำเนินการ actions.write()
และเนื้อหาของไฟล์
manifest สำหรับการดำเนินการ SourceSymlinkManifest
ระบบจะแสดงเนื้อหาไฟล์ในช่อง file_contents
พร้อม --output=
xxxproto
เมื่อใช้ --output=text
เอาต์พุตจะมี
FileWriteContents: [<base64-encoded file contents>]
บรรทัด
--skyframe_state, default=false
ทิ้ง Action Graph จาก Skyframe โดยไม่ต้องทำการวิเคราะห์เพิ่มเติม
เครื่องมือและฟีเจอร์อื่นๆ
การค้นหาเทียบกับสถานะของ Skyframe
Skyframe คือรูปแบบการประเมินและการทำงานแบบเพิ่มของ Bazel ในแต่ละอินสแตนซ์ของเซิร์ฟเวอร์ Bazel, Skyframe จะจัดเก็บกราฟการขึ้นต่อกัน ที่สร้างขึ้นจากการเรียกใช้ระยะการวิเคราะห์ก่อนหน้า
ในบางกรณี การค้นหากราฟการดำเนินการใน Skyframe จะมีประโยชน์ ตัวอย่างกรณีการใช้งานมีดังนี้
- เรียกใช้
bazel build //target_a
- เรียกใช้
bazel build //target_b
- สร้างไฟล์
foo.out
แล้ว
ในฐานะผู้ใช้ Bazel ฉันต้องการตรวจสอบว่า foo.out
สร้างขึ้นจากการสร้าง
//target_a
หรือ //target_b
คุณสามารถเรียกใช้ bazel aquery 'outputs("foo.out", //target_a)'
และ
bazel aquery 'outputs("foo.out", //target_b)'
เพื่อดูการดำเนินการที่รับผิดชอบ
ในการสร้าง foo.out
และเป้าหมายได้ อย่างไรก็ตาม จำนวนเป้าหมายที่แตกต่างกัน
ซึ่งสร้างไว้ก่อนหน้านี้อาจมากกว่า 2 รายการ ซึ่งทำให้การเรียกใช้aquery
คำสั่งหลายรายการเป็นเรื่องยุ่งยาก
หรือจะใช้แฟล็ก --skyframe_state
แทนก็ได้
# List all actions on Skyframe's action graph $ bazel aquery --output=proto --skyframe_state # or # List all actions on Skyframe's action graph, whose output matches "foo.out" $ bazel aquery --output=proto --skyframe_state 'outputs("foo.out")'
ใน--skyframe_state
โหมด aquery
จะนำเนื้อหาของ Action Graph
ที่ Skyframe เก็บไว้ในอินสแตนซ์ของ Bazel มาใช้ (ไม่บังคับ) ทำการกรอง และ
แสดงเนื้อหาโดยไม่ต้องเรียกใช้เฟสการวิเคราะห์อีกครั้ง
สิ่งที่ควรพิจารณาเป็นพิเศษ
รูปแบบเอาต์พุต
ขณะนี้ --skyframe_state
พร้อมให้บริการสำหรับ --output=proto
และ --output=textproto
เท่านั้น
การไม่รวมป้ายกำกับเป้าหมายในนิพจน์การค้นหา
ปัจจุบัน --skyframe_state
จะค้นหากราฟการดำเนินการทั้งหมดที่มีอยู่ใน Skyframe
โดยไม่คำนึงถึงเป้าหมาย การระบุป้ายกำกับเป้าหมายในคำค้นหาร่วมกับ
--skyframe_state
ถือเป็นข้อผิดพลาดทางไวยากรณ์
# WRONG: Target Included $ bazel aquery --output=proto --skyframe_state **//target_a** ERROR: Error while parsing '//target_a)': Specifying build target(s) [//target_a] with --skyframe_state is currently not supported. # WRONG: Target Included $ bazel aquery --output=proto --skyframe_state 'inputs(".*.java", **//target_a**)' ERROR: Error while parsing '//target_a)': Specifying build target(s) [//target_a] with --skyframe_state is currently not supported. # CORRECT: Without Target $ bazel aquery --output=proto --skyframe_state $ bazel aquery --output=proto --skyframe_state 'inputs(".*.java")'
การเปรียบเทียบเอาต์พุตของ Aquery
คุณสามารถเปรียบเทียบเอาต์พุตของการเรียกใช้ aquery ที่แตกต่างกัน 2 รายการได้โดยใช้aquery_differ
เครื่องมือ
เช่น เมื่อคุณทำการเปลี่ยนแปลงคำจำกัดความของกฎและต้องการยืนยันว่าบรรทัดคำสั่งที่เรียกใช้ไม่ได้เปลี่ยนแปลง aquery_differ
คือเครื่องมือสำหรับดำเนินการดังกล่าว
เครื่องมือนี้อยู่ในที่เก็บ bazelbuild/bazel หากต้องการใช้ ให้โคลนที่เก็บไปยังเครื่องของคุณ ตัวอย่างการใช้งาน
$ bazel run //tools/aquery_differ -- \ --before=/path/to/before.proto \ --after=/path/to/after.proto \ --input_type=proto \ --attrs=cmdline \ --attrs=inputs
คำสั่งข้างต้นจะแสดงความแตกต่างระหว่างเอาต์พุต before
และ after
ของ Aquery
(การดำเนินการใดที่อยู่ในเอาต์พุตหนึ่งแต่ไม่อยู่ในอีกเอาต์พุตหนึ่ง การดำเนินการใดที่มีบรรทัดคำสั่ง/อินพุตแตกต่างกันในเอาต์พุต Aquery แต่ละรายการ ฯลฯ) ผลลัพธ์ของการเรียกใช้คำสั่งข้างต้นจะเป็นดังนี้
Aquery output 'after' change contains an action that generates the following outputs that aquery output 'before' change doesn't: ... /list of output files/ ... [cmdline] Difference in the action that generates the following output(s): /path/to/abc.out --- /path/to/before.proto +++ /path/to/after.proto @@ -1,3 +1,3 @@ ... /cmdline diff, in unified diff format/ ...
ตัวเลือกคำสั่ง
--before, --after
: ไฟล์เอาต์พุตของ aquery ที่จะเปรียบเทียบ
--input_type=(proto|text_proto), default=proto
: รูปแบบของไฟล์
อินพุต เราให้การสนับสนุนสำหรับเอาต์พุต proto
และ textproto
aquery
--attrs=(cmdline|inputs), default=cmdline
: แอตทริบิวต์ของการกระทํา
ที่จะเปรียบเทียบ
Aspect-on-aspect
Aspects สามารถใช้ซ้อนกันได้ เอาต์พุต aquery ของการดำเนินการที่สร้างโดย Aspect เหล่านี้จะมีเส้นทาง Aspect ซึ่งเป็นลำดับของ Aspect ที่ใช้กับเป้าหมายซึ่งสร้างการดำเนินการ
ตัวอย่างการใช้ Aspect-on-Aspect
t0 ^ | <- a1 t1 ^ | <- a2 t2
ให้ ti เป็นเป้าหมายของกฎ ri ซึ่งใช้ Aspect ai กับการขึ้นต่อกัน
สมมติว่า a2 สร้างการกระทํา X เมื่อใช้กับเป้าหมาย t0 เอาต์พุตข้อความของ
bazel aquery --include_aspects 'deps(//t2)'
สำหรับการดำเนินการ X จะเป็นดังนี้
action ... Mnemonic: ... Target: //my_pkg:t0 Configuration: ... AspectDescriptors: [//my_pkg:rule.bzl%**a2**(foo=...) -> //my_pkg:rule.bzl%**a1**(bar=...)] ...
ซึ่งหมายความว่าการกระทำ X
เกิดจากลักษณะ a2
ที่ใช้กับ
a1(t0)
โดย a1(t0)
คือผลลัพธ์ของลักษณะ a1
ที่ใช้กับ
เป้าหมาย t0
AspectDescriptor
แต่ละรายการมีรูปแบบดังนี้
AspectClass([param=value,...])
AspectClass
อาจเป็นชื่อของคลาส Aspect (สำหรับ Aspect เนทีฟ) หรือ
bzl_file%aspect_name
(สำหรับ Aspect ของ Starlark) AspectDescriptor
จะ
เรียงตามลำดับโทโพโลยีของ
กราฟการอ้างอิง
การลิงก์กับโปรไฟล์ JSON
แม้ว่า aquery จะให้ข้อมูลเกี่ยวกับการดำเนินการที่กำลังทำงานในการสร้าง (เหตุผลที่กำลังทำงาน อินพุต/เอาต์พุต) แต่โปรไฟล์ JSON จะบอกเวลาและระยะเวลาการดำเนินการ คุณสามารถรวมข้อมูล 2 ชุดนี้ผ่านตัวหารร่วม ซึ่งก็คือเอาต์พุตหลักของการกระทํา
หากต้องการรวมเอาต์พุตของการดำเนินการไว้ในโปรไฟล์ JSON ให้สร้างโปรไฟล์ด้วย
--experimental_include_primary_output --noslim_profile
โปรไฟล์ Slim ใช้ร่วมกับการรวมเอาต์พุตหลักไม่ได้ aquery จะรวมเอาเอาต์พุตหลักของการดำเนินการ
ไว้โดยค่าเริ่มต้น
ปัจจุบันเรายังไม่มีเครื่องมือที่ใช้เป็นแหล่งข้อมูลหลักเพื่อรวมแหล่งข้อมูล 2 แหล่งนี้ แต่คุณควร สร้างสคริปต์ของคุณเองได้โดยใช้ข้อมูลข้างต้น
ปัญหาที่ทราบ
การจัดการการดำเนินการที่แชร์
บางครั้งระบบจะแชร์การดำเนินการ ระหว่างเป้าหมายที่กำหนดค่าไว้
ในระยะการดำเนินการ ระบบจะถือว่าการดำเนินการที่แชร์เหล่านั้นเป็นรายการเดียวและดำเนินการเพียงครั้งเดียว
อย่างไรก็ตาม aquery จะทํางานบนกราฟการดําเนินการก่อนการเรียกใช้และหลังการวิเคราะห์ จึงถือว่าการดําเนินการเหล่านี้
เป็นการดําเนินการแยกกันซึ่งมีอาร์ติแฟกต์เอาต์พุตที่มี execPath
เหมือนกันทุกประการ ด้วยเหตุนี้
อาร์ติแฟกต์ที่เทียบเท่าจึงปรากฏซ้ำ
ดูรายการปัญหาเกี่ยวกับ aquery/ฟีเจอร์ที่วางแผนไว้ได้ที่ GitHub
คำถามที่พบบ่อย
ActionKey จะยังคงเหมือนเดิมแม้ว่าเนื้อหาของไฟล์อินพุตจะเปลี่ยนไปแล้วก็ตาม
ในบริบทของคําค้นหา ActionKey
หมายถึง String
ที่ได้จาก
ActionAnalysisMetadata#getKey:
Returns a string encoding all of the significant behaviour of this Action that might affect the output. The general contract of `getKey` is this: if the work to be performed by the execution of this action changes, the key must change. ... Examples of changes that should affect the key are: - Changes to the BUILD file that materially affect the rule which gave rise to this Action. - Changes to the command-line options, environment, or other global configuration resources which affect the behaviour of this kind of Action (other than changes to the names of the input/output files, which are handled externally). - An upgrade to the build tools which changes the program logic of this kind of Action (typically this is achieved by incorporating a UUID into the key, which is changed each time the program logic of this action changes). Note the following exception: for actions that discover inputs, the key must change if any input names change or else action validation may falsely validate.
ซึ่งไม่รวมการเปลี่ยนแปลงเนื้อหาของไฟล์อินพุต และไม่ควรสับสนกับ RemoteCacheClient#ActionKey
อัปเดต
หากมีปัญหาหรือต้องการขอฟีเจอร์ใดๆ โปรดแจ้งปัญหาที่นี่