ビルドスタイル ガイド

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。
問題を報告 ソースを表示

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() 関数。

  • ルールとマクロの呼び出し

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

ターゲットの命名

ターゲット名はわかりやすい名前にしてください。ターゲットに 1 つのソースファイルが含まれている場合、ターゲットは通常、そのソースから取得された名前を付けます(たとえば、chat.cccc_librarychat に、DirectMessage.javajava_librarydirect_message にできます)。

パッケージの同名ターゲット(包含ディレクトリと同じ名前のターゲット)は、ディレクトリ名で記述されている機能を提供する必要があります。そのようなターゲットが存在しない場合は、同名のターゲットを作成しないでください。

同名のターゲット(//x:x ではなく //x)を参照する場合は、略称を使用します。同じパッケージ内にある場合は、ローカル参照(//x ではなく :x)を使用します。

特別な意味を持つ「予約済み」のターゲット名は使用しないでください。これには all__pkg____subpackages__ が含まれます。これらの名前には特別なセマンティクスがあり、使用中に混乱や予期しない動作が発生する可能性があります。

支配的なチームの規則がない場合、Google で広く使用されている、拘束力のない推奨事項がいくつかあります。

  • 通常は、"snake_case" を使用します。
    • src が 1 つの java_library の場合は、拡張子のないファイル名と同じではない名前を使用することを意味します。
    • Java の *_binary ルールと *_test ルールの場合は、「Upper CamelCase」を使用します。これにより、ターゲット名を src のいずれかと一致させることができます。java_test の場合、これにより、ターゲットの名前から test_class 属性が推測されます。
  • 特定のターゲットに複数のバリアントがある場合は、曖昧さを取り除くために接尾辞を追加します(例::foo_dev:foo_prod または :bar_x86:bar_x64
  • _test ターゲットを _test_unittestTest、または Tests でサフィックスにする
  • _lib_library など、意味のないサフィックスは使用しないでください(_library ターゲットと、それに対応する _binary との競合を避けるために必要な場合を除きます)。
  • proto 関連のターゲットの場合:
    • proto_library 個のターゲットの名前は _proto で終わる必要があります
    • 言語固有の *_proto_library ルールは、基盤となる proto と一致する必要がありますが、_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

[] を使用して、「ターゲットなし」を示します。一致する glob は使用しないでください。空のリストよりもエラーが発生しやすく、不明瞭です。

再帰的

再帰 glob を使用して、ソースファイル(glob(["**/*.java"]) など)を照合しないでください。

再帰的な glob を使用すると、BUILD を含むサブディレクトリがスキップされるため、BUILD ファイルは推論が難しくなります。

一般的に、再帰 glob は、ディレクトリごとに BUILD ファイルが依存関係グラフを定義している場合よりも効率が悪くなります。これは、リモート キャッシュと並列処理が改善されるためです。

各ディレクトリに BUILD ファイルを作成し、それらのファイルで依存関係グラフを定義することをおすすめします。

非再帰的

一般的に、再帰的でないグロブは許容されます。

その他の規則

  • 大文字とアンダースコアを使用して定数(GLOBAL_CONSTANT など)を宣言し、小文字とアンダースコアを使用して変数(my_variable など)を宣言します。

  • ラベルが 79 文字を超える場合でも分割しないでください。可能な限り、ラベルは文字列リテラルにします。理論的根拠: これによって検索と置換が簡単になります。また、読みやすさも向上します。

  • name 属性の値は、リテラル定数文字列にする必要があります(マクロの場合を除く)。理論的根拠: 外部ツールは、name 属性を使用してルールを参照します。コードを解釈することなくルールを見つける必要があります。

  • ブール値型の属性を設定する場合は、整数値ではなくブール値を使用します。 従来の理由から、ルールは引き続き必要に応じて整数をブール値に変換しますが、この方法はおすすめしません。理論的根拠: flaky = 1 は、「このターゲットを再実行してこのターゲットを 1 回だけ再実行する」と誤認される可能性があります。flaky = True は、「このテストは不安定です」と明確に示しています。

Python スタイルガイドとの違い

Python スタイルガイドとの互換性は目標ですが、いくつかの違いがあります。

  • 行の長さに厳密な制限はありません。長いコメントと長い文字列は 79 列に分割されることがよくありますが、必須ではありません。コードレビューや送信前スクリプトで適用しないでください。理論的根拠: ラベルは長くて、この上限を超える可能性があります。BUILD ファイルは、ツールによって生成または編集されることがよくありますが、これは行の長さの上限とは一致しません。

  • 暗黙的な文字列の連結はサポートされていません。+ 演算子を使用します。根拠: BUILD ファイルには多数の文字列リストが含まれています。カンマを忘れがちなため、完全に異なる結果が生じます。これにより、過去に多くのバグが発生しています。こちらの説明もご覧ください。

  • ルールのキーワード引数には、= 記号の前後にスペースを使用してください。理論的根拠: 名前付き引数は Python よりも頻度が高く、必ず別の行にあります。スペースを使用すると読みやすくなります。この規則は古くから存在するため、既存のすべての BUILD ファイルを変更する価値はありません。

  • デフォルトでは、文字列には二重引用符を使用します。理論的根拠: これは Python スタイルガイドで指定されていませんが、一貫性を推奨しています。そのため、二重引用符付きの文字列のみを使用することに決めました。多くの言語では、文字列リテラルに二重引用符を使用します。

  • 2 つの最上位の定義の間に 1 つの空白行を使用します。根拠: BUILD ファイルの構造は、一般的な Python ファイルとは異なります。最上位のステートメントのみが含まれます。空白行を 1 行使用すると、BUILD ファイルが短くなります。