diff options
Diffstat (limited to 'third_party/rules_pycross/pycross/private/tools/wheel_installer.py')
-rw-r--r-- | third_party/rules_pycross/pycross/private/tools/wheel_installer.py | 196 |
1 files changed, 0 insertions, 196 deletions
diff --git a/third_party/rules_pycross/pycross/private/tools/wheel_installer.py b/third_party/rules_pycross/pycross/private/tools/wheel_installer.py deleted file mode 100644 index 0c352cf..0000000 --- a/third_party/rules_pycross/pycross/private/tools/wheel_installer.py +++ /dev/null @@ -1,196 +0,0 @@ -# Copyright 2023 Jeremy Volkman. All rights reserved. -# 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. - -""" -A tool that invokes pypa/build to build the given sdist tarball. -""" - -import argparse -import os -import shutil -import subprocess -import sys -import tempfile -from pathlib import Path -from typing import Any - -from installer import install -from installer.destinations import SchemeDictionaryDestination -from installer.sources import WheelFile - -from python.pip_install.tools.wheel_installer import namespace_pkgs - - -def setup_namespace_pkg_compatibility(wheel_dir: Path) -> None: - """Converts native namespace packages to pkgutil-style packages - - Namespace packages can be created in one of three ways. They are detailed here: - https://packaging.python.org/guides/packaging-namespace-packages/#creating-a-namespace-package - - 'pkgutil-style namespace packages' (2) and 'pkg_resources-style namespace packages' (3) works in Bazel, but - 'native namespace packages' (1) do not. - - We ensure compatibility with Bazel of method 1 by converting them into method 2. - - Args: - wheel_dir: the directory of the wheel to convert - """ - - namespace_pkg_dirs = namespace_pkgs.implicit_namespace_packages( - str(wheel_dir), - ignored_dirnames=["%s/bin" % wheel_dir], - ) - - for ns_pkg_dir in namespace_pkg_dirs: - namespace_pkgs.add_pkgutil_style_namespace_pkg_init(ns_pkg_dir) - - -def main(args: Any) -> None: - dest_dir = args.directory - lib_dir = dest_dir / "site-packages" - destination = SchemeDictionaryDestination( - scheme_dict={ - "platlib": str(lib_dir), - "purelib": str(lib_dir), - "headers": str(dest_dir / "include"), - "scripts": str(dest_dir / "bin"), - "data": str(dest_dir / "data"), - }, - interpreter="/usr/bin/env python3", # Generic; it's not feasible to run these scripts directly. - script_kind="posix", - bytecode_optimization_levels=[0, 1], - ) - - link_dir = Path(tempfile.mkdtemp()) - if args.wheel_name_file: - with open(args.wheel_name_file, "r") as f: - wheel_name = f.read().strip() - else: - wheel_name = os.path.basename(args.wheel) - - link_path = link_dir / wheel_name - os.symlink(os.path.join(os.getcwd(), args.wheel), link_path) - - try: - with WheelFile.open(link_path) as source: - install( - source=source, - destination=destination, - # Additional metadata that is generated by the installation tool. - additional_metadata={ - "INSTALLER": b"https://github.com/bazelbuild/rules_python/tree/main/third_party/rules_pycross", - }, - ) - finally: - shutil.rmtree(link_dir, ignore_errors=True) - - setup_namespace_pkg_compatibility(lib_dir) - - if args.patch: - if not args.patch_tool and not args.patch_tool_target: - raise ValueError("Specify one of 'patch_tool' or 'patch_tool_target'.") - - patch_args = [ - args.patch_tool or Path.cwd() / args.patch_tool_target - ] + args.patch_arg - for patch in args.patch: - with patch.open("r") as stdin: - try: - subprocess.run( - patch_args, - stdin=stdin, - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - cwd=args.directory, - ) - except subprocess.CalledProcessError as error: - print(f"Patch {patch} failed to apply:") - print(error.stdout.decode("utf-8")) - raise - - -def parse_flags(argv) -> Any: - parser = argparse.ArgumentParser(description="Extract a Python wheel.") - - parser.add_argument( - "--wheel", - type=Path, - required=True, - help="The wheel file path.", - ) - - parser.add_argument( - "--wheel-name-file", - type=Path, - required=False, - help="A file containing the canonical name of the wheel.", - ) - - parser.add_argument( - "--enable-implicit-namespace-pkgs", - action="store_true", - help="If true, disables conversion of implicit namespace packages and will unzip as-is.", - ) - - parser.add_argument( - "--directory", - type=Path, - help="The output path.", - ) - - parser.add_argument( - "--patch", - type=Path, - default=[], - action="append", - help="A patch file to apply.", - ) - - parser.add_argument( - "--patch-arg", - type=str, - default=[], - action="append", - help="An argument for the patch tool when applying the patches.", - ) - - parser.add_argument( - "--patch-tool", - type=str, - help=( - "The tool from PATH to invoke when applying patches. " - "If set, --patch-tool-target is ignored." - ), - ) - - parser.add_argument( - "--patch-tool-target", - type=Path, - help=( - "The path to the tool to invoke when applying patches. " - "Ignored when --patch-tool is set." - ), - ) - - return parser.parse_args(argv[1:]) - - -if __name__ == "__main__": - # When under `bazel run`, change to the actual working dir. - if "BUILD_WORKING_DIRECTORY" in os.environ: - os.chdir(os.environ["BUILD_WORKING_DIRECTORY"]) - - main(parse_flags(sys.argv)) |