راهنمای سبک .bzl

این صفحه دستورالعمل‌های سبک اولیه Starlark را پوشش می‌دهد و همچنین شامل اطلاعاتی در مورد ماکروها و قوانین است.

Starlark زبانی است که نحوه ساخت نرم افزار را تعریف می کند و به این ترتیب هم یک زبان برنامه نویسی و هم یک زبان پیکربندی است.

شما از Starlark برای نوشتن فایل های BUILD ، ماکروها و قوانین ساخت استفاده خواهید کرد. ماکروها و قوانین اساساً متا زبان هستند - آنها نحوه نوشتن فایل های BUILD را مشخص می کنند. فایل های BUILD ساده و تکراری هستند.

همه نرم افزارها بیشتر از آنچه نوشته شده خوانده می شوند. این به ویژه برای Starlark صادق است، زیرا مهندسان فایل های BUILD را می خوانند تا وابستگی اهداف و جزئیات ساخت های خود را درک کنند. این خواندن اغلب به صورت گذرا، با عجله یا به موازات انجام کار دیگری اتفاق می افتد. در نتیجه، سادگی و خوانایی بسیار مهم است تا کاربران بتوانند فایل های BUILD را به سرعت تجزیه و درک کنند.

هنگامی که کاربر یک فایل BUILD را باز می کند، به سرعت می خواهد لیست اهداف موجود در فایل را بداند. یا فهرست منابع آن کتابخانه C++ را مرور کنید. یا یک وابستگی را از آن باینری جاوا حذف کنید. هر بار که یک لایه انتزاعی اضافه می کنید، انجام این وظایف را برای کاربر سخت تر می کنید.

فایل های BUILD نیز توسط بسیاری از ابزارهای مختلف تجزیه و تحلیل و به روز می شوند. اگر فایل BUILD شما از انتزاع استفاده کند، ممکن است ابزارها نتوانند فایل BUILD شما را ویرایش کنند. ساده نگه داشتن فایل‌های BUILD به شما امکان می‌دهد تا ابزار بهتری داشته باشید. با رشد پایه کد، انجام تغییرات در بسیاری از فایل های BUILD به منظور به روز رسانی یک کتابخانه یا پاکسازی بیشتر و بیشتر می شود.

توصیه های عمومی

سبک

سبک پایتون

در صورت شک، در صورت امکان، راهنمای سبک PEP 8 را دنبال کنید. به طور خاص، برای پیروی از قرارداد پایتون، از چهار فاصله به جای دو فاصله برای تورفتگی استفاده کنید.

از آنجایی که Starlark پایتون نیست ، برخی از جنبه های سبک پایتون اعمال نمی شود. به عنوان مثال، PEP 8 توصیه می کند که مقایسه با تک تن ها با is انجام شود، که یک عملگر در Starlark نیست.

Docstring

فایل ها و توابع سند را با استفاده از رشته های مستند . از یک docstring در بالای هر فایل .bzl . و یک docstring برای هر تابع عمومی استفاده کنید.

قوانین و جنبه های سند

قوانین و جنبه ها، همراه با ویژگی های آنها، و همچنین ارائه دهندگان و زمینه های آنها، باید با استفاده از استدلال doc شوند.

قرارداد نامگذاری

  • متغیرها و نام توابع از حروف کوچک با کلمات جدا شده با زیرخط ( [az][a-z0-9_]* ) استفاده می‌کنند، مانند cc_library .
  • مقادیر خصوصی سطح بالا با یک خط زیر شروع می شوند. Bazel اعمال می کند که مقادیر خصوصی را نمی توان از فایل های دیگر استفاده کرد. متغیرهای محلی نباید از پیشوند زیر خط استفاده کنند.

طول خط

