リポジトリのルール

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

外部リポジトリは、Bazel ビルドで使用可能なソースファイルを含むディレクトリ ツリーです。これは、対応するリポジトリ ルールを実行してオンデマンドで生成されます。リポジトリはさまざまな方法で定義できますが、最終的には、ビルド ターゲットがビルドルールを呼び出して定義されるのと同じように、リポジトリ ルールを呼び出して定義されます。これらを使用して、サードパーティ ライブラリ(Maven パッケージ ライブラリなど)に依存するだけでなく、Bazel が実行されているホストに固有の BUILD ファイルを生成することもできます。

リポジトリ ルールの定義

.bzl ファイルで、 repository_rule 関数を使用して 新しいリポジトリルールを定義し、グローバル変数に保存します。リポジトリ ルールを定義したら、関数として呼び出してリポジトリを定義できます。通常、この呼び出しは モジュール拡張機能の実装 関数内から行われます。

リポジトリ ルールの定義の 2 つの主要なコンポーネントは、属性スキーマと実装関数です。属性スキーマは、リポジトリ ルールの呼び出しに渡される属性の名前と型を決定します。実装関数は、リポジトリを取得する必要がある場合に実行されます。

属性

属性は、リポジトリ ルールの呼び出しに渡される引数です。リポジトリ ルールで受け入れられる属性のスキーマは、repository_rule の呼び出しでリポジトリ ルールを定義するときに attrs 引数を使用して指定します。url 属性と sha256 属性を文字列として定義する例:

http_archive = repository_rule(
    implementation=_impl,
    attrs={
        "url": attr.string(mandatory=True),
        "sha256": attr.string(mandatory=True),
    }
)

実装関数内の属性にアクセスするには、 repository_ctx.attr.<attribute_name> を使用します。

def _impl(repository_ctx):
    url = repository_ctx.attr.url
    checksum = repository_ctx.attr.sha256

すべての repository_rule には、暗黙的に定義された属性 name があります。これは、リポジトリ ルールの呼び出しへの入力として指定すると、リポジトリ名が表示される文字列属性です。ただし、repository_ctx.attr.name を使用してリポジトリ ルールの実装関数から読み取ると、正規のリポジトリ名が返されます。

実装関数

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

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

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

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

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

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

リポジトリ ルールの実装関数は、Bazel がそのリポジトリのターゲットを必要とするときに実行されます。たとえば、別のターゲット(別のリポジトリ内)がそのリポジトリに依存している場合や、コマンドラインでそのリポジトリが指定されている場合などです。この場合、実装関数はファイル システムにリポジトリを作成する必要があります。これはリポジトリの「フェッチ」と呼ばれます。

通常ターゲットとは異なり、リポジトリが異なる原因となる変更が発生しても、リポジトリが必ずしも再フェッチされるとは限りません。これは、Bazel が変更を検出できないものや、ビルドごとにオーバーヘッドが大きすぎるもの(ネットワークからフェッチされるものなど)があるためです。そのため、リポジトリは次のいずれかが変更された場合にのみ再フェッチされます。

リポジトリが再フェッチされるタイミングを制御する repository_rule のパラメータは 2 つあります。

  • configure フラグが設定されている場合、リポジトリは bazel fetch --force --configure で再フェッチされます(configure 以外のリポジトリは再フェッチされません)。
  • local フラグが設定されている場合、上記に加えて、Bazel サーバーが再起動したときにもリポジトリが再フェッチされます。

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

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

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

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

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

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