From 26419705b20cb35d4c37173491a6a177119a2bac Mon Sep 17 00:00:00 2001 From: Stephen Tridgell <stephen.tridgell@cruxml.com.au> Date: Fri, 25 Oct 2024 14:53:59 +1100 Subject: [PATCH 1/4] type(feat): Allow parsing of wheel file paths in requirements.in inside a bazel repo. --- .../pypi/dependency_resolver/dependency_resolver.py | 10 +++++++++- python/private/pypi/pip_compile.bzl | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/python/private/pypi/dependency_resolver/dependency_resolver.py b/python/private/pypi/dependency_resolver/dependency_resolver.py index 0ff9b2fb7c..8df48fe7c8 100644 --- a/python/private/pypi/dependency_resolver/dependency_resolver.py +++ b/python/private/pypi/dependency_resolver/dependency_resolver.py @@ -20,6 +20,7 @@ import sys from pathlib import Path from typing import Optional, Tuple +import multiprocessing import click import piptools.writer as piptools_writer @@ -97,6 +98,7 @@ def main( extra_args: Tuple[str, ...], ) -> None: bazel_runfiles = runfiles.Create() + runfiles_dir = Path(bazel_runfiles._python_runfiles_root) / "_main" requirements_file = _select_golden_requirements_file( requirements_txt=requirements_txt, @@ -182,10 +184,16 @@ def main( resolved_requirements_file, requirements_file_tree ) ) - cli(argv) + # Run in a process as pip tools is calling sys.exit() + piptools_process = multiprocessing.Process(target=cli, args=[argv]) + piptools_process.start() + piptools_process.join() requirements_file_relative_path = Path(requirements_file_relative) content = requirements_file_relative_path.read_text() content = content.replace(absolute_path_prefix, "") + # For windows or linux. + content = content.replace(str(runfiles_dir) + "/", "") + content = content.replace(str(runfiles_dir) + "\\", "") requirements_file_relative_path.write_text(content) else: # cli will exit(0) on success diff --git a/python/private/pypi/pip_compile.bzl b/python/private/pypi/pip_compile.bzl index dc5b186a6a..da1c1319cf 100644 --- a/python/private/pypi/pip_compile.bzl +++ b/python/private/pypi/pip_compile.bzl @@ -27,6 +27,7 @@ def pip_compile( src = None, extra_args = [], extra_deps = [], + extra_data = [], generate_hashes = True, py_binary = _py_binary, py_test = _py_test, @@ -99,7 +100,7 @@ def pip_compile( visibility = visibility, ) - data = [name, requirements_txt] + srcs + [f for f in (requirements_linux, requirements_darwin, requirements_windows) if f != None] + data = [name, requirements_txt] + srcs + [f for f in (requirements_linux, requirements_darwin, requirements_windows) if f != None] + extra_data # Use the Label constructor so this is expanded in the context of the file # where it appears, which is to say, in @rules_python From 76c57c18397675fb65ec9759a4a7cdf4c337ba9d Mon Sep 17 00:00:00 2001 From: Stephen Tridgell <stephen.tridgell@cruxml.com.au> Date: Fri, 25 Oct 2024 15:01:23 +1100 Subject: [PATCH 2/4] type(feat): Document extra_data for pip_compile --- python/private/pypi/pip_compile.bzl | 1 + 1 file changed, 1 insertion(+) diff --git a/python/private/pypi/pip_compile.bzl b/python/private/pypi/pip_compile.bzl index da1c1319cf..885aebf76e 100644 --- a/python/private/pypi/pip_compile.bzl +++ b/python/private/pypi/pip_compile.bzl @@ -67,6 +67,7 @@ def pip_compile( [PEP621](https://peps.python.org/pep-0621/). extra_args: passed to pip-compile. extra_deps: extra dependencies passed to pip-compile. + extra_data: extra data passed to pip-compile. generate_hashes: whether to put hashes in the requirements_txt file. py_binary: the py_binary rule to be used. py_test: the py_test rule to be used. From 21185530a9dddf23df3855cc9293d365861c1f26 Mon Sep 17 00:00:00 2001 From: Stephen Tridgell <stephen.tridgell@cruxml.com.au> Date: Fri, 25 Oct 2024 17:01:11 +1100 Subject: [PATCH 3/4] type(feat): This is a bit ugly having to provide whl file again. Is there a better way to do this? --- .../pypi/requirements.bzl.tmpl.workspace | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/python/private/pypi/requirements.bzl.tmpl.workspace b/python/private/pypi/requirements.bzl.tmpl.workspace index 2f4bcd6916..a76002c562 100644 --- a/python/private/pypi/requirements.bzl.tmpl.workspace +++ b/python/private/pypi/requirements.bzl.tmpl.workspace @@ -35,7 +35,7 @@ def _get_annotation(requirement): name = requirement.split(" ")[0].split("=")[0].split("[")[0] return _annotations.get(name) -def install_deps(**whl_library_kwargs): +def install_deps(whl_files = {}, **whl_library_kwargs): """Repository rule macro. Install dependencies from `pip_parse`. Args: @@ -61,12 +61,23 @@ def install_deps(**whl_library_kwargs): for name, requirement in _packages: group_name = requirement_group_mapping.get(name.replace("%%NAME%%_", "")) group_deps = all_requirement_groups.get(group_name, []) - - whl_library( - name = name, - requirement = requirement, - group_name = group_name, - group_deps = group_deps, - annotation = _get_annotation(requirement), - **whl_config - ) + if "@ file://" in requirement: + whl_file = whl_files[name] + whl_library( + name = name, + requirement = requirement, + group_name = group_name, + group_deps = group_deps, + annotation = _get_annotation(requirement), + whl_file = whl_file, + **whl_config + ) + else: + whl_library( + name = name, + requirement = requirement, + group_name = group_name, + group_deps = group_deps, + annotation = _get_annotation(requirement), + **whl_config + ) From 705ed917bf7d9ebd6ed0f98428fda11d49d30ff7 Mon Sep 17 00:00:00 2001 From: Stephen Tridgell <stephen.tridgell@cruxml.com.au> Date: Wed, 30 Oct 2024 13:53:34 +1100 Subject: [PATCH 4/4] Refactor and fix indentation. --- .../pypi/requirements.bzl.tmpl.workspace | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/python/private/pypi/requirements.bzl.tmpl.workspace b/python/private/pypi/requirements.bzl.tmpl.workspace index a76002c562..03736e5fef 100644 --- a/python/private/pypi/requirements.bzl.tmpl.workspace +++ b/python/private/pypi/requirements.bzl.tmpl.workspace @@ -62,22 +62,15 @@ def install_deps(whl_files = {}, **whl_library_kwargs): group_name = requirement_group_mapping.get(name.replace("%%NAME%%_", "")) group_deps = all_requirement_groups.get(group_name, []) if "@ file://" in requirement: - whl_file = whl_files[name] - whl_library( - name = name, - requirement = requirement, - group_name = group_name, - group_deps = group_deps, - annotation = _get_annotation(requirement), - whl_file = whl_file, - **whl_config - ) + whl_file = whl_files[name] else: - whl_library( - name = name, - requirement = requirement, - group_name = group_name, - group_deps = group_deps, - annotation = _get_annotation(requirement), - **whl_config - ) + whl_file = None + whl_library( + name = name, + requirement = requirement, + group_name = group_name, + group_deps = group_deps, + annotation = _get_annotation(requirement), + whl_file = whl_file, + **whl_config + )