बिल्ड इवेंट प्रोटोकॉल की पूरी जानकारी इसके प्रोटोकॉल बफ़र डेफ़िनिशन में देखी जा सकती है. हालांकि, स्पेसिफ़िकेशन को देखने से पहले, इनके बारे में कुछ और जानकारी हासिल करने से मदद मिल सकती है.
एक आसान 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 ...
चलाते समय जनरेट किए गए बिल्ड इवेंट का बिल्ड ग्राफ़, नीचे दिए गए ग्राफ़ की तरह दिखेगा. ऐरो ऊपर बताए गए माता-पिता और बच्चे के संबंध को दिखाते हैं. ध्यान दें कि कम शब्दों में सटीक जानकारी देने के लिए, कुछ बिल्ड इवेंट और ज़्यादातर फ़ील्ड हटा दिए गए हैं.
पहला डायग्राम. बीईपी ग्राफ़.
शुरुआत में, 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
इवेंट, अपने fileSets
फ़ील्ड में NamedSetOfFiles
इवेंट को दिखाता है.
फ़ाइलों को रेफ़र करने वाले इवेंट में, आम तौर पर फ़ाइल के नाम और पाथ एम्बेड नहीं किए जाते. इसके बजाय, इनमें NamedSetOfFiles
इवेंट का बिल्ड इवेंट आइडेंटिफ़ायर शामिल होता है, जिसमें असल फ़ाइल के नाम और पाथ शामिल होते हैं. NamedSetOfFiles
इवेंट, फ़ाइलों के सेट को एक बार रिपोर्ट करने और कई टारगेट को रेफ़र करने की अनुमति देता है. यह संरचना इसलिए ज़रूरी है, क्योंकि कुछ मामलों में बिल्ड इवेंट प्रोटोकॉल का आउटपुट साइज़, फ़ाइलों की संख्या के साथ चार तेज़ी से बढ़ जाएगा. ऐसा भी हो सकता है कि किसी NamedSetOfFiles
इवेंट में उसकी सभी फ़ाइलें एम्बेड न की गई हों. इसके बजाय, उसके बिल्ड इवेंट आइडेंटिफ़ायर की मदद से अन्य NamedSetOfFiles
इवेंट को देखें.
ऊपर दिए गए ग्राफ़ से //foo:foo_lib
टारगेट के लिए, TargetComplete
इवेंट का उदाहरण नीचे दिया गया है. इसे प्रोटोकॉल बफ़र के 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)
पेयर से जुड़ी कार्रवाइयों का आकलन करते हैं. ज़रूरी शर्तों को पूरा करने के बाद, Bazel,
(target, configuration,
aspect)
तीनों से जुड़े टारगेट का भी आकलन करता है. ऐसा, हर उस टारगेट के लिए किया जाता है जिस पर दिए गए किसी चालू आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) का असर पड़ा हो.
पहलू के हिसाब से इवेंट टाइप उपलब्ध न होने के बावजूद, बीईपी में पहलुओं के आकलन के नतीजे उपलब्ध होते हैं. लागू होने वाले हर (target, configuration)
पेयर के लिए, Bazel एक और TargetConfigured
और
TargetComplete
इवेंट पब्लिश करता है. इस इवेंट में, टारगेट पर इस आसपेक्ट को लागू करने के नतीजे के बारे में जानकारी दी जाती है. उदाहरण के लिए, अगर //:foo_lib
को --aspects=aspects/myaspect.bzl%custom_aspect
की मदद से बनाया गया है, तो यह इवेंट बीईपी में भी दिखेगा:
{
"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
इवेंट के बार-बार मिलने वाले और शेयर किए गए स्ट्रक्चर पर चर्चा की गई है, जो स्टारलार्क डिप्सेट के स्ट्रक्चर से मेल खाता है.
NamedSetOfFiles
इवेंट को प्रोसेस करते समय, उपभोक्ताओं को क्वाड्रेटिक एल्गोरिदम से बचना चाहिए, क्योंकि बड़े बिल्ड में हज़ारों इवेंट हो सकते हैं. ऐसे में, क्वाड्रेटिक जटिलता वाले प्लान के साथ ट्रेवर्सल में करोड़ों कार्रवाइयां करने की ज़रूरत पड़ती है.
दूसरा डायग्राम. NamedSetOfFiles
बीईपी ग्राफ़.
NamedSetOfFiles
इवेंट, बीईपी स्ट्रीम में हमेशा उस TargetComplete
या NamedSetOfFiles
इवेंट से पहले दिखता है जिसमें उस इवेंट का रेफ़रंस होता है. यह "पैरंट-चाइल्ड" इवेंट के संबंध से बिलकुल उलट है, जहां पहले इवेंट को छोड़कर बाकी सभी, कम से कम एक इवेंट के एलान के बाद दिखते हैं. NamedSetOfFiles
इवेंट का एलान, Progress
इवेंट से किया जाता है. इसमें सिमैंटिक नहीं होता.
ऑर्डर और शेयर करने की इन सीमाओं को देखते हुए, एक आम उपभोक्ता को बीईपी स्ट्रीम खत्म होने तक सभी
NamedSetOfFiles
इवेंट बफ़र करना होगा. नीचे दिए गए 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)