מדריך סגנון של BUILD

הפורמט של קובצי 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 קבצים.