Untuk menyederhanakan proses yang sering kali rumit dalam berpindah dari WORKSPACE
ke Bzlmod, sebaiknya gunakan skrip migrasi. Alat bantu ini mengotomatiskan banyak langkah yang terlibat dalam memigrasikan sistem pengelolaan dependensi eksternal Anda.
Catatan: Jika Anda ingin mencoba migrasi Bzlmod yang didukung AI, lihat Penyiapan Agen Migrasi Bzlmod.
Fungsi Inti
Fungsi utama skrip adalah:
- Mengumpulkan informasi dependensi: Menganalisis file
WORKSPACE
project Anda untuk mengidentifikasi repositori eksternal yang digunakan oleh target build tertentu, menggunakan tanda experimental_repository_resolved_file Bazel untuk membuat file dependensi yang telah di-resolve yang berisi informasi ini. - Mengidentifikasi dependensi langsung: Menggunakan
bazel query
untuk menentukan repositori mana yang merupakan dependensi langsung untuk target yang ditentukan. - Bermigrasi ke Bzlmod: Menerjemahkan dependensi
WORKSPACE
yang relevan ke dalam padanannya di Bzlmod. Proses ini terdiri dari dua langkah:- Perkenalkan semua dependensi langsung yang diidentifikasi ke file
MODULE.bazel
. - Bangun target yang ditentukan dengan Bzlmod diaktifkan, lalu identifikasi dan perbaiki error yang dapat dikenali secara iteratif. Langkah ini diperlukan karena beberapa dependensi mungkin tidak ada di langkah pertama.
- Perkenalkan semua dependensi langsung yang diidentifikasi ke file
- Membuat laporan migrasi: Membuat file
migration_info.md
yang mendokumentasikan proses migrasi. Laporan ini mencakup daftar dependensi langsung, deklarasi Bzlmod yang dihasilkan, dan langkah-langkah manual yang mungkin diperlukan untuk menyelesaikan migrasi.
Alat migrasi mendukung:
- Dependensi yang tersedia di Bazel Central Registry
- Aturan repositori kustom yang ditentukan pengguna
- Dependensi pengelola paket
- Maven
- Go
- Python
Catatan Penting:
- Alat migrasi adalah utilitas upaya terbaik. Selalu periksa kembali rekomendasi yang diberikan untuk memastikan kebenarannya.
- Gunakan alat migrasi dengan Bazel 7 (tidak didukung dengan Bazel 8).
Cara Menggunakan Alat Migrasi
Sebelum memulai:
- Lakukan upgrade ke rilis Bazel 7 terbaru, yang memberikan dukungan yang andal untuk WORKSPACE dan Bzlmod.
Verifikasi bahwa perintah berikut berhasil dijalankan untuk target build utama project Anda:
bazel build --nobuild --enable_workspace --noenable_bzlmod <targets>
Perintah untuk menjalankan skrip
Setelah prasyarat terpenuhi, jalankan perintah berikut untuk menggunakan alat migrasi:
# 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 cdmigrate2bzlmod -t
File yang dihasilkan oleh skrip ini
MODULE.bazel
- File manifes pusat untuk Bzlmod, yang mendeklarasikan metadata project dan dependensi langsungnya pada modul Bazel lainnya.migration_info.md
- File yang memberikan petunjuk langkah demi langkah tentang cara menjalankan alat migrasi, yang dirancang untuk membantu penyelesaian proses migrasi secara manual, jika perlu.resolved_deps.py
- Berisi daftar lengkap dependensi eksternal project, yang dihasilkan dengan menganalisis fileWORKSPACE
project, yang berfungsi sebagai referensi selama transisi.query_direct_deps
- Berisi informasi yang relevan dengan migrasi terkait target yang digunakan, yang diperoleh dengan memanggil Bazel dengan--output=build
pada fileWORKSPACE
project. File ini terutama digunakan oleh skrip migrasi.extension_for_XXX
- File yang berisi definisi ekstensi modul. Alat migrasi membuat file ini untuk dependensi yang bukan modul Bazel standar, tetapi dapat dikelola menggunakan ekstensi modul Bzlmod.
Tanda
Flag yang tersedia dalam skrip migrasi ini adalah:
--t
/--target
: Target yang akan dimigrasikan. Flag ini dapat diulang, dan targetnya diakumulasikan.--i
/--initial
: Menghapus fileMODULE.bazel
,resolved_deps.py
,migration_info.md
dan memulai dari awal - Mendeteksi dependensi langsung, memperkenalkannya di MODULE.bazel, dan menjalankan kembali pembuatan dependensi yang telah di-resolve.
Pembersihan pascamigrasi
- Hapus
migration_info.md
,resolved_deps.py
, danquery_direct_deps
. - Hapus komentar dari file
MODULE.bazel
yang digunakan untuk migrasi, seperti# -- bazel_dep definitions -- #
.
Contoh Migrasi
Untuk melihat cara kerja skrip migrasi, pertimbangkan skenario berikut saat dependensi Python, Maven, dan Go dideklarasikan dalam file WORKSPACE
.
Klik di sini untuk melihat file 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",
],
)
Selain itu, untuk mendemonstrasikan penggunaan ekstensi modul, makro kustom dipanggil dari
WORKSPACE
dan ditentukan di my_custom_macro.bzl
.
Klik di sini untuk melihat file 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)
Tujuan akhirnya adalah memiliki file MODULE.bazel
dan menghapus file WORKSPACE
, tanpa memengaruhi pengalaman pengguna.
Langkah pertama adalah mengikuti Cara Menggunakan Alat Migrasi, yang sebagian besar memeriksa versi bazel (harus Bazel 7) dan menambahkan alias ke skrip migrasi.
Kemudian, menjalankan migrate2bzlmod -t=//...
akan menghasilkan:
bazel 7.6.1 Generating ./resolved_deps.py file - It might take a while... RESOLVED:rules_java
has been introduced as a Bazel module. RESOLVED:bazel_gazelle
has been introduced as a Bazel module. RESOLVED:io_bazel_rules_go
has been introduced as a Bazel module. RESOLVED:rules_python
has 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_deps
has been introduced as python extension. RESOLVED:org_golang_x_net
has been introduced as go extension. RESOLVED:rules_jvm_external
has been introduced as a Bazel module. RESOLVED:org.antlr
has been introduced as maven extension. RESOLVED:rules_shell
has 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.
yang memberikan informasi penting berikut:
- Membuat file
./resolved_deps.py
, yang berisi info tentang semua repositori eksternal yang dideklarasikan dan dimuat menggunakan fileWORKSPACE
Anda. - Kata kunci
RESOLVED
menjelaskan semua dependensi yang diselesaikan oleh alat dan ditambahkan ke fileMODULE.bazel
. - Kata kunci
IMPORTANT
menjelaskan informasi penting yang layak untuk dipelajari. - Semua dependensi telah diselesaikan dalam contoh ini, setidaknya dengan
flag
--nobuild
. - Penting untuk menjalankan build lengkap (perintah yang ditentukan) dan memperbaiki error potensial secara manual (misalnya, toolchain tidak terdaftar dengan benar).
- File
migration_info.md
berisi detail tentang migrasi. Lihat detailnya di bagian ini.
Transformasi
Bagian ini mengilustrasikan migrasi kode dari file WORKSPACE
ke
MODULE.bazel
.
WORKSPACE - Bazel Module
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 - Modul Bazel
bazel_dep(name = "rules_shell", version = "0.6.1")
WORKSPACE - Go Extension
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 - Ekstensi 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 - Python Extension
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 - Ekstensi 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 - Maven Extension
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 - Ekstensi 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 - Repo rule
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 - Aturan repo
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 - Module extension
load(":my_custom_macro.bzl", "my_custom_macro") my_custom_macro( name = "my_custom_repo", )
MODULE.bazel - Ekstensi modul
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)
Tips untuk proses debug
Bagian ini memberikan perintah dan informasi yang berguna untuk membantu men-debug masalah yang mungkin muncul selama migrasi Bzlmod.
Tips berguna
Mengganti versi - Tidak jarang terjadi bahwa mengupgrade versi dependensi menyebabkan masalah. Bzlmod dapat mengubah versi dependensi karena algoritma MVS. Untuk menggunakan versi yang sama atau serupa seperti di RUANG KERJA, ganti dengan single_version_override. Perhatikan bahwa ini berguna untuk men-debug perbedaan antara WORKSPACE dan Bzlmod, tetapi Anda tidak boleh mengandalkan fitur ini dalam jangka panjang.
single_version_override(module_name = "{dep_name}", version = "{version}")
Gunakan perintah bazel mod.
Periksa versi repo tertentu dengan perintah
show_repo
. Contoh:bazel mod show_repo @rules_python
Periksa informasi tentang ekstensi modul dengan perintah
show_extension
. Contoh:bazel mod show_extension @rules_python//python/extensions:pip.bzl%pip
Gunakan mode vendor untuk membuat salinan lokal repo saat Anda ingin memantau atau mengontrol sumber repo. Contoh:
bazel vendor --enable_bzlmod --vendor_dir=vendor_src --repo=@protobuf
Pembuatan Laporan Migrasi
File ini diperbarui dengan setiap menjalankan skrip migrasi atau dibuat
dari awal jika ini adalah proses pertama atau jika tanda --i
digunakan. Laporan ini berisi:
- Perintah untuk pengujian lokal.
- Daftar dependensi langsung (setidaknya yang digunakan langsung dalam project).
Untuk setiap dependensi, menu drop-down untuk memeriksa tempat deklarasi repositori dalam file
WORKSPACE
, yang sangat berguna untuk proses pen-debug-an. Anda dapat melihatnya sebagai:> Click here to see where and how the repo was declared in the WORKSPACE file
Untuk setiap dependensi, cara penerapannya dalam file
MODULE.bazel
. Dari Contoh Migrasi sebelumnya, akan terlihat seperti:Dependensi modul Bazel -
Migration of rules_python
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")`
- Skrip akan otomatis menggunakan
perfect name match
jika menemukannya. Jika terjadi error, Anda dapat memeriksa ulang apakah nama telah ditambahkan dengan benar.
- Skrip akan otomatis menggunakan
Ekstensi Python -
Migration of my_python_deps
pip.parse( hub_name = "my_python_deps", requirements_lock = "//:requirements_lock.txt", python_version = "3.11", ) use_repo(pip, "my_python_deps")
Ekstensi Maven -
Migration of org.antlr (px_deps):
maven.artifact( name = "px_deps", group = "org.antlr", artifact = "antlr4", version = "4.11.1" )
Ekstensi Go -
Migration of org_golang_x_net
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", ], )
- Library ini telah diperkenalkan sebagai modul go dengan bantuan
go.mod
. Jikago.mod
dango.sum
tidak tersedia, modul go akan ditambahkan langsung ke fileMODULE.bazel
. gazelle_override
digunakan untuk menambahkan direktif tertentu.
- Library ini telah diperkenalkan sebagai modul go dengan bantuan
Link penting
- Halaman resmi untuk ekstensi eksternal
- Postingan dan video komunitas
Masukan
Jika Anda ingin berkontribusi, lakukan dengan membuat Masalah atau PR di bazel-central-registry.