Skip to content

Commit 693a158

Browse files
authored
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.
1 parent 1383bd4 commit 693a158

File tree

7 files changed

+82
-2
lines changed

7 files changed

+82
-2
lines changed

.bazelrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
# This lets us glob() up all the files inside the examples to make them inputs to tests
44
# (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it)
55
# To update these lines, run tools/bazel_integration_test/update_deleted_packages.sh
6-
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
7-
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
6+
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
7+
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
88

99
test --test_output=errors
1010

examples/bzlmod/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ py_binary(
3535
py_test(
3636
name = "test",
3737
srcs = ["test.py"],
38+
main = "test.py",
3839
deps = [":lib"],
3940
)
4041

examples/bzlmod/MODULE.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,19 @@ register_toolchains(
2424
"@python3_9_toolchains//:all",
2525
)
2626

27+
interpreter = use_extension("@rules_python//python/extensions:interpreter.bzl", "interpreter")
28+
interpreter.install(
29+
name = "interpreter_python3_9",
30+
python_name = "python3_9",
31+
)
32+
use_repo(interpreter, "interpreter_python3_9")
33+
2734
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
2835
pip.parse(
2936
name = "pip",
3037
# Intentionally set it false because the "true" case is already covered by examples/bzlmod_build_file_generation
3138
incompatible_generate_aliases = False,
39+
python_interpreter_target = "@interpreter_python3_9//:python",
3240
requirements_lock = "//:requirements_lock.txt",
3341
requirements_windows = "//:requirements_windows.txt",
3442
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
load("@pip//:requirements.bzl", "entry_point")
2+
load("@rules_python//python:defs.bzl", "py_test")
3+
4+
alias(
5+
name = "yamllint",
6+
actual = entry_point("yamllint"),
7+
)
8+
9+
py_test(
10+
name = "entry_point_test",
11+
srcs = ["test_entry_point.py"],
12+
data = [
13+
":yamllint",
14+
],
15+
env = {
16+
"YAMLLINT_ENTRY_POINT": "$(rlocationpath :yamllint)",
17+
},
18+
main = "test_entry_point.py",
19+
deps = ["@rules_python//python/runfiles"],
20+
)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Copyright 2023 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
import pathlib
17+
import subprocess
18+
import unittest
19+
20+
from python.runfiles import runfiles
21+
22+
23+
class ExampleTest(unittest.TestCase):
24+
def test_entry_point(self):
25+
rlocation_path = os.environ.get("YAMLLINT_ENTRY_POINT")
26+
assert (
27+
rlocation_path is not None
28+
), "expected 'YAMLLINT_ENTRY_POINT' env variable to be set to rlocation of the tool"
29+
30+
entry_point = pathlib.Path(runfiles.Create().Rlocation(rlocation_path))
31+
self.assertTrue(entry_point.exists(), f"'{entry_point}' does not exist")
32+
33+
proc = subprocess.run(
34+
[str(entry_point), "--version"],
35+
check=True,
36+
stdout=subprocess.PIPE,
37+
stderr=subprocess.PIPE,
38+
)
39+
self.assertEqual(proc.stdout.decode("utf-8").strip(), "yamllint 1.28.0")
40+
41+
42+
if __name__ == "__main__":
43+
unittest.main()

python/pip_install/pip_repository.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ def _pip_repository_bzlmod_impl(rctx):
387387
for p in bzl_packages
388388
]),
389389
"%%MACRO_TMPL%%": macro_tmpl,
390+
"%%NAME%%": rctx.attr.name,
390391
"%%REQUIREMENTS_LOCK%%": str(requirements_txt),
391392
})
392393

python/pip_install/pip_repository_requirements_bzlmod.bzl.tmpl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,10 @@ def data_requirement(name):
2222

2323
def dist_info_requirement(name):
2424
return "%%MACRO_TMPL%%".format(_clean_name(name), "dist_info")
25+
26+
def entry_point(pkg, script = None):
27+
"""entry_point returns the target of the canonical label of the package entrypoints.
28+
"""
29+
if not script:
30+
script = pkg
31+
return "@@%%NAME%%_{}//:rules_python_wheel_entry_point_{}".format(_clean_name(pkg), script)

0 commit comments

Comments
 (0)