.bzl स्टाइल गाइड

किसी समस्या की शिकायत करें स्रोत देखें

इस पेज पर Starlark के लिए स्टाइल से जुड़े बुनियादी दिशा-निर्देश दिए गए हैं. इसमें मैक्रो और नियमों की जानकारी भी शामिल है.

Starlark एक ऐसी भाषा है जो सॉफ़्टवेयर बनाने के तरीके को तय करती है. साथ ही, यह एक प्रोग्रामिंग और कॉन्फ़िगरेशन भाषा, दोनों है.

BUILD फ़ाइलें, मैक्रो लिखने और नियम बनाने के लिए आपको Starlark का इस्तेमाल करना होगा. मैक्रो और नियम, मुख्य रूप से मेटा-भाषा हैं - इनसे तय होता है कि BUILD फ़ाइलों में क्या लिखा जाएगा. BUILD फ़ाइलें आसान और दोहराए जाने वाली हैं.

सभी सॉफ़्टवेयर, लिखे जाने से ज़्यादा बार पढ़े जाते हैं. यह स्टारलार्क के लिए खास तौर पर सही है, क्योंकि इंजीनियर अपने टारगेट और उनके बिल्ड की डिपेंडेंसी के लिए BUILD फ़ाइलों को पढ़ते हैं. अक्सर यह रीडिंग, जल्दबाज़ी में या किसी अन्य काम को पूरा करने के साथ-साथ होती है. नतीजतन, आसान और पढ़ने में आसान होना बहुत ज़रूरी है, ताकि उपयोगकर्ता तेज़ी से BUILD फ़ाइलों को पार्स कर सकें और उन्हें समझ सकें.

जब कोई उपयोगकर्ता BUILD की कोई फ़ाइल खोलता है, तो वह फ़ाइल में मौजूद टारगेट की सूची को तेज़ी से जानना चाहता है या उस C++ लाइब्रेरी के सोर्स की सूची देखना चाहता है. इसके अलावा, वह उस Java बाइनरी से डिपेंडेंसी हटाना चाहता है. हर बार ऐब्स्ट्रैक्शन की एक लेयर जोड़ने पर, आपके लिए उपयोगकर्ता के लिए इन टास्क को करना मुश्किल हो जाता है.

कई अलग-अलग टूल से भी BUILD फ़ाइलों का विश्लेषण किया जाता है और उन्हें अपडेट किया जाता है. अगर BUILD फ़ाइल में ऐब्स्ट्रैक्शन का इस्तेमाल किया गया है, तो हो सकता है कि इसमें बदलाव न किया जा सके. BUILD फ़ाइलें आसान रखें, ताकि आप बेहतर टूल पा सकें. जैसे-जैसे कोड बेस बढ़ता है, लाइब्रेरी अपडेट करने या क्लीनअप करने के लिए, वह कई BUILD फ़ाइलों में बदलाव करने लगता है.

सामान्य सलाह

स्टाइल

Python स्टाइल

अगर समझ में न आए, तो पीईपी 8 स्टाइल गाइड का पालन करें. खास तौर पर, इंडेंटेशन के लिए दो स्पेस के बजाय चार स्पेस का इस्तेमाल करें, ताकि आप Python का पालन कर सकें.

स्टारलार्क Python नहीं है, इसलिए Python शैली के कुछ पहलू लागू नहीं होते. उदाहरण के लिए, PEP 8 सलाह देता है कि सिंगलटन की तुलना is के साथ की जाए, जो Starlark में ऑपरेटर न हो.

डॉकस्ट्रिंग

docstring का इस्तेमाल करके, फ़ाइलों और फ़ंक्शन का दस्तावेज़ बनाएं. हर .bzl फ़ाइल के सबसे ऊपर दिए गए docstring और हर सार्वजनिक फ़ंक्शन के लिए एक docstring का इस्तेमाल करें.

दस्तावेज़ के नियम और पहलू

doc आर्ग्युमेंट का इस्तेमाल करके, नियमों और पहलुओं के साथ-साथ, एट्रिब्यूट और सेवा देने वाली कंपनियों और उनके फ़ील्ड भी दर्ज होने चाहिए.

