モジュール拡張機能

<ph type="x-smartling-placeholder"></ph> 問題を報告する <ph type="x-smartling-placeholder"></ph> ソースを表示 夜間 · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

モジュール拡張機能により、ユーザーは入力データを読み取ってモジュール システムを拡張できる 解決に必要なロジックを実行して、依存関係グラフ全体の 最後に、Repo ルールを呼び出してリポジトリを作成します。これらの拡張機能 Repo ルールに似た機能があり、ファイルの I/O の実行、 ネットワーク リクエストの送信などです。特に、Bazel は以下を可能にしています。 他のパッケージ管理システムと相互作用します。また、パッケージ管理システムの Bazel モジュールから構築された依存関係グラフ。

リポジトリ ルールと同様に、.bzl ファイルでモジュール拡張機能を定義できます。それらは 直接呼び出されることはありません。各モジュールで「タグ」と呼ばれるデータを指定します。 読み取りますBazel は、何かを評価する前にモジュールの解決を実行 できます。この拡張機能は、拡張機能に属しているすべてのタグを読み取り、 依存関係グラフを作成します。

拡張機能の使用状況

拡張機能は、Bazel モジュール自体でホストされます。拡張機能を使用するには、 まず、拡張機能をホストするモジュールに bazel_dep を追加してから、 use_extension 組み込み関数を呼び出す スコープに入ります次の例をご覧ください。 MODULE.bazel ファイルを使用して「maven」を使用します。拡張子が rules_jvm_external 説明します。

bazel_dep(name = "rules_jvm_external", version = "4.5")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

これにより、use_extension の戻り値が変数にバインドされ、 ユーザーは、ドット構文を使用して拡張機能のタグを指定するように指示できます。タグは 対応するタグクラスで定義されたスキーマ 拡張機能の定義をご覧ください。たとえば、一部の Pod を maven.install タグと maven.artifact タグ:

maven.install(artifacts = ["org.junit:junit:4.13.2"])
maven.artifact(group = "com.google.guava",
               artifact = "guava",
               version = "27.0-jre",
               exclusions = ["com.google.j2objc:j2objc-annotations"])

use_repo ディレクティブを使用してリポジトリを導入する 現在のモジュールのスコープに拡張します。

use_repo(maven, "maven")

拡張機能によって生成されたリポジトリは、拡張機能の API の一部です。この例では、 「maven」モジュール拡張機能により、maven というリポジトリが生成されることが約束されます。 宣言を使用すると、拡張機能は 「maven」によって生成されたリポジトリを指す @maven//:org_junit_junit あります。

広告表示オプションの定義

モジュール拡張機能をリポジトリ ルールと同様に定義するには、 module_extension 関数。ただし、 Repo ルールには多くの属性がありますが、モジュール拡張機能には、 tag_class。各オブジェクトには複数の 属性です。タグクラスは、この拡張機能で使用されるタグのスキーマを定義します。対象 たとえば「maven」上記の拡張子は次のように定義できます。

# @rules_jvm_external//:extensions.bzl

_install = tag_class(attrs = {"artifacts": attr.string_list(), ...})
_artifact = tag_class(attrs = {"group": attr.string(), "artifact": attr.string(), ...})
maven = module_extension(
  implementation = _maven_impl,
  tag_classes = {"install": _install, "artifact": _artifact},
)

これらの宣言は、maven.install タグと maven.artifact タグに 指定した属性スキーマを使用して指定します。

モジュール拡張機能の実装関数はリポジトリと同様 module_ctx オブジェクトを取得する点が異なります。 拡張機能とすべての関連するタグを使用するすべてのモジュールへのアクセスを許可します。 次に、実装関数はリポジトリ ルールを呼び出してリポジトリを生成します。

# @rules_jvm_external//:extensions.bzl

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")  # a repo rule
def _maven_impl(ctx):
  # This is a fake implementation for demonstration purposes only

  # collect artifacts from across the dependency graph
  artifacts = []
  for mod in ctx.modules:
    for install in mod.tags.install:
      artifacts += install.artifacts
    artifacts += [_to_artifact(artifact) for artifact in mod.tags.artifact]

  # call out to the coursier CLI tool to resolve dependencies
  output = ctx.execute(["coursier", "resolve", artifacts])
  repo_attrs = _process_coursier_output(output)

  # call repo rules to generate repos
  for attrs in repo_attrs:
    http_file(**attrs)
  _generate_hub_repo(name = "maven", repo_attrs)

