يتّبع تنسيق الملفات 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()
.استدعاءات القواعد ووحدات الماكرو
يفرّق أداة Buildifer بين تعليق مستقل وتعليق مرفق بعنصر. إذا لم يتم إرفاق تعليق بعنصر محدد، استخدم سطرًا فارغًا بعده. والتمييز بينهما مهم عند إجراء تغييرات مبرمَجة (مثل الاحتفاظ بتعليق أو إزالته عند حذف قاعدة).
# 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"
- بالنسبة إلى
java_library
باستخدام واحدsrc
، هذا يعني استخدام اسم ليس مطابقًا لاسم الملف بدون الامتداد - بالنسبة إلى قاعدتي Java
*_binary
و*_test
، استخدِم "Upper CamelCase". يسمح ذلك للاسم المستهدَف بأن يتطابق مع أحد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
بشكل فردي فقط للأهداف في واجهة برمجة التطبيقات الخاصة بالمشروع. قد تكون هذه المكتبات المصممة للاعتماد عليها
في المشاريع الثنائية أو البرامج الثنائية التي يمكن استخدامها في مشروع إنشاء
خارجي.
المهام التابعة
يجب أن تقتصر المهام التابعة على التبعيات المباشرة (الاعتماديات التي تحتاج إليها المصادر المدرجة في القاعدة). لا تُدرِج العناصر التابعة.
يجب إدراج التبعيات المحلية للحزمة أولاً والإشارة إليها بطريقة متوافقة مع القسم المراجع المستهدفة في الحزمة الحالية أعلاه (وليس حسب اسم الحزمة المطلقة).
أفضِّل إدراج التبعيات مباشرةً كقائمة واحدة. يؤدي وضع عامل التشغيل "common" بعدة أهداف متعددة في متغيّر إلى تقليل قابلية الحفاظ عليه، ويجعل من الصعب على الأدوات تغيير تبعيات الهدف، ويمكن أن يؤدي إلى تبعيات غير مستخدَمة.
كرات أرضية
الإشارة إلى "لا أهداف"& مع []
. لا تستخدم الكرة الأرضية التي لا تتطابق مع أي شيء: فهي أكثر عرضة للخطأ وأقل وضوحًا من القائمة الفارغة.
متكرر
لا تستخدِم الكرات متكرّرة لمطابقة الملفات المصدر (مثل glob(["**/*.java"])
).
تجعل الملفات العاكسة المتكررة الملفات BUILD
مهمة يصعُب الإجابة عنها لأنّها تتخطّى
الأدلة الفرعية التي تحتوي على ملفات BUILD
.
تكون الكرات الغنائية المتكررة أقل فعالية بشكل عام من توفّر ملف BUILD
لكل دليل مع رسم بياني للاعتمادية يحدده، ما يتيح إمكانية التخزين المؤقت عن بُعد والتوازي.
من المفيد كتابة ملف BUILD
في كل دليل وتحديد
رسم بياني تابع له.
غير متكرر
وتكون الكرات غير المتكرّرة مقبولاً بشكل عام.
اصطلاحات أخرى
استخدِم الأحرف الكبيرة والشرطات السفلية للثوابت (مثل
GLOBAL_CONSTANT
) واستخدِم الأحرف الصغيرة والشرطات السفلية لتعريف المتغيرات (مثلmy_variable
).يجب عدم تقسيم التصنيفات مطلقًا، حتى إذا كانت أطول من 79 حرفًا. يجب أن تكون التصنيفات عبارة عن سلاسل حرفية كلما أمكن ذلك. الأسباب: تُسهّل هذه الميزة العثور عليها واستبدالها. كما يحسِّن مستوى سهولة القراءة.
يجب أن تكون قيمة سمة الاسم سلسلة ثابتة حرفية (باستثناء وحدات الماكرو). الأسباب: تستخدم الأدوات الخارجية سمة الاسم لإحالة قاعدة. وهم بحاجة إلى العثور على قواعد بدون الحاجة إلى تفسير الرمز.
عند ضبط سمات النوع المنطقي، استخدِم القيم المنطقية، وليس القيم الصحيحة. لأسباب قديمة، لا تزال القواعد تحوّل الأرقام الصحيحة إلى قيم منطقية حسب الحاجة، لكن لا ننصح بذلك. الأسباب: قد يُخطئ
flaky = 1
في قول أنّه ":قلِّل هذا الهدف من خلال إعادة تشغيله مرة واحدة". يقولflaky = True
بوضوح
الاختلافات مع دليل أسلوب Python
على الرغم من أن التوافق مع دليل أسلوب Python هو هدف، إلا أنّ هناك بعض الاختلافات:
ليس هناك حد أقصى لطول السطر. غالبًا ما يتم تقسيم التعليقات الطويلة والسلاسل الطويلة إلى 79 عمودًا، ولكنها ليست مطلوبة. ويجب ألا يتم فرضه على مراجعات الرموز أو النصوص البرمجية قبل الإرسال. الأسباب: يمكن أن تكون التصنيفات طويلة وتتجاوز هذا الحد. من الشائع أن يتم إنشاء ملفات
BUILD
أو تعديلها باستخدام أدوات، وذلك لا يتوافق مع حدّ طول السطر.تسلسل السلسلة الضمني غير متاح. يمكنك استخدام عامل التشغيل
+
. الأسباب: تحتوي ملفاتBUILD
على العديد من قوائم السلاسل. من السهل حذف الفاصلة، التي تؤدي إلى نتيجة مختلفة تمامًا. وقد أدى ذلك إلى حدوث العديد من الأخطاء في الماضي. الاطّلاع أيضًا على هذه المناقشةاستخدم المسافات حول العلامة
=
لوسيطات الكلمات الرئيسية في القواعد. الأسباب: الوسيطات المُعنونة أكثر تكرارًا من Python وتكون دائمًا في سطر منفصل. تسهم مساحات العمل في تحسين إمكانية القراءة. تم استخدام هذه الاتفاقية منذ وقت طويل، ولا يستحق تعديل جميع ملفاتBUILD
الحالية.حسب الإعدادات التلقائية، يمكنك استخدام علامات الاقتباس المزدوجة للسلاسل. الأسباب: لم يتم تحديد ذلك في دليل نمط Python، ولكنه يقترح الاتّساق. لذلك، قررنا استخدام سلاسل ذات علامات اقتباس فقط. تستخدم العديد من اللغات علامات الاقتباس المزدوجة للحرف اليدوية للسلسلة.
استخدِم سطرًا فارغًا واحدًا بين تعريفَين على المستوى الأعلى. الأسباب: لا تشبه بنية ملف
BUILD
ملف Python العادي. يتضمّن فقط كيانات المستوى الأعلى. يؤدي استخدام سطر واحد فارغ إلى اختصارBUILD
ملف.