नेमिंग कनवेंशन

  • वैरिएबल और फ़ंक्शन के नाम में अंडरस्कोर ([a-z][a-z0-9_]*) से अलग किए गए शब्दों के साथ लोअरकेस का इस्तेमाल होता है, जैसे कि cc_library.
  • शीर्ष-स्तरीय निजी मान एक अंडरस्कोर से प्रारंभ होते हैं. बेज़ल लागू करता है कि निजी मानों का इस्तेमाल दूसरी फ़ाइलों से नहीं किया जा सकता. स्थानीय वैरिएबल में अंडरस्कोर प्रीफ़िक्स का इस्तेमाल नहीं करना चाहिए.

लाइन की लंबाई

BUILD फ़ाइलों की तरह, इस पर लाइन की कोई सख्त सीमा नहीं है, क्योंकि लेबल लंबे हो सकते हैं. हर लाइन में ज़्यादा से ज़्यादा 79 वर्ण इस्तेमाल करने की कोशिश करें. Python की स्टाइल गाइड में, पीईपी 8 देखें. इस दिशा-निर्देश को सख्ती से लागू नहीं किया जाना चाहिए: एडिटर को 80 से ज़्यादा कॉलम दिखाने चाहिए, अपने-आप होने वाले बदलावों से अक्सर लंबी लाइनें दिखेंगी. साथ ही, लोगों को पहले से पढ़ने लायक लाइनों को बांटने में समय नहीं लगाना चाहिए.

कीवर्ड के तर्क

कीवर्ड के आर्ग्युमेंट में, बराबर के निशान के आस-पास के स्पेस को प्राथमिकता दी जाती है:

def fct(name, srcs):
    filtered_srcs = my_filter(source = srcs)
    native.cc_library(
        name = name,
        srcs = filtered_srcs,
        testonly = True,
    )

बूलियन वैल्यू

बूलियन वैल्यू (जैसे, किसी नियम में बूलियन एट्रिब्यूट का इस्तेमाल करना) के लिए, True और False (1 और 0 के बजाय) वैल्यू को प्राथमिकता दें.

प्रोडक्शन कोड में print() फ़ंक्शन का इस्तेमाल न करें; यह सिर्फ़ डीबग करने के लिए है. यह आपकी .bzl फ़ाइल के सभी सीधे और दूसरे उपयोगकर्ताओं को स्पैम भेजेगा. अपवाद यह है कि आप print() का इस्तेमाल करने वाला कोड सबमिट कर सकते हैं. ऐसा तब होता है, जब print() डिफ़ॉल्ट रूप से बंद हो और उसे सिर्फ़ सोर्स में बदलाव करके ही चालू किया जा सकता हो. उदाहरण के लिए, अगर print() के सभी इस्तेमाल के लिए if DEBUG: की सुरक्षा की जाती है, जहां DEBUG को False पर हार्डकोड किया जाता है. ध्यान रखें कि ये स्टेटमेंट पढ़ने लायक होने के लिए अपने असर को सही साबित करने के लिए उपयोगी हैं या नहीं.

मैक्रो

मैक्रो एक ऐसा फ़ंक्शन है, जो लोडिंग चरण के दौरान एक या उससे ज़्यादा नियमों को इंस्टैंशिएट करता है. आम तौर पर, जब भी संभव हो, मैक्रो के बजाय नियमों का इस्तेमाल करें. उपयोगकर्ता ने जिस बिल्ड ग्राफ़ को देखा है वह बिल्ड के दौरान इस्तेमाल किए गए बिल्ड ग्राफ़ के जैसा नहीं है - मैक्रो को Bzel का कोई भी ग्राफ़ ग्राफ़ विश्लेषण करने से पहले बड़ा कर दिया जाता है.

