mod 命令

报告问题 查看源代码 每夜 build · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel 6.3.0 中引入的 mod 命令提供了一系列工具,可帮助用户在启用 Bzlmod 时了解其外部依赖项图。借助该工具,您可以直观地查看依赖项图、了解特定模块或模块版本出现在图中的原因、查看为模块提供支持的代码库定义、检查模块扩展程序的用法以及它们生成的代码库,等等。

语法

bazel mod <subcommand> [<options>] [<arg> [<arg>...]]

可用子命令及其各自的必需参数如下:

  • graph:显示项目的完整依赖项图,从根模块开始。如果在 --from 中指定了一个或多个模块,这些模块会直接显示在根目录下,并且图表仅从这些模块开始展开(请参阅示例)。

  • deps <arg>...:显示每个指定模块的已解析直接依赖项,与 graph 类似。

  • all_paths <arg>...:显示从根目录到指定 <arg>... 的所有现有路径。如果在 --from 中指定了一个或多个模块,这些模块会直接显示在根目录下,并且图表中包含从 --from 模块到实参模块的任何现有路径(请参阅示例)。

  • path <arg>...:与 all_paths 具有相同的语义,但仅显示从某个 --from 模块到某个实参模块的单个路径。

  • explain <arg>...:显示指定模块在依赖项图中出现的所有位置,以及直接依赖于它们的模块。explain 命令的输出本质上是 all_paths 命令的修剪版本,其中包含 1) 根模块;2) 根模块的直接依赖项(会导致参数模块);3) 参数模块的直接依赖项;以及 4) 参数模块本身(请参阅示例)。

  • show_repo <arg>...:显示指定代码库的定义(请参阅示例)。

  • show_extension <extension>...:显示每个指定扩展程序的相关信息:生成的代码库及其使用 use_repo 导入这些代码库的模块的列表,以及该扩展程序在其被使用的每个模块中的用法列表,其中包含指定的标记和 use_repo 调用(请参阅示例)。

<arg> 是指一个或多个模块或代码库。可以是以下选项之一:

  • 字面量字符串 <root>:表示当前项目的根模块。

  • <name>@<version>:版本为 <version> 的模块 <name>。对于具有非注册表替换项的模块,请使用下划线 (_) 作为 <version>

  • <name>:模块 <name> 的所有现有版本。

  • @<repo_name>:在 --base_module 上下文中具有给定外观名称的代码库。

  • @@<repo_name>:具有给定规范名称的代码库。

在需要指定模块的上下文中,还可以使用指向与模块对应的代码库(而不是扩展程序生成的代码库)的 <arg>。反之,在需要指定代码库的上下文中,引用模块的 <arg> 可以代替相应的代码库。

