बिल्ड स्टाइल गाइड

BUILD फ़ाइल फ़ॉर्मैट, Go के लिए भी एक समान तरीका अपनाता है, जहां एक स्टैंडर्डाइज़ किया गया टूल ज़्यादातर फ़ॉर्मैटिंग समस्याओं को हल करता है. Buildifier एक ऐसा टूल है जो स्रोत कोड को मानक शैली में पार्स करता है और छोड़ता है. इसलिए, हर BUILD फ़ाइल को एक ही तरह से फ़ॉर्मैट किया जाता है. इसकी वजह से, कोड की समीक्षाओं के दौरान फ़ॉर्मैटिंग को बिना समस्या के फ़ॉर्मैट किया जाता है. इससे टूल के लिए BUILD फ़ाइलों को समझना, उनमें बदलाव करना, और जनरेट करना आसान हो जाता है.

BUILD फ़ाइल फ़ॉर्मैटिंग, buildifier के आउटपुट से मेल खानी चाहिए.

फ़ॉर्मैट का उदाहरण

# Test code implementing the Foo controller.
package(default_testonly = True)

py_test(
    name = "foo_test",
    srcs = glob(["*.py"]),
    data = [
        "//data/production/foo:startfoo",
        "//foo",
        "//third_party/java/jdk:jdk-k8",
    ],
    flaky = True,
    deps = [
        ":check_bar_lib",
        ":foo_data_check",
        ":pick_foo_port",
        "//pyglib",
        "//testing/pybase",
    ],
)

फ़ाइल का स्ट्रक्चर

सुझाव: नीचे दिए गए क्रम का इस्तेमाल करें (हर एलिमेंट ज़रूरी नहीं है):

  • पैकेज की जानकारी (एक टिप्पणी)

  • सभी load() स्टेटमेंट

  • package() फ़ंक्शन.

  • नियम और मैक्रो के लिए कॉल

बिल्डिफ़ायर, स्टैंडअलोन टिप्पणी और किसी एलिमेंट से जुड़ी टिप्पणी के बीच अंतर दिखाता है. अगर कोई टिप्पणी किसी खास एलिमेंट पर अटैच नहीं है, तो उसके बाद एक खाली लाइन इस्तेमाल करें. अपने-आप बदलाव करते समय फ़र्क़ बहुत अहम होता है (उदाहरण के लिए, किसी नियम को मिटाते समय किसी टिप्पणी को रखना या हटाना).

# Standalone comment (such as to make a section in a file)

# Comment for the cc_library below
cc_library(name = "cc")

मौजूदा पैकेज में टारगेट के लिए संदर्भ

फ़ाइलों को उनके पाथ से पैकेज डायरेक्ट्री से जुड़ा होना चाहिए (बिना किसी रेफ़रंस के कभी भी इस्तेमाल करें, जैसे कि ..). जनरेट की गई फ़ाइलों में ":" शामिल होना चाहिए, ताकि यह बताया जा सके कि वे स्रोत नहीं हैं. स्रोत फ़ाइलों को : से पहले नहीं जोड़ना चाहिए. नियमों के पहले : होना चाहिए. उदाहरण के लिए, x.cc का मान एक सोर्स फ़ाइल होना चाहिए:

cc_library(
    name = "lib",
    srcs = ["x.cc"],
    hdrs = [":gen_header"],
)

genrule(
    name = "gen_header",
    srcs = [],
    outs = ["x.h"],
    cmd = "echo 'int x();' > $@",
)

टारगेट का नाम

टारगेट के नाम में पूरी जानकारी होनी चाहिए. अगर किसी टारगेट में एक स्रोत फ़ाइल है, तो टारगेट में आम तौर पर उस स्रोत से जुड़ा नाम होना चाहिए (उदाहरण के लिए, cc_library इनके लिएchat.cc नाम दिया जा सकता हैchat, याjava_library इनके लिए:DirectMessage.java नाम दिया जा सकता हैdirect_message ).

किसी पैकेज के लिए इस्तेमाल किया गया टारगेट (जिसका नाम उस डायरेक्ट्री से जुड़ा है जिसका नाम है), उस डायरेक्ट्री के नाम के बारे में बताया गया होना चाहिए. अगर ऐसा कोई टारगेट नहीं है, तो कोई छोटा नाम टारगेट न बनाएं.

