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 つ含まれている場合、
通常、ターゲットにはそのソースから派生した名前を付けます(たとえば、
cc_library の chat.cc は chat、java_library の
DirectMessage.java は direct_message など)。
パッケージの同名ターゲット( 包含ディレクトリと同じ名前のターゲット)は、 ディレクトリ名で説明されている機能を提供する必要があります。そのようなターゲットがない場合は、同名 ターゲットを作成しないでください。
同名ターゲットを参照する場合は、短い名前(//x:x ではなく //x)を使用することをおすすめします。同じパッケージ内にある場合は、ローカル参照(//x ではなく :x)を使用することをおすすめします。
特別な意味を持つ「予約済み」のターゲット名は使用しないでください。これには
all、__pkg__、および__subpackages__が含まれます。これらの名前には特別な
セマンティクスがあり、使用すると混乱や予期しない動作を引き起こす可能性があります。
チームの慣例がない場合は、Google で広く使用されている拘束力のない 推奨事項をいくつかご紹介します。
- 一般に、"snake_case"
-
を使用します。
java_libraryが 1 つの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 関連のターゲットの場合:
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 は使用しないでください。空のリストよりもエラーが発生しやすく、わかりにくいです。
Recursive
再帰的な glob を使用してソースファイルを照合しないでください(例:
glob(["**/*.java"]))。
再帰的な glob は、BUILD ファイルを含むサブディレクトリをスキップするため、BUILD ファイルの理由付けが難しくなります。
通常、再帰的な glob は、ディレクトリごとに BUILD ファイルがあり、それらの間に依存関係グラフが定義されている場合よりも効率が低くなります。これにより、リモート キャッシュと並列処理が向上します。
各ディレクトリに BUILD ファイルを作成し、それらの間に
依存関係グラフを定義することをおすすめします。
Non-recursive
通常、非再帰的な glob は許容されます。
その他の慣例
定数(
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ファイル が短くなります。