Bazel モジュール

問題を報告する ソースを表示 ナイトリー · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel モジュールは、複数のバージョンを持つことができる Bazel プロジェクトです。各バージョンは、依存する他のモジュールに関するメタデータを公開します。これは、 他の依存関係管理システムにおけるよく知られた概念に似ています。たとえば、依存関係管理システム Maven アーティファクト、npm パッケージ、Go モジュール、または Cargo クレート

モジュールには、リポジトリのルートに MODULE.bazel ファイルが必要です。このファイルはモジュールのマニフェストで、名前、バージョン、直接依存関係のリストなどの情報を宣言します。基本的な例:

module(name = "my-module", version = "1.0")

bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")

利用可能なディレクティブの一覧をご覧ください。 MODULE.bazel ファイル。

モジュールを解決するために、Bazel はまずルート モジュールのルート モジュールの MODULE.bazel ファイルを実行し、次に依存関係のリクエストを Bazel レジストリから MODULE.bazel ファイルを取得します。 依存関係グラフ全体を検出します。

デフォルトでは、Bazel は使用する各モジュールの 1 つのバージョンを選択します。Bazel は各モジュールをリポジトリで表し、レジストリを参照します。 各リポジトリの定義方法を学びましょう

バージョン形式

Bazel には多様なエコシステムがあり、プロジェクトはさまざまなバージョニング スキームを使用しています。最も人気があるのは SemVer ですが、Abseil など、日付ベースのバージョン(20210324.2 など)を使用する有名なプロジェクトもあります。

そのため、Bzlmod では SemVer 仕様のより緩和されたバージョンを採用しています。「 次のような違いがあります。

  • SemVer では、バージョンの「リリース」部分は 3 つのセグメント(MAJOR.MINOR.PATCH)で構成する必要があります。Bazel ではこの要件が緩和されているため、 いくつでもセグメントが許可されます
  • SemVer では、「リリース」部分の各セグメントは数字のみにする必要があります。Bazel ではこれを緩めて文字も許容しています。 「identifiers」と一致するようにします。「プレリリース版」をなります。
  • さらに、メジャー バージョン、マイナー バージョン、パッチ バージョンの増加のセマンティクスは、 適用されます。ただし、互換性レベルを参照してください。 下位互換性の示し方に関する詳細です。

有効な SemVer バージョンとは、有効な Bazel モジュール バージョンのことです。また、2 つの SemVer バージョン aba < b と比較されるのは、Bazel モジュール バージョンとして比較した場合に同じ結果が得られる場合に限られます。

バージョンの選択

バージョン管理された依存関係管理の分野では定番のダイアモンド依存関係の問題について考えてみましょう。次のような依存関係グラフがあるとします。

       A 1.0
      /     \
   B 1.0    C 1.1
     |        |
   D 1.0    D 1.1

どのバージョンの D を使用すればよいですか?この問題を解決するために、Bzlmod は 最小バージョンの選択 (MVS)アルゴリズムが Go モジュール システムに導入されました。MVS は、モジュールの新しいバージョンはすべて下位互換性があると想定するため、依存関係によって指定された最高バージョン(この例では D 1.1)を選択します。「ミニマル」と呼ばれています これは、D 1.1 が要件を満たす最も古いバージョンだからです。 D 1.2 以降が存在しても選択されません。MVS を使用すると、忠実度が高く再現可能なバージョン選択プロセスが作成されます。

取り消されたバージョン

レジストリでは、特定のバージョンを回避する必要がある場合(セキュリティの脆弱性など)に、そのバージョンを削除済みとして宣言できます。モジュールの yanked バージョンを選択すると、Bazel でエラーがスローされます。このエラーを修正するには、新しい ヤンクされていないバージョンを使用するか、 --allow_yanked_versions ヤンクされたバージョンを明示的に許可します。

互換性レベル

Go では、後方互換性に関する MVS の想定は機能します。 下位互換性のないバージョンのモジュールを、独立したモジュールとして運用できます。SemVer では、A 1.xA 2.x は異なるモジュールと見なされ、解決された依存関係グラフで共存できます。これを可能にしているのが Go のパッケージパスでメジャー バージョンをエンコードしているため、 コンパイル時またはリンク時の競合。

ただし、Bazel ではこのような保証を提供できないため、下位互換性のないバージョンを検出するには「メジャー バージョン」番号が必要です。この番号は 互換性レベルがあります。これは、Terraform のモジュール バージョンの各モジュール バージョンで module() ディレクティブ。この情報により、Bazel は、解決された依存関係グラフに互換性レベルが異なる同じモジュールのバージョンが存在することを検出すると、エラーをスローできます。

オーバーライド

MODULE.bazel ファイルでオーバーライドを指定して、Bazel モジュール解決の動作を変更します。ルート モジュールのオーバーライドのみが有効になります。モジュールが依存関係として使用されている場合、そのオーバーライドは無視されます。