प्राथमिकता वाले टारगेट (//x:x के बजाय //x) का इस्तेमाल करते समय छोटे नाम का इस्तेमाल करना पसंद करें. अगर आप एक ही पैकेज में हैं, तो स्थानीय पहचान फ़ाइल का इस्तेमाल करें (//x के बजाय :x).

"रिज़र्व किए गए" टारगेट नाम का इस्तेमाल करने से बचें, जिसका खास मतलब हो. इसमें all, __pkg__, और __subpackages__ जैसे नाम शामिल हैं. इन नामों में खास सिमेंटिक हैं और इनका इस्तेमाल करते समय भ्रम की स्थिति और अनचाहा व्यवहार हो सकता है.

किसी मौजूदा टीम के कन्वेंशन के अभाव में, ये कुछ गैर-बाइंडिंग सुझाव हैं, जिनका Google पर बड़े पैमाने पर इस्तेमाल किया जाता है:

  • आम तौर पर, "Snake_case" का इस्तेमाल करें
    • src वाले java_library के लिए इसका मतलब है कि ऐसे नाम का इस्तेमाल करना जो एक्सटेंशन के बिना फ़ाइल नाम से अलग हो
    • Java *_binary और *_test के नियमों के लिए, "Upper Camelकेस" इस्तेमाल करें. इसकी मदद से टारगेट नाम, src में से किसी एक से मेल खा सकता है. java_test से, test_class एट्रिब्यूट के लिए, टारगेट के नाम का इस्तेमाल किया जा सकता है.
  • अगर किसी खास टारगेट के कई वैरिएंट हैं, तो अंतर बताने के लिए एक सफ़िक्स जोड़ें जैसे कि. :foo_dev, :foo_prod या :bar_x86, :bar_x64)
  • _test टारगेट के लिए _test, _unittest, Test या Tests सफ़िक्स लगाएं
  • _lib या _library जैसे मतलब वाले सफ़िक्स से बचें (जब तक कि _library के टारगेट और उससे जुड़े _binary के बीच टकराव से बचने की ज़रूरत न हो)
  • प्रोटो से जुड़े टारगेट के लिए:
    • proto_library टारगेट के नाम _proto पर खत्म होने चाहिए
    • किसी खास भाषा के लिए बने *_proto_library नियमों की भाषा, बुनियादी प्रोटोकॉल से मेल खानी चाहिए. हालांकि, _proto के बजाय, किसी खास भाषा के सफ़िक्स का इस्तेमाल किया जाना चाहिए, जैसे कि:
      • cc_proto_library: _cc_proto
      • java_proto_library: _java_proto
      • java_lite_proto_library: _java_proto_lite

किसको दिखे

दृश् यता का दायरा जितना संभव हो उतना करीब से होना चाहिए. साथ ही, टेस्ट और रिवर्स डिपेंडेंसी से ऐक्सेस की अनुमति दी जाती है. __pkg__ और __subpackages__ का इस्तेमाल सही तरीके से करें.

पैकेज default_visibility को //visibility:public पर सेट करने से बचें. //visibility:public को सिर्फ़ प्रोजेक्ट के सार्वजनिक एपीआई में मौजूद टारगेट के लिए अलग-अलग सेट किया जाना चाहिए. ये ऐसी लाइब्रेरी हो सकती हैं जिन्हें किसी बाहरी प्रोजेक्ट या बाइनरी के आधार पर डिज़ाइन किया गया है और जिनका इस्तेमाल किसी बाहरी प्रोजेक्ट की बिल्ड प्रोसेस के ज़रिए किया जा सकता है.

डिपेंडेंसी

निर्भरता सीधे तौर पर डिपेंडेंसी तक सीमित होनी चाहिए (यह नियम में दिए गए स्रोतों पर निर्भर करता है). ट्रांज़िट पर निर्भर करने वाली चीज़ों की सूची न बनाएं.

सबसे पहले पैकेज-लोकल डिपेंडेंसी सूची में होनी चाहिए और उसे ऊपर दिए गए मौजूदा पैकेज में टारगेट के संदर्भ के साथ काम करने वाले तरीके से रेफ़र किया जाना चाहिए (उनके पूरे पैकेज नाम से नहीं) चुनें.

किसी एक सूची के रूप में सीधे तौर पर डिपेंडेंसी शामिल करना चाहते हैं. कई टारगेट के "सामान्य" डिपेंडेंसी को वैरिएबल में रखने से रखरखाव कम होता है, टूल के लिए डिपेंडेंसी को बदलना मुश्किल हो जाता है और इससे डिपेंडेंसी इस्तेमाल नहीं हो पाती है.

ग्लोब

[] को "कोई टारगेट नहीं" के तौर पर दिखाएं. किसी ऐसे ग्लोब का इस्तेमाल न करें जो किसी चीज़ से मेल न खाता हो: इसमें गड़बड़ी की संभावना ज़्यादा होती है और खाली सूची की तुलना में कम जानकारी होती है.