<extension> 必须采用 <arg><label_to_bzl_file>%<extension_name> 格式。<label_to_bzl_file> 部分必须是相对于代码库的标签(例如 //pkg/path:file.bzl)。

以下选项仅会影响用于输出图表的子命令(graphdepsall_pathspathexplain):

  • --from <arg>[,<arg>[,...]] 默认值:<root>:在 graphall_pathspathexplain 中,用于展开图表的模块。如需了解详情,请参阅子命令的说明。

  • --verbose 默认值:“false”:在输出图表中添加有关每个模块的版本解析的额外信息。如果模块版本在解析期间发生变化,请显示替换它的版本或原始版本、替换原因,以及如果原因为选择最小版本,则显示请求新版本的模块。

  • --include_unused 默认值:“false”:在输出图表中包含最初存在于依赖项图中,但在模块解析后未使用的模块。

  • --extension_info <mode>:在输出图表中包含有关模块扩展程序使用情况的信息(请参阅示例)。<mode> 可以是以下各项之一:

    • hidden (默认):不显示任何有关扩展程序的信息。

    • usages:在每个使用扩展程序的模块下显示扩展程序。它们以 $<extension> 的形式输出。

    • repos:除了 usages 之外,在每次扩展程序使用情况下方显示使用 use_repo 导入的代码库。

    • all:除了 usagesrepos 之外,还会显示未被任何模块导入的扩展程序生成的代码库。这些额外的代码库会显示在输出中生成扩展程序的首次出现位置下方,并用虚线连接。

  • --extension_filter <extension>[,<extension>[,...]]:如果指定,输出图表仅包含使用指定扩展程序的模块以及指向这些模块的路径。指定一个空的扩展程序列表(如 --extension_filter= 中所示)等同于指定依赖项图中任何模块使用的所有扩展程序。

  • --depth <N>:输出图表的深度。深度为 1 时,系统仅显示根目录及其直接依赖项。默认为 explain 为 1、deps 为 2,其他为无穷大。

  • --cycles 默认值:“false”:在输出图表中包含循环边。

  • --include_builtin 默认值:“false”:在输出图中包含内置模块(例如 @bazel_tools)。此标志默认处于停用状态,因为每个其他模块都隐式依赖于内置模块,这会极大地混乱输出。

  • --charset <charset> 默认值:utf8:指定要用于文本输出的字符集。有效值为 "utf8""ascii"。唯一的显著区别在于,用于以 "text" 输出格式绘制图表的特殊字符在 "ascii" 字符集中不存在。因此,"ascii" 字符集也支持在无法使用 Unicode 的旧版平台上使用。

  • --output <mode>:在输出图表中添加有关模块扩展用法的信息。<mode> 可以是以下各项之一:

    • text(默认):输出图的直观易懂的表示法(展开为树)。

    • json:以 JSON 对象的形式输出图表(展开为树)。

    • graph:以 Graphviz dot 表示法输出图表。

    bazel mod graph --output graph | dot -Tsvg > /tmp/graph.svg
    

其他选项包括:

  • --base_module <arg> 默认值:<root>:指定一个模块,系统会根据该模块来解读参数中的显式代码库名称。请注意,此参数本身可以采用 @<repo_name> 的形式;此参数始终相对于根模块进行解读。

  • --extension_usages <arg>[,<arg>[,...]]:过滤 show_extension,以仅显示指定模块中的扩展程序用法。

示例

下面展示了在真实 Bazel 项目中使用 mod 命令的一些可能用法,以便您大致了解如何使用该命令检查项目的外部依赖项。

MODULE.bazel 文件:

module(
  name = "my_project",
  version = "1.0",
)

bazel_dep(name = "bazel_skylib", version = "1.1.1", repo_name = "skylib1")
bazel_dep(name = "bazel_skylib", version = "1.2.0", repo_name = "skylib2")
multiple_version_override(module_name = "bazel_skylib", versions = ["1.1.1", "1.2.0"])

bazel_dep(name = "stardoc", version = "0.5.0")
bazel_dep(name = "rules_java", version = "5.0.0")

toolchains = use_extension("@rules_java//java:extensions.bzl", "toolchains")
use_repo(toolchains, my_jdk="remotejdk17_linux")
解决之前的图表
解决问题之前的图表
解决问题后的图表
解决问题后的图表
  1. 显示项目的整个依赖关系图。

    bazel mod graph
    
    <root> (my_project@1.0)
    ├───bazel_skylib@1.1.1
    │   └───platforms@0.0.4
    ├───bazel_skylib@1.2.0
    │   └───platforms@0.0.4 ...
    ├───rules_java@5.0.0
    │   ├───platforms@0.0.4 ...
    │   ├───rules_cc@0.0.1
    │   │   ├───bazel_skylib@1.1.1 ...
    │   │   └───platforms@0.0.4 ...
    │   └───rules_proto@4.0.0
    │       ├───bazel_skylib@1.1.1 ...
    │       └───rules_cc@0.0.1 ...
    └───stardoc@0.5.0
        ├───bazel_skylib@1.1.1 ...
        └───rules_java@5.0.0 ...
    
  2. 显示整个依赖项图(包括未使用的模块以及有关版本解析的额外信息)。

    bazel mod graph --include_unused --verbose
    
    <root> (my_project@1.0)
    ├───bazel_skylib@1.1.1
    │   └───platforms@0.0.4
    ├───bazel_skylib@1.2.0
    │   └───platforms@0.0.4 ...
    ├───rules_java@5.0.0
    │   ├───platforms@0.0.4 ...
    │   ├───rules_cc@0.0.1
    │   │   ├───bazel_skylib@1.0.3 ... (to 1.1.1, cause multiple_version_override)
    │   │   ├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
    │   │   └───platforms@0.0.4 ...
    │   └───rules_proto@4.0.0
    │       ├───bazel_skylib@1.0.3 ... (to 1.1.1, cause multiple_version_override)
    │       ├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
    │       └───rules_cc@0.0.1 ...
    └───stardoc@0.5.0
        ├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
        ├───rules_java@5.0.0 ... (was 4.0.0, cause <root>, bazel_tools@_)
        ├───bazel_skylib@1.0.3 (to 1.1.1, cause multiple_version_override)
        │   └───platforms@0.0.4 ...
        └───rules_java@4.0.0 (to 5.0.0, cause <root>, bazel_tools@_)
            ├───bazel_skylib@1.0.3 ... (to 1.1.1, cause multiple_version_override)
            └───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
    
  3. 显示从某些特定模块展开的依赖关系图。

    bazel mod graph --from rules_java --include_unused
    
    <root> (my_project@1.0)
    ├───rules_java@5.0.0
    │   ├───platforms@0.0.4
    │   ├───rules_cc@0.0.1
    │   │   ├───bazel_skylib@1.0.3 ... (unused)
    │   │   ├───bazel_skylib@1.1.1 ...
    │   │   └───platforms@0.0.4 ...
    │   └───rules_proto@4.0.0
    │       ├───bazel_skylib@1.0.3 ... (unused)
    │       ├───bazel_skylib@1.1.1 ...
    │       └───rules_cc@0.0.1 ...
    └╌╌rules_java@4.0.0 (unused)
        ├───bazel_skylib@1.0.3 (unused)
        │   └───platforms@0.0.4 ...
        └───bazel_skylib@1.1.1
            └───platforms@0.0.4 ...
    
  4. 显示两个模块之间的所有路径。

    bazel mod all_paths bazel_skylib@1.1.1 --from rules_proto
    
    <root> (my_project@1.0)
    └╌╌rules_proto@4.0.0
        ├───bazel_skylib@1.1.1
        └───rules_cc@0.0.1
            └───bazel_skylib@1.1.1 ...
    
  5. 了解项目依赖于某些模块的原因和方式。

    bazel mod explain @skylib1 --verbose --include_unused
    
    <root> (my_project@1.0)
    ├───bazel_skylib@1.1.1
    ├───rules_java@5.0.0
    │   ├───rules_cc@0.0.1
    │   │   └───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
    │   └───rules_proto@4.0.0
    │       ├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
    │       └───rules_cc@0.0.1 ...
    └───stardoc@0.5.0
        ├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
        ├╌╌rules_cc@0.0.1
        │   └───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
        └╌╌rules_proto@4.0.0
            ├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
            └───rules_cc@0.0.1 ...
    
  6. 查看某些模块代码库的底层规则。

    bazel mod show_repo rules_cc stardoc
    
    ## rules_cc@0.0.1:
    # <builtin>
    http_archive(
      name = "rules_cc+",
      urls = ["https://bcr.bazel.build/test-mirror/github.com/bazelbuild/rules_cc/releases/download/0.0.1/rules_cc-0.0.1.tar.gz", "https://github.com/bazelbuild/rules_cc/releases/download/0.0.1/rules_cc-0.0.1.tar.gz"],
      integrity = "sha256-Tcy/0iwN7xZMj0dFi9UODHFI89kgAs20WcKpamhJgkE=",
      strip_prefix = "",
      remote_patches = {"https://bcr.bazel.build/modules/rules_cc/0.0.1/patches/add_module_extension.patch": "sha256-g3+zmGs0YT2HKOVevZpN0Jet89Ylw90Cp9XsIAY8QqU="},
      remote_patch_strip = 1,
    )
    # Rule http_archive defined at (most recent call last):
    #   /home/user/.cache/bazel/_bazel_user/6e893e0f5a92cc4cf5909a6e4b2770f9/external/bazel_tools/tools/build_defs/repo/http.bzl:355:31 in <toplevel>
    
    ## stardoc:
    # <builtin>
    http_archive(
      name = "stardoc+",
      urls = ["https://bcr.bazel.build/test-mirror/github.com/bazelbuild/stardoc/releases/download/0.5.0/stardoc-0.5.0.tar.gz", "https://github.com/bazelbuild/stardoc/releases/download/0.5.0/stardoc-0.5.0.tar.gz"],
      integrity = "sha256-yXlNzIAmow/2fPfPkeviRcopSyCwcYRdEsGSr+JDrXI=",
      strip_prefix = "",
      remote_patches = {},
      remote_patch_strip = 0,
    )
    # Rule http_archive defined at (most recent call last):
    #   /home/user/.cache/bazel/_bazel_user/6e893e0f5a92cc4cf5909a6e4b2770f9/external/bazel_tools/tools/build_defs/repo/http.bzl:355:31 in <toplevel>
    
  7. 查看依赖项图中使用的模块扩展程序。

    bazel mod graph --extension_info=usages --extension_filter=all
    
    <root> (my_project@1.0)
    ├───$@@rules_java.5.0.0//java:extensions.bzl%toolchains
    ├───rules_java@5.0.0 #
    │   ├───$@@rules_java.5.0.0//java:extensions.bzl%toolchains
    │   ├───rules_cc@0.0.1 #
    │   │   └───$@@rules_cc.0.0.1//bzlmod:extensions.bzl%cc_configure
    │   └───rules_proto@4.0.0
    │       └───rules_cc@0.0.1 ...
    └───stardoc@0.5.0
        └───rules_java@5.0.0 ...
    
  8. 查看依赖项图中生成并从某个特定扩展程序导入的代码库。

    bazel mod show_extension @@rules_java+5.0.0//java:extensions.bzl%toolchains
    
    <root> (my_project@1.0)
    ├───$@@rules_java.5.0.0//java:extensions.bzl%toolchains
    │   ├───remotejdk17_linux
    │   ├╌╌remotejdk11_linux
    │   ├╌╌remotejdk11_linux_aarch64
    │   ├╌╌remotejdk11_linux_ppc64le
    │   ├╌╌remotejdk11_linux_s390x
    ...(some lines omitted)...
    ├───rules_java@5.0.0 #
    │   └───$@@rules_java.5.0.0//java:extensions.bzl%toolchains ...
    │       ├───local_jdk
    │       ├───remote_java_tools
    │       ├───remote_java_tools_darwin
    │       ├───remote_java_tools_linux
    │       ├───remote_java_tools_windows
    │       ├───remotejdk11_linux_aarch64_toolchain_config_repo
    │       ├───remotejdk11_linux_ppc64le_toolchain_config_repo
    ...(some lines omitted)...
    └───stardoc@0.5.0
        └───rules_java@5.0.0 ...
    
  9. 查看扩展程序生成的代码库列表,以及该扩展程序在每个模块中的使用方式。

    bazel mod graph --extension_info=all --extension_filter=@rules_java//java:extensions.bzl%toolchains
    
    ## @@rules_java.5.0.0//java:extensions.bzl%toolchains:
    
    Fetched repositories:
      -   local_jdk (imported by bazel_tools@_, rules_java@5.0.0)
      -   remote_java_tools (imported by bazel_tools@_, rules_java@5.0.0)
      -   remote_java_tools_darwin (imported by bazel_tools@_, rules_java@5.0.0)
      -   remote_java_tools_linux (imported by bazel_tools@_, rules_java@5.0.0)
      -   remote_java_tools_windows (imported by bazel_tools@_, rules_java@5.0.0)
      -   remotejdk11_linux_aarch64_toolchain_config_repo (imported by rules_java@5.0.0)
      -   remotejdk11_linux_ppc64le_toolchain_config_repo (imported by rules_java@5.0.0)
    ...(some lines omitted)...
      -   remotejdk17_linux (imported by <root>)
      -   remotejdk11_linux
      -   remotejdk11_linux_aarch64
      -   remotejdk11_linux_ppc64le
      -   remotejdk11_linux_s390x
      -   remotejdk11_macos
    ...(some lines omitted)...
    
    # Usage in <root> at <root>/MODULE.bazel:14:27 with the specified attributes:
    use_repo(
      toolchains,
      my_jdk="remotejdk17_linux",
    )
    
    # Usage in bazel_tools@_ at bazel_tools@_/MODULE.bazel:23:32 with the specified attributes:
    use_repo(
      toolchains,
      "local_jdk",
      "remote_java_tools",
      "remote_java_tools_linux",
      "remote_java_tools_windows",
      "remote_java_tools_darwin",
    )
    
    # Usage in rules_java@5.0.0 at rules_java@5.0.0/MODULE.bazel:30:27 with the specified attributes:
    use_repo(
      toolchains,
      "remote_java_tools",
      "remote_java_tools_linux",
      "remote_java_tools_windows",
      "remote_java_tools_darwin",
      "local_jdk",
      "remotejdk11_linux_toolchain_config_repo",
      "remotejdk11_macos_toolchain_config_repo",
      "remotejdk11_macos_aarch64_toolchain_config_repo",
      ...(some lines omitted)...
    )
    
  10. 查看某些扩展程序生成的代码库的底层规则。

    bazel mod show_repo --base_module=rules_java @remote_java_tools
    
    ## @remote_java_tools:
    # <builtin>
    http_archive(
      name = "rules_java++toolchains+remote_java_tools",
      urls = ["https://mirror.bazel.build/bazel_java_tools/releases/java/v11.5/java_tools-v11.5.zip", "https://github.com/bazelbuild/java_tools/releases/download/java_v11.5/java_tools-v11.5.zip"],
      sha256 = "b763ee80e5754e593fd6d5be6d7343f905bc8b73d661d36d842b024ca11b6793",
    )
    # Rule http_archive defined at (most recent call last):
    #   /home/user/.cache/bazel/_bazel_user/6e893e0f5a92cc4cf5909a6e4b2770f9/external/bazel_tools/tools/build_defs/repo/http.bzl:355:31 in <toplevel>