Skip to content

Update Migration tool - Add support for Maven extensions #4811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# NB: don't ignore the modules/ folder as it contains inputs to bazel test targets.
tools/bzlmod_migration_test_examples
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
tools/__pycache__
tools/node_modules
tools/bzlmod_migration_test_examples/*/bazel-*
tools/bzlmod_migration_test_examples/*/__pycache__
/bazel-*
MODULE.bazel.lock
temp_test_repos
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build --java_runtime_version=21
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7.6.1
11 changes: 11 additions & 0 deletions tools/bzlmod_migration_test_examples/maven_extensions/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
load("@rules_java//java:defs.bzl", "java_binary")

java_binary(
name = "px_deps_bin",
main_class = "org.antlr.v4.Tool",
runtime_deps = [
"@px_deps//:org_antlr_antlr4",
"@px_deps//:com_google_jimfs_jimfs",
"@px_deps//:com_google_truth_truth",
],
)
31 changes: 31 additions & 0 deletions tools/bzlmod_migration_test_examples/maven_extensions/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "rules_java",
sha256 = "c999cdbb4e8414d49c4117bb73800cff95c438c15da075531ae004275ab23144",
urls = ["https://github.com/bazelbuild/rules_java/releases/download/7.12.0/rules_java-7.12.0.tar.gz"],
)

http_archive(
name = "rules_jvm_external",
sha256 = "23fe83890a77ac1a3ee143e2306ec12da4a845285b14ea13cb0df1b1e23658fe",
strip_prefix = "rules_jvm_external-4.3",
urls = ["https://github.com/bazelbuild/rules_jvm_external/archive/refs/tags/4.3.tar.gz"],
)

load("@rules_jvm_external//:defs.bzl", "maven_install")

maven_install(
name = "px_deps",
artifacts = [
"org.antlr:antlr4:4.11.1",
"com.google.jimfs:jimfs:1.2",
"com.google.truth:truth:1.4.0",
],
repositories = [
"https://repo1.maven.org/maven2",
],
)

load("@px_deps//:defs.bzl", pinned_maven_install = "pinned_maven_install")
pinned_maven_install()
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import unittest
import subprocess
import os
from unittest import main


class BazelBuildTest(unittest.TestCase):
"""
A test suite for verifying Bzlmod migration tool for maven extensions.
"""

_CREATED_FILES = [
"MODULE.bazel",
"MODULE.bazel.lock",
"WORKSPACE.bzlmod",
"migration_info.md",
"query_direct_deps",
"resolved_deps.py",
]

def _cleanup_created_files(self):
"""
Remove files which were created by migration tool.
"""
for file_name in self._CREATED_FILES:
file_path = os.path.join(os.getcwd(), file_name)
if os.path.exists(file_path):
os.remove(file_path)

def _run_command(self, command, expected_failure=False):
"""
Helper function to run a command and return its result.
It captures `stdout`, `stderr` and `returncode` for debugging.
"""
try:
result = subprocess.run(command, capture_output=True, text=True, check=True)
return result
except FileNotFoundError:
self.fail("Command not found.")
except subprocess.CalledProcessError as e:
if expected_failure:
return e
self.fail(f"Command failed with exit code {e.returncode}:\nSTDOUT:\n{e.stdout}\nSTDERR:\n{e.stderr}")

def _print_message(self, message):
GREEN = "\033[92m"
RESET = "\033[0m"
print(f"{GREEN}{message}{RESET}")

def modify_build_file(self, old, new):
with open("BUILD", "r") as f:
original_content = f.read()
with open("BUILD", "w") as f:
modified_content = str(original_content).replace(old, new)
f.write(modified_content)

def test_migration_of_module_deps(self):
self._cleanup_created_files()

# Verify bazel build is successful with enabled workspace
print("\n--- Running bazel build with enabled workspace ---")
result = self._run_command(["bazel", "build", "--nobuild", "--enable_workspace", "--noenable_bzlmod", "//..."])
assert result.returncode == 0
self._print_message("Success.")

# Run migration script
print("\n--- Running migration script ---")
result = self._run_command(["../../migrate_to_bzlmod.py", "-t=/..."], expected_failure=True)
assert result.returncode == 2
assert "`px_deps` is a maven extension" in result.stdout
assert "no such package '@@[unknown repo 'px_deps'" in result.stderr
assert os.path.exists(
"migration_info.md"
), "File 'migration_info.md' should be created during migration, but it doesn't exist."
self._print_message("Expected error: User need to modify `@px_deps` into `@maven`.")

# Verify Bzlmod have error
print("\n--- Running bazel build with enabled bzlmod ---")
result = self._run_command(
["bazel", "build", "--noenable_workspace", "--enable_bzlmod", "//..."], expected_failure=True
)
assert result.returncode == 1
self._print_message("Expected Bzlmod failure since manual change of BUILD file is needed")

# Modify BUILD file
self.modify_build_file("px_deps", "maven")
print("\n--- Modifying BUILD file ---")
self._print_message("Success.")

# Verify MODULE.bazel was created successfully
print("\n--- Running bazel build with enabled bzlmod ---")
result = self._run_command(["bazel", "build", "--noenable_workspace", "--enable_bzlmod", "//..."])
assert result.returncode == 0
self._print_message("Success with modified BUILD file.")

