diff --git a/dev-python/installer/installer-0.5.1.recipe b/dev-python/installer/installer-0.5.1.recipe new file mode 100644 index 000000000..685f6e469 --- /dev/null +++ b/dev-python/installer/installer-0.5.1.recipe @@ -0,0 +1,67 @@ +SUMMARY="A library for installing Python wheels" +DESCRIPTION="This is a low-level library for installing a Python package from a wheel distribution. +It provides basic functionality and abstractions for handling wheels and installing packages from \ +wheels. + +- Logic for unpacking a wheel (i.e. installation). +- Abstractions for various parts of the unpacking process. +- Extensible simple implementations of the abstractions. +- Platform-independent Python script wrapper generation." +HOMEPAGE="https://pypi.org/project/installer/" +COPYRIGHT="2020 Pradyun Gedam" +LICENSE="MIT" +REVISION="1" +pypiVersion="74/b7/9187323cd732840f1cddd6a9f05961406636b50c799eef37c920b63110c0" +SOURCE_URI="https://files.pythonhosted.org/packages/$pypiVersion/installer-$portVersion.tar.gz" +CHECKSUM_SHA256="f970995ec2bb815e2fdaf7977b26b2091e1e386f0f42eafd5ac811953dc5d445" +PATCHES="1a3a7d208fd48446de3d35e5c640378dc1dfd437.patch" + +ARCHITECTURES="any" + +PROVIDES=" + $portName = $portVersion + " +REQUIRES=" + haiku + " + +BUILD_REQUIRES=" + haiku_devel + " + +PYTHON_PACKAGES=(python3 python38 python39 python310) +PYTHON_VERSIONS=(3.7 3.8 3.9 3.10) +for i in "${!PYTHON_PACKAGES[@]}"; do +pythonPackage=${PYTHON_PACKAGES[i]} +pythonVersion=${PYTHON_VERSIONS[$i]} +eval "PROVIDES_${pythonPackage}=\"\ + ${portName}_$pythonPackage = $portVersion\ + \"; \ +REQUIRES_$pythonPackage=\"\ + haiku\n\ + cmd:python$pythonVersion\ + \"" +BUILD_REQUIRES="$BUILD_REQUIRES + setuptools_$pythonPackage" +BUILD_PREREQUIRES="$BUILD_PREREQUIRES + cmd:python$pythonVersion" +done + +INSTALL() +{ + for i in "${!PYTHON_PACKAGES[@]}"; do + pythonPackage=${PYTHON_PACKAGES[i]} + pythonVersion=${PYTHON_VERSIONS[$i]} + + python=python$pythonVersion + installLocation=$prefix/lib/$python/vendor-packages/ + export PYTHONPATH=$installLocation:$PYTHONPATH + mkdir -p $installLocation + rm -rf build + $python setup.py build install \ + --root=/ --prefix=$prefix + + packageEntries $pythonPackage \ + $prefix/lib/python* + done +} diff --git a/dev-python/installer/patches/1a3a7d208fd48446de3d35e5c640378dc1dfd437.patch b/dev-python/installer/patches/1a3a7d208fd48446de3d35e5c640378dc1dfd437.patch new file mode 100644 index 000000000..fb0c247c7 --- /dev/null +++ b/dev-python/installer/patches/1a3a7d208fd48446de3d35e5c640378dc1dfd437.patch @@ -0,0 +1,120 @@ +From 1a3a7d208fd48446de3d35e5c640378dc1dfd437 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= +Date: Sun, 5 Jun 2022 12:08:44 +0200 +Subject: [PATCH] main: Implement --prefix option to override install path + +Implement a --prefix option that can be used to override platbase +and base when expanding the paths from install scheme. This can be used +to install paths to a layout using another prefix than the one used +to run installer. + +Gentoo use case for this is running installer inside a venv to prepare +installation images for the real system. The nixOS maintainers have +also indicated interest in this feature. +--- + src/installer/__main__.py | 23 ++++++++++++++++++----- + tests/test_main.py | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 48 insertions(+), 5 deletions(-) + +diff --git a/src/installer/__main__.py b/src/installer/__main__.py +index 3357ec5..51014b9 100644 +--- a/src/installer/__main__.py ++++ b/src/installer/__main__.py +@@ -23,6 +23,13 @@ def _get_main_parser() -> argparse.ArgumentParser: + type=str, + help="destination directory (prefix to prepend to each file)", + ) ++ parser.add_argument( ++ "--prefix", ++ "-p", ++ metavar="path", ++ type=str, ++ help="override prefix to install packages to", ++ ) + parser.add_argument( + "--compile-bytecode", + action="append", +@@ -39,12 +46,18 @@ def _get_main_parser() -> argparse.ArgumentParser: + return parser + + +-def _get_scheme_dict(distribution_name: str) -> Dict[str, str]: ++def _get_scheme_dict( ++ distribution_name: str, prefix: Optional[str] = None ++) -> Dict[str, str]: + """Calculate the scheme dictionary for the current Python environment.""" +- scheme_dict = sysconfig.get_paths() ++ vars = {} ++ if prefix is None: ++ installed_base = sysconfig.get_config_var("base") ++ assert installed_base ++ else: ++ vars["base"] = vars["platbase"] = installed_base = prefix + +- installed_base = sysconfig.get_config_var("base") +- assert installed_base ++ scheme_dict = sysconfig.get_paths(vars=vars) + + # calculate 'headers' path, not currently in sysconfig - see + # https://bugs.python.org/issue44445. This is based on what distutils does. +@@ -72,7 +85,7 @@ def _main(cli_args: Sequence[str], program: Optional[str] = None) -> None: + + with WheelFile.open(args.wheel) as source: + destination = SchemeDictionaryDestination( +- scheme_dict=_get_scheme_dict(source.distribution), ++ scheme_dict=_get_scheme_dict(source.distribution, prefix=args.prefix), + interpreter=sys.executable, + script_kind=get_launcher_kind(), + bytecode_optimization_levels=bytecode_levels, +diff --git a/tests/test_main.py b/tests/test_main.py +index c6f7c40..391a13d 100644 +--- a/tests/test_main.py ++++ b/tests/test_main.py +@@ -1,3 +1,5 @@ ++import os ++ + from installer.__main__ import _get_scheme_dict as get_scheme_dict + from installer.__main__ import _main as main + +@@ -7,6 +9,14 @@ def test_get_scheme_dict(): + assert set(d.keys()) >= {"purelib", "platlib", "headers", "scripts", "data"} + + ++def test_get_scheme_dict_prefix(): ++ d = get_scheme_dict(distribution_name="foo", prefix="/foo") ++ for key in ("purelib", "platlib", "headers", "scripts", "data"): ++ assert d[key].startswith( ++ f"{os.sep}foo" ++ ), f"{key} does not start with /foo: {d[key]}" ++ ++ + def test_main(fancy_wheel, tmp_path): + destdir = tmp_path / "dest" + +@@ -23,6 +33,26 @@ def test_main(fancy_wheel, tmp_path): + } + + ++def test_main_prefix(fancy_wheel, tmp_path): ++ destdir = tmp_path / "dest" ++ ++ main([str(fancy_wheel), "-d", str(destdir), "-p", "/foo"], "python -m installer") ++ ++ installed_py_files = list(destdir.rglob("*.py")) ++ ++ for f in installed_py_files: ++ assert str(f.parent).startswith( ++ str(destdir / "foo") ++ ), f"path does not respect destdir+prefix: {f}" ++ assert {f.stem for f in installed_py_files} == {"__init__", "__main__", "data"} ++ ++ installed_pyc_files = destdir.rglob("*.pyc") ++ assert {f.name.split(".")[0] for f in installed_pyc_files} == { ++ "__init__", ++ "__main__", ++ } ++ ++ + def test_main_no_pyc(fancy_wheel, tmp_path): + destdir = tmp_path / "dest" +