feat(bzlmod): support entry_point macro (#1220)
Add `entry_point` macro to the repo generated by the `pip.parse`
extension.
This works by using the canonical label literal, so should work without
users
needing to add the spoke repos to the `use_repo` statement. We test this
by
having an extra folder in the `bzlmod` example.
Fixes #958.
diff --git a/.bazelrc b/.bazelrc
index e7e4af7..fe542b3 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -3,8 +3,8 @@
# This lets us glob() up all the files inside the examples to make them inputs to tests
# (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it)
# To update these lines, run tools/bazel_integration_test/update_deleted_packages.sh
-build --deleted_packages=examples/build_file_generation,examples/build_file_generation/get_url,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/multi_python_versions,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_import,examples/py_proto_library,examples/relative_requirements,tests/compile_pip_requirements,tests/pip_repository_entry_points,tests/pip_deps
-query --deleted_packages=examples/build_file_generation,examples/build_file_generation/get_url,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/multi_python_versions,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_import,examples/py_proto_library,examples/relative_requirements,tests/compile_pip_requirements,tests/pip_repository_entry_points,tests/pip_deps
+build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_point,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,tests/compile_pip_requirements,tests/compile_pip_requirements_test_from_external_workspace,tests/ignore_root_user_error,tests/pip_repository_entry_points
+query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_point,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/runfiles,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_install,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,tests/compile_pip_requirements,tests/compile_pip_requirements_test_from_external_workspace,tests/ignore_root_user_error,tests/pip_repository_entry_points
test --test_output=errors
diff --git a/examples/bzlmod/BUILD.bazel b/examples/bzlmod/BUILD.bazel
index 3183608..e1f5790 100644
--- a/examples/bzlmod/BUILD.bazel
+++ b/examples/bzlmod/BUILD.bazel
@@ -35,6 +35,7 @@
py_test(
name = "test",
srcs = ["test.py"],
+ main = "test.py",
deps = [":lib"],
)
diff --git a/examples/bzlmod/MODULE.bazel b/examples/bzlmod/MODULE.bazel
index d2d7d63..145cebd 100644
--- a/examples/bzlmod/MODULE.bazel
+++ b/examples/bzlmod/MODULE.bazel
@@ -24,11 +24,19 @@
"@python3_9_toolchains//:all",
)
+interpreter = use_extension("@rules_python//python/extensions:interpreter.bzl", "interpreter")
+interpreter.install(
+ name = "interpreter_python3_9",
+ python_name = "python3_9",
+)
+use_repo(interpreter, "interpreter_python3_9")
+
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
pip.parse(
name = "pip",
# Intentionally set it false because the "true" case is already covered by examples/bzlmod_build_file_generation
incompatible_generate_aliases = False,
+ python_interpreter_target = "@interpreter_python3_9//:python",
requirements_lock = "//:requirements_lock.txt",
requirements_windows = "//:requirements_windows.txt",
)
diff --git a/examples/bzlmod/entry_point/BUILD.bazel b/examples/bzlmod/entry_point/BUILD.bazel
new file mode 100644
index 0000000..dfc02b0
--- /dev/null
+++ b/examples/bzlmod/entry_point/BUILD.bazel
@@ -0,0 +1,20 @@
+load("@pip//:requirements.bzl", "entry_point")
+load("@rules_python//python:defs.bzl", "py_test")
+
+alias(
+ name = "yamllint",
+ actual = entry_point("yamllint"),
+)
+
+py_test(
+ name = "entry_point_test",
+ srcs = ["test_entry_point.py"],
+ data = [
+ ":yamllint",
+ ],
+ env = {
+ "YAMLLINT_ENTRY_POINT": "$(rlocationpath :yamllint)",
+ },
+ main = "test_entry_point.py",
+ deps = ["@rules_python//python/runfiles"],
+)
diff --git a/examples/bzlmod/entry_point/test_entry_point.py b/examples/bzlmod/entry_point/test_entry_point.py
new file mode 100644
index 0000000..5a37458
--- /dev/null
+++ b/examples/bzlmod/entry_point/test_entry_point.py
@@ -0,0 +1,43 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import pathlib
+import subprocess
+import unittest
+
+from python.runfiles import runfiles
+
+
+class ExampleTest(unittest.TestCase):
+ def test_entry_point(self):
+ rlocation_path = os.environ.get("YAMLLINT_ENTRY_POINT")
+ assert (
+ rlocation_path is not None
+ ), "expected 'YAMLLINT_ENTRY_POINT' env variable to be set to rlocation of the tool"
+
+ entry_point = pathlib.Path(runfiles.Create().Rlocation(rlocation_path))
+ self.assertTrue(entry_point.exists(), f"'{entry_point}' does not exist")
+
+ proc = subprocess.run(
+ [str(entry_point), "--version"],
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ self.assertEqual(proc.stdout.decode("utf-8").strip(), "yamllint 1.28.0")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/python/pip_install/pip_repository.bzl b/python/pip_install/pip_repository.bzl
index 406e121..5239fd5 100644
--- a/python/pip_install/pip_repository.bzl
+++ b/python/pip_install/pip_repository.bzl
@@ -387,6 +387,7 @@
for p in bzl_packages
]),
"%%MACRO_TMPL%%": macro_tmpl,
+ "%%NAME%%": rctx.attr.name,
"%%REQUIREMENTS_LOCK%%": str(requirements_txt),
})
diff --git a/python/pip_install/pip_repository_requirements_bzlmod.bzl.tmpl b/python/pip_install/pip_repository_requirements_bzlmod.bzl.tmpl
index 1b2e217..b77bf39 100644
--- a/python/pip_install/pip_repository_requirements_bzlmod.bzl.tmpl
+++ b/python/pip_install/pip_repository_requirements_bzlmod.bzl.tmpl
@@ -22,3 +22,10 @@
def dist_info_requirement(name):
return "%%MACRO_TMPL%%".format(_clean_name(name), "dist_info")
+
+def entry_point(pkg, script = None):
+ """entry_point returns the target of the canonical label of the package entrypoints.
+ """
+ if not script:
+ script = pkg
+ return "@@%%NAME%%_{}//:rules_python_wheel_entry_point_{}".format(_clean_name(pkg), script)