इस वजह से, अगर कोई गड़बड़ी होती है, तो बिल्ड से जुड़ी समस्याओं को हल करने के लिए, उपयोगकर्ता को आपके मैक्रो को लागू करने के बारे में समझना होगा. साथ ही, नतीजों में दिखाए गए टारगेट, बड़ा करने से मिलते हैं. इसलिए, bazel query के नतीजों को समझना मुश्किल हो सकता है. आखिर में, मैक्रो को जानकारी नहीं होती है. इसलिए, आसपेक्ट (आईडीई) और दूसरी चीज़ों के आधार पर टूल को अपडेट नहीं किया जा सकता.

मैक्रो के लिए एक सुरक्षित इस्तेमाल है बैजल सीएलआई या बीयूआईएलडी फ़ाइलों में रेफ़र किए जाने के लिए टारगेट किए गए अतिरिक्त टारगेट को परिभाषित करना: उस मामले में, उन टारगेट के सिर्फ़ असली उपयोगकर्ताओं को उनके बारे में जानने की ज़रूरत होती है और मैक्रो से शुरू होने वाली बिल्ड से जुड़ी समस्याएं कभी भी उनके इस्तेमाल से दूर नहीं होती हैं.

जनरेट किए गए टारगेट को तय करने वाले मैक्रो (मैक्रो के लागू होने की ऐसी जानकारी जिन्हें सीएलआई में रेफ़र नहीं किया जाना चाहिए या उन मैक्रो पर निर्भर नहीं रहना चाहिए) के लिए ये सबसे सही तरीके अपनाएं:

  • मैक्रो में name तर्क लेना चाहिए और उस नाम का टारगेट तय करना चाहिए. यह टारगेट उस मैक्रो का मुख्य टारगेट बन जाता है.
  • जनरेट किए गए टारगेट, अन्य सभी टारगेट होते हैं जो किसी मैक्रो से तय होते हैं. इनमें ये शामिल हैं:
    • अपने नाम के आगे <name> या _<name> लगाएं. उदाहरण के लिए, name = '%s_bar' % (name) का इस्तेमाल करके.
    • जिनके पास सीमित विज़िबिलिटी (//visibility:private) है, और
    • वाइल्डकार्ड टारगेट (:all, ..., :* वगैरह) को बड़ा होने से बचाने के लिए, manual टैग जोड़ें.
  • name का इस्तेमाल सिर्फ़ टारगेट के नाम पाने के लिए किया जाना चाहिए. मैक्रो का नाम किसी और चीज़ के लिए नहीं होना चाहिए. उदाहरण के लिए, नाम का इस्तेमाल ऐसी डिपेंडेंसी या इनपुट फ़ाइल के बारे में जानने के लिए न करें जिसे मैक्रो ने खुद जनरेट नहीं किया है.
  • मैक्रो में बनाए गए सभी लक्ष्यों को किसी तरीके से मुख्य लक्ष्य से जोड़ा जाना चाहिए.
  • पैरामीटर के नामों को मैक्रो में एक जैसा रखें. अगर किसी पैरामीटर को मुख्य टारगेट के एट्रिब्यूट की वैल्यू के तौर पर पास किया जाता है, तो उसका नाम वही रखें. अगर मैक्रो पैरामीटर का मतलब वही है जो समान नियम एट्रिब्यूट का है, जैसे कि deps, तो नाम को वैसे ही करें जैसे आप एट्रिब्यूट के लिए (नीचे देखें).
  • मैक्रो कॉल करते समय, केवल कीवर्ड तर्कों का उपयोग करें. यह नियमों के अनुकूल है और पढ़ने की क्षमता को बहुत बेहतर बनाता है.

इंजीनियर अक्सर मैक्रो लिखते हैं, जब प्रासंगिक नियमों का Starlark API उनके खास इस्तेमाल के उदाहरण के लिए काफ़ी नहीं होता है, चाहे नियम मूल कोड में Bazel में दिए गए हों या Starlark में. अगर आपको यह समस्या आ रही है, तो नियम के लेखक से पूछें कि क्या वे आपके लक्ष्यों को पूरा करने के लिए एपीआई को बढ़ा सकते हैं.

बुनियादी नियम के मुताबिक, नियम जितने ज़्यादा मैक्रो होंगे, उतना ही बेहतर होगा.

मैक्रो भी देखें.

नियम

  • नियमों, पहलुओं और उनकी विशेषताओं में लोअर केस (छोटे-छोटे अक्षर) के नामों का इस्तेमाल करना चाहिए ("स्नेक केस").
  • नियम के नाम, संज्ञा होती है जो नियम के ज़रिए बनाए गए मुख्य आर्टफ़ैक्ट के बारे में बताती हैं, जो डिपेंडेंसी के हिसाब से (या पत्ती के नियमों के लिए) होती हैं. यह हमेशा फ़ाइल सफ़िक्स नहीं होता. जैसे, Python एक्सटेंशन के तौर पर इस्तेमाल करने के लिए, C++ आर्टफ़ैक्ट बनाने वाले नियम को py_extension कहा जा सकता है. ज़्यादातर भाषाओं के सामान्य नियमों में ये शामिल हैं:
    • *_library - कंपाइलेशन यूनिट या "मॉड्यूल".
    • *_binary - एक्ज़ीक्यूटेबल या डिप्लॉयमेंट यूनिट बनाने वाला टारगेट.
    • *_test - टेस्ट टारगेट. इसमें एक से ज़्यादा जांच शामिल हो सकती हैं. *_test टारगेट में मौजूद सभी टेस्ट एक ही थीम के अलग-अलग वर्शन होने चाहिए. उदाहरण के लिए, एक लाइब्रेरी का टेस्ट करना.
    • *_import, ऐसा टारगेट जिसमें पहले से कंपाइल किए गए आर्टफ़ैक्ट को शामिल किया गया है, जैसे कि .jar या .dll. इसका इस्तेमाल कंपाइलेशन के दौरान किया जाता है.
  • एट्रिब्यूट के लिए, एक जैसे नाम और टाइप का इस्तेमाल करें. आम तौर पर, कुछ एट्रिब्यूट इन पर लागू होते हैं:
    • srcs: label_list: फ़ाइलों को अनुमति दे रही हैं: सोर्स फ़ाइलें, आम तौर पर मानवीय रूप से लिखी गई.
    • deps: label_list, आम तौर पर, फ़ाइलों को अनुमति देने नहीं की जाती है: कंपाइलेशन.
    • data: label_list: फ़ाइलों को अनुमति दें: डेटा फ़ाइलें, जैसे कि टेस्ट डेटा वगैरह.
    • runtime_deps: label_list: रनटाइम डिपेंडेंसी, जो कंपाइलेशन के लिए ज़रूरी नहीं होती हैं.
  • बिना किसी खास व्यवहार वाले किसी भी एट्रिब्यूट (उदाहरण के लिए, खास बदले गए स्ट्रिंग टेंप्लेट या खास ज़रूरतों के साथ लागू किए गए टूल) के लिए, एट्रिब्यूट सबमिट करें. इसके लिए, एट्रिब्यूट के एलान (attr.label_list() या इससे मिलते-जुलते) के लिए, doc कीवर्ड आर्ग्युमेंट का इस्तेमाल करें.
  • नियम लागू करने के फ़ंक्शन करीब-करीब हमेशा निजी फ़ंक्शन होने चाहिए (नाम वाले अंडरस्कोर का नाम). myrule_myrule_implनाम को लागू करने का फ़ंक्शन देना एक सामान्य स्टाइल है.
  • एक बेहतर तय किए गए इंटरफ़ेस का इस्तेमाल करके, अपने नियमों के बीच जानकारी शेयर करें. एलान और दस्तावेज़ देने वाली कंपनी के फ़ील्ड का एलान करें.
  • एक्सटेंशन को ध्यान में रखते हुए अपना नियम डिज़ाइन करें. इस बात पर विचार करें कि दूसरे नियम आपके नियम से इंटरैक्ट करना चाहें, कंपनियों को ऐक्सेस करना चाहें, और आपके बनाए कामों का फिर से इस्तेमाल करना चाहें.
  • अपने नियमों में परफ़ॉर्मेंस से जुड़े दिशा-निर्देशों का पालन करें.