.bzl スタイルガイド

問題を報告する ソースを表示 夜間 7.4 をタップします。 7.3 7.2 7.1 7.0 6.5

このページでは、Starlark の基本的なスタイルガイドラインについて説明します。また、マクロとルールに関する情報も記載しています。

Starlark は、 ソフトウェアの構築方法を定義する言語であり、したがって、 構成言語を使用します。

Starlark を使用して、BUILD ファイル、マクロ、ビルドルールを記述します。マクロとルールは本質的にメタ言語であり、BUILD ファイルの作成方法を定義します。BUILD ファイルはシンプルで反復的なファイルです。

すべてのソフトウェアは、書き込みよりも頻繁に読み取られます。これは特に Starlark。エンジニアは、BUILD ファイルを読み取って、依存関係を把握します。 ビルドの詳細を確認できます。多くの場合、こうした読み取りは、 急いでいることも、他の作業を並行して行うこともあります。その結果 シンプルさと読みやすさが非常に重要です。 BUILD ファイルをすばやく理解できます。

ユーザーが BUILD ファイルを開いたときに、そのファイル内のターゲットのリストをすばやく確認したり、その C++ ライブラリのソースのリストを表示したり、その Java バイナリから依存関係を削除したりできます。抽象化レイヤを追加するたびに、 ユーザーが行う操作が難しくなります

BUILD ファイルもさまざまなツールで分析、更新されます。ツールによる禁止 抽象化を使用している場合、BUILD ファイルを編集できるようになります。BUILD の保持 ファイルをシンプルにすることで、より優れたツールを利用できます。コードベースが大きくなるにつれて そのため、多数の BUILD ファイルに変更を加える頻度がますます高まっています。 ライブラリの更新やクリーンアップを行います

一般的なアドバイス

スタイル

Python スタイル

不明な点がある場合は、可能な限り PEP 8 スタイルガイドに従ってください。特に、Python の規則に従って、インデントに 2 つのスペースではなく 4 つのスペースを使用します。

Starlark は Python ではないため、Python スタイルの一部の側面は適用されません。たとえば PEP 8 では、 シングルトンとの比較は is で実行します。これは次の言語の演算子ではありません スターラーク。

docstring

docstring を使用してファイルと関数を記述します。各 .bzl ファイルの上部にドキュメント コメントを使用し、公開関数ごとにドキュメント コメントを使用します。

ルールとアスペクトを文書化する

ルールとアスペクト、その属性、プロバイダと doc 引数を使用してドキュメント化する必要があります。

命名規則

  • 変数名と関数名は小文字で、単語はアンダースコア([a-z][a-z0-9_]*)で区切ります(cc_library など)。
  • 最上位の非公開値は 1 つのアンダースコアで始まります。Bazel は以下を適用しました: 他のファイルからは使用できません。ローカル変数は 使用します。

行の長さ

BUILD ファイルと同様に、ラベルは長くできるため、厳格な行長の制限はありません。 可能な限り、1 行あたり最大 79 文字を使用するようにします(Python の スタイルガイド、PEP 8)。このガイドラインは 厳格に適用しないでください。エディタは 80 を超える列を表示する必要があります。 自動化された変更では長い行が頻繁に挿入され、人間が行わないようにする必要があります。 読み取れる行を分割するのに 時間を費やすことになります

キーワード引数

キーワード引数では、等号の周囲にスペースを入れることをおすすめします。

def fct(name, srcs):
    filtered_srcs = my_filter(source = srcs)
    native.cc_library(
        name = name,
        srcs = filtered_srcs,
        testonly = True,
    )

ブール値

ブール値には(10 ではなく)TrueFalse の値を優先します (ブール値属性をルールで使用する場合など)。

本番環境のコードでは print() 関数を使用しないでください。Chronicle SOAR は デバッグを行い、.bzl ファイルの直接的および間接的なすべてのユーザーにスパム行為を働きます。唯一の例外は、print() がデフォルトで無効になっており、ソースの編集によってのみ有効にできる場合に、print() を使用するコードを送信できることです。たとえば、print() のすべての使用が if DEBUG: でガードされ、DEBUGFalse にハードコードされている場合などです。これらの記述が、正当化するのに十分有用であるかどうかに留意してください。 理解しやすくなっています。

マクロ

マクロは、読み込みフェーズ中に 1 つ以上のルールをインスタンス化する関数です。一般に、可能な限りマクロではなくルールを使用します。ユーザーが確認できるビルドグラフは、ビルド中に Bazel が使用するビルドグラフとは異なります。マクロは、Bazel がビルドグラフの分析を行う前に展開されます。

