blob: 522e9ee8f8e3db7d9bc422061f3faf1c47c88632 [file] [log] [blame]
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 &lt;your project root&gt;
migrate2bzlmod -t &lt;targets&gt;
</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).