יצירת דוגמאות לפרוטוקול של אירוע

אפשר למצוא את המפרט המלא של פרוטוקול Event Build דרך הגדרת המאגר של הפרוטוקול. עם זאת, כדאי לפתח אינטואיציה לפני עיון במפרט.

כדאי לשקול סביבת עבודה פשוטה של 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 ... בפרויקט הזה, תרשים ה-build של אירועי ה-build שנוצרו ייראה דומה לתרשים למטה. החיצים מציינים את הקשר הקודם של הורה וילד. לתשומת ליבך, חלק מאירועי ה-build ורוב השדות הושמטו לשם קיצור.

Bep-graph

איור 1. תרשים BEP.

בהתחלה פורסם אירוע BuildStarted. האירוע מודיע לנו שה-build הופעל באמצעות הפקודה bazel test ומכריז על אירועים צאצאים:

  • OptionsParsed
  • WorkspaceStatus
  • CommandLine
  • UnstructuredCommandLine
  • BuildMetadata
  • BuildFinished
  • PatternExpanded
  • Progress

שלושת האירועים הראשונים מספקים מידע על האופן שבו Bazel הופעל.

אירוע ה-build של PatternExpanded מספק תובנות לגבי הטירגוט הספציפי שהדפוס ... הורחב אליו: //foo:foo_lib ו-//foo:foo_test. הוא עושה זאת על ידי הצהרה על TargetConfigured אירועים כילדים. לתשומת לבך, אירוע TargetConfigured מצהיר על אירוע Configuration כאירוע צאצא, אף על פי שConfiguration פורסם לפני אירוע TargetConfigured.

מלבד הקשר בין ההורה לילד, ייתכן שהאירועים יתייחסו זה לזה באמצעות מזהי האירועים שלהם. לדוגמה, בתרשים שלמעלה האירוע TargetComplete מתייחס לאירוע NamedSetOfFiles בשדה fileSets שלו.

כדאי ליצור אירועים שמפנים לקבצים שלא בדרך כלל מטמיעים את שמות הקבצים והנתיבים באירוע. במקום זאת, הם מכילים את מזהה אירוע ה-build של אירוע NamedSetOfFiles, שמכיל את השמות והנתיבים של הקבצים בפועל. האירוע NamedSetOfFiles מאפשר דיווח על קבוצת קבצים עם הפנייה של יעדים רבים. המבנה הזה הכרחי, כי במקרים אחרים בתגובה, מספר הפלט של ה-Build של אירוע ה-build יגדל בריבוע עם מספר הקבצים. ייתכן גם שאירוע NamedSetOfFiles לא יוטמע בכל הקבצים שלו, אלא במקום זאת תייחס לאירועים אחרים מסוג NamedSetOfFiles דרך מזהי ה-build של האירועים.

לפניכם מופע של האירוע TargetComplete עבור היעד //foo:foo_lib בתרשים שלמעלה, שהודפס בייצוג ה-JSON של מאגר הפרוטוקול. המזהה של אירוע ה-build מכיל את היעד כמחרוזת אטומה ומתייחס לאירוע Configuration באמצעות המזהה של אירוע ה-build שלו. האירוע לא מכריז על אירועי צאצא. המטען הייעודי כולל מידע על האם היעד נוצר בהצלחה, על קבוצת קובצי הפלט ועל סוג היעד שנבנה.

{
  "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 מפרסמת אירוע נוסף ב-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

קביעת פריטי המידע שנוצרו על ידי יעד (או היבט) נתון היא תרחיש נפוץ לשימוש ב-BEP, שניתן לבצע אותו ביעילות בשילוב עם הכנה כלשהי. הקטע הזה מתייחס למבנה

הצרכנים צריכים לנקוט משנה זהירות כדי להימנע מאלגוריתמים אזוריים במהלך עיבוד NamedSetOfFiles אירועים, כי מבנים גדולים יכולים להכיל עשרות אלפי אירועים כאלה, כך שמאות מיליוני פעולות יידרשו בנתיב עם מורכבות ריבועית.

שם מערך

איור 2. תרשים BEP של NamedSetOfFiles.

אירוע NamedSetOfFiles תמיד מופיע בזרם BEP לפני אירוע TargetComplete או NamedSetOfFiles שמאזכר אותו. זהו ההיפך בין יחסי האירוע "parent-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)