Skip to content

Commit 1a5e0c7

Browse files
committed
fix: update correct requirements lock file when using os specific lock files
1 parent 693a158 commit 1a5e0c7

File tree

6 files changed

+133
-26
lines changed

6 files changed

+133
-26
lines changed

.bazelci/presubmit.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,54 @@ tasks:
471471
- "! git diff --exit-code"
472472
- "bazel run //:requirements.update"
473473
- "git diff --exit-code"
474+
integration_test_compile_pip_os_specific_requirements_ubuntu:
475+
<<: *reusable_build_test_all
476+
name: compile_pip_os_specific_requirements integration tests on Ubuntu
477+
working_directory: tests/compile_pip_requirements
478+
platform: ubuntu2004
479+
shell_commands:
480+
# Make a change to the locked requirements and then assert that //:os_specific_requirements.update does the
481+
# right thing.
482+
- "echo '' > requirements_lock_linux.txt"
483+
- "! git diff --exit-code"
484+
- "bazel run //:os_specific_requirements.update"
485+
- "git diff --exit-code"
486+
integration_test_compile_pip_os_specific_requirements_debian:
487+
<<: *reusable_build_test_all
488+
name: compile_pip_os_specific_requirements integration tests on Debian
489+
working_directory: tests/compile_pip_requirements
490+
platform: debian11
491+
shell_commands:
492+
# Make a change to the locked requirements and then assert that //:os_specific_requirements.update does the
493+
# right thing.
494+
- "echo '' > requirements_lock_linux.txt"
495+
- "! git diff --exit-code"
496+
- "bazel run //:os_specific_requirements.update"
497+
- "git diff --exit-code"
498+
integration_test_compile_pip_os_specific_requirements_macos:
499+
<<: *reusable_build_test_all
500+
name: compile_pip_os_specific_requirements integration tests on macOS
501+
working_directory: tests/compile_pip_requirements
502+
platform: macos
503+
shell_commands:
504+
# Make a change to the locked requirements and then assert that //:os_specific_requirements.update does the
505+
# right thing.
506+
- "echo '' > requirements_lock_darwin.txt"
507+
- "! git diff --exit-code"
508+
- "bazel run //:os_specific_requirements.update"
509+
- "git diff --exit-code"
510+
integration_test_compile_pip_os_specific_requirements_windows:
511+
<<: *reusable_build_test_all
512+
name: compile_pip_os_specific_requirements integration tests on Windows
513+
working_directory: tests/compile_pip_requirements
514+
platform: windows
515+
shell_commands:
516+
# Make a change to the locked requirements and then assert that //:os_specific_requirements.update does the
517+
# right thing.
518+
- "echo '' > requirements_lock_windows.txt"
519+
- "! git diff --exit-code"
520+
- "bazel run //:os_specific_requirements.update"
521+
- "git diff --exit-code"
474522

475523
integration_test_pip_repository_entry_points_ubuntu_min:
476524
<<: *minimum_supported_version

python/pip_install/tools/dependency_resolver/dependency_resolver.py

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -95,25 +95,30 @@ def _locate(bazel_runfiles, file):
9595
requirements_windows = parse_str_none(sys.argv.pop(1))
9696
update_target_label = sys.argv.pop(1)
9797

98+
requirements_file = _select_golden_requirements_file(
99+
requirements_txt=requirements_txt, requirements_linux=requirements_linux,
100+
requirements_darwin=requirements_darwin, requirements_windows=requirements_windows
101+
)
102+
98103
resolved_requirements_in = _locate(bazel_runfiles, requirements_in)
99-
resolved_requirements_txt = _locate(bazel_runfiles, requirements_txt)
104+
resolved_requirements_file = _locate(bazel_runfiles, requirements_file)
100105

