#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" source "${SCRIPT_DIR}/package_common.sh" require_command python3 require_command tar require_command sha256sum require_command uv export UV_CACHE_DIR="${UV_CACHE_DIR:-${ROOT_DIR}/.uv-cache}" export PIP_CACHE_DIR="${PIP_CACHE_DIR:-${ROOT_DIR}/.pip-cache}" mkdir -p "${UV_CACHE_DIR}" "${PIP_CACHE_DIR}" VERSION="$(project_version)" PACKAGE_NAME="$(project_name)" BUNDLE_NAME="${PACKAGE_NAME}-x11-linux-${VERSION}" PORTABLE_STAGE_DIR="${BUILD_DIR}/portable/${BUNDLE_NAME}" PORTABLE_TARBALL="${DIST_DIR}/${BUNDLE_NAME}.tar.gz" PORTABLE_CHECKSUM="${PORTABLE_TARBALL}.sha256" TEST_WHEELHOUSE_ROOT="${AMAN_PORTABLE_TEST_WHEELHOUSE_ROOT:-}" copy_prebuilt_wheelhouse() { local source_root="$1" local target_root="$2" local tag for tag in cp310 cp311 cp312; do local source_dir="${source_root}/${tag}" if [[ ! -d "${source_dir}" ]]; then echo "missing test wheelhouse directory: ${source_dir}" >&2 exit 1 fi mkdir -p "${target_root}/${tag}" cp -a "${source_dir}/." "${target_root}/${tag}/" done } export_requirements() { local python_version="$1" local output_path="$2" local raw_path="${output_path}.raw" uv export \ --package "${PACKAGE_NAME}" \ --no-dev \ --no-editable \ --format requirements-txt \ --python "${python_version}" >"${raw_path}" python3 - "${raw_path}" "${output_path}" <<'PY' from pathlib import Path import sys raw_path = Path(sys.argv[1]) output_path = Path(sys.argv[2]) lines = raw_path.read_text(encoding="utf-8").splitlines() filtered = [] for line in lines: stripped = line.strip() if not stripped or stripped == ".": continue filtered.append(line) output_path.write_text("\n".join(filtered) + "\n", encoding="utf-8") raw_path.unlink() PY } download_python_wheels() { local python_tag="$1" local python_version="$2" local abi="$3" local requirements_path="$4" local target_dir="$5" mkdir -p "${target_dir}" python3 -m pip download \ --requirement "${requirements_path}" \ --dest "${target_dir}" \ --only-binary=:all: \ --implementation cp \ --python-version "${python_version}" \ --abi "${abi}" } build_wheel WHEEL_PATH="$(latest_wheel_path)" rm -rf "${PORTABLE_STAGE_DIR}" mkdir -p "${PORTABLE_STAGE_DIR}/wheelhouse/common" mkdir -p "${PORTABLE_STAGE_DIR}/requirements" mkdir -p "${PORTABLE_STAGE_DIR}/systemd" cp "${WHEEL_PATH}" "${PORTABLE_STAGE_DIR}/wheelhouse/common/" cp "${ROOT_DIR}/packaging/portable/install.sh" "${PORTABLE_STAGE_DIR}/install.sh" cp "${ROOT_DIR}/packaging/portable/uninstall.sh" "${PORTABLE_STAGE_DIR}/uninstall.sh" cp "${ROOT_DIR}/packaging/portable/portable_installer.py" "${PORTABLE_STAGE_DIR}/portable_installer.py" cp "${ROOT_DIR}/packaging/portable/systemd/aman.service.in" "${PORTABLE_STAGE_DIR}/systemd/aman.service.in" chmod 0755 \ "${PORTABLE_STAGE_DIR}/install.sh" \ "${PORTABLE_STAGE_DIR}/uninstall.sh" \ "${PORTABLE_STAGE_DIR}/portable_installer.py" python3 "${ROOT_DIR}/packaging/portable/portable_installer.py" \ write-manifest \ --version "${VERSION}" \ --output "${PORTABLE_STAGE_DIR}/manifest.json" TMP_REQ_DIR="${BUILD_DIR}/portable/requirements" mkdir -p "${TMP_REQ_DIR}" export_requirements "3.10" "${TMP_REQ_DIR}/cp310.txt" export_requirements "3.11" "${TMP_REQ_DIR}/cp311.txt" export_requirements "3.12" "${TMP_REQ_DIR}/cp312.txt" cp "${TMP_REQ_DIR}/cp310.txt" "${PORTABLE_STAGE_DIR}/requirements/cp310.txt" cp "${TMP_REQ_DIR}/cp311.txt" "${PORTABLE_STAGE_DIR}/requirements/cp311.txt" cp "${TMP_REQ_DIR}/cp312.txt" "${PORTABLE_STAGE_DIR}/requirements/cp312.txt" if [[ -n "${TEST_WHEELHOUSE_ROOT}" ]]; then copy_prebuilt_wheelhouse "${TEST_WHEELHOUSE_ROOT}" "${PORTABLE_STAGE_DIR}/wheelhouse" else download_python_wheels "cp310" "310" "cp310" "${TMP_REQ_DIR}/cp310.txt" "${PORTABLE_STAGE_DIR}/wheelhouse/cp310" download_python_wheels "cp311" "311" "cp311" "${TMP_REQ_DIR}/cp311.txt" "${PORTABLE_STAGE_DIR}/wheelhouse/cp311" download_python_wheels "cp312" "312" "cp312" "${TMP_REQ_DIR}/cp312.txt" "${PORTABLE_STAGE_DIR}/wheelhouse/cp312" fi rm -f "${PORTABLE_TARBALL}" "${PORTABLE_CHECKSUM}" tar -C "${BUILD_DIR}/portable" -czf "${PORTABLE_TARBALL}" "${BUNDLE_NAME}" ( cd "${DIST_DIR}" sha256sum "$(basename "${PORTABLE_TARBALL}")" >"$(basename "${PORTABLE_CHECKSUM}")" ) echo "built ${PORTABLE_TARBALL}"