そのため、何か問題が起きたときには、 マクロの実装方法を確認して、ビルドの問題のトラブルシューティングを行います。また、結果に表示されるターゲットはマクロ展開によるものであるため、bazel query の結果を解釈するのは難しい場合があります。最後に、アスペクトはマクロを認識しないため、アスペクトに依存するツール(IDE など)が失敗する可能性があります。

マクロを安全に使用するには、Bazel CLI または BUILD ファイルで直接参照することを目的とした追加のターゲットを定義します。その場合、それらのターゲットのエンドユーザーのみがそれらについて知る必要があり、マクロによって発生するビルドの問題は、その使用から遠く離れることはありません。

生成されたターゲットを定義するマクロ(CLI で参照されることも、そのマクロによってインスタンス化されないターゲットによって依存されることもないマクロの実装の詳細)には、次のベスト プラクティスに従ってください。

  • マクロは name 引数を取り、その名前のターゲットを定義する必要があります。このターゲットが、そのマクロのメインのターゲットになります。
  • 生成されたターゲット(マクロで定義された他のすべてのターゲット)は、次の条件を満たす必要があります。
    • 名前の前に <name> または _<name> が付いています。たとえば、name = '%s_bar' % (name) を使用します。
    • 公開が制限されている(//visibility:private
    • ワイルドカード ターゲット(:all...:* など)の拡張を回避するために manual タグがある。
  • name は、 マクロで指定し、その他のアクションは行いません。たとえば、マクロ自体によって生成されていない依存関係や入力ファイルを名前を使用して導出しないでください。
  • マクロで作成されたターゲットはすべて、なんらかの方法でメイン ターゲットに結合する必要があります。
  • マクロ内のパラメータ名は一貫させます。パラメータを属性値としてメイン ターゲットに渡す場合は、名前を同じにします。マクロが 共通のルール属性と同じ目的を果たします。 deps: 属性と同様の名前を付けます(下記参照)。
  • マクロを呼び出すときは、キーワード引数のみを使用します。これはルールに準拠しており、読みやすさが大幅に向上します。

エンジニアは、ルールが Bazel 内でネイティブ コードで定義されているか Starlark で定義されているかにかかわらず、関連するルールの Starlark API が特定のユースケースに不十分な場合に、マクロを記述することがよくあります。問題がある場合 ルールの作成者に API を拡張して目的を達成できるかどうかを あります。

経験則では、ルールに近いマクロが多いほど、より良い結果が得られます。

マクロもご覧ください。

ルール

  • ルール、アスペクト、およびそれらの属性には、小文字の名前(「スネークケース」)を使用する必要があります。
  • ルール名は、ルールによって生成される という観点から(リーフルールの場合は、 できます。これは必ずしもファイル接尾辞ではありません。たとえば、Python 拡張機能として使用することを目的とした C++ アーティファクトを生成するルールは py_extension という名前にします。ほとんどの言語では、一般的なルールは次のとおりです。
    • *_library - コンパイル単位または「モジュール」。
    • *_binary - 実行可能ファイルまたはデプロイ ユニットを生成するターゲット。
    • *_test - テスト ターゲット。複数のテストを含めることができます。すべてを表示 *_test ターゲット内のテストを、同じテーマのバリエーションとして使用することはできません。 単一のライブラリをテストする場合です。
    • *_import: 事前コンパイル済みアーティファクト(.jar など)またはコンパイル時に使用される .dll をカプセル化するターゲット。
  • 属性には一貫した名前と型を使用します。一般に適用される属性には次のようなものがあります。
    • srcs: label_list。ファイル(通常は人間が作成したソースファイル)を許可します。
    • deps: label_list。通常、ファイル: コンパイル依存関係を許可しません
    • data: label_list。ファイル(テストデータなどのデータファイル)を許可します。
    • runtime_deps: label_list: コンパイルに必要ないランタイム依存関係。
  • 動作がわかりにくい属性(特別な置換を含む文字列テンプレートや、特定の要件で呼び出されるツールなど)については、属性の宣言(attr.label_list() など)に doc キーワード引数を使用してドキュメントを提供します。
  • ルールの実装関数は、ほとんどの場合、プライベート関数(先頭にアンダースコアが付いた名前)にする必要があります。一般的なスタイルは、 myrule の実装関数(名前は _myrule_impl
  • 明確に定義されたプロバイダ インターフェースを使用して、ルール間で情報を渡します。プロバイダ フィールドを宣言してドキュメント化します。
  • 拡張性を念頭に置いてルールを設計してください。他のルールによって プロバイダへのアクセス、ルールの再利用など、 できます。
  • ルールのパフォーマンス ガイドラインに従います。