リポジトリのルール

このページでは、リポジトリ ルールを作成する方法について説明し、詳細な例を示します。

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

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

実装関数

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

この関数には、入力パラメータが 1 つだけあります。repository_ctx です。この関数は、指定されたパラメータでルールを再現できることを示す 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 ファイルでのリポジトリ ルールの宣言。
  • environ 関数の repository_rule 属性で宣言された環境変数の値。これらの環境変数の値は、コマンドラインから --action_env フラグを使用して強制的に適用できます(ただし、このフラグはビルドのすべてのアクションを無効にします)。
  • ラベルで使用および参照されるファイルのコンテンツ(mypkg/label.txt ではなく //mypkg:label.txt など)。

外部リポジトリの再フェッチを強制する

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

また、ローカル マシンを検査するルールもあり、ローカル マシンがアップグレードされると古くなる可能性があります。ここで、bazel に、 定義に configure 属性が設定されている外部リポジトリのみを再フェッチするように指示するには、bazel sync --configure を使用します。repository_rule

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

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

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