From 5e0fd54a92361ffc2a581bfe8ee339ee8c6434b3 Mon Sep 17 00:00:00 2001 From: Andrew Hamilton Date: Tue, 4 Aug 2026 10:33:13 +1000 Subject: [PATCH] Use pyinstaller build for Docker images, drop shiv The shiv zipapp's shebang points at the system python3 (GIL-enabled), which cannot load the cp314t extensions built under the free-threaded 3.14 project venv, so ./dist/eris failed at runtime. pyinstaller bundles its own 3.14t interpreter and works, so the Dockerfiles now run the pyinstaller binary directly instead of via a python wrapper, and the debian image no longer needs to install uv/python. Remove build-shiv and the shiv dev dependency; build comments use podman. --- packaging/Dockerfile.alpine | 2 +- packaging/Dockerfile.arch | 7 ++- packaging/Dockerfile.debian | 12 ++-- packaging/Dockerfile.fedora | 7 ++- packaging/Dockerfile.ubuntu | 7 ++- packaging/build-pyinstaller | 2 - packaging/build-shiv | 26 --------- pyproject.toml | 2 +- uv.lock | 108 +++++++++++++++++++++++++----------- 9 files changed, 95 insertions(+), 78 deletions(-) delete mode 100755 packaging/build-shiv diff --git a/packaging/Dockerfile.alpine b/packaging/Dockerfile.alpine index 1a05189..42389b6 100644 --- a/packaging/Dockerfile.alpine +++ b/packaging/Dockerfile.alpine @@ -12,4 +12,4 @@ RUN eris --install-all-tools ENTRYPOINT ["eris"] -# docker build -t eris -f packaging/Dockerfile.alpine . +# podman build -t eris -f packaging/Dockerfile.alpine . diff --git a/packaging/Dockerfile.arch b/packaging/Dockerfile.arch index 51c82b0..5a27f9d 100644 --- a/packaging/Dockerfile.arch +++ b/packaging/Dockerfile.arch @@ -1,12 +1,13 @@ +# dist/eris must be built with packaging/build-pyinstaller (not shiv). FROM archlinux:latest RUN pacman -Sy --noconfirm sudo python COPY dist/eris /usr/local/bin/eris -RUN python3 /usr/local/bin/eris --install-all-tools +RUN /usr/local/bin/eris --install-all-tools -ENTRYPOINT ["python3", "/usr/local/bin/eris"] +ENTRYPOINT ["/usr/local/bin/eris"] -# docker build -t eris -f packaging/Dockerfile.arch . +# podman build -t eris -f packaging/Dockerfile.arch . diff --git a/packaging/Dockerfile.debian b/packaging/Dockerfile.debian index 0ffc4df..ab12288 100644 --- a/packaging/Dockerfile.debian +++ b/packaging/Dockerfile.debian @@ -1,15 +1,13 @@ +# dist/eris must be built with packaging/build-pyinstaller (not shiv). FROM debian:trixie -RUN apt-get update && apt-get install -y curl sudo -RUN curl -LsSf https://astral.sh/uv/install.sh | sh -ENV PATH="/root/.local/bin:${PATH}" -RUN uv python install 3.14 +RUN apt-get update && apt-get install -y python3 sudo COPY dist/eris /usr/local/bin/eris -RUN python3.14 /usr/local/bin/eris --install-all-tools +RUN /usr/local/bin/eris --install-all-tools -ENTRYPOINT ["python3.14", "/usr/local/bin/eris"] +ENTRYPOINT ["/usr/local/bin/eris"] -# docker build -t eris -f packaging/Dockerfile.debian . +# podman build -t eris -f packaging/Dockerfile.debian . diff --git a/packaging/Dockerfile.fedora b/packaging/Dockerfile.fedora index a9dbd48..54c1982 100644 --- a/packaging/Dockerfile.fedora +++ b/packaging/Dockerfile.fedora @@ -1,12 +1,13 @@ +# dist/eris must be built with packaging/build-pyinstaller (not shiv). FROM fedora:44 RUN dnf -y install sudo python3 COPY dist/eris /usr/local/bin/eris -RUN python3 /usr/local/bin/eris --install-all-tools +RUN /usr/local/bin/eris --install-all-tools -ENTRYPOINT ["python3", "/usr/local/bin/eris"] +ENTRYPOINT ["/usr/local/bin/eris"] -# docker build -t eris -f packaging/Dockerfile.fedora . +# podman build -t eris -f packaging/Dockerfile.fedora . diff --git a/packaging/Dockerfile.ubuntu b/packaging/Dockerfile.ubuntu index 42d4b30..4d96a44 100644 --- a/packaging/Dockerfile.ubuntu +++ b/packaging/Dockerfile.ubuntu @@ -1,12 +1,13 @@ +# dist/eris must be built with packaging/build-pyinstaller (not shiv). FROM ubuntu:26.04 RUN apt-get update && apt-get install -y sudo python3 COPY dist/eris /usr/local/bin/eris -RUN python3 /usr/local/bin/eris --install-all-tools +RUN /usr/local/bin/eris --install-all-tools -ENTRYPOINT ["python3", "/usr/local/bin/eris"] +ENTRYPOINT ["/usr/local/bin/eris"] -# docker build -t eris -f packaging/Dockerfile.ubuntu . +# podman build -t eris -f packaging/Dockerfile.ubuntu . diff --git a/packaging/build-pyinstaller b/packaging/build-pyinstaller index 62315f7..c3fa4db 100755 --- a/packaging/build-pyinstaller +++ b/packaging/build-pyinstaller @@ -8,8 +8,6 @@ set -x cd "$(dirname "$0")/.." mkdir -p dist -uv pip install pyinstaller - COMMON_ARGS=( --onefile --add-data "$PWD/eris/tools.toml:eris" diff --git a/packaging/build-shiv b/packaging/build-shiv deleted file mode 100755 index 82cde4a..0000000 --- a/packaging/build-shiv +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - - -set -e -set -x - - -cd "$(dirname "$0")/.." -mkdir -p dist -REQS=$(mktemp) -uv export --no-dev --no-header --no-emit-project --no-hashes > "$REQS" -uv build --wheel --out-dir dist -WHEEL=$(ls dist/eris-*.whl 2>/dev/null | head -1) -if [ -z "$WHEEL" ]; then - echo "No wheel found in dist/" >&2 - exit 1 -fi -uv run shiv \ - -e "eris.__main__:entry_point" \ - -o dist/eris \ - --compile-pyc \ - --reproducible \ - --no-deps \ - -r "$REQS" \ - "$WHEEL" -rm -f "$REQS" "$WHEEL" diff --git a/pyproject.toml b/pyproject.toml index f9a2c46..a41f2a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,7 @@ homepage = "https://github.com/ahamilton/eris" [dependency-groups] dev = [ "pytest>=9.1.1", - "shiv>=1.0.8", + "pyinstaller>=6.21.0", ] [tool.pytest.ini_options] diff --git a/uv.lock b/uv.lock index 061599b..bf421aa 100644 --- a/uv.lock +++ b/uv.lock @@ -3,15 +3,12 @@ revision = 3 requires-python = ">=3.14" [[package]] -name = "click" -version = "8.4.2" +name = "altgraph" +version = "0.17.5" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/76/d4/81420972a676e8ffea40450d8c8c92943e7218a78fe9b64359836cc9876b/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6", size = 338000, upload-time = "2026-06-24T17:45:15.148Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/f8/97fdf103f38fed6792a1601dbc16cc8aac56e7459a9fff08c812d8ae177a/altgraph-0.17.5.tar.gz", hash = "sha256:c87b395dd12fabde9c99573a9749d67da8d29ef9de0125c7f536699b4a9bc9e7", size = 48428, upload-time = "2025-11-21T20:35:50.583Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" }, + { url = "https://files.pythonhosted.org/packages/a9/ba/000a1996d4308bc65120167c21241a3b205464a2e0b58deda26ae8ac21d1/altgraph-0.17.5-py2.py3-none-any.whl", hash = "sha256:f3a22400bce1b0c701683820ac4f3b159cd301acab067c51c653e06961600597", size = 21228, upload-time = "2025-11-21T20:35:49.444Z" }, ] [[package]] @@ -53,8 +50,8 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "pyinstaller" }, { name = "pytest" }, - { name = "shiv" }, ] [package.metadata] @@ -70,8 +67,8 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ + { name = "pyinstaller", specifier = ">=6.21.0" }, { name = "pytest", specifier = ">=9.1.1" }, - { name = "shiv", specifier = ">=1.0.8" }, ] [[package]] @@ -100,6 +97,18 @@ dependencies = [ { name = "termstr" }, ] +[[package]] +name = "macholib" +version = "1.16.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "altgraph" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/10/2f/97589876ea967487978071c9042518d28b958d87b17dceb7cdc1d881f963/macholib-1.16.4.tar.gz", hash = "sha256:f408c93ab2e995cd2c46e34fe328b130404be143469e41bc366c807448979362", size = 59427, upload-time = "2025-11-22T08:28:38.373Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/d1/a9f36f8ecdf0fb7c9b1e78c8d7af12b8c8754e74851ac7b94a8305540fc7/macholib-1.16.4-py2.py3-none-any.whl", hash = "sha256:da1a3fa8266e30f0ce7e97c6a54eefaae8edd1e5f86f3eb8b95457cae90265ea", size = 38117, upload-time = "2025-11-22T08:28:36.939Z" }, +] + [[package]] name = "packaging" version = "26.2" @@ -109,6 +118,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, ] +[[package]] +name = "pefile" +version = "2024.8.26" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/03/4f/2750f7f6f025a1507cd3b7218691671eecfd0bbebebe8b39aa0fe1d360b8/pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632", size = 76008, upload-time = "2024-08-26T20:58:38.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/16/12b82f791c7f50ddec566873d5bdd245baa1491bac11d15ffb98aecc8f8b/pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f", size = 74766, upload-time = "2024-08-26T21:01:02.632Z" }, +] + [[package]] name = "pexpect" version = "4.9.0" @@ -171,15 +189,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3d/68/1f3066acedf37673694a7141381d8f811ae97f30d34413d236abe7d489f1/pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59", size = 2567491, upload-time = "2026-07-01T11:56:23.506Z" }, ] -[[package]] -name = "pip" -version = "26.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/96/e6f8e9d9d7b9cc4457092712a7e919c3186aa2c2fa9ffed2c5d29cc947e8/pip-26.2.tar.gz", hash = "sha256:2d8542afcc84cdd8e846c2b36b2861fad1da376dd98f8e7113e9108a3c331690", size = 1848845, upload-time = "2026-07-29T21:57:56.407Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/62/36/a3aed958d60531cb442b7ab4596cda7b3621cfb916f8ae1d6769795c7dc1/pip-26.2-py3-none-any.whl", hash = "sha256:931c303696af6fa3417112103b1cad26890e5a07eccb5b99783700e33f2b8aad", size = 1816475, upload-time = "2026-07-29T21:57:54.763Z" }, -] - [[package]] name = "pluggy" version = "1.6.0" @@ -213,6 +222,46 @@ version = "0.0.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d6/b4/b44fccc7040b01449af37f8ff3ffa64755dc7dcfb92477a2f61c2639a6ee/pyinotify-elephant-fork-0.0.1.tar.gz", hash = "sha256:a366b27e0d5be8cef60c836f89132c515500b5012ab6190d9c255c645df884ae", size = 109161, upload-time = "2023-10-12T04:19:16.906Z" } +[[package]] +name = "pyinstaller" +version = "6.21.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "altgraph" }, + { name = "macholib", marker = "sys_platform == 'darwin'" }, + { name = "packaging" }, + { name = "pefile", marker = "sys_platform == 'win32'" }, + { name = "pyinstaller-hooks-contrib" }, + { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d5/4d/ec706c3fcf39e26888c35b39615ff4d5865d184069666c47492cff1fbe50/pyinstaller-6.21.0.tar.gz", hash = "sha256:bb9fab705983e393a2d1cac77d6972513057ad800215fd861dc15ff5272e98fd", size = 4061519, upload-time = "2026-06-13T14:15:06.25Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/4a/53cf98bf66daed012dc9cd78c8203f19a675d696f2fc12afcf8c5049a0e0/pyinstaller-6.21.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:327d132389f37912609e01be62810cf96b5aa95b613903e4b8692e0d12fb0eda", size = 1052350, upload-time = "2026-06-13T14:13:55.88Z" }, + { url = "https://files.pythonhosted.org/packages/30/83/b591295c352ef464c50b4c6ffff1c4f771d875c9e833f578d1b9f564f6b3/pyinstaller-6.21.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7071d4b094d5b40deeef5fa3d3b98a1b846087f7562b49209663d5f9281fe251", size = 748477, upload-time = "2026-06-13T14:14:00.327Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8f/88fff4e403873b1e22286911350e75ff00db014aa08e57045da9d4328993/pyinstaller-6.21.0-py3-none-manylinux2014_i686.whl", hash = "sha256:6b6374d652107dd4a2eeece903ff82bb4045bb5e1006c5a158a6dcdbefe84bf2", size = 760877, upload-time = "2026-06-13T14:14:04.836Z" }, + { url = "https://files.pythonhosted.org/packages/8a/13/f0e48fbdfd1d05d948157121cea8b1b823dcb89efe6934b71fdd8bdb3f0f/pyinstaller-6.21.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:4e3108b3f02384560da70e39b8bf22b0ad597d02bd68a40d76ea91c1cfa00cad", size = 759194, upload-time = "2026-06-13T14:14:10.61Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d5/ea7878cf9924ed30d946d8288777424e6d069d94f5bde56b4d0890069664/pyinstaller-6.21.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:697532279f535ad572bda613db4f821540e235c7854ca6da4d3bf0373f4415ee", size = 754979, upload-time = "2026-06-13T14:14:15.226Z" }, + { url = "https://files.pythonhosted.org/packages/9f/09/51b8905714b733bac66dbc041a7821372d70d888d273ae474c4037d4202d/pyinstaller-6.21.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:605169523a6b5ace39f13dfbff21add9f2bc43df99c7daf9394fefb2c45e8b6f", size = 754812, upload-time = "2026-06-13T14:14:20.264Z" }, + { url = "https://files.pythonhosted.org/packages/4b/43/d77779439d8c6c2e27a77bcfbd1d5cc0f568ebb611bb472b11af81b5f177/pyinstaller-6.21.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:5fa56746c1e76f93634d018502301378a2d0c382553d37d8c3c34ff436c12dd1", size = 753887, upload-time = "2026-06-13T14:14:25.268Z" }, + { url = "https://files.pythonhosted.org/packages/51/8f/c22df1f6837784ac349057ba693f08e7b1ca7a0e06f9c33c63bc6280007b/pyinstaller-6.21.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:42395ec76df8e8120c36b13339d9db8cab83e316a12839ee303cc00fc941bb74", size = 753779, upload-time = "2026-06-13T14:14:29.445Z" }, + { url = "https://files.pythonhosted.org/packages/c9/76/1ce8a27ce62ba8cf3a87c9ce6d575610f4e55d7cb0123e7512fc3f4b921a/pyinstaller-6.21.0-py3-none-win32.whl", hash = "sha256:c6b28d30d8fd99ce162ff3aab5013ed44dbfb747566b1f01b9bed7964d7c14e9", size = 1336462, upload-time = "2026-06-13T14:14:35.785Z" }, + { url = "https://files.pythonhosted.org/packages/c1/fa/ca1d7e5257dd8566a9dfc0dfb02f8a8075eeb53d4b2d3c579f1276759042/pyinstaller-6.21.0-py3-none-win_amd64.whl", hash = "sha256:7fae06c494ce0ebfe6bd3055c0e409def884f63af2e3705d06bd431ad9237fc7", size = 1397487, upload-time = "2026-06-13T14:14:42.328Z" }, + { url = "https://files.pythonhosted.org/packages/dc/75/21b51523ce8d96629b71311775a0a65f5f5a872124ab0de33e5c848f8bff/pyinstaller-6.21.0-py3-none-win_arm64.whl", hash = "sha256:f13c95c9c03fb567217135919f93815c305813126780b0ed6e0123cb8acaf025", size = 1346094, upload-time = "2026-06-13T14:14:48.914Z" }, +] + +[[package]] +name = "pyinstaller-hooks-contrib" +version = "2026.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/94/5b/c9fe0db5e83ee1c39b2258fa21d23b15e1a60786b6c5990ee5074ead8bb6/pyinstaller_hooks_contrib-2026.6.tar.gz", hash = "sha256:bef5002c32f4f50bd55b005da12cff64eca8783e7eaf86a06a62410164bab725", size = 173354, upload-time = "2026-06-08T22:37:16.152Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/31/f2d7343d8ed5f7c4678377886f6ce533e6eaaa131b252ce950114c2a7efa/pyinstaller_hooks_contrib-2026.6-py3-none-any.whl", hash = "sha256:fd13b8ac126b35361175edacd41a0d97080b75dd5f4b594ecefefff969509dd3", size = 457159, upload-time = "2026-06-08T22:37:14.722Z" }, +] + [[package]] name = "pytest" version = "9.1.1" @@ -229,6 +278,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, ] +[[package]] +name = "pywin32-ctypes" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", size = 29471, upload-time = "2024-08-14T10:15:34.626Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", size = 30756, upload-time = "2024-08-14T10:15:33.187Z" }, +] + [[package]] name = "setuptools" version = "83.0.0" @@ -238,20 +296,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/40/e1e72872c6354b306daef1703549e8e83b4d43cfea356311bf722a043752/setuptools-83.0.0-py3-none-any.whl", hash = "sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3", size = 1008090, upload-time = "2026-07-04T15:31:20.885Z" }, ] -[[package]] -name = "shiv" -version = "1.0.8" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "pip" }, - { name = "setuptools" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/85/004e7123b4821c64be6d9bfed27f63147b4dde929a1cd848f137befeada4/shiv-1.0.8.tar.gz", hash = "sha256:2a68d69e98ce81cb5b8fdafbfc1e27efa93e6d89ca14bfae33482e4176f561d6", size = 32806, upload-time = "2024-11-01T19:47:46.189Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/ec/afbb46f7c1ab071a50d92424daf149420ca1f0e02dc51239485747151d6c/shiv-1.0.8-py2.py3-none-any.whl", hash = "sha256:a60e4b05a2d2f8b820d567b1d89ee59af731759771c32c282d03c4ceae6aba24", size = 20516, upload-time = "2024-11-01T19:47:45.061Z" }, -] - [[package]] name = "termstr" version = "2026.8.3"