| keywords: bzlmod |
| |
| {# disableFinding(LINE_OVER_80_LINK) #} |
| {# disableFinding(SNIPPET_NO_LANG) #} |
| {# disableFinding(LINK_MISSING_ID) #} |
| {# disableFinding("repo") #} |
| |
| --- |
| title: 'Bzlmod Migration Tool' |
| --- |
| |
| [migration_script]: https://github.com/bazelbuild/bazel-central-registry/blob/main/tools/migrate_to_bzlmod.py |
| [gemini_cli_setup]: https://github.com/bazelbuild/bazel-central-registry/tree/main/tools/code-agent |
| |
| To simplify the often complex process of moving from `WORKSPACE` to Bzlmod, it's |
| highly recommended to use the [migration script][migration_script]. This helper |
| tool automates many of the steps involved in migrating your external dependency |
| management system. |
| |
| **Note**: If you want to try out the AI driven Bzlmod migration, check [Bzlmod Migration Agent Setup][gemini_cli_setup]. |
| |
| ## Core Functionality {:#migration-tool-core-functionality} |
| |
| The script's primary functions are: |
| |
| * **Collecting dependency information:** Analyzing your project's `WORKSPACE` |
| file to identify external repositories used by specified build targets, |
| using Bazel's |
| [experimental_repository_resolved_file](https://bazel.build/versions/8.2.0/reference/command-line-reference#flag--experimental_repository_resolved_file) |
| flag to generate a resolved dependencies file containing this information. |
| * **Identifying direct dependencies:** Using `bazel query` to determine which |
| repositories are direct dependencies for the specified targets. |
| * **Migrating to Bzlmod:** Translating relevant `WORKSPACE` dependencies into |
| their Bzlmod equivalents. This is a two-step process: |
| 1. Introduce all identified direct dependencies to the |
| `MODULE.bazel` file. |
| 2. Build specified targets with Bzlmod enabled, then |
| iteratively identify and fix recognizable errors. This step is |
| needed since some dependencies might be missing in the first step. |
| * **Generating a migration report:** Creating a `migration_info.md` file that |
| documents the migration process. This report includes a list of direct |
| dependencies, the generated Bzlmod declarations, and any manual steps that |
| may be required to complete the migration. |
| |
| The migration tool supports: |
| |
| * Dependencies available in the Bazel Central Registry |
| * User-defined custom repository rules |
| * Package manager dependencies |
| * Maven |
| * Go |
| * Python |
| |
| **Important Notes**: |
| |
| * The migration tool is a best-effort utility. Always double-check its |
| recommendations for correctness. |
| * Use the migration tool with Bazel 7 (not supported with Bazel 8). |
| |
| ## How to Use the Migration Tool {:#migration-tool-how-to-use} |
| |
| Before you begin: |
| |
| * Upgrade to the latest Bazel 7 release, which provides robust support for |
| both WORKSPACE and Bzlmod. |
| * Verify the following command runs successfully for your project's main build |
| targets: |
| |
| ```shell |
| bazel build --nobuild --enable_workspace --noenable_bzlmod <targets> |
| ``` |
| |
| ### Command for running the script {:#migration-script-command} |
| |
| Once the prerequisites are met, run the following commands to use the migration |
| tool: |
| |
| <pre class="prettyprint lang-shell" style="font-size: 12px;"> |
| # Clone the Bazel Central Registry repository |
| git clone https://github.com/bazelbuild/bazel-central-registry.git |
| cd bazel-central-registry |
| |
| # Build the migration tool |
| bazel build //tools:migrate_to_bzlmod |
| |
| # Create a convenient alias for the tool |
| alias migrate2bzlmod=$(realpath ./bazel-bin/tools/migrate_to_bzlmod) |
| |
| # Navigate to your project's root directory and run the tool |
| cd <your project root> |
| migrate2bzlmod -t <targets> |
| </pre> |
| |
| ### Files generated by this script {:#migration-script-files} |
| |
| * `MODULE.bazel` - The central manifest file for Bzlmod, which declares the |
| project's metadata and its direct dependencies on other Bazel modules. |
| * `migration_info.md` - A file providing step-by-step instructions on how the |
| migration tool was executed, designed to assist in the manual completion of |
| the migration process, if necessary. |
| * `resolved_deps.py` - Contains a comprehensive list of the project's external |
| dependencies, generated by analyzing the project's `WORKSPACE` file, serving |
| as a reference during the transition. |
| * `query_direct_deps` - Contains migration-relevant information regarding the |
| utilized targets, obtained by invoking Bazel with `--output=build` on the |
| project's `WORKSPACE` file. This file is primarily consumed by the migration |
| script. |
| * `extension_for_XXX` - A file containing a module extension |
| definition. The migration tool generates these files for dependencies that |
| are not standard Bazel modules but can be managed using Bzlmod's [module |
| extensions](/external/extension). |
| |
| ### Flags {:#migration-script-flags} |
| |
| Flags available in this migration scripts are: |
| |
| * `--t`/`--target`: Targets to migrate. This flag is repeatable, and the |
| targets are accumulated. |
| * `--i`/`--initial`: Deletes `MODULE.bazel`, `resolved_deps.py`, |
| `migration_info.md` files and starts from scratch - Detect direct |
| dependencies, introduce them in MODULE.bazel and rerun generation of |
| resolved dependencies. |
| |
| ### Post-migration cleanup {:#post-migration-cleanup} |
| |
| * Delete `migration_info.md`, `resolved_deps.py` and `query_direct_deps`. |
| * Clean up comments from `MODULE.bazel` file which were used for the |
| migration, such as `# -- bazel_dep definitions -- #`. |
| |
| ## Migration Example {:#migration-tool-example} |
| |
| To see the migration script in action, consider the following scenario when |
| Python, Maven and Go dependencies are declared in `WORKSPACE` file. |
| |
| <details> |
| <summary style="padding: 16px"> |
| Click here to see `WORKSPACE` file |
| </summary> |
| |
| ```python |
| workspace(name="example") |
| |
| load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") |
| load(":my_custom_macro.bzl", "my_custom_macro") |
| |
| http_archive( |
| name = "rules_cc", |
| sha256 = "b8b918a85f9144c01f6cfe0f45e4f2838c7413961a8ff23bc0c6cdf8bb07a3b6", |
| strip_prefix = "rules_cc-0.1.5", |
| urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.1.5/rules_cc-0.1.5.tar.gz"], |
| ) |
| |
| # Module dependency |
| # ------------------- |
| http_archive( |
| name = "rules_shell", |
| sha256 = "3e114424a5c7e4fd43e0133cc6ecdfe54e45ae8affa14fadd839f29901424043", |
| strip_prefix = "rules_shell-0.4.0", |
| url = "https://github.com/bazelbuild/rules_shell/releases/download/v0.4.0/rules_shell-v0.4.0.tar.gz", |
| ) |
| |
| # Repo rule |
| # ------------------- |
| http_archive( |
| name = "com_github_cockroachdb_cockroach", |
| sha256 = "6c3568ef244ce6b874694eeeecb83ed4f5d5dff6cf037c952ecde76828a6c502", |
| strip_prefix = "cockroach-22.1.6", |
| url = "https://github.com/cockroachdb/cockroach/archive/v22.1.6.tar.gz", |
| ) |
| |
| # Module extension |
| # ------------------- |
| # Macro which invokes repository_rule |
| my_custom_macro( |
| name = "my_custom_repo", |
| ) |
| |
| # Go dependencies |
| # ------------------- |
| http_archive( |
| name = "io_bazel_rules_go", |
| integrity = "sha256-M6zErg9wUC20uJPJ/B3Xqb+ZjCPn/yxFF3QdQEmpdvg=", |
| urls = [ |
| "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.48.0/rules_go-v0.48.0.zip", |
| "https://github.com/bazelbuild/rules_go/releases/download/v0.48.0/rules_go-v0.48.0.zip", |
| ], |
| ) |
| |
| http_archive( |
| name = "bazel_gazelle", |
| integrity = "sha256-12v3pg/YsFBEQJDfooN6Tq+YKeEWVhjuNdzspcvfWNU=", |
| urls = [ |
| "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz", |
| "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz", |
| ], |
| ) |
| |
| load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") |
| load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository") |
| |
| go_rules_dependencies() |
| go_register_toolchains(version = "1.23.1") |
| gazelle_dependencies() |
| |
| go_repository( |
| name = "org_golang_x_net", |
| importpath = "golang.org/x/net", |
| sum = "h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=", |
| version = "v0.0.0-20190311183353-d8887717615a", |
| build_file_proto_mode = "disable", |
| build_naming_convention = "import", |
| ) |
| |
| # Python dependencies |
| # ------------------- |
| http_archive( |
| name = "rules_python", |
| integrity = "sha256-qDdnnxOC8mlowe5vg5x9r5B5qlMSgGmh8oFd7KpjcwQ=", |
| strip_prefix = "rules_python-1.4.0", |
| url = "https://github.com/bazelbuild/rules_python/releases/download/1.4.0/rules_python-1.4.0.tar.gz", |
| ) |
| |
| load("@rules_python//python:repositories.bzl", "py_repositories") |
| py_repositories() |
| |
| load("@rules_python//python:pip.bzl", "pip_parse") |
| pip_parse( |
| name = "my_python_deps", |
| requirements_lock = "@example//:requirements_lock.txt", |
| ) |
| |
| load("@my_python_deps//:requirements.bzl", "install_deps") |
| install_deps() |
| |
| load("@rules_python//python:repositories.bzl", "python_register_toolchains") |
| python_register_toolchains( |
| name = "python_3_11", |
| python_version = "3.11", |
| ) |
| |
| # Maven dependencies |
| # __________________ |
| |
| RULES_JVM_EXTERNAL_TAG = "4.5" |
| RULES_JVM_EXTERNAL_SHA = "b17d7388feb9bfa7f2fa09031b32707df529f26c91ab9e5d909eb1676badd9a6" |
| |
| http_archive( |
| name = "rules_jvm_external", |
| strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG, |
| sha256 = RULES_JVM_EXTERNAL_SHA, |
| url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG, |
| ) |
| |
| load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps") |
| rules_jvm_external_deps() |
| load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup") |
| rules_jvm_external_setup() |
| |
| load("@rules_jvm_external//:defs.bzl", "maven_install") |
| maven_install( |
| name = "px_deps", |
| artifacts = [ |
| "org.antlr:antlr4:4.11.1", |
| ], |
| repositories = [ |
| "https://repo1.maven.org/maven2", |
| ], |
| ) |
| ``` |
| </details> |
| |
| Moreover, to demonstrate usage of module extension, custom macro is invoked from |
| `WORKSPACE` and it is defined in `my_custom_macro.bzl`. |
| |
| <details> |
| <summary style="padding: 16px"> |
| Click here to see `my_custom_macro.bzl` file |
| </summary> |
| |
| ```python |
| """Repo rule and macro used for testing""" |
| |
| def _test_repo_rule_impl(repository_ctx): |
| repository_ctx.file( |
| "BUILD", |
| content = """ |
| genrule( |
| name = "foo", |
| outs = ["rule_name.out"], |
| cmd = "touch $@", |
| visibility = ["//visibility:public"], |
| ) |
| """ |
| ) |
| |
| _test_repo_rule = repository_rule( |
| implementation = _test_repo_rule_impl, |
| ) |
| |
| def my_custom_macro(name): |
| _test_repo_rule(name = name) |
| ``` |
| </details> |
| |
| The end goal is to have `MODULE.bazel` file and delete the `WORKSPACE` file, |
| without impacting the user experience. |
| |
| The first step is to follow [How to Use the Migration |
| Tool](#migration-tool-how-to-use), which mostly is checking the bazel version |
| (it must be Bazel 7) and adding an alias to the migration script. |
| |
| Then, running `migrate2bzlmod -t=//...` outputs: |
| |
| <pre style="font-size: 12px;"> |
| bazel 7.6.1 |
| |
| Generating ./resolved_deps.py file - It might take a while... |
| |
| <span style="color:green;">RESOLVED:</span> <code>rules_java</code> has been introduced as a Bazel module. |
| <span style="color:green;">RESOLVED:</span> <code>bazel_gazelle</code> has been introduced as a Bazel module. |
| <span style="color:green;">RESOLVED:</span> <code>io_bazel_rules_go</code> has been introduced as a Bazel module. |
| <span style="color:green;">RESOLVED:</span> <code>rules_python</code> has been introduced as a Bazel module. |
| <span style="color:orange;">IMPORTANT:</span> 3.11 is used as a default python version. If you need a different version, please change it manually and then rerun the migration tool. |
| <span style="color:green;">RESOLVED:</span> <code>my_python_deps</code> has been introduced as python extension. |
| <span style="color:green;">RESOLVED:</span> <code>org_golang_x_net</code> has been introduced as go extension. |
| <span style="color:green;">RESOLVED:</span> <code>rules_jvm_external</code> has been introduced as a Bazel module. |
| <span style="color:green;">RESOLVED:</span> <code>org.antlr</code> has been introduced as maven extension. |
| <span style="color:green;">RESOLVED:</span> <code>rules_shell</code> has been introduced as a Bazel module. |
| |
| Congratulations! All external repositories needed for building //... are available with Bzlmod! |
| <span style="color:orange;">IMPORTANT:</span> Fix potential build time issues by running the following command: |
| <span style="font-weight: 700;">bazel build --enable_bzlmod --noenable_workspace //...</span> |
| |
| <span style="color:orange;">IMPORTANT:</span> <code>For details about the migration process, check `migration_info.md` file.</code> |
| </pre> |
| |
| which gives the following important information: |
| |
| * Generates `./resolved_deps.py` file, which contains info about all external |
| repositories declared and loaded using your `WORKSPACE` file. |
| * `RESOLVED` keyword describes all dependencies which are resolved by the tool |
| and added to the `MODULE.bazel` file. |
| * `IMPORTANT` keyword describes significant information worth investing time. |
| * All dependencies have been resolved in this example, at least with |
| `--nobuild` flag. |
| * It is important to run the full build (command specified) and manually fix |
| potential errors (e.g. toolchain not registered correctly). |
| * `migration_info.md` file contains details about the migration. Check details |
| [at this section](#migration-tool-report-generation). |
| |
| ### Transformations {:#migration-tool-transformations} |
| |
| This section illustrates the migration of code from the `WORKSPACE` file to |
| `MODULE.bazel`. |
| |
| <div style="display: flex; flex-wrap: wrap; gap: 16px;"> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>WORKSPACE - Bazel Module</strong></p> |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| http_archive( |
| name = "rules_shell", |
| sha256 = "3e114424a5c7e4fd43e0133cc6ecdfe54e45ae8affa14fadd839f29901424043", |
| strip_prefix = "rules_shell-0.4.0", |
| url = "https://github.com/bazelbuild/rules_shell/releases/download/v0.4.0/rules_shell-v0.4.0.tar.gz", |
| ) |
| </pre> |
| </div> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>MODULE.bazel - Bazel Module</strong></p> |
| <pre class="prettyprint lang-py" style="font-size: 12px;"> |
| bazel_dep(name = "rules_shell", version = "0.6.1") |
| </pre> |
| </div> |
| </div> |
| |
| <hr style="height: 1px; background-color: black; border: none;"> |
| |
| <div style="display: flex; flex-wrap: wrap; gap: 16px;"> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>WORKSPACE - Go Extension</strong></p> |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| http_archive( |
| name = "io_bazel_rules_go", |
| integrity = "sha256-M6zErg9wUC20uJPJ/B3Xqb+ZjCPn/yxFF3QdQEmpdvg=", |
| urls = [ |
| "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.48.0/rules_go-v0.48.0.zip", |
| "https://github.com/bazelbuild/rules_go/releases/download/v0.48.0/rules_go-v0.48.0.zip", |
| ], |
| ) |
| http_archive( |
| name = "bazel_gazelle", |
| integrity = "sha256-12v3pg/YsFBEQJDfooN6Tq+YKeEWVhjuNdzspcvfWNU=", |
| urls = [ |
| "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz", |
| "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz", |
| ], |
| ) |
| |
| load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") |
| load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository") |
| |
| go_rules_dependencies() |
| go_register_toolchains(version = "1.23.1") |
| gazelle_dependencies() |
| |
| go_repository( |
| name = "org_golang_x_net", |
| importpath = "golang.org/x/net", |
| sum = "h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=", |
| version = "v0.0.0-20190311183353-d8887717615a", |
| build_file_proto_mode = "disable", |
| build_naming_convention = "import", |
| ) |
| </pre> |
| </div> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>MODULE.bazel - Go Extension</strong></p> |
| <pre class="prettyprint lang-py" style="font-size: 12px;"> |
| go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps") |
| go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk") |
| |
| go_deps.from_file(go_mod = "//:go.mod") |
| use_repo(go_deps, "org_golang_x_net") |
| go_sdk.from_file(go_mod = "//:go.mod") |
| |
| go_deps.gazelle_override( |
| path = "golang.org/x/net", |
| directives = [ |
| "gazelle:proto disable", |
| "gazelle:go_naming_convention import", |
| ], |
| ) |
| </pre> |
| </div> |
| </div> |
| |
| <hr style="height: 1px; background-color: black; border: none;"> |
| |
| <div style="display: flex; flex-wrap: wrap; gap: 16px;"> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>WORKSPACE - Python Extension</strong></p> |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| http_archive( |
| name = "rules_python", |
| integrity = "sha256-qDdnnxOC8mlowe5vg5x9r5B5qlMSgGmh8oFd7KpjcwQ=", |
| strip_prefix = "rules_python-1.4.0", |
| url = "https://github.com/bazelbuild/rules_python/releases/download/1.4.0/rules_python-1.4.0.tar.gz", |
| ) |
| |
| load("@rules_python//python:repositories.bzl", "py_repositories") |
| py_repositories() |
| |
| load("@rules_python//python:pip.bzl", "pip_parse") |
| pip_parse( |
| name = "my_python_deps", |
| requirements_lock = "@example//:requirements_lock.txt", |
| ) |
| |
| load("@my_python_deps//:requirements.bzl", "install_deps") |
| install_deps() |
| |
| load("@rules_python//python:repositories.bzl", "python_register_toolchains") |
| python_register_toolchains( |
| name = "python_3_11", |
| python_version = "3.11", |
| ) |
| </pre> |
| </div> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>MODULE.bazel - Python Extension</strong></p> |
| <pre class="prettyprint lang-py" style="font-size: 12px;"> |
| pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") |
| pip.parse( |
| hub_name = "my_python_deps", |
| python_version = "3.11", |
| requirements_lock = "//:requirements_lock.txt", |
| ) |
| use_repo(pip, "my_python_deps") |
| |
| python = use_extension("@rules_python//python/extensions:python.bzl", "python") |
| python.defaults(python_version = "3.11") |
| python.toolchain(python_version = "3.11") |
| </pre> |
| </div> |
| </div> |
| |
| <hr style="height: 1px; background-color: black; border: none;"> |
| |
| <div style="display: flex; flex-wrap: wrap; gap: 16px;"> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>WORKSPACE - Maven Extension</strong></p> |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| |
| RULES_JVM_EXTERNAL_TAG = "4.5" |
| RULES_JVM_EXTERNAL_SHA = "b17d7388feb9bfa7f2fa09031b32707df529f26c91ab9e5d909eb1676badd9a6" |
| |
| http_archive( |
| name = "rules_jvm_external", |
| strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG, |
| sha256 = RULES_JVM_EXTERNAL_SHA, |
| url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG, |
| ) |
| |
| load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps") |
| rules_jvm_external_deps() |
| load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup") |
| rules_jvm_external_setup() |
| |
| load("@rules_jvm_external//:defs.bzl", "maven_install") |
| maven_install( |
| name = "px_deps", |
| artifacts = [ |
| "org.antlr:antlr4:4.11.1", |
| ], |
| repositories = [ |
| "https://repo1.maven.org/maven2", |
| ], |
| ) |
| </pre> |
| </div> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>MODULE.bazel - Maven Extension</strong></p> |
| <pre class="prettyprint lang-py" style="font-size: 12px;"> |
| bazel_dep(name = "rules_jvm_external", version = "6.8") |
| |
| maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") |
| use_repo(maven, "px_deps") |
| |
| maven.artifact( |
| name = "px_deps", |
| group = "org.antlr", |
| artifact = "antlr4", |
| version = "4.11.1" |
| ) |
| </pre> |
| </div> |
| </div> |
| |
| <hr style="height: 1px; background-color: black; border: none;"> |
| |
| <div style="display: flex; flex-wrap: wrap; gap: 16px;"> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>WORKSPACE - Repo rule</strong></p> |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") |
| |
| http_archive( |
| name = "com_github_cockroachdb_cockroach", |
| sha256 = "6c3568ef244ce6b874694eeeecb83ed4f5d5dff6cf037c952ecde76828a6c502", |
| strip_prefix = "cockroach-22.1.6", |
| url = "https://github.com/cockroachdb/cockroach/archive/v22.1.6.tar.gz", |
| ) |
| </pre> |
| </div> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>MODULE.bazel - Repo rule</strong></p> |
| <pre class="prettyprint lang-py" style="font-size: 12px;"> |
| http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") |
| |
| http_archive( |
| name = "com_github_cockroachdb_cockroach", |
| url = "https://github.com/cockroachdb/cockroach/archive/v22.1.6.tar.gz", |
| sha256 = "6c3568ef244ce6b874694eeeecb83ed4f5d5dff6cf037c952ecde76828a6c502", |
| strip_prefix = "cockroach-22.1.6", |
| ) |
| </pre> |
| </div> |
| </div> |
| |
| <hr style="height: 1px; background-color: black; border: none;"> |
| |
| <div style="display: flex; flex-wrap: wrap; gap: 16px;"> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>WORKSPACE - Module extension</strong></p> |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| load(":my_custom_macro.bzl", "my_custom_macro") |
| |
| my_custom_macro( |
| name = "my_custom_repo", |
| ) |
| </pre> |
| </div> |
| <div style="flex: 1; min-width: 300px;"> |
| <p><strong>MODULE.bazel - Module extension</strong></p> |
| <pre class="prettyprint lang-py" style="font-size: 12px;"> |
| extension_for_my_custom_macro = use_extension("//:extension_for_my_custom_macro.bzl", "extension_for_my_custom_macro") |
| use_repo(extension_for_my_custom_macro, "my_custom_repo") |
| </pre> |
| <p><strong>extension_for_my_custom_macro.bzl</strong></p> |
| <pre class="prettyprint lang-py" style="font-size: 12px;"> |
| load("//:my_custom_macro.bzl", "my_custom_macro") |
| |
| def _extension_for_my_custom_macro_impl(ctx): |
| my_custom_macro( |
| name = "my_custom_repo", |
| ) |
| |
| extension_for_my_custom_macro = module_extension(implementation = _extension_for_my_custom_macro_impl) |
| </pre> |
| </div> |
| </div> |
| |
| <hr style="height: 1px; background-color: black; border: none;"> |
| |
| ## Tips with debugging {:#migration-tool-tips} |
| |
| This section provides useful commands and information to help debug issues that |
| may arise during the Bzlmod migration. |
| |
| ### Useful tips {:#debugging-useful-tips} |
| |
| * Override version - Not rarely it happens that upgrading the version of a |
| dependency causes troubles. Bzlmod could change the version of the |
| dependency due to the [MVS algorithm](/external/module#version-selection). |
| In order to use the same or similar version as it was in the WORKSPACE, |
| override it with |
| [single_version_override](/rules/lib/globals/module#single_version_override). |
| Note that this is useful for debugging differences between WORKSPACE and |
| Bzlmod, but you shouldn't rely on this feature in the long term. |
| |
| `single_version_override(module_name = "{dep_name}", version = "{version}")` |
| |
| * Use [bazel mod](/external/mod-command#syntax) command. |
| * Check the version of a specified repo with `show_repo` |
| command. For example: |
| |
| `bazel mod show_repo @rules_python` |
| |
| * Check information about a module extension with the `show_extension` |
| command. For example: |
| |
| `bazel mod show_extension @rules_python//python/extensions:pip.bzl%pip` |
| |
| * Use [vendor mode](/external/vendor) to create a local copy of a repo when |
| you want to monitor or control the source of the repo. For example: |
| |
| `bazel vendor --enable_bzlmod --vendor_dir=vendor_src --repo=@protobuf` |
| |
| ### Migration Report Generation {:#migration-tool-report-generation} |
| |
| This file is updated with each run of the migration script or it's generated |
| from scratch if it's the first run or if the [`--i` |
| flag](#migration-script-flags) is used. The report contains: |
| |
| * Command for local testing. |
| * List of direct dependencies (at least the ones which are directly used in |
| the project). |
| * For each dependency, a drop-down menu for checking where the repository was |
| declared in the `WORKSPACE` file, which is particularly useful for the |
| debugging. You can see it as: |
| |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| > Click here to see where and how the repo was declared in the WORKSPACE |
| file |
| </pre> |
| |
| * For each dependency, how it was implemented in `MODULE.bazel` file. From the |
| earlier [Migration Example](#migration-tool-example), that would look as: |
| 1. Bazel module Dependency - `Migration of rules_python` |
| |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| Found perfect name match in BCR: rules_python |
| Found partially name matches in BCR: rules_python_gazelle_plugin |
| |
| It has been introduced as a Bazel module: |
| `bazel_dep(name = "rules_python", version = "1.6.1")` |
| </pre> |
| |
| * The script will automatically use the `perfect name match` if it finds |
| it. In case of an error, you can double check if the name was correctly |
| added. |
| 2. Python extension - `Migration of my_python_deps` |
| |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| pip.parse( |
| hub_name = "my_python_deps", |
| requirements_lock = "//:requirements_lock.txt", |
| python_version = "3.11", |
| ) |
| use_repo(pip, "my_python_deps") |
| </pre> |
| |
| 3. Maven extension - `Migration of org.antlr (px_deps):` |
| |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| maven.artifact( |
| name = "px_deps", |
| group = "org.antlr", |
| artifact = "antlr4", |
| version = "4.11.1" |
| ) |
| </pre> |
| |
| 4. Go extension - `Migration of org_golang_x_net` |
| |
| <pre class="prettyprint lang-java" style="font-size: 12px;"> |
| go_deps.from_file(go_mod = "//:go.mod") |
| go_sdk.from_file(go_mod = "//:go.mod") |
| |
| go_deps.gazelle_override( |
| path = "golang.org/x/net", |
| directives = [ |
| "gazelle:proto disable", |
| "gazelle:go_naming_convention import", |
| ], |
| ) |
| </pre> |
| |
| * It has been introduced as a go module with the help of `go.mod`. If |
| `go.mod` and `go.sum` are not available, go module is added directly |
| to the `MODULE.bazel` file. |
| * `gazelle_override` is used for adding specific directives. |
| |
| ## Useful links {:#useful-links} |
| |
| * Official pages for the external extensions |
| * [rules_jvm_external](https://github.com/bazelbuild/rules_jvm_external/blob/master/docs/bzlmod.md) |
| * [rules_go](https://github.com/bazelbuild/rules_go/blob/master/docs/go/core/bzlmod.md) |
| * [rules_python](https://rules-python.readthedocs.io/en/latest/pypi/download.html) |
| * Community posts and videos |
| * [Migrating to Bazel Modules](https://blog.engflow.com/2025/01/16/migrating-to-bazel-modules-aka-bzlmod---module-extensions/index.html#migrating-to-bazel-modules-aka-bzlmod-module-extensions). |
| * [Moving to Bzlmod](https://www.youtube.com/watch?v=W9uXRYLVHUk). |
| * [How Uber Manages Go Dependencies with Bzlmod](https://www.youtube.com/watch?v=hIqzkUE_pSY). |
| |
| ## Feedback {:#feedback} |
| |
| If you would like to contribute, do so by creating an Issue or PR at |
| [bazel-central-registry](https://github.com/bazelbuild/bazel-central-registry). |