リポジトリのルール

このページでは、リポジトリ ルールの作成方法と、例を示します。

外部リポジトリWORKSPACE ファイルでのみ使用できるルールであり、Bazel の読み込みフェーズで非密閉型オペレーションを有効にします。各外部リポジトリ ルールでは、独自の BUILD ファイルとアーティファクトを含む独自のワークスペースが作成されます。サードパーティのライブラリ(Maven パッケージ ライブラリなど)に依存する場合だけでなく、Bazel が実行されているホストに固有の BUILD ファイルを生成する場合にも使用できます。

リポジトリ ルールの作成

.bzl ファイルで、repository_rule 関数を使用して新しいリポジトリ ルールを作成し、グローバル変数に格納します。

カスタム リポジトリ ルールは、ネイティブ リポジトリ ルールと同様に使用できます。必須の name 属性があり、ビルドファイル内に存在するすべてのターゲットは @<name>//package:target として参照できます(<name>name 属性の値)。

ルールは、明示的にビルドしたとき、またはビルドの依存関係である場合に読み込まれます。この場合、Bazel は implementation 関数を実行します。この関数は、リポジトリ、そのコンテンツ、BUILD ファイルの作成方法を記述します。

属性

属性は、urlsha256 などのルール引数です。リポジトリ ルールを定義するときは、属性とそのタイプをリストする必要があります。

local_repository = repository_rule(
    implementation=_impl,
    local=True,
    attrs={"path": attr.string(mandatory=True)})

属性にアクセスするには、repository_ctx.attr.<attribute_name> を使用します。

すべての repository_rule には、(ビルドルールと同様に)暗黙的に定義された属性があります。暗黙的な属性は、name(ビルドルールの場合と同様)と repo_mapping の 2 つです。リポジトリ ルールの名前は、repository_ctx.name でアクセスできます。repo_mapping の意味は、ネイティブ リポジトリ ルールの local_repositorynew_local_repository と同じです。

_ で始まる属性名は非公開であり、ユーザーは設定できません。

実装関数

すべてのリポジトリ ルールに implementation 関数が必要です。ルールの実際のロジックが含まれ、厳密に読み込みフェーズで実行されます。

この関数には、入力パラメータ repository_ctx が 1 つだけあります。この関数は、指定されたパラメータでルールが再現可能であることを示す None を返します。または、同じリポジトリを生成する再現可能なルールに変換するルールのパラメータ セットを含む dict を返します。たとえば、git リポジトリを追跡するルールの場合、最初に指定されたフローティング ブランチではなく、特定の commit ID を返します。

入力パラメータ repository_ctx は、属性値と非密閉関数(バイナリの検索、バイナリの実行、リポジトリ内のファイルの作成、インターネットからのファイルのダウンロード)にアクセスするために使用できます。詳細については、ライブラリをご覧ください。例:

def _impl(repository_ctx):
  repository_ctx.symlink(repository_ctx.attr.path, "")

local_repository = repository_rule(
    implementation=_impl,
    ...)

実装関数はいつ実行されますか。

リポジトリが local として宣言されている場合、依存関係グラフの依存関係(WORKSPACE ファイル自体を含む)が変更されると、実装関数が実行されます。

実装関数は、リクエストする依存関係がない場合に再起動できます。実装関数の先頭は、依存関係が解決された後に再実行されます。不要な再起動(ネットワーク アクセスを繰り返す必要があるため、コストがかかる)を避けるために、すべてのラベル引数を既存のファイルに解決できる場合に、ラベル引数がプリフェッチされます。関数の実行中にのみ作成された文字列またはラベルからパスを解決すると、再起動が発生する可能性があります。

最後に、local 以外のリポジトリでは、次の依存関係の変更のみが再起動される可能性があります。

  • リポジトリ ルールの定義には .bzl ファイルが必要です。
  • WORKSPACE ファイルでのリポジトリ ルールの宣言。
  • repository_rule 関数の environ 属性で宣言された環境変数の値。これらの環境変数の値は、--action_env フラグを使用してコマンドラインから適用できます(ただし、このフラグはビルドのすべてのアクションを無効にします)。
  • ラベルによって使用および参照されるファイルのコンテンツ(たとえば、mypkg/label.txt ではなく //mypkg:label.txt)。

外部リポジトリの強制再取得

外部リポジトリは、定義や依存関係を変更せずに古くなることがあります。たとえば、ソースを取得するリポジトリがサードパーティ リポジトリの特定のブランチに従い、そのブランチで新しい commit を利用できます。この場合、bazel sync を呼び出して、すべての外部リポジトリを無条件に再取得するよう bazel にリクエストできます。

さらに、一部のルールはローカルマシンを検査し、ローカルマシンがアップグレードされると古い場合があります。ここでは、repository_rule 定義に configure 属性が設定されている外部リポジトリのみを再取得するよう bazel に指示できます(bazel sync --configure を使用します)。

  • C++ 自動構成ツールチェーン: リポジトリ ルールを使用して、ローカル C++ コンパイラ、環境、C++ コンパイラがサポートするフラグを検索して、Bazel 用の C++ 構成ファイルを自動的に作成します。

  • Go リポジトリは、いくつかの repository_rule を使用して、Go ルールを使用するために必要な依存関係のリストを定義します。

  • rules_jvm_external は、デフォルトで @maven という外部リポジトリを作成します。このリポジトリは、推移的依存関係ツリー内のすべての Maven アーティファクトのビルド ターゲットを生成します。