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.cc
の cc_library
には chat
という名前、DirectMessage.java
の java_library
には direct_message
という名前を付けることができます)。
パッケージの同じ名前のターゲット(格納されているディレクトリと同じ名前のターゲット)は、ディレクトリ名によって記述された機能を提供する必要があります。このようなターゲットが存在しない場合は、同じ名前のターゲットを作成しないでください。
同名のターゲット(//x:x
ではなく //x
)を参照する場合は、略称を使用します。同じパッケージの場合は、ローカル参照(//x
ではなく :x
)を優先します。
特別な意味を持つ「予約済み」のターゲット名は使用しないでください。これには、all
、__pkg__
、__subpackages__
が含まれます。これらの名前には特別な意味があり、使用すると混乱や予期しない動作が発生する可能性があります。
チームの慣行がない場合は、Google で広く使用されている拘束力のない推奨事項を以下に示します。
- 通常は "snake_case" を使用します。
- 1 つの
src
を含むjava_library
の場合、拡張子のないファイル名とは異なる名前を使用します。 - Java の
*_binary
ルールと*_test
ルールの場合は、「大文字のケイマンケース」を使用します。これにより、ターゲット名をsrc
のいずれかに一致させることができます。java_test
の場合、これにより、ターゲットの名前からtest_class
属性を推測できます。
- 1 つの
- 特定のターゲットに複数のバリエーションがある場合は、末尾に接尾辞を追加して区別します(例:
:foo_dev
、:foo_prod
、または:bar_x86
、:bar_x64
) _test
ターゲットの接尾辞を_test
、_unittest
、Test
、または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
[]
で「ターゲットなし」を指定します。何も一致しないグロブは使用しないでください。空のリストよりもエラーが発生しやすく、わかりにくいためです。
Recursive
ソースファイルの照合に再帰 glob を使用しないでください(例: glob(["**/*.java"])
)。
再帰的なグロブを使用すると、BUILD
ファイルを含むサブディレクトリがスキップされるため、BUILD
ファイルの推論が難しくなります。
一般に、再帰的なグロブは、ディレクトリごとに BUILD
ファイルがあり、それらの間に依存関係グラフが定義されている場合よりも効率が低くなります。これは、リモート キャッシュと並列処理を改善できるためです。
各ディレクトリに BUILD
ファイルを作成し、それらの間の依存関係グラフを定義することをおすすめします。
非再帰
非再帰の glob は通常使用できます。
その他の規則
定数の宣言には大文字とアンダースコアを使用し(例:
GLOBAL_CONSTANT
)、変数の宣言には小文字とアンダースコアを使用します(例:my_variable
)。ラベルは、79 文字を超える場合でも分割しないでください。ラベルは、可能な限り文字列リテラルである必要があります。説明: 検索や置換が簡単になります。また、読みやすさも向上します。
name 属性の値は、リテラル定数文字列にする必要があります(マクロを除く)。理由: 外部ツールはルールを参照するために name 属性を使用します。コードを解釈することなくルールを見つける必要があります。
ブール値型の属性を設定する場合は、整数値ではなくブール値を使用します。以前の理由により、ルールでは引き続き必要に応じて整数をブール値に変換しますが、これは推奨されません。根拠:
flaky = 1
は、「1 回再実行してこのターゲットをデフレークする」と誤解される可能性があります。flaky = True
は「このテストは不安定である」と明確に示します。
Python スタイルガイドとの違い
Python スタイルガイドとの互換性が目標ですが、いくつかの違いがあります。
行の長さに厳密な制限はありません。長いコメントや長い文字列は 79 列に分割されることがよくありますが、必須ではありません。コードレビューや presubmit スクリプトでは適用しないでください。理由: ラベルは長く、この上限を超えることができます。
BUILD
ファイルはツールで生成または編集するのが一般的ですが、行の長さ制限にはあまり適しません。暗黙的な文字列の連結はサポートされていません。
+
演算子を使用します。理由:BUILD
ファイルには多くの文字列リストが含まれています。カンマを忘れると、まったく異なる結果になります。過去には、このことが原因で多くのバグが発生しました。こちらのディスカッションもご覧ください。ルールのキーワード引数では、
=
記号の前後にスペースを使用します。理由: 名前付き引数は Python よりもはるかに頻繁に使用され、常に別の行に配置されます。スペースを入れると読みやすくなります。この規則は長い間使用されており、既存のBUILD
ファイルをすべて変更する価値はありません。デフォルトでは、文字列に二重引用符を使用します。理論的根拠: Python スタイルガイドでは説明されていませんが、一貫性を推奨しています。そのため、二重引用符で囲まれた文字列のみを使用することにしました。多くの言語では、文字列リテラルに二重引用符を使用します。
2 つのトップレベルの定義の間には 1 行の空白行を使用します。理由:
BUILD
ファイルの構造は、一般的な Python ファイルとは異なります。トップレベルのステートメントのみがあります。1 行を空白にすると、BUILD
ファイルが短くなります。