स्टाइल गाइड बनाएं

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

BUILD फ़ाइल फ़ॉर्मैट करने का तरीका, Go जैसा ही है, जहां स्टैंडर्ड फ़ॉर्मैट टूल, फ़ॉर्मैट से जुड़ी ज़्यादातर समस्याओं को ठीक करता है. Buildifer एक ऐसा टूल है जो सोर्स कोड को स्टैंडर्ड स्टाइल में पार्स और बाहर करता है. इसलिए, हर 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() फ़ंक्शन.

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

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

# 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();' > $@",
)

टारगेट किया गया नाम

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

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

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

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

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

  • आम तौर पर, "स्नेक_केस" का इस्तेमाल करें
    • एक src वाले java_library के लिए इसका मतलब किसी ऐसे नाम से है जो एक्सटेंशन के बिना फ़ाइल के नाम से अलग है
    • Java *_binary और *_test नियमों के लिए, "Upper CamelCase" का उपयोग करें. इससे टारगेट नाम src में से एक से मेल खाता है. java_test के लिए, इससे test_class एट्रिब्यूट के लिए टारगेट के नाम से यह अनुमान लगाया जा सकता है.
  • अगर किसी खास टारगेट के कई वैरिएंट हैं, तो पहचान में अंतर करने के लिए सफ़िक्स जोड़ें (जैसे कि :foo_dev, :foo_prod या :bar_x86, :bar_x64)
  • _test, _unittest, Test या Tests के साथ _test टारगेट सफ़िक्स
  • _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 से ज़्यादा वर्ण हों. जब भी मुमकिन हो, लेबल स्ट्रिंग लिटरल होने चाहिए. Rainale: इससे लोगों को ढूंढना और बदलना आसान हो जाता है. इससे पढ़ने में आसानी होती है.

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

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

Python शैली गाइड में फ़र्क़

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

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

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

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

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

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