拡張機能の ID

モジュールの拡張機能は、名前と、表示される .bzl ファイルで識別できます。 use_extension への呼び出しで。次の例では、拡張機能 maven は、 .bzl ファイル @rules_jvm_external//:extension.bzl と name maven:

maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

別の .bzl ファイルから拡張機能を再エクスポートすると、新しい ID が付与される 推移的モジュール グラフで両方のバージョンの拡張機能が使用されている場合は、 個別に評価され 関連付けられています

拡張機能の作成では、ユーザーが拡張機能の 1 つの .bzl ファイルから拡張できます。

リポジトリ名と公開設定

拡張機能によって生成されたリポジトリには、module_repo_canonical_name+extension_name+repo_name 形式の正規名が付けられます。なお 正規名は は、依存すべき API ではなく、いつでも変更される可能性があります。

この命名ポリシーにより、各拡張機能には独自の「リポジトリ名前空間」があります。2 異なる拡張機能ごとに、同じ名前でリポジトリを定義できる 防ぐことができます。また、repository_ctx.name は正規名をレポートします。 リポジトリの名前。これは、Repo ルールで指定された名前とは異なります あります。

モジュール拡張機能によって生成されたリポジトリを考慮すると、 いくつかのリポジトリの公開設定ルールがあります。

  • Bazel モジュール リポジトリでは、MODULE.bazel ファイルに導入されたすべてのリポジトリを確認できます。 bazel_dep 経由、および use_repo
  • モジュール拡張機能によって生成されたリポジトリは、 拡張機能をホストするモジュールと、拡張機能によって生成された 同じモジュール拡張(リポジトリ ルール呼び出しで指定された名前を使用) 明らかな名前)。
    • 競合が発生する可能性があります。モジュールのリポジトリで、 名前が foo になり、拡張機能によってリポジトリが生成されます。 指定された名前 foo、その拡張機能によって生成されたすべてのリポジトリ foo は前者を指します。

ベスト プラクティス

このセクションでは、拡張機能の記述に関するベスト プラクティスについて説明します。 使いやすくメンテナンスしやすく、時間の経過に伴う変更にうまく適応できる必要があります。

各拡張機能を個別のファイルに配置する

拡張機能が別のファイルにある場合、1 つの拡張機能を読み込むことができる 他の拡張機能によって生成されたリポジトリに 保存されたデータなどですこれを使用せずに 必要に応じて別のファイルに保存することをおすすめします。 後で説明しますこれは、拡張機能の識別がファイルに基づいて行われるため、 拡張子を別のファイルに追加すると、後で公開 API が変更されるため、 適用することもできます。

再現性を指定する

拡張機能で常に同じ入力を指定して同じリポジトリを定義する場合 (拡張機能タグ、読み取るファイルなど)であり、特に 保護されていないダウンロード チェックサムを返す場合は、 extension_metadatareproducible = True。これにより、Bazel は以下を書き込むときにこの拡張機能をスキップできます。 表示されます。

オペレーティング システムとアーキテクチャを指定する

拡張機能がオペレーティング システムまたはそのアーキテクチャ タイプに依存している場合は、 拡張機能の定義で、os_dependent arch_dependent ブール値属性です。これにより、Bazel はエラーを 再評価の必要性が生じます

このようなホストへの依存は、システムのメンテナンスが ロックファイルのエントリがない場合は、 可能であれば、拡張機能を再現可能としてマークします。

リポジトリ名に直接影響するのはルート モジュールのみ

拡張機能がリポジトリを作成すると、リポジトリは 拡張機能の名前空間です。つまり、異なる 1 つのサーバー間で 各モジュールが同じ拡張機能を使用し、最終的に同じ 表示されます。これは多くの場合、name を持つモジュール拡張機能の tag_class として現れます。 リポジトリ ルールの name 値として渡される引数。

たとえば、ルート モジュール A がモジュール B に依存しているとします。両方のモジュール モジュール mylang に依存します。AB の両方が呼び出した場合 mylang.toolchain(name="foo") の場合、どちらも名前のリポジトリを作成しようとします。 mylang モジュール内で foo を返すと、エラーが発生します。

これを回避するには、リポジトリ名を直接設定する機能を削除します。 または、ルート モジュールのみを許可するように指定できます。ルート モジュールに許可しても構わないが、 リソースへの依存がないため 競合する名前になっている場合があります。