各オーバーライドは特定のモジュール名に対して指定され、そのモジュール名に影響し、 確認できます。ルート モジュールのオーバーライドのみが有効になりますが、ルート モジュールが直接依存していない推移的な依存関係に対しても適用できます。

単一バージョンのオーバーライド

single_version_override 多岐にわたります。

  • version 属性を使用すると、特定の依存関係に依存関係を固定できます。 リクエストされる依存関係のバージョンにかかわらず、 依存関係グラフを作成します。
  • registry 属性を使用すると、この依存関係を 通常のレジストリに従うのではなく、 選択プロセスに進みます。
  • patch* 属性を使用すると、ダウンロードしたモジュールに適用するパッチのセットを指定できます。

これらの属性はすべて省略可能で、組み合わせて使用できます。

複数バージョンのオーバーライド

multiple_version_override 同じモジュールの複数のバージョンを同じモジュールに共存させる 解決済みの依存関係グラフ。

モジュールで許可されるバージョンのリストを明示的に指定できます。このリストは、解決前に依存関係グラフにすべて存在している必要があります。許可される各バージョンに応じて、いくつかの伝播依存関係が存在している必要があります。解決後、許可されたバージョンのモジュールのみが残り、他のバージョンのモジュールは、同じ互換性レベルで最も近い上位の許可されたバージョンにアップグレードされます。同じ互換性で、それ以上のバージョンが許可されていない場合 レベルが存在する場合、Bazel はエラーをスローします。

たとえば、解決前に依存関係グラフにバージョン 1.11.31.51.72.0 が存在し、メジャー バージョンが互換性レベルの場合:

  • 1.31.72.0 を許可する複数バージョンのオーバーライドを使用すると、1.11.3 にアップグレードされ、1.51.7 にアップグレードされ、他のバージョンは同じままになります。
  • 1.52.0 を許可する複数バージョンのオーバーライドでは、1.7 にアップグレードする同じ互換性レベルのバージョンがないため、エラーが発生します。
  • 1.92.0 を許可する複数バージョンのオーバーライドでは、解決前に依存関係グラフに 1.9 が存在しないため、エラーが発生します。

また、単一バージョンのオーバーライドと同様に、registry 属性を使用してレジストリをオーバーライドすることもできます。

レジストリ以外のオーバーライド

レジストリ以外のオーバーライドは、バージョン解決からモジュールを完全に削除します。Bazel これらの MODULE.bazel ファイルをレジストリではなく、 できます。

Bazel は、次のレジストリ以外のオーバーライドをサポートしています。

Bazel モジュールを表さないリポジトリを定義する

bazel_dep を使用すると、他の Bazel モジュールを表すリポジトリを定義できます。 Bazel を表していないリポジトリを定義する必要がある場合があります module;たとえば、データとして読み取られるプレーン JSON ファイルを含むファイルなどです。

この場合、use_repo_rule ディレクティブを使用してリポジトリを直接 リポジトリのルールを呼び出します。このリポジトリは、定義されているモジュールにのみ表示されます。

内部的には、これは module Extensions を使用すると、より充実したリポジトリを定義できます。 柔軟性が必要です

リポジトリ名と厳密な依存関係

コンテナの背後にあるリポジトリの見かけ上の名前 その直接の依存先にあるモジュール名はデフォルトでそのモジュール名になります。ただし、 bazel_deprepo_name 属性 示されます。つまり、モジュールはダイレクト レスポンスの 確認します。これにより、伝播依存関係の変更による意図しない破損を防ぐことができます。

バックエンドをバックアップするリポジトリの正規名 モジュールは、module_name+versionbazel_skylib+1.0.3 など)または module_name+bazel_features+ など)のいずれかになります。 依存関係グラフ全体に配置された複数のバージョンのモジュールの multiple_version_override)。 正規名の形式は API ではなく、 は随時変更される場合があります。正規名をハードコードする代わりに サポートされている方法を使用して、Bazel から直接取得します。 * BUILD ファイルと .bzl ファイルでは、次のコマンドを使用します。 Label インスタンスに対する Label.repo_name リポジトリの名前(例: Label("@bazel_skylib").repo_name。 * runfile を検索する際は、 $(rlocationpath ...) または @bazel_tools//tools/{bash,cpp,java}/runfiles。ルールセット rules_foo の場合は、 (@rules_foo//foo/runfiles) * IDE や言語などの外部ツールから Bazel を操作する場合 bazel mod dump_repo_mapping コマンドを使用して、マッピングを取得します。 見かけ上、リポジトリ セットの正規名から変わっていきます。

モジュール拡張機能を使用すると、モジュールの公開スコープに追加のリポジトリを導入することもできます。