बार-बार होने वाला

स्रोत फ़ाइलों से मिलान करने के लिए बार-बार होने वाले ग्लोब का इस्तेमाल न करें (उदाहरण के लिए, glob(["**/*.java"])).

बार-बार ग्लाइड करने की सुविधा की वजह से BUILD फ़ाइलों को समझना मुश्किल हो जाता है, क्योंकि ये BUILD फ़ाइलों वाली सबडायरेक्ट्री को छोड़ देती हैं.

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

हर डायरेक्ट्री में BUILD फ़ाइल बनाना और उनके बीच के डिपेंडेंसी ग्राफ़ को तय करना सबसे अच्छा तरीका है.

बार-बार नहीं होने वाली

आम तौर पर, ऐसा ग्लोब नहीं होता जो बार-बार दिखता हो.

अन्य कन्वेंशन

  • स्थिरांक (जैसे कि GLOBAL_CONSTANT) का एलान करने के लिए, अपरकेस और अंडरस्कोर का इस्तेमाल करें. वैरिएबल की जानकारी देने के लिए, लोअरकेस और अंडरस्कोर (जैसे कि my_variable) का इस्तेमाल करें.

  • लेबल कभी भी अलग नहीं किए जाने चाहिए, भले ही वे 79 वर्णों से ज़्यादा लंबे हों. लेबल को जहां तक हो सके स्ट्रिंग की लिटरल वैल्यू होनी चाहिए. रैशनल: इससे ढूंढना और बदलना आसान हो जाता है. साथ ही, इसे पढ़ने में आसानी होती है.

  • नाम एट्रिब्यूट का मान कोई स्थायी स्ट्रिंग होनी चाहिए (मैक्रो को छोड़कर). रेक्शन: बाहरी टूल किसी नियम को रेफ़र करने के लिए, नाम एट्रिब्यूट का इस्तेमाल करते हैं. उन्हें कोड की व्याख्या किए बिना नियम ढूंढने की ज़रूरत होती है.

  • बूलियन-टाइप एट्रिब्यूट सेट करते समय, बूलियन मान का इस्तेमाल करें, पूर्णांक मानों का नहीं. विरासती वजहों से, नियम अब भी पूरी तरह से बूलियन को बूलियन में बदलते हैं. हालांकि, ऐसा करने से बचने की सलाह दी जाती है. रैशनल: flaky = 1 को यह कहा जा सकता है कि "इस टारगेट को एक बार फिर से चलाकर, इसे शुरू कर दें". flaky = True साफ़ तौर पर बताता है कि "यह टेस्ट फ़्लेक्सी है".

Python शैली गाइड में अंतर

हालांकि, Python शैली गाइड के साथ काम करना एक लक्ष्य है, लेकिन यहां कुछ अंतर हैं:

  • कोई सख्त लाइन लंबाई सीमा नहीं. लंबी टिप्पणियों और लंबी स्ट्रिंग को अक्सर 79 कॉलम में बांटा जाता है, लेकिन इसकी ज़रूरत नहीं है. इसे, कोड समीक्षाओं में या स्क्रिप्ट को पहले से सबमिट करने पर लागू नहीं किया जाना चाहिए. आयन: लेबल लंबे हो सकते हैं और इस सीमा से ज़्यादा हो सकते हैं. टूल के ज़रिए, BUILD फ़ाइलों को जनरेट करना या उनमें बदलाव करना आम बात है, जो लाइन की सीमा के साथ ठीक से काम नहीं करता.

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

  • नियमों में कीवर्ड तर्कों के लिए, = साइन इन के आस-पास स्पेस का इस्तेमाल करें. Rationale: Python के मुकाबले नाम वाले तर्क अक्सर ज़्यादा होते हैं और ये हमेशा एक अलग लाइन में होते हैं. खाली जगह, पढ़ने को बेहतर बनाती है. यह काफ़ी समय हो गया है और अब सभी मौजूदा BUILD फ़ाइलों में बदलाव नहीं किया जा सकता.

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

  • टॉप-लेवल दो परिभाषाओं के बीच एक खाली लाइन का इस्तेमाल करें. आयन: BUILD फ़ाइल की संरचना किसी सामान्य Python फ़ाइल की तरह नहीं होती. इसमें केवल टॉप-लेवल स्टेटमेंट होते हैं. एक खाली लाइन के इस्तेमाल से, BUILD फ़ाइलें छोटी हो जाती हैं.