このページでは、リポジトリ ルールを作成する方法について説明し、詳細な例を示します。
外部リポジトリは、WORKSPACE
ファイルでのみ使用できるルールで、Bazel の読み込みフェーズで非密閉型のオペレーションを可能にします。各外部リポジトリ ルールは、独自の BUILD
ファイルとアーティファクトを含む独自のワークスペースを作成します。これらは、サードパーティ ライブラリ(Maven パッケージ ライブラリなど)に依存するために使用できますが、Bazel が実行されているホストに固有の BUILD
ファイルを生成するためにも使用できます。
リポジトリ ルールの作成
.bzl
ファイルで、repository_rule 関数を使用して新しいリポジトリルールを作成し、グローバル変数に保存します。
カスタム リポジトリルールは、ネイティブ リポジトリルールと同様に使用できます。必須の name
属性があり、ビルドファイルに存在するすべてのターゲットは @<name>//package:target
として参照できます。ここで、<name>
は name
属性の値です。
ルールは、明示的にビルドする場合、またはビルドの依存関係である場合に読み込まれます。この場合、Bazel は implementation
関数を実行します。この関数は、リポジトリ、そのコンテンツ、BUILD
ファイルの作成方法を記述します。
属性
属性は、url
や sha256
などのルール引数です。リポジトリ ルールを定義するときは、属性とその型を一覧表示する必要があります。
local_repository = repository_rule(
implementation=_impl,
local=True,
attrs={"path": attr.string(mandatory=True)})
属性にアクセスするには、repository_ctx.attr.<attribute_name>
を使用します。
すべての repository_rule
には、暗黙的に定義された属性があります(ビルドルールと同様)。2 つの暗黙的属性は、name
(ビルドルールの場合と同様)と repo_mapping
です。リポジトリ ルールの名前には repository_ctx.name
でアクセスできます。repo_mapping
の意味は、ネイティブ リポジトリ ルール local_repository
と new_local_repository
の場合と同じです。
属性名が _
で始まる場合、その属性は非公開であり、ユーザーは設定できません。
実装関数
すべてのリポジトリ ルールには implementation
関数が必要です。ルールの実際のロジックが含まれており、読み込みフェーズで厳密に実行されます。
この関数には、入力パラメータ repository_ctx
が 1 つだけあります。この関数は、指定されたパラメータでルールを再現できることを示す None
を返すか、そのルールを再現可能なものにして同じリポジトリを生成するパラメータのセットを含む辞書を返します。たとえば、git リポジトリを追跡するルールの場合、元々指定されたフローティング ブランチではなく、特定の commit 識別子を返すことになります。
入力パラメータ 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 アーティファクトのビルド ターゲットを生成します。