ดูข้อกำหนดทั้งหมดของ Build Event Protocol ได้ในคำจำกัดความของ Protocol Buffer อย่างไรก็ตาม การสร้างสัญชาตญาณบางอย่างอาจเป็นประโยชน์ ก่อนที่จะดูข้อกำหนด
ลองพิจารณาพื้นที่ทำงาน Bazel อย่างง่ายที่ประกอบด้วยสคริปต์เชลล์ว่าง 2 รายการ
foo.sh
และ foo_test.sh
รวมถึงไฟล์ BUILD
ต่อไปนี้
sh_library(
name = "foo_lib",
srcs = ["foo.sh"],
)
sh_test(
name = "foo_test",
srcs = ["foo_test.sh"],
deps = [":foo_lib"],
)
เมื่อเรียกใช้ bazel test ...
ในโปรเจ็กต์นี้ กราฟการสร้างของเหตุการณ์การสร้างที่สร้างขึ้นจะคล้ายกับกราฟด้านล่าง
ลูกศรแสดงถึง
ความสัมพันธ์หลักและย่อยที่กล่าวถึงข้างต้น โปรดทราบว่าเราได้ละเว้นเหตุการณ์การสร้างบางอย่างและฟิลด์ส่วนใหญ่เพื่อความกระชับ
รูปที่ 1 กราฟ BEP
ในตอนแรก ระบบจะเผยแพร่เหตุการณ์ BuildStarted
เหตุการณ์นี้จะแจ้งให้เราทราบว่ามีการเรียกใช้บิลด์ผ่านคำสั่ง bazel test
และประกาศเหตุการณ์ย่อย ดังนี้
OptionsParsed
WorkspaceStatus
CommandLine
UnstructuredCommandLine
BuildMetadata
BuildFinished
PatternExpanded
Progress
เหตุการณ์ 3 รายการแรกให้ข้อมูลเกี่ยวกับวิธีเรียกใช้ Bazel
PatternExpanded
เหตุการณ์การสร้างให้ข้อมูลเชิงลึก
เกี่ยวกับเป้าหมายที่เฉพาะเจาะจงซึ่ง...
รูปแบบขยายไปถึง
//foo:foo_lib
และ //foo:foo_test
โดยทำได้ด้วยการประกาศเหตุการณ์ 2 รายการ
TargetConfigured
เป็นเหตุการณ์ย่อย โปรดทราบว่าTargetConfigured
event
จะประกาศ Configuration
event เป็นเหตุการณ์ย่อย แม้ว่า Configuration
จะโพสต์ก่อน TargetConfigured
event
นอกจากความสัมพันธ์ระหว่างผู้ปกครองกับบุตรหลานแล้ว เหตุการณ์ยังอาจอ้างอิงถึงกัน
โดยใช้ตัวระบุเหตุการณ์ที่สร้างขึ้น ตัวอย่างเช่น ในกราฟด้านบน เหตุการณ์ TargetComplete
หมายถึงเหตุการณ์ NamedSetOfFiles
ในฟิลด์ fileSets
โดยปกติแล้ว เหตุการณ์การสร้างที่อ้างอิงถึงไฟล์จะไม่ฝังชื่อและเส้นทางของไฟล์ไว้ในเหตุการณ์ แต่จะมีตัวระบุเหตุการณ์บิลด์ของเหตุการณ์ NamedSetOfFiles
ซึ่งจะมีชื่อไฟล์และเส้นทางจริง NamedSetOfFiles
เหตุการณ์ช่วยให้ระบบรายงานชุดไฟล์ได้ครั้งเดียวและ
อ้างอิงได้โดยเป้าหมายหลายรายการ โครงสร้างนี้จำเป็นเนื่องจากในบางกรณีขนาดเอาต์พุตของ Build Event Protocol จะเพิ่มขึ้นแบบกำลังสองตามจำนวนไฟล์ NamedSetOfFiles
เหตุการณ์อาจไม่มีไฟล์ทั้งหมด
ฝังอยู่ แต่อ้างอิงถึงNamedSetOfFiles
เหตุการณ์อื่นๆ ผ่าน
ตัวระบุเหตุการณ์บิลด์แทน
ด้านล่างนี้เป็นอินสแตนซ์ของTargetComplete
event สำหรับ//foo:foo_lib
target จากกราฟด้านบน ซึ่งพิมพ์ในการแสดง JSON ของ Protocol Buffer
ตัวระบุเหตุการณ์บิลด์มีเป้าหมายเป็นสตริงทึบแสงและอ้างอิงถึงConfiguration
เหตุการณ์โดยใช้ตัวระบุเหตุการณ์บิลด์ เหตุการณ์นี้ไม่ได้
ประกาศเหตุการณ์ย่อยใดๆ เพย์โหลดมีข้อมูลว่าสร้างเป้าหมายสําเร็จหรือไม่ ชุดไฟล์เอาต์พุต และประเภทเป้าหมายที่สร้าง
{
"id": {
"targetCompleted": {
"label": "//foo:foo_lib",
"configuration": {
"id": "544e39a7f0abdb3efdd29d675a48bc6a"
}
}
},
"completed": {
"success": true,
"outputGroup": [{
"name": "default",
"fileSets": [{
"id": "0"
}]
}],
"targetKind": "sh_library rule"
}
}
ผลลัพธ์ของลักษณะใน BEP
บิลด์ปกติจะประเมินการดำเนินการที่เชื่อมโยงกับ(target, configuration)
คู่ เมื่อสร้างโดยเปิดใช้แง่มุม Bazel
จะประเมินเป้าหมายที่เชื่อมโยงกับ (target, configuration,
aspect)
triples เพิ่มเติมสำหรับแต่ละเป้าหมายที่ได้รับผลกระทบจากแง่มุมที่เปิดใช้
ผลการประเมินแง่มุมจะพร้อมใช้งานใน BEP แม้ว่าจะไม่มีประเภทเหตุการณ์เฉพาะแง่มุมก็ตาม
สำหรับคู่ (target, configuration)
แต่ละคู่ที่มีแง่มุมที่เกี่ยวข้อง Bazel จะเผยแพร่เหตุการณ์ TargetConfigured
และ TargetComplete
เพิ่มเติมซึ่งมีผลลัพธ์จากการใช้แง่มุมกับเป้าหมาย ตัวอย่างเช่น หากสร้าง //:foo_lib
ด้วย
--aspects=aspects/myaspect.bzl%custom_aspect
เหตุการณ์นี้จะปรากฏใน
BEP ด้วย
{
"id": {
"targetCompleted": {
"label": "//foo:foo_lib",
"configuration": {
"id": "544e39a7f0abdb3efdd29d675a48bc6a"
},
"aspect": "aspects/myaspect.bzl%custom_aspect"
}
},
"completed": {
"success": true,
"outputGroup": [{
"name": "default",
"fileSets": [{
"id": "1"
}]
}]
}
}
การใช้ NamedSetOfFiles
การระบุอาร์ติแฟกต์ที่สร้างขึ้นโดยเป้าหมาย (หรือแง่มุม) ที่กำหนดเป็น Use Case ทั่วไปของ BEP ซึ่งสามารถทำได้อย่างมีประสิทธิภาพด้วยการเตรียมการบางอย่าง ส่วนนี้
จะอธิบายโครงสร้างแบบเรียกซ้ำและโครงสร้างที่แชร์ซึ่งมีให้ในNamedSetOfFiles
เหตุการณ์ ซึ่งตรงกับโครงสร้างของ Depset ของ Starlark
ผู้ใช้ต้องระมัดระวังเพื่อหลีกเลี่ยงอัลกอริทึมแบบกำลังสองเมื่อประมวลผลNamedSetOfFiles
เหตุการณ์ เนื่องจากบิลด์ขนาดใหญ่อาจมีเหตุการณ์ดังกล่าวหลายหมื่นรายการ ซึ่งต้องใช้การดำเนินการหลายร้อยล้านรายการในการข้ามผ่านที่มีความซับซ้อนแบบกำลังสอง
รูปที่ 2 NamedSetOfFiles
กราฟ BEP
เหตุการณ์ NamedSetOfFiles
จะปรากฏในสตรีม BEP ก่อนเหตุการณ์
TargetComplete
หรือ NamedSetOfFiles
ที่อ้างอิงถึงเหตุการณ์นั้นเสมอ ซึ่งเป็น
ส่วนกลับของความสัมพันธ์ของเหตุการณ์ "หลัก-ย่อย" โดยที่เหตุการณ์ทั้งหมด
ยกเว้นเหตุการณ์แรกจะปรากฏหลังจากมีเหตุการณ์อย่างน้อย 1 รายการที่ประกาศเหตุการณ์นั้น NamedSetOfFiles
เหตุการณ์จะประกาศโดยProgress
เหตุการณ์ที่ไม่มีความหมาย
เนื่องจากข้อจำกัดในการจัดลำดับและการแชร์เหล่านี้ ผู้ใช้ทั่วไปจึงต้องบัฟเฟอร์เหตุการณ์ NamedSetOfFiles
ทั้งหมดจนกว่าสตรีม BEP จะหมด สตรีมเหตุการณ์ JSON
และโค้ด Python ต่อไปนี้แสดงวิธีสร้างแผนที่จาก
เป้าหมาย/แง่มุมไปยังอาร์ติแฟกต์ที่สร้างขึ้นในกลุ่มเอาต์พุต "default" และวิธี
ประมวลผลเอาต์พุตสำหรับชุดย่อยของเป้าหมาย/แง่มุมที่สร้างขึ้น
named_sets = {} # type: dict[str, NamedSetOfFiles]
outputs = {} # type: dict[str, dict[str, set[str]]]
for event in stream:
kind = event.id.WhichOneof("id")
if kind == "named_set":
named_sets[event.id.named_set.id] = event.named_set_of_files
elif kind == "target_completed":
tc = event.id.target_completed
target_id = (tc.label, tc.configuration.id, tc.aspect)
outputs[target_id] = {}
for group in event.completed.output_group:
outputs[target_id][group.name] = {fs.id for fs in group.file_sets}
for result_id in relevant_subset(outputs.keys()):
visit = outputs[result_id].get("default", [])
seen_sets = set(visit)
while visit:
set_name = visit.pop()
s = named_sets[set_name]
for f in s.files:
process_file(result_id, f)
for fs in s.file_sets:
if fs.id not in seen_sets:
visit.add(fs.id)
seen_sets.add(fs.id)