From 060e6911488f38d19eb696562336b9d11e1a8724 Mon Sep 17 00:00:00 2001 From: Martin Medler Date: Sun, 10 Dec 2023 19:58:40 +0100 Subject: [PATCH 1/5] Start using bzlmod We can't use bzlmod with Bazel versions < 6.2.0. Publishing DWYU to the central registry will be done in later steps. For now we only enable using bzlmod while developing. One downside of bzlmod is that rules_python no longer allows defining the Python toolchain with patch level precision. As a consequence we have to change the Python toolchains to the defaults defined by rules_python. --- .bazelrc | 5 + MODULE.bazel | 114 ++++++++++++++++++ WORKSPACE.bzlmod | 0 dev_setup_step_2.bzl | 8 +- .../complex_includes/ext_repo/MODULE.bazel | 1 + test/aspect/execute_tests.py | 19 ++- test/aspect/external_repo/repo/MODULE.bazel | 1 + third_party/dependencies.bzl | 2 + third_party/extensions.bzl | 8 ++ 9 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 MODULE.bazel create mode 100644 WORKSPACE.bzlmod create mode 100644 test/aspect/complex_includes/ext_repo/MODULE.bazel create mode 100644 test/aspect/external_repo/repo/MODULE.bazel create mode 100644 third_party/extensions.bzl diff --git a/.bazelrc b/.bazelrc index e257c6d7..8955ad92 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,6 +1,11 @@ # Always tell why tests fail test --test_output=errors +# We use Bazel's modern dependency management system. This works for us only with Bazel >= 6.2.0 +# This is the deprecated version. "--enable_bzlmod" is the forward path. However, as Bazel < 6.0.0 does not support the +# new flag. We keep using the deprecated one until we no longer support Bazel 5. +build --experimental_enable_bzlmod=true + # Mypy integration build:mypy --aspects=@mypy_integration//:mypy.bzl%mypy_aspect build:mypy --output_groups=mypy diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 00000000..90caca4e --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,114 @@ +module( + name = "depend_on_what_you_use", + bazel_compatibility = [">=5.4.0"], + compatibility_level = 0, +) + +bazel_dep( + name = "bazel_skylib", + # Keep in sync with //third_party/dependencies.bzl + version = "1.5.0", +) +bazel_dep( + name = "rules_python", + # Keep in sync with //third_party/dependencies.bzl + version = "0.27.0", +) + +pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") +pip.parse( + hub_name = "dwyu_py_deps", + python_version = "3.10", + requirements_lock = "//third_party:requirements.txt", +) +use_repo(pip, "dwyu_py_deps") + +### +### Development Dependencies +### + +# Update with each rules_python update for easy lookup until specifying the patch version for toolchain is possible again +# Keep in syc with test/aspect/execute_tests.py +# PATCH_MAPPING: +# "3.10": "3.10.13" +# "3.11": "3.11.6" +# "3.12": "3.12.0" +# "3.8": "3.8.18" +# "3.9": "3.9.18" +# Choose different version via: --@rules_python//python/config_settings:python_version=Major.Minor.Patch mathing one of +# the registered toolchains below. +python = use_extension( + "@rules_python//python/extensions:python.bzl", + "python", + dev_dependency = True, +) +python.toolchain( + python_version = "3.8", +) +python.toolchain( + python_version = "3.9", +) +python.toolchain( + is_default = True, + python_version = "3.10", +) +python.toolchain( + python_version = "3.11", +) + +pip_dev = use_extension( + "@rules_python//python/extensions:pip.bzl", + "pip", + dev_dependency = True, +) +pip_dev.parse( + hub_name = "dwyu_mypy_deps", + python_version = "3.10", + requirements_lock = "//third_party:mypy_requirements.txt", +) +use_repo(pip_dev, "dwyu_mypy_deps") + +non_module_dependencies = use_extension( + "//third_party:extensions.bzl", + "non_module_dependencies", + dev_dependency = True, +) +use_repo(non_module_dependencies, "mypy_integration") + +bazel_dep( + name = "ext_repo", + version = "0.0.0", + dev_dependency = True, +) +local_path_override( + module_name = "ext_repo", + path = "test/aspect/external_repo/repo", +) + +bazel_dep( + name = "complex_includes_repo", + version = "0.0.0", + dev_dependency = True, +) +local_path_override( + module_name = "complex_includes_repo", + path = "test/aspect/complex_includes/ext_repo", +) + +### +### The Migration phase using WORKSPACE.bzlmod and MODULE.bazel together does not support properly loading the implicit +### Bazel dependencies. Thus, we need to load some basic things directly. This should become superfluous when we are +### only using bzlmod eventually +### Reference https://github.com/bazelbuild/bazel/blob/master/src/MODULE.tools +### + +bazel_dep( + name = "platforms", + version = "0.0.7", + dev_dependency = True, +) +bazel_dep( + name = "rules_cc", + version = "0.0.1", + dev_dependency = True, +) diff --git a/WORKSPACE.bzlmod b/WORKSPACE.bzlmod new file mode 100644 index 00000000..e69de29b diff --git a/dev_setup_step_2.bzl b/dev_setup_step_2.bzl index 8af6b5ce..844848c5 100644 --- a/dev_setup_step_2.bzl +++ b/dev_setup_step_2.bzl @@ -19,10 +19,10 @@ def dev_setup_step_2(): # Choose different version via: --@rules_python//python/config_settings:python_version=X python_register_multi_toolchains( name = "python", - default_version = "3.10.9", + default_version = "3.10", python_versions = [ - "3.8.15", - "3.9.16", - "3.11.1", + "3.8", + "3.9", + "3.11", ], ) diff --git a/test/aspect/complex_includes/ext_repo/MODULE.bazel b/test/aspect/complex_includes/ext_repo/MODULE.bazel new file mode 100644 index 00000000..8269dc74 --- /dev/null +++ b/test/aspect/complex_includes/ext_repo/MODULE.bazel @@ -0,0 +1 @@ +module(name = "complex_includes_repo") diff --git a/test/aspect/execute_tests.py b/test/aspect/execute_tests.py index 38822608..538e08d5 100755 --- a/test/aspect/execute_tests.py +++ b/test/aspect/execute_tests.py @@ -13,16 +13,25 @@ # Test matrix. We don't combine each Bazel version with each Python version as there is no significant benefit. We # manually define pairs which make sure each Bazel and Python version we care about is used at least once. +# Keep in sync with MODULE.bazel TESTED_VERSIONS = [ - TestedVersions(bazel="5.4.1", python="3.8.15"), - TestedVersions(bazel="6.0.0", python="3.9.16"), - TestedVersions(bazel="6.4.0", python="3.10.9"), - TestedVersions(bazel="7.0.0rc5", python="3.11.1"), - TestedVersions(bazel="8.0.0-pre.20231030.2", python="3.11.1"), + TestedVersions(bazel="5.4.1", python="3.8.18"), + TestedVersions(bazel="6.0.0", python="3.9.18"), + TestedVersions(bazel="6.4.0", python="3.10.13"), + TestedVersions(bazel="7.0.0rc5", python="3.11.6"), + TestedVersions(bazel="8.0.0-pre.20231030.2", python="3.11.6"), ] # When Bazel 7.0.0 releases we have to look again at the flags and check if more flags are available VERSION_SPECIFIC_ARGS = { + # We support Bazel's modern dependency management system, but it works only as desired with a recent Bazel version + "--experimental_enable_bzlmod=false": CompatibleVersions(max="6.1.99"), + # We are not yet sure if we really want to lock the bzlmod resolution down given we test with various Bazel versions + # and configurations. It seems the main benefits of the lock file are not having to reanalyze the central registry + # when working without a cached workspace and being safeguarded against changed or yanked modules in the central + # registry. Both don't matter much to us right now. + "--lockfile_mode=off": CompatibleVersions(min="6.2.0"), + # Incompatible changes "--incompatible_legacy_local_fallback=false": CompatibleVersions(min="5.0.0"), # false is the forward path behavior "--incompatible_enforce_config_setting_visibility": CompatibleVersions(min="5.0.0"), "--incompatible_config_setting_private_default_visibility": CompatibleVersions(min="5.0.0"), diff --git a/test/aspect/external_repo/repo/MODULE.bazel b/test/aspect/external_repo/repo/MODULE.bazel new file mode 100644 index 00000000..eb93cad9 --- /dev/null +++ b/test/aspect/external_repo/repo/MODULE.bazel @@ -0,0 +1 @@ +module(name = "ext_repo") diff --git a/third_party/dependencies.bzl b/third_party/dependencies.bzl index 60fafb24..278bf6a6 100644 --- a/third_party/dependencies.bzl +++ b/third_party/dependencies.bzl @@ -2,6 +2,7 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") def dependencies(): + # Keep in sync with MODULE.bazel rules_python_version = "0.27.0" maybe( http_archive, @@ -11,6 +12,7 @@ def dependencies(): urls = ["https://github.com/bazelbuild/rules_python/releases/download/{v}/rules_python-{v}.tar.gz".format(v = rules_python_version)], ) + # Keep in sync with MODULE.bazel skylib_version = "1.5.0" http_archive( name = "bazel_skylib", diff --git a/third_party/extensions.bzl b/third_party/extensions.bzl new file mode 100644 index 00000000..560fdfa0 --- /dev/null +++ b/third_party/extensions.bzl @@ -0,0 +1,8 @@ +load("//third_party:dev_dependencies.bzl", "dev_dependencies") + +def _non_module_dependencies_impl(_ctx): + dev_dependencies() + +non_module_dependencies = module_extension( + implementation = _non_module_dependencies_impl, +) From 0712b8ef99bd4699fc3391902661e934625e73b3 Mon Sep 17 00:00:00 2001 From: Martin Medler Date: Sun, 17 Dec 2023 10:45:42 +0100 Subject: [PATCH 2/5] More descriptive test repo names Now that the external integration testing repos are mentioned in a root level file their names should be more descriptive. --- MODULE.bazel | 8 ++++---- test/aspect/complex_includes/BUILD | 2 +- test/aspect/complex_includes/ext_repo.bzl | 2 +- test/aspect/complex_includes/ext_repo/MODULE.bazel | 2 +- test/aspect/execute_tests.py | 2 +- test/aspect/external_repo/BUILD | 4 ++-- test/aspect/external_repo/repo.bzl | 2 +- test/aspect/external_repo/repo/MODULE.bazel | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 90caca4e..5999ff65 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -76,22 +76,22 @@ non_module_dependencies = use_extension( use_repo(non_module_dependencies, "mypy_integration") bazel_dep( - name = "ext_repo", + name = "external_test_repo", version = "0.0.0", dev_dependency = True, ) local_path_override( - module_name = "ext_repo", + module_name = "external_test_repo", path = "test/aspect/external_repo/repo", ) bazel_dep( - name = "complex_includes_repo", + name = "complex_includes_test_repo", version = "0.0.0", dev_dependency = True, ) local_path_override( - module_name = "complex_includes_repo", + module_name = "complex_includes_test_repo", path = "test/aspect/complex_includes/ext_repo", ) diff --git a/test/aspect/complex_includes/BUILD b/test/aspect/complex_includes/BUILD index 10346ac6..08ebd4fb 100644 --- a/test/aspect/complex_includes/BUILD +++ b/test/aspect/complex_includes/BUILD @@ -19,5 +19,5 @@ cc_library( cc_library( name = "use_complex_includes_from_extern", srcs = ["use_complex_includes.cpp"], - deps = ["@complex_includes_repo//:complex_includes"], + deps = ["@complex_includes_test_repo//:complex_includes"], ) diff --git a/test/aspect/complex_includes/ext_repo.bzl b/test/aspect/complex_includes/ext_repo.bzl index fda53177..7084ca4d 100644 --- a/test/aspect/complex_includes/ext_repo.bzl +++ b/test/aspect/complex_includes/ext_repo.bzl @@ -1,6 +1,6 @@ # buildifier: disable=unnamed-macro def load_complex_includes_repo(): native.local_repository( - name = "complex_includes_repo", + name = "complex_includes_test_repo", path = "test/aspect/complex_includes/ext_repo", ) diff --git a/test/aspect/complex_includes/ext_repo/MODULE.bazel b/test/aspect/complex_includes/ext_repo/MODULE.bazel index 8269dc74..2b94e80a 100644 --- a/test/aspect/complex_includes/ext_repo/MODULE.bazel +++ b/test/aspect/complex_includes/ext_repo/MODULE.bazel @@ -1 +1 @@ -module(name = "complex_includes_repo") +module(name = "complex_includes_test_repo") diff --git a/test/aspect/execute_tests.py b/test/aspect/execute_tests.py index 538e08d5..f1b4d7fa 100755 --- a/test/aspect/execute_tests.py +++ b/test/aspect/execute_tests.py @@ -248,7 +248,7 @@ ), TestCase( name="complex_includes_in_ext_repo", - cmd=TestCmd(target="@complex_includes_repo//...", aspect=DEFAULT_ASPECT), + cmd=TestCmd(target="@complex_includes_test_repo//...", aspect=DEFAULT_ASPECT), expected=ExpectedResult(success=True), ), TestCase( diff --git a/test/aspect/external_repo/BUILD b/test/aspect/external_repo/BUILD index 861c6cd4..22b902d1 100644 --- a/test/aspect/external_repo/BUILD +++ b/test/aspect/external_repo/BUILD @@ -2,7 +2,7 @@ cc_library( name = "use_external_libs", hdrs = ["use_external_libs.h"], deps = [ - "@ext_repo//:ext_bar", - "@ext_repo//:ext_foo", + "@external_test_repo//:ext_bar", + "@external_test_repo//:ext_foo", ], ) diff --git a/test/aspect/external_repo/repo.bzl b/test/aspect/external_repo/repo.bzl index c5ae404e..23e95c73 100644 --- a/test/aspect/external_repo/repo.bzl +++ b/test/aspect/external_repo/repo.bzl @@ -1,6 +1,6 @@ # buildifier: disable=unnamed-macro def load_external_repo(): native.local_repository( - name = "ext_repo", + name = "external_test_repo", path = "test/aspect/external_repo/repo", ) diff --git a/test/aspect/external_repo/repo/MODULE.bazel b/test/aspect/external_repo/repo/MODULE.bazel index eb93cad9..b648d00c 100644 --- a/test/aspect/external_repo/repo/MODULE.bazel +++ b/test/aspect/external_repo/repo/MODULE.bazel @@ -1 +1 @@ -module(name = "ext_repo") +module(name = "external_test_repo") From b6495349add4d86765f79b2a6f04a52b2bf08dc1 Mon Sep 17 00:00:00 2001 From: Martin Medler Date: Sun, 17 Dec 2023 10:52:08 +0100 Subject: [PATCH 3/5] Update Bazel and Python versions --- .bazelversion | 2 +- MODULE.bazel | 3 +++ test/aspect/execute_tests.py | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.bazelversion b/.bazelversion index 6abaeb2f..19b860c1 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -6.2.0 +6.4.0 diff --git a/MODULE.bazel b/MODULE.bazel index 5999ff65..87603a22 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -55,6 +55,9 @@ python.toolchain( python.toolchain( python_version = "3.11", ) +python.toolchain( + python_version = "3.12", +) pip_dev = use_extension( "@rules_python//python/extensions:pip.bzl", diff --git a/test/aspect/execute_tests.py b/test/aspect/execute_tests.py index f1b4d7fa..b979624f 100755 --- a/test/aspect/execute_tests.py +++ b/test/aspect/execute_tests.py @@ -18,8 +18,8 @@ TestedVersions(bazel="5.4.1", python="3.8.18"), TestedVersions(bazel="6.0.0", python="3.9.18"), TestedVersions(bazel="6.4.0", python="3.10.13"), - TestedVersions(bazel="7.0.0rc5", python="3.11.6"), - TestedVersions(bazel="8.0.0-pre.20231030.2", python="3.11.6"), + TestedVersions(bazel="7.0.0", python="3.11.6"), + TestedVersions(bazel="8.0.0-pre.20231030.2", python="3.12.0"), ] # When Bazel 7.0.0 releases we have to look again at the flags and check if more flags are available From a8177a72f688b0cad65772ce163c6dc632e03cdc Mon Sep 17 00:00:00 2001 From: Martin Medler Date: Sun, 17 Dec 2023 10:55:05 +0100 Subject: [PATCH 4/5] Update buildifier --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ab36820d..58676f3a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,7 +21,7 @@ repos: additional_dependencies: - mdformat-gfm - repo: https://github.com/keith/pre-commit-buildifier - rev: 6.3.3.1 + rev: 6.4.0 hooks: - id: buildifier args: [ "--warnings=+out-of-order-load,+unsorted-dict-items,+native-py" ] From c495faddae061119b982f43f68a39fef1937f994 Mon Sep 17 00:00:00 2001 From: Martin Medler Date: Sun, 17 Dec 2023 11:16:40 +0100 Subject: [PATCH 5/5] Update incompatibility flags --- test/aspect/execute_tests.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/aspect/execute_tests.py b/test/aspect/execute_tests.py index b979624f..b513e3e3 100755 --- a/test/aspect/execute_tests.py +++ b/test/aspect/execute_tests.py @@ -39,7 +39,6 @@ "--incompatible_struct_has_no_methods": CompatibleVersions(min="5.0.0"), "--incompatible_use_platforms_repo_for_constraints": CompatibleVersions(min="5.0.0", max="6.99.99"), "--incompatible_disallow_empty_glob": CompatibleVersions(min="5.0.0"), - "--incompatible_existing_rules_immutable_view": CompatibleVersions(min="5.0.0"), "--incompatible_no_implicit_file_export": CompatibleVersions(min="5.0.0"), "--incompatible_use_cc_configure_from_rules_cc": CompatibleVersions(min="5.0.0"), "--incompatible_default_to_explicit_init_py": CompatibleVersions(min="5.0.0"), @@ -49,8 +48,13 @@ "--incompatible_sandbox_hermetic_tmp": CompatibleVersions(min="6.0.0"), "--incompatible_check_testonly_for_output_files": CompatibleVersions(min="6.0.0"), "--incompatible_check_visibility_for_toolchains": CompatibleVersions(min="7.0.0"), + "--incompatible_auto_exec_groups": CompatibleVersions(min="7.0.0"), + "--incompatible_disable_non_executable_java_binary": CompatibleVersions(min="7.0.0"), + # TODO for us to work on those: + # "--incompatible_stop_exporting_language_modules": CompatibleVersions(min="5.0.0"), # Theoretically interesting for our project, but Bazel itself does not adhere to it # "--incompatible_python_disallow_native_rules": CompatibleVersions(min="7.0.0"), + # Theoretically of interest for us, but rules_python does not comply to this. # "--incompatible_disallow_struct_provider_syntax": CompatibleVersions(min="7.0.0"), }