# Restore BUILD file to the initial content
self.modify_build_file("maven", "px_deps")
self._cleanup_created_files()


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build --java_runtime_version=21
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7.6.1
48 changes: 48 additions & 0 deletions tools/bzlmod_migration_test_examples/simple_module_deps/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_binary")
load("@rules_java//java:defs.bzl", "java_library", "java_binary")
load("@rules_shell//shell:sh_library.bzl", "sh_library")
load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library")
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")

cc_library(
name = "cc_lib",
srcs = ["test.cc"],
visibility = ["//visibility:public"],
)

cc_binary(
name = "cc_bin",
deps = [":cc_lib"],
)

java_library(
name = "java_lib",
srcs = ["Test.java"],
visibility = ["//visibility:public"],
)

java_binary(
name = "java_bin",
main_class = "Test",
runtime_deps = [":java_lib"],
)

bzl_library(
name = "rules-java-docs",
srcs = [
"@rules_java//java:defs.bzl",
],
)

sh_library(name='sh_lib')

proto_library(
name = "proto_lib",
srcs = ["test.proto"]
)

cc_proto_library(
name = "cc_proto_lib",
deps = [":proto_lib"]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
public class Test {
public static void main(String[] args) {
}
}
52 changes: 52 additions & 0 deletions tools/bzlmod_migration_test_examples/simple_module_deps/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "rules_java",
sha256 = "c999cdbb4e8414d49c4117bb73800cff95c438c15da075531ae004275ab23144",
urls = ["https://github.com/bazelbuild/rules_java/releases/download/7.12.0/rules_java-7.12.0.tar.gz"],
)

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",
)

http_archive(
name = "rules_cc",
sha256 = "f4aadd8387f381033a9ad0500443a52a0cea5f8ad1ede4369d3c614eb7b2682e",
strip_prefix = "rules_cc-0.0.15",
urls = [
"https://github.com/bazelbuild/rules_cc/releases/download/0.0.15/rules_cc-0.0.15.tar.gz",
],
)

http_archive(
name = "bazel_skylib",
urls = [
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz",
],
sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d",
)

http_archive(
name = "com_google_protobuf",
sha256 = "a7e735f510520b41962d07459f6f5b99dd594c7ed4690bf1191b9924bec094a2",
strip_prefix = "protobuf-27.0",
urls = [
"https://mirror.bazel.build/github.com/protocolbuffers/protobuf/archive/v27.0.zip",
"https://github.com/protocolbuffers/protobuf/archive/v27.0.zip",
],
)

http_archive(
name = "rules_python",
sha256 = "5868e73107a8e85d8f323806e60cad7283f34b32163ea6ff1020cf27abef6036",
strip_prefix = "rules_python-0.25.0",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.25.0/rules_python-0.25.0.tar.gz",
)

load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import unittest
import subprocess
import os
from unittest import main


class BazelBuildTest(unittest.TestCase):
"""
A test suite for verifying Bzlmod migration tool for simple module deps.
"""

_CREATED_FILES = [
"MODULE.bazel",
"MODULE.bazel.lock",
"WORKSPACE.bzlmod",
"migration_info.md",
"query_direct_deps",
"resolved_deps.py",
]

def _cleanup_created_files(self):
"""
Remove files which were created by migration tool.
"""
for file_name in self._CREATED_FILES:
file_path = os.path.join(os.getcwd(), file_name)
if os.path.exists(file_path):
os.remove(file_path)

def _run_command(self, command):
"""
Helper function to run a command and return its result.
It captures `stdout`, `stderr` and `returncode` for debugging.
"""
try:
result = subprocess.run(command, capture_output=True, text=True, check=True)
return result
except FileNotFoundError:
self.fail("Command not found.")
except subprocess.CalledProcessError as e:
self.fail(f"Command failed with exit code {e.returncode}:\nSTDOUT:\n{e.stdout}\nSTDERR:\n{e.stderr}")

def _print_success(self):
GREEN = "\033[92m"
RESET = "\033[0m"
print(f"{GREEN}Success{RESET}")

def test_migration_of_module_deps(self):
self._cleanup_created_files()

# Verify bazel build is successful with enabled workspace
print("\n--- Running bazel build with enabled workspace ---")
result = self._run_command(["bazel", "build", "--enable_workspace", "--noenable_bzlmod", "//..."])
assert result.returncode == 0
self._print_success()

# Run migration script
print("\n--- Running migration script ---")
result = self._run_command(["../../migrate_to_bzlmod.py", "-t=/..."])
assert result.returncode == 0
assert os.path.exists(
"migration_info.md"
), "File 'migration_info.md' should be created during migration, but it doesn't exist."
self._print_success()

# Verify MODULE.bazel was created successfully
print("\n--- Running bazel build with enabled bzlmod ---")
result = self._run_command(["bazel", "build", "--noenable_workspace", "--enable_bzlmod", "//..."])
assert result.returncode == 0
self._print_success()

self._cleanup_created_files()


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <iostream>

int main() {
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
syntax = "proto3";

package test;

message Test {
}
Loading
Loading