101106
# Files in the runfiles directory has the following naming schema:
102107
# Main repo: __main__/<path_to_file>
103108
# External repo: <workspace name>/<path_to_file>
104109
# We want to strip both __main__ and <workspace name> from the absolute prefix
105110
# to keep the requirements lock file agnostic.
106-
repository_prefix = requirements_txt[: requirements_txt.index("/") + 1]
107-
absolute_path_prefix = resolved_requirements_txt[
108-
: -(len(requirements_txt) - len(repository_prefix))
111+
repository_prefix = requirements_file[: requirements_file.index("/") + 1]
112+
absolute_path_prefix = resolved_requirements_file[
113+
: -(len(requirements_file) - len(repository_prefix))
109114
]
110115

111116
# As requirements_in might contain references to generated files we want to
112117
# use the runfiles file first. Thus, we need to compute the relative path
113118
# from the execution root.
114119
# Note: Windows cannot reference generated files without runfiles support enabled.
115-
requirements_in_relative = requirements_in[len(repository_prefix) :]
116-
requirements_txt_relative = requirements_txt[len(repository_prefix) :]
120+
requirements_in_relative = requirements_in[len(repository_prefix):]
121+
requirements_file_relative = requirements_file[len(repository_prefix):]
117122

118123
# Before loading click, set the locale for its parser.
119124
# If it leaks through to the system setting, it may fail:
@@ -135,11 +140,11 @@ def _locate(bazel_runfiles, file):
135140
sys.argv.append(os.environ["TEST_TMPDIR"])
136141
# Make a copy for pip-compile to read and mutate.
137142
requirements_out = os.path.join(
138-
os.environ["TEST_TMPDIR"], os.path.basename(requirements_txt) + ".out"
143+
os.environ["TEST_TMPDIR"], os.path.basename(requirements_file) + ".out"
139144
)
140145
# Those two files won't necessarily be on the same filesystem, so we can't use os.replace
141146
# or shutil.copyfile, as they will fail with OSError: [Errno 18] Invalid cross-device link.
142-
shutil.copy(resolved_requirements_txt, requirements_out)
147+
shutil.copy(resolved_requirements_file, requirements_out)
143148

144149
update_command = os.getenv("CUSTOM_COMPILE_COMMAND") or "bazel run %s" % (
145150
update_target_label,
@@ -150,7 +155,7 @@ def _locate(bazel_runfiles, file):
150155

151156
sys.argv.append("--generate-hashes")
152157
sys.argv.append("--output-file")
153-
sys.argv.append(requirements_txt_relative if UPDATE else requirements_out)
158+
sys.argv.append(requirements_file_relative if UPDATE else requirements_out)
154159
sys.argv.append(
155160
requirements_in_relative
156161
if Path(requirements_in_relative).exists()
@@ -159,28 +164,28 @@ def _locate(bazel_runfiles, file):
159164
print(sys.argv)
160165

161166
if UPDATE:
162-
print("Updating " + requirements_txt_relative)
167+
print("Updating " + requirements_file_relative)
163168
if "BUILD_WORKSPACE_DIRECTORY" in os.environ:
164169
workspace = os.environ["BUILD_WORKSPACE_DIRECTORY"]
165-
requirements_txt_tree = os.path.join(workspace, requirements_txt_relative)
166-
# In most cases, requirements_txt will be a symlink to the real file in the source tree.
167-
# If symlinks are not enabled (e.g. on Windows), then requirements_txt will be a copy,
170+
requirements_file_tree = os.path.join(workspace, requirements_file_relative)
171+
# In most cases, requirements_file will be a symlink to the real file in the source tree.
172+
# If symlinks are not enabled (e.g. on Windows), then requirements_file will be a copy,
168173
# and we should copy the updated requirements back to the source tree.
169-
if not os.path.samefile(resolved_requirements_txt, requirements_txt_tree):
174+
if not os.path.samefile(resolved_requirements_file, requirements_file_tree):
170175
atexit.register(
171176
lambda: shutil.copy(
172-
resolved_requirements_txt, requirements_txt_tree
177+
resolved_requirements_file, requirements_file_tree
173178
)
174179
)
175180
cli()
176-
requirements_txt_relative_path = Path(requirements_txt_relative)
177-
content = requirements_txt_relative_path.read_text()
181+
requirements_file_relative_path = Path(requirements_file_relative)
182+
content = requirements_file_relative_path.read_text()
178183
content = content.replace(absolute_path_prefix, "")
179-
requirements_txt_relative_path.write_text(content)
184+
requirements_file_relative_path.write_text(content)
180185
else:
181186
# cli will exit(0) on success
182187
try:
183-
print("Checking " + requirements_txt)
188+
print("Checking " + requirements_file)
184189
cli()
185190
print("cli() should exit", file=sys.stderr)
186191
sys.exit(1)
@@ -194,13 +199,7 @@ def _locate(bazel_runfiles, file):
194199
)
195200
sys.exit(1)
196201
elif e.code == 0:
197-
golden_filename = _select_golden_requirements_file(
198-
requirements_txt,
199-
requirements_linux,
200-
requirements_darwin,
201-
requirements_windows,
202-
)
203-
golden = open(_locate(bazel_runfiles, golden_filename)).readlines()
202+
golden = open(_locate(bazel_runfiles, requirements_file)).readlines()
204203
out = open(requirements_out).readlines()
205204
out = [line.replace(absolute_path_prefix, "") for line in out]
206205
if golden != out:

tests/compile_pip_requirements/BUILD.bazel

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,33 @@ compile_pip_requirements(
3232
requirements_in = "requirements.txt",
3333
requirements_txt = "requirements_lock.txt",
3434
)
35+
36+
genrule(
37+
name = "generate_os_specific_requirements_in",
38+
srcs = [],
39+
outs = ["requirements_os_specific.in"],
40+
cmd = """
41+
cat > $@ <<EOF
42+
pip==22.3.0 ; sys_platform == "linux"
43+
pip==22.2.2 ; sys_platform == "darwin"
44+
pip==22.2.1 ; sys_platform == "win32"
45+
EOF
46+
""",
47+
)
48+
49+
compile_pip_requirements(
50+
name = "os_specific_requirements",
51+
data = [
52+
"requirements_extra.in",
53+
"requirements_os_specific.in",
54+
],
55+
extra_args = [
56+
"--allow-unsafe",
57+
"--resolver=backtracking",
58+
],
59+
requirements_darwin = "requirements_lock_darwin.txt",
60+
requirements_in = "requirements_os_specific.in",
61+
requirements_linux = "requirements_lock_linux.txt",
62+
requirements_txt = "requirements_lock.txt",
63+
requirements_windows = "requirements_lock_windows.txt",
64+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#
2+
# This file is autogenerated by pip-compile with Python 3.9
3+
# by the following command:
4+
#
5+
# bazel run //:os_specific_requirements.update
6+
#
7+
pip==22.2.2 ; sys_platform == "darwin" \
8+
--hash=sha256:3fd1929db052f056d7a998439176d3333fa1b3f6c1ad881de1885c0717608a4b \
9+
--hash=sha256:b61a374b5bc40a6e982426aede40c9b5a08ff20e640f5b56977f4f91fed1e39a
10+
# via -r ./requirements_os_specific.in
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#
2+
# This file is autogenerated by pip-compile with Python 3.9
3+
# by the following command:
4+
#
5+
# bazel run //:os_specific_requirements.update
6+
#
7+
pip==22.3 ; sys_platform == "linux" \
8+
--hash=sha256:1daab4b8d3b97d1d763caeb01a4640a2250a0ea899e257b1e44b9eded91e15ab \
9+
--hash=sha256:8182aec21dad6c0a49a2a3d121a87cd524b950e0b6092b181625f07ebdde7530
10+
# via -r ./requirements_os_specific.in
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#
2+
# This file is autogenerated by pip-compile with Python 3.9
3+
# by the following command:
4+
#
5+
# bazel run //:os_specific_requirements.update
6+
#
7+
pip==22.2.1 ; sys_platform == "win32" \
8+
--hash=sha256:0bbbc87dfbe6eed217beff0021f8b7dea04c8f4a0baa9d31dc4cff281ffc5b2b \
9+
--hash=sha256:50516e47a2b79e77446f0d05649f0d53772c192571486236b1905492bfc24bac
10+
# via -r ./requirements_os_specific.in

0 commit comments

Comments
 (0)