مشخصات کامل پروتکل Build Event را می توان در تعریف بافر پروتکل آن یافت. با این حال، ممکن است قبل از بررسی مشخصات، کمی شهود ایجاد کنید.
یک فضای کاری ساده Bazel را در نظر بگیرید که از دو اسکریپت پوسته خالی 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
سه رویداد اول اطلاعاتی در مورد چگونگی فراخوانی بازل ارائه می دهد.
رویداد ساخت PatternExpanded
بینشی را ارائه می دهد که الگوی ...
به کدام اهداف خاص گسترش یافته است: //foo:foo_lib
و //foo:foo_test
. این کار را با اعلام دو رویداد TargetConfigured
در کودکی انجام می دهد. توجه داشته باشید که رویداد TargetConfigured
رویداد Configuration
را به عنوان یک رویداد فرزند اعلام می کند، حتی اگر Configuration
قبل از رویداد TargetConfigured
پست شده باشد.
علاوه بر رابطه والد و فرزند، رویدادها همچنین ممکن است با استفاده از شناسه رویداد ساخت خود به یکدیگر اشاره کنند. به عنوان مثال، در نمودار بالا، رویداد TargetComplete
به رویداد NamedSetOfFiles
در قسمت fileSets
آن اشاره دارد.
رویدادهای ساخت که به فایلها اشاره میکنند معمولاً نام فایلها و مسیرها را در رویداد جاسازی نمیکنند. در عوض، آنها حاوی شناسه رویداد ساخت یک رویداد NamedSetOfFiles
، که سپس شامل نامها و مسیرهای فایل واقعی میشود. رویداد NamedSetOfFiles
به مجموعه ای از فایل ها اجازه می دهد تا یک بار گزارش شوند و توسط بسیاری از اهداف ارجاع داده شوند. این ساختار ضروری است زیرا در غیر این صورت در برخی موارد اندازه خروجی پروتکل رویداد ساخت به صورت درجه دوم با تعداد فایل ها افزایش می یابد. رویداد NamedSetOfFiles
ممکن است همه فایلهایش را جاسازی نکرده باشد، اما در عوض از طریق شناسههای رویداد ساخت به رویدادهای دیگر NamedSetOfFiles
مراجعه کند.
در زیر نمونهای از رویداد TargetComplete
برای هدف //foo:foo_lib
از نمودار بالا است که در نمایش JSON بافر پروتکل چاپ شده است. شناسه رویداد ساخت شامل هدف به عنوان یک رشته مات است و به رویداد 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)
سهگانه را برای هر هدفی که تحت تأثیر یک جنبه فعال مشخص قرار میگیرد، ارزیابی میکند.
نتایج ارزیابی برای جنبهها علیرغم عدم وجود انواع رویدادهای خاص در BEP موجود است. برای هر جفت (target, configuration)
با یک جنبه کاربردی، Bazel یک رویداد TargetComplete
و TargetConfigured
اضافی را منتشر می کند که نتیجه اعمال جنبه را به هدف نشان می دهد. برای مثال، اگر //: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
تعیین مصنوعات تولید شده توسط یک هدف (یا جنبه) یک مورد معمول استفاده از BEP است که می تواند با آمادگی خاصی انجام شود. این بخش ساختار بازگشتی و مشترک ارائه شده توسط رویداد NamedSetOfFiles
را مورد بحث قرار می دهد که با ساختار Starlark Depset مطابقت دارد.
مصرف کنندگان باید مراقب باشند که هنگام پردازش رویدادهای NamedSetOfFiles
از الگوریتم های درجه دوم اجتناب کنند، زیرا ساخت های بزرگ می توانند حاوی ده ها هزار رویداد از این قبیل باشند که به صدها میلیون عملیات در یک پیمایش با پیچیدگی درجه دوم نیاز دارند.
شکل 2. نمودار BEP NamedSetOfFiles
.
یک رویداد NamedSetOfFiles
همیشه قبل از رویداد TargetComplete
یا NamedSetOfFiles
که به آن ارجاع می دهد در جریان BEP ظاهر می شود. این معکوس رابطه رویداد "والد-فرزند" است، جایی که همه رویدادها به جز اولین رویداد حداقل پس از اعلام یک رویداد ظاهر می شوند. یک رویداد NamedSetOfFiles
توسط یک رویداد Progress
بدون معنایی اعلام می شود.
با توجه به این محدودیتهای سفارش و اشتراکگذاری، یک مصرفکننده معمولی باید تمام رویدادهای NamedSetOfFiles
را تا زمانی که جریان BEP تمام شود، بافر کند. جریان رویداد JSON و کد پایتون زیر نحوه پر کردن نقشه از هدف/جنبه به مصنوعات ساخته شده در گروه خروجی پیشفرض و نحوه پردازش خروجیها برای زیرمجموعهای از اهداف/جنبههای ساخته شده را نشان میدهد:
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)