הפורמט של קובצי BUILD
זהה לזו של Go, שבו הכלי הסטנדרטי מטפל במרבית הבעיות.
Builderier הוא כלי לניתוח ולפלט של קוד המקור בסגנון רגיל. לכן, כל קובץ (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
).
הימנעו משימוש ב-"reserve"שמות יעד שיש להם משמעות מיוחדת. השמות האלה כוללים מאפיינים סמנטיים של 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
בנפרד ליעדים ב-API הציבורי של הפרויקט. אלו יכולות להיות ספריות שעוצבו בהתאם לפרויקטים חיצוניים או קבצים בינאריים שניתן להשתמש בהם בתהליך בנייה של פרויקט חיצוני.
יחסי תלות
יחסי תלות צריכים להיות מוגבלים לתלות ישירה (קשרי תלות הנדרשים על ידי המקורות המפורטים בכלל). אין לציין יחסי תלות חולפים.
כדי לרשום יחסי תלות של חבילה מקומית, יש לציין אותם תחילה בהתאם לחומר העזר לטירגוטים בחבילה הנוכחית (ולא לפי שם החבילה המוחלט).
העדפה רשימת תלות באופן ישיר, כרשימה אחת. ציון ה&תלויה;התלויות של מספר יעדים במשתנה מצמצם את התחזוקה שלו, לא מאפשר לשנות את התלות של היעד ולהביא לתלויות שאינן בשימוש.
גלובוסים
יש לציין "ללא יעדים" עם []
. אל תשתמשו בגלובוס שלא תואם לאף דבר: הוא נוטה יותר לשגיאות ופחות ברור מאשר רשימה ריקה.
רקורסיבי
אין להשתמש בגלובוסים חוזרים כדי להתאים לקובצי מקור (לדוגמה,
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
קבצים.