Para simplificar el proceso, a menudo complejo, de pasar de WORKSPACE a Bzlmod, se
recomienda usar la secuencia de comandos de migración. Esta herramienta auxiliar
automatiza muchos de los pasos involucrados en la migración de tu sistema externo de administración de dependencias.
Nota: Si quieres probar la migración a Bzlmod basada en IA, consulta Configuración del agente de migración a Bzlmod.
Funcionalidad principal
Las funciones principales de la secuencia de comandos son las siguientes:
- Recopilación de información de dependencias: Analiza el archivo
WORKSPACEde tu proyecto para identificar los repositorios externos que usan los destinos de compilación especificados, con la marca experimental_repository_resolved_file de Bazel para generar un archivo de dependencias resueltas que contenga esta información. - Identificación de dependencias directas: Usa
bazel querypara determinar qué repositorios son dependencias directas de los destinos especificados. - Migración a Bzlmod: Traduce las dependencias relevantes de
WORKSPACEa sus equivalentes de Bzlmod. Este es un proceso de dos pasos:- Introduce todas las dependencias directas identificadas en el
MODULE.bazelarchivo. - Compila los destinos especificados con Bzlmod habilitado y, luego, identifica y corrige de forma iterativa los errores reconocibles. Este paso es necesario, ya que es posible que falten algunas dependencias en el primer paso.
- Introduce todas las dependencias directas identificadas en el
- Generación de un informe de migración: Crea un archivo
migration_info.mdque documente el proceso de migración. Este informe incluye una lista de dependencias directas , las declaraciones de Bzlmod generadas y los pasos manuales que pueden ser necesarios para completar la migración.
La herramienta de migración admite lo siguiente:
- Dependencias disponibles en el Registro central de Bazel
- Reglas de repositorio personalizadas definidas por el usuario
- Dependencias del administrador de paquetes
- Maven
- Go
- Python
Notas importantes:
- La herramienta de migración es una utilidad de mejor esfuerzo. Siempre vuelve a verificar sus recomendaciones para confirmar la exactitud.
- Usa la herramienta de migración con Bazel 7 (no es compatible con Bazel 8).
Cómo usar la herramienta de migración
Antes de comenzar:
- Actualiza a la versión más reciente de Bazel 7, que proporciona una compatibilidad sólida con WORKSPACE y Bzlmod.
Verifica que el siguiente comando se ejecute correctamente para los destinos de compilación principales de tu proyecto:
bazel build --nobuild --enable_workspace --noenable_bzlmod <targets>
Comando para ejecutar la secuencia de comandos
Una vez que se cumplan los requisitos previos, ejecuta los siguientes comandos para usar la herramienta de migración:
# 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>
Archivos generados por esta secuencia de comandos
MODULE.bazel- Es el archivo de manifiesto central para Bzlmod, que declara los metadatos del proyecto y sus dependencias directas en otros módulos de Bazel.migration_info.md- Es un archivo que proporciona instrucciones paso a paso sobre cómo se ejecutó la herramienta de migración, diseñada para ayudar a completar manualmente el proceso de migración, si es necesario.resolved_deps.py- Contiene una lista completa de las dependencias externas del proyecto, generada mediante el análisis del archivoWORKSPACEdel proyecto, que sirve como referencia durante la transición.query_direct_deps- Contiene información relevante para la migración sobre los destinos utilizados, que se obtiene invocando a Bazel con--output=builden el archivoWORKSPACEdel proyecto. Esta secuencia de comandos de migración consume principalmente este archivo.extension_for_XXX- Es un archivo que contiene una definición de extensión de módulo. La herramienta de migración genera estos archivos para dependencias que no son módulos estándar de Bazel, pero que se pueden administrar con las extensiones de módulo de Bzlmod.
Marcas
Las marcas disponibles en estas secuencias de comandos de migración son las siguientes:
--t/--target: Destinos para migrar. Esta marca se puede repetir y los destinos se acumulan.--i/--initial: Borra los archivosMODULE.bazel,resolved_deps.py,migration_info.mdy comienza desde cero. Detecta dependencias directas, las introduce en MODULE.bazel y vuelve a ejecutar la generación de dependencias resueltas.
Limpieza después de la migración
- Borra
migration_info.md,resolved_deps.pyyquery_direct_deps. - Limpia los comentarios del archivo
MODULE.bazelque se usaron para la migración, como# -- bazel_dep definitions -- #.
Ejemplo de migración
Para ver la secuencia de comandos de migración en acción, considera la siguiente situación cuando
se declaran las dependencias de Python, Maven y Go en el archivo WORKSPACE.
Haz clic aquí para ver el archivo WORKSPACE
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",
],
)
Además, para demostrar el uso de la extensión del módulo, se invoca una macro personalizada desde
WORKSPACE y se define en my_custom_macro.bzl.
Haz clic aquí para ver el archivo my_custom_macro.bzl
"""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)
El objetivo final es tener el archivo MODULE.bazel y borrar el archivo WORKSPACE,
sin afectar la experiencia del usuario.
El primer paso es seguir Cómo usar la herramienta de migración, que consiste principalmente en verificar la versión de Bazel (debe ser Bazel 7) y agregar un alias a la secuencia de comandos de migración.
Luego, la ejecución de migrate2bzlmod -t=//... genera lo siguiente:
bazel 7.6.1 Generating ./resolved_deps.py file - It might take a while... RESOLVED:rules_javahas been introduced as a Bazel module. RESOLVED:bazel_gazellehas been introduced as a Bazel module. RESOLVED:io_bazel_rules_gohas been introduced as a Bazel module. RESOLVED:rules_pythonhas been introduced as a Bazel module. IMPORTANT: 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. RESOLVED:my_python_depshas been introduced as python extension. RESOLVED:org_golang_x_nethas been introduced as go extension. RESOLVED:rules_jvm_externalhas been introduced as a Bazel module. RESOLVED:org.antlrhas been introduced as maven extension. RESOLVED:rules_shellhas been introduced as a Bazel module. Congratulations! All external repositories needed for building //... are available with Bzlmod! IMPORTANT: Fix potential build time issues by running the following command: bazel build --enable_bzlmod --noenable_workspace //... IMPORTANT:For details about the migration process, check `migration_info.md` file.
que proporciona la siguiente información importante:
- Genera el archivo
./resolved_deps.py, que contiene información sobre todos los repositorios externos declarados y cargados con tu archivoWORKSPACE. - La palabra clave
RESOLVEDdescribe todas las dependencias que resuelve la herramienta y que se agregan al archivoMODULE.bazel. - La palabra clave
IMPORTANTdescribe información importante que vale la pena invertir tiempo. - En este ejemplo, se resolvieron todas las dependencias, al menos con
--nobuildmarca. - Es importante ejecutar la compilación completa (comando especificado) y corregir manualmente los posibles errores (p.ej., la cadena de herramientas no se registró correctamente).
- El archivo
migration_info.mdcontiene detalles sobre la migración. Consulta los detalles en esta sección.
Transformaciones
En esta sección, se ilustra la migración de código del archivo WORKSPACE a
MODULE.bazel.
WORKSPACE: Módulo de Bazel
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", )
MODULE.bazel: Módulo de Bazel
bazel_dep(name = "rules_shell", version = "0.6.1")
WORKSPACE: Extensión de Go
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", )
MODULE.bazel: Extensión de Go
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", ], )
WORKSPACE: Extensión de Python
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", )
MODULE.bazel: Extensión de Python
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")
WORKSPACE: Extensión de Maven
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", ], )
MODULE.bazel: Extensión de Maven
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" )
WORKSPACE: Regla de repositorio
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", )
MODULE.bazel: Regla de repositorio
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", )
WORKSPACE: Extensión de módulo
load(":my_custom_macro.bzl", "my_custom_macro") my_custom_macro( name = "my_custom_repo", )
MODULE.bazel: Extensión de módulo
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")
extension_for_my_custom_macro.bzl
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)
Sugerencias para la depuración
En esta sección, se proporcionan comandos e información útiles para ayudar a depurar los problemas que pueden surgir durante la migración a Bzlmod.
Sugerencias útiles
Anular la versión: No es raro que la actualización de la versión de una dependencia cause problemas. Bzlmod podría cambiar la versión de la dependencia debido al algoritmo MVS. Para usar la misma versión o una similar a la que estaba en WORKSPACE, anúlala con single_version_override. Ten en cuenta que esto es útil para depurar las diferencias entre WORKSPACE y Bzlmod, pero no debes depender de esta función a largo plazo.
single_version_override(module_name = "{dep_name}", version = "{version}")Usa el comando bazel mod.
Verifica la versión de un repositorio especificado con
show_repocomando. Por ejemplo:bazel mod show_repo @rules_pythonVerifica la información sobre una extensión de módulo con el
show_extensioncomando. Por ejemplo:bazel mod show_extension @rules_python//python/extensions:pip.bzl%pip
Usa el modo de proveedor para crear una copia local de un repositorio cuando quieras supervisar o controlar la fuente del repositorio. Por ejemplo:
bazel vendor --enable_bzlmod --vendor_dir=vendor_src --repo=@protobuf
Generación de informes de migración
Este archivo se actualiza con cada ejecución de la secuencia de comandos de migración o se genera
desde cero si es la primera ejecución o si se usa la --i
marca. El informe contiene lo siguiente:
- Comando para pruebas locales
- Lista de dependencias directas (al menos las que se usan directamente en el proyecto)
Para cada dependencia, un menú desplegable para verificar dónde se declaró el repositorio en el archivo
WORKSPACE, lo que es particularmente útil para la depuración. Puedes verlo de la siguiente manera:> Click here to see where and how the repo was declared in the WORKSPACE file
Para cada dependencia, cómo se implementó en el archivo
MODULE.bazel. En el ejemplo de migración anterior, se vería de la siguiente manera:Dependencia del módulo de Bazel:
Migration of rules_pythonFound 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")`
- La secuencia de comandos usará automáticamente la
perfect name matchsi la encuentra. En caso de error, puedes volver a verificar si el nombre se agregó correctamente.
- La secuencia de comandos usará automáticamente la
Extensión de Python:
Migration of my_python_depspip.parse( hub_name = "my_python_deps", requirements_lock = "//:requirements_lock.txt", python_version = "3.11", ) use_repo(pip, "my_python_deps")
Extensión de Maven:
Migration of org.antlr (px_deps):maven.artifact( name = "px_deps", group = "org.antlr", artifact = "antlr4", version = "4.11.1" )
Extensión de Go:
Migration of org_golang_x_netgo_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", ], )
- Se introdujo como un módulo de Go con la ayuda de
go.mod. Sigo.modygo.sumno están disponibles, el módulo de Go se agrega directamente al archivoMODULE.bazel. gazelle_overridese usa para agregar directivas específicas.
- Se introdujo como un módulo de Go con la ayuda de
Vínculos útiles
- Páginas oficiales de las extensiones externas
- Publicaciones y videos de la comunidad
Comentarios
Si quieres contribuir, crea un problema o una solicitud de extracción en bazel-central-registry.