يمكن العثور على المواصفات الكاملة لبروتوكول أحداث الإصدار في تعريف المخزن المؤقت للبروتوكول الخاص بها. وقد يكون من المفيد بناء بعض المشاعر قبل الاطّلاع على المواصفات.
ننصحك باستخدام مساحة عمل Bazel بسيطة تتألف من نصَين برمجيَين فارغَين لتطبيق Shell
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
الأحداث الثلاثة الأولى تقدم معلومات عن كيفية استدعاء Bazel.
ويقدّم حدث الإصدار PatternExpanded
إحصاءات
حول الاستهدافات المحدّدة التي يتم توسيع نمط ...
إليها:
//foo:foo_lib
و//foo:foo_test
. وينفّذ ذلك عن طريق الإعلان عن
حدثَين (TargetConfigured
) باعتبارهما أطفالاً. تجدر الإشارة إلى أن الفعالية TargetConfigured
تُعلن أنّ الحدث Configuration
هو فعالية فرعية، على الرغم من نشر السمة Configuration
قبل فعالية TargetConfigured
.
بالإضافة إلى العلاقة بين الوالدَين والطفل، قد تشير الأحداث أيضًا إلى بعضها البعض باستخدام معرّفات أحداث الإصدار الخاصة بها. على سبيل المثال، في الرسم البياني أعلاه، يشير الحدث TargetComplete
إلى الحدث NamedSetOfFiles
في حقل fileSets
.
لا يتم عادةً تضمين أسماء الملفات
والمسارات في الحدث في أحداث الإصدار التي تشير إلى ملفات. وبدلاً من ذلك، تحتوي الملفات على معرّف حدث الإصدار
لحدث NamedSetOfFiles
، والذي سيتضمّن عندئذٍ أسماء الملفات ومساراتها الفعلية. يسمح الحدث NamedSetOfFiles
بالإبلاغ عن مجموعة من الملفات مرة واحدة والإشارة إليها من خلال العديد من الأهداف. تُعد هذه البنية ضرورية لأنه في بعض الحالات
سيزداد حجم مخرجات حدث Build بشكل ربعي مع عدد
الملفات. قد لا يتم أيضًا تضمين جميع ملفات حدث 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"
}
}
عرض نسبة العرض إلى الارتفاع في لوحة اللمس
تُقيِّم الإصدارات العادية الإجراءات المرتبطة بعمليات إقران (target, configuration)
. وعند إنشاء مواقع إلكترونية مفعّلة، يقيّم البازيل أيضًا الأهداف المرتبطة بثلاث مرات (target, configuration,
aspect)
، في كل هدف متأثر جانب معيّن تم تفعيله.
تتوفر نتائج التقييم للجوانب في 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
ويُعدّ تحديد القطع الأثرية الناتجة عن هدف (أو جانب) معيّن حالة استخدام شائعة يمكن تنفيذها بشكل فعّال مع بعض الاستعدادات. يناقش هذا القسم
البنية المتكررة والمتكررة التي يقدمها حدث NamedSetOfFiles
، والتي تطابق بنية
ستارلارك Depset.
يجب أن يحرص المستهلكون على تجنّب الخوارزميات التربيعية عند معالجة أحداث NamedSetOfFiles
لأنّ الإصدارات الكبيرة يمكن أن تحتوي على عشرات الآلاف من هذه الأحداث، ما يتطلّب مئات الملايين من العمليات في اجتياز مع التربيع التعقيدي.
الشكل 2. رسم بياني لـ BEP NamedSetOfFiles
.
تظهر الفعالية NamedSetOfFiles
دائمًا في بث BEP قبل
الحدث TargetComplete
أو NamedSetOfFiles
الذي يشير إليه. ويكون هذا هو عكس الحدث "&&;;Child-child" حيث يظهر الكل ولكن الحدث الأول بعد حدث واحد على الأقل يعلن عنه. يتم الإعلان عن فعالية NamedSetOfFiles
من خلال فعالية Progress
لا تتضمّن دلالات.
نظرًا لقيود الترتيب والمشاركة هذه، على المستهلك العادي تخزين كل
NamedSetOfFiles
أحداث حتى يتم استنفاد ساحة مشاركات BEP. يوضّح تدفق حدث JSON ورمز Python التالي كيفية تعبئة خريطة من العناصر المستهدفة/النسبية إلى العناصر المُصمَّمة في مجموعة الإخراج ومضمونة وكيفية استخراج النتائج لمجموعة فرعية من الأهداف/الجوانب المنشأة:
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)