همانطور که در فایل های BUILD ، هیچ محدودیت دقیقی برای طول خط وجود ندارد زیرا برچسب ها می توانند طولانی باشند. در صورت امکان، سعی کنید از حداکثر 79 کاراکتر در هر خط استفاده کنید (به دنبال راهنمای سبک پایتون، PEP 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() توسط if DEBUG: جایی که DEBUG است. هاردکد شده به False . توجه داشته باشید که آیا این عبارات به اندازه کافی مفید هستند تا تأثیر آنها بر خوانایی را توجیه کنند.

ماکروها

ماکرو تابعی است که یک یا چند قانون را در مرحله بارگذاری نمونه می‌کند. به طور کلی، تا حد امکان به جای ماکروها از قوانین استفاده کنید. نمودار ساختی که کاربر مشاهده می کند با نموداری که Bazel در طول ساخت استفاده می کند یکسان نیست - ماکروها قبل از اینکه Bazel تجزیه و تحلیل گراف ساخت را انجام دهد گسترش می یابد.

به همین دلیل، هنگامی که مشکلی پیش می‌آید، کاربر باید پیاده‌سازی ماکرو شما را برای عیب‌یابی مشکلات ساخت درک کند. علاوه بر این، تفسیر نتایج bazel query می تواند دشوار باشد زیرا اهداف نشان داده شده در نتایج از گسترش کلان می آیند. در نهایت، جنبه‌ها از ماکروها آگاه نیستند، بنابراین ابزارسازی بسته به جنبه‌ها (IDE و موارد دیگر) ممکن است با شکست مواجه شود.

استفاده ایمن برای ماکروها برای تعریف اهداف اضافی است که قرار است مستقیماً در Bazel CLI یا در فایل های BUILD به آنها ارجاع داده شود: در این صورت، فقط کاربران نهایی آن اهداف باید در مورد آنها بدانند و هر گونه مشکل ساخت که توسط ماکروها معرفی می شود هرگز وجود ندارد. دور از کاربرد آنها

برای ماکروهایی که اهداف تولید شده را تعریف می‌کنند (جزئیات پیاده‌سازی ماکرو که قرار نیست در CLI ارجاع داده شوند یا به اهدافی که توسط آن ماکرو نمونه‌سازی نشده‌اند وابسته باشند)، بهترین شیوه‌ها را دنبال کنید:

  • یک ماکرو باید آرگومان name را بگیرد و هدفی را با آن نام تعریف کند. آن هدف به هدف اصلی آن کلان تبدیل می شود.
  • اهداف تولید شده، یعنی تمام اهداف دیگری که توسط یک ماکرو تعریف می شوند، باید:
    • پیشوند نام آنها با <name> یا _<name> باشد. به عنوان مثال، با استفاده از name = '%s_bar' % (name) .
    • دارای دید محدود ( //visibility:private )، و
    • یک تگ manual برای جلوگیری از گسترش در اهداف عام داشته باشید ( :all ، ... ، :* ، و غیره).
  • این name فقط باید برای استخراج نام اهداف تعریف شده توسط ماکرو استفاده شود و نه برای چیز دیگری. به عنوان مثال، از نام برای استخراج یک فایل وابستگی یا ورودی که توسط خود ماکرو تولید نشده است استفاده نکنید.
  • تمام اهداف ایجاد شده در ماکرو باید به نحوی با هدف اصلی جفت شوند.
  • نام پارامترها را در ماکرو ثابت نگه دارید. اگر پارامتری به عنوان یک مقدار مشخصه به هدف اصلی ارسال شد، نام آن را ثابت نگه دارید. اگر یک پارامتر کلان همان هدفی را که یک مشخصه قانون رایج است، مانند deps انجام می دهد، نام آن را به عنوان ویژگی انجام می دهد (به زیر مراجعه کنید).
  • هنگام فراخوانی یک ماکرو، فقط از آرگومان های کلمه کلیدی استفاده کنید. این با قوانین سازگار است و خوانایی را تا حد زیادی بهبود می بخشد.

مهندسان اغلب زمانی ماکروها را می نویسند که Starlark API قوانین مربوطه برای مورد استفاده خاص آنها کافی نباشد، صرف نظر از اینکه این قانون در Bazel در کد بومی یا Starlark تعریف شده است. اگر با این مشکل مواجه هستید، از نویسنده قانون بپرسید که آیا می‌تواند API را برای دستیابی به اهداف شما گسترش دهد.

به عنوان یک قاعده کلی، هرچه ماکروها بیشتر به قوانین شباهت داشته باشند، بهتر است.

ماکروها را نیز ببینید.

قوانین

  • قوانین، جنبه‌ها و ویژگی‌های آنها باید از نام‌های کوچکتر استفاده کنند ("مورد مار").
  • نام‌های قوانین، اسم‌هایی هستند که نوع اصلی مصنوع تولید شده توسط قانون را از دیدگاه وابستگی‌های آن (یا برای قوانین برگ، کاربر) توصیف می‌کنند. این لزوما یک پسوند فایل نیست. به عنوان مثال، قانونی که مصنوعات C++ را تولید می کند که به عنوان پسوند پایتون مورد استفاده قرار می گیرند، ممکن است py_extension نامیده شود. برای اکثر زبان ها، قوانین معمولی عبارتند از:
    • *_library - یک واحد تالیف یا "ماژول".
    • *_binary - هدفی که یک واحد اجرایی یا یک واحد استقرار تولید می کند.
    • *_test - یک هدف آزمایشی. این می تواند شامل چندین آزمایش باشد. انتظار می‌رود که تمام تست‌های یک هدف *_test ، تغییراتی در یک موضوع باشند، به عنوان مثال، آزمایش یک کتابخانه واحد.
    • *_import : هدفی که یک مصنوع از پیش کامپایل شده، مانند .jar . یا .dll را که در حین کامپایل استفاده می شود، محصور می کند.
  • از نام ها و انواع ثابت برای ویژگی ها استفاده کنید. برخی از ویژگی های قابل اجرا عبارتند از:
    • srcs : label_list ، به فایل‌ها اجازه می‌دهد: فایل‌های منبع، که معمولاً توسط انسان نوشته شده‌اند.
    • deps : label_list ، معمولاً به فایل‌ها: وابستگی‌های کامپایل اجازه نمی‌دهد .
    • data : label_list ، اجازه دادن به فایل‌ها: فایل‌های داده، مانند داده‌های آزمایشی و غیره.
    • runtime_deps : label_list : وابستگی های زمان اجرا که برای کامپایل مورد نیاز نیستند.
  • برای هر ویژگی با رفتار غیر آشکار (مثلاً الگوهای رشته‌ای با جایگزین‌های خاص یا ابزارهایی که با الزامات خاص فراخوانی می‌شوند)، مستنداتی را با استفاده از آرگومان کلمه کلیدی doc برای اعلان ویژگی ( attr.label_list() یا موارد مشابه ارائه کنید.
  • توابع اجرای قانون تقریباً همیشه باید توابع خصوصی باشند (با یک زیرخط اصلی نامگذاری می شوند). یک سبک رایج این است که به تابع پیاده سازی myrule نام _myrule_impl شود.
  • با استفاده از یک رابط ارائه دهنده به خوبی تعریف شده، اطلاعات را بین قوانین خود منتقل کنید. فیلدهای ارائه دهنده را اعلام و مستند کنید.
  • قانون خود را با در نظر گرفتن قابلیت توسعه طراحی کنید. در نظر بگیرید که سایر قوانین ممکن است بخواهند با قانون شما تعامل داشته باشند، به ارائه دهندگان شما دسترسی داشته باشند و از اقداماتی که ایجاد می کنید استفاده مجدد کنند.
  • دستورالعمل های عملکرد را در قوانین خود دنبال کنید.