From f46e70249c407897bc3d43952fe0a8b401afe630 Mon Sep 17 00:00:00 2001 From: Ivan Date: Fri, 24 Jul 2026 06:19:27 -0500 Subject: [PATCH] refactor: update wheel and APK handling in build scripts by replacing glob patterns with array expansions and find commands. --- meshchatx.rsm | Bin 176239 -> 176239 bytes scripts/android/sync-codec2-jni-libs.sh | 2 +- scripts/build-android-wheels-local.sh | 22 +++++++++++------- scripts/build-macos-universal.sh | 2 +- scripts/build/fetch_repository_wheels.py | 2 +- scripts/ci/android-emulator-smoke.sh | 2 +- scripts/ci/attest-release-assets.sh | 6 ++--- scripts/ci/ci-node-path.sh | 2 +- scripts/ci/docker-tags.sh | 9 ++++--- scripts/ci/exec-priv.sh | 1 + scripts/ci/github-apt-linux-packaging.sh | 8 +++---- scripts/ci/github-build-macos.sh | 2 +- .../ci/github-draft-release-upload-assets.sh | 3 +-- .../ci/github-ensure-macos-x86-64-homebrew.sh | 2 +- .../github-install-macos-x64-python-deps.sh | 10 ++++---- scripts/ci/install-git-hooks.sh | 2 +- scripts/ci/macos-normalize-pycodec2-dylib.sh | 2 +- scripts/ci/setup-cosign.sh | 1 + scripts/ci/setup-task.sh | 1 + scripts/ci/sign-tree-rsm.sh | 2 +- scripts/ci/tree-manifest.sh | 2 +- scripts/ci/trivy-fs-scan.sh | 2 +- scripts/ci/verify-package-contents-smoke.sh | 2 +- scripts/ci/verify-package-contents.sh | 8 +++---- scripts/ci/verify-tree-rsm.sh | 2 +- scripts/ci/verify-workspace-clean.sh | 2 +- scripts/docker-bake-lxst-filterlib-musl.py | 4 ++-- scripts/ensure-flatpak-flathub-remote.sh | 2 +- scripts/rpi/install_meshchatx.sh | 2 +- scripts/setup_wine_env.sh | 2 +- scripts/sign-android-apks.sh | 6 ++--- scripts/unify-backend-plain-files.sh | 8 +++---- 32 files changed, 64 insertions(+), 59 deletions(-) diff --git a/meshchatx.rsm b/meshchatx.rsm index 523462e5936f838cd93049dfe7fe262ed039c22c..10934b1268700a204369630cbfb933475a013cd2 100644 GIT binary patch delta 2408 zcmY*bO~{>B5#|lSln*yT1QXH_DyfRZ&N*|=%$!v&C$+_>uIaxeEib7r2ud0%^V z=e1XNj{o|hH=jEC@f#Qax+gvT^Z)$vU*FyN;n6!jdh^X6+<5-WU%30hcYOcWq0M)8 z+6!;{#Wz2AW#{TU-}mzGmlJ<^{pDBA{riodJ@Tik#}6F2b>R{L59sDrS!nL%rMhjU;6y==M}|CX=GNbUVF~eN*F;}j%qSzr`mcQGZj>^lypdI zg^MK{sT7v=_a0jwJ5Cf+?Ce!qBFSE3>&1+v=B(OcPrQBJokr@oF-N1~U2<;Xb*>+H ze7U^h;8P5xsTajDC9Z)iO>${s(L?4^WZ*aFkx3i%XoF&`twi$mx1LzuwfV>s%l&bSgC80 z5b78M=le+3GsiMI2UG81vI1=NG0k(sz&Wq)xV+rGnziI2xfGJ5l5GsdOigMLw@{#uxq*}wknmF1r+OLZpHQ)S7}WR%ouN+Wb-WzQYrAfB~D^TjI> zxGqwyk2;yNZ%Z9qA9`{*y)w!|3FGLf0~3XsRhm~r_1LCGrsx_YGe##=@)l-k6lRyy zll;G{SDsuxyHYE)nMMPX!3FMM!?aSSNWk?D-KQ|{cLhDEwV~Fi)qrmj)9tSIub+Er zd3-gpv@vEI0k$v$_?QpV_1=PYaNlv$Xr&EckVh=!7*Rvw#NKsm&VFgxw|AvAhuVcQ z>{`)m_k{L+1`v@#Dig#uWI>Vv5YF~{guP)C)qIuLb3wW29M}rDFGZ8xh?gZNw1Vd>Y zpjk{>xv7FwhS?2D%WskBuAl$(*<=08?y37uZ#4?_R|7FaXYeSB4vks7lz=#cs`_Co zLO##~@}XrV%s(d7F^y}qb^F@#(8?7Kj=j0TF<{e$5uV73Bs0<^l~OyWSWBw}uT2;g zQV!mTBaF5_aBX>HB_oZN0+7rRtd;Ii*X-O{k0l{`2@pdUio0}rnk@{rW-;U(5Eknf zuPui!DqF9iTTMMU(1*{!oxmIj$%;Ib(nl{M0;@<2b!JIEbSQu{Zg0Ws{JB#Pe&*QR zJ+|BHZNP9pF?bdeBaB-kv;hiXP~Kw3hqZc%>~N;l5s?2v1YOo%3I1CDcfB0F_t@?O zXYThc0oV$vko=gF8>VNJK_+_7frBFX0x*fFqgDHKC|53!Q4 zI1B~oq->sOa3g3tAgrs%b}5x(*fCjdlfCG>-=jOv-U+&tw5<@m7z`8A>pA&1fOn$W^~6^Gzf}n8U=}7JB)x=fKais zTN;?(k*}$(U%0Wnd&O8%oY5{+AlS@VJxdAA0#TQlh6bce#0Y2@i%1pk1St~EAZx|f z_Uv+K6#@EoPb)GZVEYY*RIw#wGDhXR?G!s>dq?UW$FXq?nKzW?@R>HxJi9!z;9X^6 zmy6}-1->iTngmrFxIxxoj~T>cTe-tWFo`D&Gp%EXDw4KdI(c*1oV>Yb-@g9={ldmy delta 2412 zcmY*bP3T=$5$Bd@LU5UiDYb@bEh7Ks%=w(@Ca;QB5m!P%LGYZJIZ3EZLjEzPR*h*| z68a(b!@M9U7Qq^tl^_r4LKj95v2|06P^6$6K`2O7vh(-aRe8L{yZ631GrzC7Z@szy ztvB}{`Te86{qG;{`OM+#_wg^DeeUny`}$X3xcTQFf8p}IcfWq>zPtW&_QoS`@B8N) z_wW1E&Tr2B?*6Mc@7+1K`s>r<^@|sOt!F>?+A~KE9=h@V8-J=NzWcvNp1kno58nFA zf4}^`hyVDM2R?E1O5StfXD{9S(uH%sI=8%fVHHORI;{1U*lG)PDvi*|+fa>(d(~uI zN1~kE1y6CAQNxfHsCivqdUW~6s!w;FoKPUnWRvnpQ=H9}3eC|=4<#qAPLK2wXMvbRQ>eOT(H)I4#$M;e{S`k}{` z%d4iGTc5Gyk)ZjHi1t8$~*G z0ckawMWHq|wc0r8oFbsFq{f>QmzM{Y^P^HIMTk|!(O8TO1Sb28JSzUwnYL&E{!}Cs z>pjm>G!?B@Ne>;`)zimMo!LFC#}C^{eb7(uoask*@7X=JzoA~{6a%{PC|z3y`jWG{ z#)|24{4fLXTBblnBw=JP?42P6E;iR+dt$k5l@cV-qFVw}O0m<7AY63zp<*(eShxW( zKwJ`Nv{c44pwq?(bNz!Smjmlpo><;qQSU6VmAU0M4(gCxEF=-FaJ7`WK-ZzyG#LDm z*W8D*q=<>Dr){a**0(>koLJ>j2>ncql|sw~mVq)ta0X~V9^#T|&7px=GoVFLQ0q>S z7(=|<)!&|4zO^c;Hwd8$j@Q<-45ma7kibIR#0ck$)krh6SSt->(}_75cy)TW)b*#A z$6#OZ1Q|sgYGzW0fvCh8enAU@S;GiYa9eAZI4NZ|4n4bS?s0SK`^(-vs|d@%@Kz`c zoDdF&OMsLWUvTBYCeTs*pn+8BNxR9#f;5f>_KXMKS`- z9D%6ogIAXCtR|b4J|Y4w8V;`sNq~?_h{-UA7o;S5@B#**rW&@f0NJNHlVaxeU#={7 zoQE+8nuV8YP@{=l6y%|S02|vpt=?GwUw9r!5|wuZ#5G;Z&~>&)rnXCK~~yF0tu z-vKOIWet_5M;B=nVRCp1y!XnmV*5ye#9LAlH^*@;%-R4}%m{ELyK;5;*yne4A3FJ< zZwUxBR4>DuMm7q_=TJ}zhs=n`LN1oJB?D{CIYmQ5VaHtDYxBGa|Xud6v2cCHg8;AKDn#{a=*`uDz=z<~k#S%Oz;^VOkjrDn&1ZkK+_`7fAPG^!3@x-d1j&L1Th73~fQ<|&IOjNK z4-JbH>vWs?AtMm6GsEWEPnLh}#V#z^SU3Hlr~}7ko(r4 zYkqOLeI*T1u`5j9bw`XA=f|*h6I6uRRalaAvL*l?Ao$9cI}qEd;bsl Cbjt7m diff --git a/scripts/android/sync-codec2-jni-libs.sh b/scripts/android/sync-codec2-jni-libs.sh index 774fd377..e981f678 100755 --- a/scripts/android/sync-codec2-jni-libs.sh +++ b/scripts/android/sync-codec2-jni-libs.sh @@ -23,7 +23,7 @@ fi for abi in ${ABI_LIST//,/ }; do tag="$(abi_to_tag "${abi}")" - lib_wheel="$(ls "${VENDOR_DIR}"/chaquopy_libcodec2-*-android_*_"${tag}".whl 2>/dev/null | tail -n 1 || true)" + lib_wheel="$(find "${VENDOR_DIR}" -maxdepth 1 -type f -name "chaquopy_libcodec2-*-android_*_${tag}.whl" 2>/dev/null | sort | tail -n 1 || true)" if [[ -z "${lib_wheel}" ]]; then echo "No chaquopy_libcodec2 wheel for ${abi} under ${VENDOR_DIR}" >&2 exit 1 diff --git a/scripts/build-android-wheels-local.sh b/scripts/build-android-wheels-local.sh index e323756d..184d186c 100755 --- a/scripts/build-android-wheels-local.sh +++ b/scripts/build-android-wheels-local.sh @@ -320,14 +320,14 @@ VENV_DIR="${PYPIDIR}/.venv-local" rm -rf "${VENV_DIR}" "${PYTHON_BIN}" -m venv "${VENV_DIR}" # Some Python images only provide python3/python3.X in venv bin, while the -# script below invokes `${VENV_DIR}/bin/python`. +# script below invokes the venv bin/python entrypoint. if [[ ! -e "${VENV_DIR}/bin/python" && -e "${VENV_DIR}/bin/python3" ]]; then ln -sf python3 "${VENV_DIR}/bin/python" fi "${VENV_DIR}/bin/pip" install --upgrade pip "${VENV_DIR}/bin/pip" install -r "${PYPIDIR}/requirements.txt" "${VENV_DIR}/bin/pip" install "numpy==${NUMPY_VERSION}" -# Chaquopy build-wheel.py shells out to `wheel pack`, so ensure the venv scripts are first on PATH. +# Chaquopy build-wheel.py shells out to wheel pack, so ensure the venv scripts are first on PATH. export PATH="${VENV_DIR}/bin:${PATH}" if ! command -v wheel >/dev/null 2>&1; then echo "Missing required wheel CLI in virtualenv at ${VENV_DIR}" >&2 @@ -677,8 +677,12 @@ done popd >/dev/null mkdir -p "${OUT_DIR}" -cp -f "${PYPIDIR}/dist/chaquopy-libcodec2"/chaquopy_libcodec2-"${LIBCODEC2_VERSION}"-*.whl "${OUT_DIR}/" -cp -f "${PYPIDIR}/dist/pycodec2"/pycodec2-"${PYCODEC2_VERSION}"-*.whl "${OUT_DIR}/" +shopt -s nullglob +_codec2_wheels=("${PYPIDIR}/dist/chaquopy-libcodec2/chaquopy_libcodec2-${LIBCODEC2_VERSION}-"*.whl) +_pycodec2_wheels=("${PYPIDIR}/dist/pycodec2/pycodec2-${PYCODEC2_VERSION}-"*.whl) +shopt -u nullglob +cp -f "${_codec2_wheels[@]}" "${OUT_DIR}/" +cp -f "${_pycodec2_wheels[@]}" "${OUT_DIR}/" echo "Bundling libcodec2.so into pycodec2 wheels (Android dlopen)" "${VENV_DIR}/bin/python" "${ROOT_DIR}/scripts/repack-android-pycodec2-wheels.py" --vendor-dir "${OUT_DIR}" @@ -1080,12 +1084,14 @@ PY --abi "${abi}" \ "${RECIPE_DST}" - WHEEL_GLOB="${PYPIDIR}/dist/${PACKAGE_NAME}"/*android_"${API_LEVEL}"_"${abi_tag}".whl - if ! ls ${WHEEL_GLOB} >/dev/null 2>&1; then + shopt -s nullglob + wheels=("${PYPIDIR}/dist/${PACKAGE_NAME}/"*android_"${API_LEVEL}_${abi_tag}".whl) + shopt -u nullglob + if [[ ${#wheels[@]} -eq 0 ]]; then echo "Missing wheel output for ${PACKAGE_NAME} ${PACKAGE_VERSION} ${abi}" >&2 exit 1 fi - for built_wheel in ${WHEEL_GLOB}; do + for built_wheel in "${wheels[@]}"; do cp -f "${built_wheel}" "${OUT_DIR}/" fix_wheel_libpython_needed "${OUT_DIR}/$(basename "${built_wheel}")" "libpython${PYTHON_MINOR}.so" done @@ -1116,4 +1122,4 @@ fi echo "Done." echo "Built wheels in: ${OUT_DIR}" -ls -1 "${OUT_DIR}" | sort +find "${OUT_DIR}" -mindepth 1 -maxdepth 1 -printf '%f\n' | sort diff --git a/scripts/build-macos-universal.sh b/scripts/build-macos-universal.sh index 7a45744f..1af5c9bf 100644 --- a/scripts/build-macos-universal.sh +++ b/scripts/build-macos-universal.sh @@ -17,7 +17,7 @@ cd "$ROOT" # @electron/universal merges x64 and arm64 app bundles and requires every non-binary # file present in both trees to have identical bytes. Per-arch backend-manifest.json -# contents always differ, so skip embedding it here; electron/main.js treats a missing +# contents always differ, so skip embedding it here. electron/main.js treats a missing # manifest as "skip integrity check" (see verifyBackendIntegrity). export MESHCHATX_SKIP_BACKEND_MANIFEST=1 diff --git a/scripts/build/fetch_repository_wheels.py b/scripts/build/fetch_repository_wheels.py index 80633141..4093fa8b 100644 --- a/scripts/build/fetch_repository_wheels.py +++ b/scripts/build/fetch_repository_wheels.py @@ -8,7 +8,7 @@ copies any missing *.whl files from that directory into each identity's repository-server/bundled folder (no network required). The PyPI/sdist wheel intentionally omits this tree (see MANIFEST.in and -tool.setuptools.exclude-package-data); use this script for desktop or +tool.setuptools.exclude-package-data). Use this script for desktop or Android builds, or refresh bundled wheels when online. If dist/reticulum_meshchatx-*.whl exists at the project root, it is copied into the bundled directory after PyPI downloads so the shipped wheel matches this diff --git a/scripts/ci/android-emulator-smoke.sh b/scripts/ci/android-emulator-smoke.sh index b472335c..9ed4bffb 100755 --- a/scripts/ci/android-emulator-smoke.sh +++ b/scripts/ci/android-emulator-smoke.sh @@ -68,7 +68,7 @@ fail_with_logs() { probe_status_ok() { # Probe from inside the emulator (server binds 127.0.0.1 on-device). - # Prefer toybox wget (API 30+ images); fall back to python if present. + # Prefer toybox wget (API 30+ images). Fall back to python if present. local body="" if adb shell "command -v wget >/dev/null 2>&1" >/dev/null 2>&1; then body="$(adb shell "wget -qO- --no-check-certificate https://127.0.0.1:8000${STATUS_PATH}" 2>/dev/null | tr -d '\r' || true)" diff --git a/scripts/ci/attest-release-assets.sh b/scripts/ci/attest-release-assets.sh index aef66668..caaf3e87 100755 --- a/scripts/ci/attest-release-assets.sh +++ b/scripts/ci/attest-release-assets.sh @@ -1,8 +1,8 @@ #!/bin/sh # Create SLSA v1 cosign bundle attestations next to each release binary under DIR. -# Requires: cosign on PATH; COSIGN_KEY_PATH to cosign private key PEM; COSIGN_PASSWORD +# Requires: cosign on PATH, COSIGN_KEY_PATH to cosign private key PEM, and COSIGN_PASSWORD # if the key is encrypted. Run from repository root so scripts/ci/slsa-predicate.py resolves. -# Cosign v3+: uses cosign-signing-config-no-rekor.json (no Rekor upload); verify with +# Cosign v3+: uses cosign-signing-config-no-rekor.json (no Rekor upload). Verify with # cosign verify-blob-attestation --insecure-ignore-tlog=true when using the repo public key. # # Usage: attest-release-assets.sh @@ -10,7 +10,7 @@ set -eu DIR="${1:?directory}" KEY="${COSIGN_KEY_PATH:?set COSIGN_KEY_PATH}" -SCI_DIR="$(CDPATH= cd -- "$(dirname "$0")" && pwd)" +SCI_DIR="$(CDPATH='' cd -- "$(dirname "$0")" && pwd)" SIGNCFG="${SCI_DIR}/cosign-signing-config-no-rekor.json" if [ ! -f "$KEY" ]; then diff --git a/scripts/ci/ci-node-path.sh b/scripts/ci/ci-node-path.sh index ffbddbb6..68eafa16 100755 --- a/scripts/ci/ci-node-path.sh +++ b/scripts/ci/ci-node-path.sh @@ -1,6 +1,6 @@ #!/bin/sh # Ensure /usr/local/bin (go-task, etc.) is on PATH without shadowing actions/setup-node. -# ARM64 GitHub-hosted images may ship Node 20 in /usr/local/bin; prepending it breaks pnpm 11. +# ARM64 GitHub-hosted images may ship Node 20 in /usr/local/bin. Prepending it breaks pnpm 11. case ":${PATH}:" in *:/usr/local/bin:*) ;; *) PATH="${PATH}:/usr/local/bin" ;; diff --git a/scripts/ci/docker-tags.sh b/scripts/ci/docker-tags.sh index 68b8e408..2161079d 100755 --- a/scripts/ci/docker-tags.sh +++ b/scripts/ci/docker-tags.sh @@ -4,8 +4,8 @@ # Usage: docker-tags.sh [output_file] # Environment: GITEA_REF / GITHUB_REF, GITEA_REF_NAME / GITHUB_REF_NAME, TAG_SUFFIX # -# The output file contains one `-t registry/image:tag` per line, -# suitable for passing directly to `docker buildx build`. +# The output file contains one -t registry/image:tag per line, +# suitable for passing directly to docker buildx build. set -eu IMAGE="$1" @@ -14,11 +14,10 @@ SUFFIX="${TAG_SUFFIX:-}" : > "$OUTPUT" _suffix_tag() { - local tag="$1" if [ -n "$SUFFIX" ]; then - printf '%s' "${tag}${SUFFIX}" + printf '%s' "${1}${SUFFIX}" else - printf '%s' "$tag" + printf '%s' "$1" fi } diff --git a/scripts/ci/exec-priv.sh b/scripts/ci/exec-priv.sh index 7d6a59d8..b4867ce6 100755 --- a/scripts/ci/exec-priv.sh +++ b/scripts/ci/exec-priv.sh @@ -3,5 +3,6 @@ # Usage: sh scripts/ci/exec-priv.sh apt-get update set -eu +# shellcheck source=priv.sh disable=SC1091 . "$(dirname "$0")/priv.sh" run_priv "$@" diff --git a/scripts/ci/github-apt-linux-packaging.sh b/scripts/ci/github-apt-linux-packaging.sh index e022aa3d..1192de67 100755 --- a/scripts/ci/github-apt-linux-packaging.sh +++ b/scripts/ci/github-apt-linux-packaging.sh @@ -2,7 +2,7 @@ # APT packages needed for Linux Electron packaging (AppImage, deb, rpm) on Debian/Ubuntu or in Dockerfile.build (root). set -euo pipefail -# shellcheck source=scripts/ci/priv.sh +# shellcheck source=priv.sh disable=SC1091 . "$(dirname "$0")/priv.sh" _HOST_ARCH="$(uname -m)" @@ -11,8 +11,8 @@ if [ "$_HOST_ARCH" = "x86_64" ]; then fi run_priv apt-get update -y -_PKGS="patchelf libopusfile0 espeak-ng zip rpm elfutils fakeroot file" +_PKGS=(patchelf libopusfile0 espeak-ng zip rpm elfutils fakeroot file) if [ "$_HOST_ARCH" = "x86_64" ]; then - _PKGS="$_PKGS libc6:i386 libstdc++6:i386" + _PKGS+=("libc6:i386" "libstdc++6:i386") fi -run_priv apt-get install -y --no-install-recommends $_PKGS +run_priv apt-get install -y --no-install-recommends "${_PKGS[@]}" diff --git a/scripts/ci/github-build-macos.sh b/scripts/ci/github-build-macos.sh index a7feb5a1..7968b20c 100755 --- a/scripts/ci/github-build-macos.sh +++ b/scripts/ci/github-build-macos.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Build macOS universal (x64 + arm64) DMG via electron-builder. Unsigned CI build; signing is disabled. +# Build macOS universal (x64 + arm64) DMG via electron-builder. Unsigned CI build. Signing is disabled. set -euo pipefail ROOT="$(cd "$(dirname "$0")/../.." && pwd)" diff --git a/scripts/ci/github-draft-release-upload-assets.sh b/scripts/ci/github-draft-release-upload-assets.sh index d3111b62..7179da46 100755 --- a/scripts/ci/github-draft-release-upload-assets.sh +++ b/scripts/ci/github-draft-release-upload-assets.sh @@ -48,7 +48,6 @@ skip_noise() { library.zip | library.zip.cosign.bundle) return 0 ;; *__library.zip | *__library.zip.cosign.bundle) return 0 ;; *.so.yml | *.so.yml.cosign.bundle) return 0 ;; - *__*.so.yml | *__*.so.yml.cosign.bundle) return 0 ;; esac return 1 } @@ -118,7 +117,7 @@ mapfile -t files < <(find "$STAGE" -type f) for f in "${files[@]}"; do b=$(basename "$f") hash=$(sha256sum "$f" | awk '{print $1}') - printf '| %s | `%s` |\n' "$b" "$hash" + printf "| %s | \`%s\` |\n" "$b" "$hash" done echo echo "## Verification" diff --git a/scripts/ci/github-ensure-macos-x86-64-homebrew.sh b/scripts/ci/github-ensure-macos-x86-64-homebrew.sh index c458d747..32d711ff 100755 --- a/scripts/ci/github-ensure-macos-x86-64-homebrew.sh +++ b/scripts/ci/github-ensure-macos-x86-64-homebrew.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Ensure an x86_64 (Rosetta) Homebrew exists at /usr/local/bin/brew. -# GitHub-hosted Apple Silicon runners ship /opt/homebrew only; cx_Freeze universal +# GitHub-hosted Apple Silicon runners ship /opt/homebrew only. cx_Freeze universal # x64 slices need x86_64 libraries from /usr/local (see codec2, libyaml steps). set -euo pipefail diff --git a/scripts/ci/github-install-macos-x64-python-deps.sh b/scripts/ci/github-install-macos-x64-python-deps.sh index 59eea3cb..d6d672b6 100755 --- a/scripts/ci/github-install-macos-x64-python-deps.sh +++ b/scripts/ci/github-install-macos-x64-python-deps.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Install locked Python deps for the darwin-x64 cx_Freeze slice on Apple Silicon CI. -# The arm64 slice uses uv sync into .venv; this script mirrors that with .venv-x64 so +# The arm64 slice uses uv sync into .venv. This script mirrors that with .venv-x64 so # NumPy/LXST native wheels match the lockfile instead of unpinned pip -e . resolution. set -euo pipefail @@ -66,7 +66,7 @@ if [[ -z "$_NUMPY_VERSION" || -z "$_PYCODEC2_VERSION" ]]; then exit 1 fi -# Host is arm64; without --python-platform uv still resolves macOS wheels for aarch64. +# Host is arm64. Without --python-platform uv still resolves macOS wheels for aarch64. # pycodec2 has no cp314 macOS x86_64 wheel, so uv would build it from sdist and pull # numpy into an isolated cross build (meson: "Can not run test applications"). uv sync --frozen --group dev \ @@ -90,7 +90,7 @@ uv pip install --python "$_PY" \ # native extension is installed as x86_64-only, so the arm64-loaded interpreter # fails to dlopen it ("incompatible architecture"). Building the wheel ourselves # lets us force x86_64 on the one interpreter invocation that runs native code -# (via `arch -x86_64`), then hand uv a finished wheel to install, which is a +# (via arch -x86_64), then hand uv a finished wheel to install, which is a # plain file copy where uv's own architecture no longer matters. _lock_sdist_url() { awk -v pkg="$1" ' @@ -128,8 +128,8 @@ uv pip install --python "$_PY" \ --python-platform x86_64-apple-darwin \ "$_pycodec2_wheel" -# Cython/wheel are build-time-only tools for the pycodec2 sdist compile above; -# the finished wheel's .so no longer needs them at runtime. uv.lock does not +# Cython/wheel are build-time-only tools for the pycodec2 sdist compile above. +# The finished wheel's .so no longer needs them at runtime. uv.lock does not # pin either, so leaving them installed would make this venv's site-packages # diverge from .venv's (arm64, which never builds pycodec2 from source and # never needs them) -- cx_Freeze's module finder bundles whatever is actually diff --git a/scripts/ci/install-git-hooks.sh b/scripts/ci/install-git-hooks.sh index 43493fcd..54d432f8 100755 --- a/scripts/ci/install-git-hooks.sh +++ b/scripts/ci/install-git-hooks.sh @@ -2,7 +2,7 @@ # Point this clone at .githooks/ (tracked git hooks). set -eu -ROOT="$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd)" +ROOT="$(CDPATH='' cd -- "$(dirname "$0")/../.." && pwd)" cd "$ROOT" git config core.hooksPath .githooks diff --git a/scripts/ci/macos-normalize-pycodec2-dylib.sh b/scripts/ci/macos-normalize-pycodec2-dylib.sh index d9b9eda3..ffe1d952 100755 --- a/scripts/ci/macos-normalize-pycodec2-dylib.sh +++ b/scripts/ci/macos-normalize-pycodec2-dylib.sh @@ -2,7 +2,7 @@ # Normalize the installed pycodec2 package's bundled libcodec2 into a fixed, # arch-independent relative layout: # -# pycodec2/pycodec2*.so (extension module; @loader_path/libcodec2.dylib) +# pycodec2/pycodec2*.so (extension module, @loader_path/libcodec2.dylib) # pycodec2/libcodec2.dylib (single canonical name, no .dylibs/ subfolder) # # Published macOS wheels bundle libcodec2 under pycodec2/.dylibs/libcodec2..dylib diff --git a/scripts/ci/setup-cosign.sh b/scripts/ci/setup-cosign.sh index 484746cd..bba3fc3d 100755 --- a/scripts/ci/setup-cosign.sh +++ b/scripts/ci/setup-cosign.sh @@ -3,6 +3,7 @@ # Usage: setup-cosign.sh [version] set -eu +# shellcheck source=priv.sh disable=SC1091 . "$(dirname "$0")/priv.sh" COSIGN_VERSION="${1:-3.0.6}" diff --git a/scripts/ci/setup-task.sh b/scripts/ci/setup-task.sh index bdafb9aa..69303283 100755 --- a/scripts/ci/setup-task.sh +++ b/scripts/ci/setup-task.sh @@ -4,6 +4,7 @@ # Usage: setup-task.sh [version] set -eu +# shellcheck source=priv.sh disable=SC1091 . "$(dirname "$0")/priv.sh" TASK_VERSION="${1:-3.49.1}" diff --git a/scripts/ci/sign-tree-rsm.sh b/scripts/ci/sign-tree-rsm.sh index 165714cf..6d2ec872 100755 --- a/scripts/ci/sign-tree-rsm.sh +++ b/scripts/ci/sign-tree-rsm.sh @@ -12,7 +12,7 @@ # RNS_ID_PATH=~/.local/share/reticulum-go/reticulum-go-release.rid sh scripts/ci/sign-tree-rsm.sh set -eu -ROOT="$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd)" +ROOT="$(CDPATH='' cd -- "$(dirname "$0")/../.." && pwd)" cd "$ROOT" ID_PATH="${RNS_ID_PATH:-}" diff --git a/scripts/ci/tree-manifest.sh b/scripts/ci/tree-manifest.sh index 395c53b4..45765258 100755 --- a/scripts/ci/tree-manifest.sh +++ b/scripts/ci/tree-manifest.sh @@ -18,7 +18,7 @@ # tree-manifest.sh verify-tracked [inv] also fail if tracked files are missing from inv set -eu -ROOT="$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd)" +ROOT="$(CDPATH='' cd -- "$(dirname "$0")/../.." && pwd)" cd "$ROOT" MANIFEST_HEADER="# meshchatx tree manifest v1" diff --git a/scripts/ci/trivy-fs-scan.sh b/scripts/ci/trivy-fs-scan.sh index 45eba086..64feaac5 100755 --- a/scripts/ci/trivy-fs-scan.sh +++ b/scripts/ci/trivy-fs-scan.sh @@ -4,7 +4,7 @@ set -eu # MeshChatX runtime Python deps come from uv.lock (and pip-audit). Vendored trees may -# ship upstream poetry.lock files for standalone development only; skip them here. +# ship upstream poetry.lock files for standalone development only. Skip them here. exec trivy fs --exit-code 1 --severity HIGH,CRITICAL \ --skip-dirs .pnpm-store,.venv,temp-tests \ --skip-files vendor/lxmfy/poetry.lock,vendor/lxmfy/docs/poetry.lock \ diff --git a/scripts/ci/verify-package-contents-smoke.sh b/scripts/ci/verify-package-contents-smoke.sh index 6e128448..7c3151a4 100755 --- a/scripts/ci/verify-package-contents-smoke.sh +++ b/scripts/ci/verify-package-contents-smoke.sh @@ -2,7 +2,7 @@ # Smoke tests for verify-package-contents.sh (no full freeze required). set -euo pipefail -ROOT="$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd)" +ROOT="$(CDPATH='' cd -- "$(dirname "$0")/../.." && pwd)" SCRIPT="$ROOT/scripts/ci/verify-package-contents.sh" tmp="$(mktemp -d "${TMPDIR:-/tmp}/pkg-bloat-test.XXXXXX")" trap 'rm -rf "$tmp"' EXIT INT diff --git a/scripts/ci/verify-package-contents.sh b/scripts/ci/verify-package-contents.sh index 8bb3f66b..ebadbde1 100755 --- a/scripts/ci/verify-package-contents.sh +++ b/scripts/ci/verify-package-contents.sh @@ -15,7 +15,7 @@ # PACKAGE_BLOAT_MAX_HITS stop after N hits (default 40) set -euo pipefail -ROOT="$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd)" +ROOT="$(CDPATH='' cd -- "$(dirname "$0")/../.." && pwd)" MODE="${1:-}" TARGET="${2:-}" MAX_HITS="${PACKAGE_BLOAT_MAX_HITS:-40}" @@ -113,7 +113,7 @@ scan_directory_tree() { deny_re="$2" # Process substitution keeps scan_path_list in this shell (hits accumulate). scan_path_list "$deny_re" < <( - CDPATH= cd -- "$root" || exit 1 + CDPATH='' cd -- "$root" || exit 1 find . -print 2>/dev/null | sed 's|^\./||' ) } @@ -149,7 +149,7 @@ scan_dir() { scan_wheel() { whl="${TARGET:-}" if [ -z "$whl" ]; then - whl="$(ls -1 "$ROOT"/python-dist/*.whl 2>/dev/null | head -n 1 || true)" + whl="$(find "$ROOT/python-dist" -maxdepth 1 -type f -name '*.whl' -print 2>/dev/null | head -n 1 || true)" fi [ -n "$whl" ] && [ -f "$whl" ] || { echo "verify-package-contents.sh: wheel not found" >&2 @@ -193,7 +193,7 @@ scan_appimage() { echo "verify-package-contents.sh: extracting AppImage $ai" chmod +x "$ai" || true ( - CDPATH= cd -- "$tmp" + CDPATH='' cd -- "$tmp" "$ai" --appimage-extract >/dev/null ) scan_directory_tree "$tmp/squashfs-root" "$FROZEN_DENY_RE" diff --git a/scripts/ci/verify-tree-rsm.sh b/scripts/ci/verify-tree-rsm.sh index 5baa3a27..3f8fa5cb 100755 --- a/scripts/ci/verify-tree-rsm.sh +++ b/scripts/ci/verify-tree-rsm.sh @@ -15,7 +15,7 @@ # sh scripts/ci/verify-tree-rsm.sh set -eu -ROOT="$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd)" +ROOT="$(CDPATH='' cd -- "$(dirname "$0")/../.." && pwd)" cd "$ROOT" SIGNER="${RNS_REQUIRED_SIGNER:-e46112d44649266d71fe2193e00a4710}" diff --git a/scripts/ci/verify-workspace-clean.sh b/scripts/ci/verify-workspace-clean.sh index 093fa0ef..d422f8d6 100755 --- a/scripts/ci/verify-workspace-clean.sh +++ b/scripts/ci/verify-workspace-clean.sh @@ -13,7 +13,7 @@ # RNS_TREE_VERIFY_STRICT if 1, fail the process on verify errors set -eu -ROOT="$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd)" +ROOT="$(CDPATH='' cd -- "$(dirname "$0")/../.." && pwd)" cd "$ROOT" STRICT="${RNS_TREE_VERIFY_STRICT:-0}" diff --git a/scripts/docker-bake-lxst-filterlib-musl.py b/scripts/docker-bake-lxst-filterlib-musl.py index 2813533f..96b0a46f 100644 --- a/scripts/docker-bake-lxst-filterlib-musl.py +++ b/scripts/docker-bake-lxst-filterlib-musl.py @@ -3,13 +3,13 @@ """Alpine/musl Docker: copy cffi-built filter shared library to LXST.filterlib name. -LXST ships glibc-tagged filterlib*.so wheels; musl ignores them and cffi +LXST ships glibc-tagged filterlib*.so wheels. On musl, those are ignored and cffi verify() drops the musl artifact under LXST/__pycache__/_cffi__*.so. Without this step, a fresh process cannot resolve LXST.filterlib for ffi.dlopen() and would try to compile again at runtime (no gcc). The cffi artifact is a plain shared library (loaded via dlopen), not a Python -extension module (no PyInit_filterlib); do not import LXST.filterlib. +extension module (no PyInit_filterlib). Do not import LXST.filterlib. """ from __future__ import annotations diff --git a/scripts/ensure-flatpak-flathub-remote.sh b/scripts/ensure-flatpak-flathub-remote.sh index 23a10d9a..63d139e3 100644 --- a/scripts/ensure-flatpak-flathub-remote.sh +++ b/scripts/ensure-flatpak-flathub-remote.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# flatpak-bundler installs runtimes with flatpak --user and a bare ref; that only works +# flatpak-bundler installs runtimes with flatpak --user and a bare ref. That only works # once the Flathub remote exists (see @malept/flatpak-bundler ensureRef). set -euo pipefail diff --git a/scripts/rpi/install_meshchatx.sh b/scripts/rpi/install_meshchatx.sh index 206c856c..bc8fd788 100755 --- a/scripts/rpi/install_meshchatx.sh +++ b/scripts/rpi/install_meshchatx.sh @@ -5,7 +5,7 @@ set -euo pipefail # MESHCHATX_RELEASES_RSS Release feed (default: .../MeshChatX/releases.rss) # MESHCHATX_REPO_BASE Repo root for synthesized wheel URLs if RSS has no # .whl link in descriptions (default: derived from RSS URL) -# Cosign: Sigstore attestation verify needs the real cosign binary; this script can +# Cosign: Sigstore attestation verify needs the real cosign binary. This script can # download a checksum-verified release from GitHub to /tmp if none is on PATH. # MESHCHATX_COSIGN_VERSION (default: 3.0.6) # MESHCHATX_COSIGN_PUB_URL (default: raw cosign.pub from master in this repo) diff --git a/scripts/setup_wine_env.sh b/scripts/setup_wine_env.sh index febf3b7d..c23d15bc 100755 --- a/scripts/setup_wine_env.sh +++ b/scripts/setup_wine_env.sh @@ -29,7 +29,7 @@ echo "Downloading Windows Python and Git..." wget -q "$PYTHON_URL" wget -q "$GIT_URL" -chmod +x *.exe +chmod +x ./*.exe echo "Initializing Wine prefix in $WINEPREFIX..." wine_wrap wine wineboot --init diff --git a/scripts/sign-android-apks.sh b/scripts/sign-android-apks.sh index 485a6209..a009ff96 100755 --- a/scripts/sign-android-apks.sh +++ b/scripts/sign-android-apks.sh @@ -70,7 +70,7 @@ if [[ -z "${ANDROID_HOME}" ]]; then exit 1 fi -BT_DIR="$(ls -d "${ANDROID_HOME}"/build-tools/* 2>/dev/null | sort -V | tail -n 1)" +BT_DIR="$(find "${ANDROID_HOME}/build-tools" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort -V | tail -n 1)" if [[ -z "${BT_DIR}" ]]; then echo "No Android build-tools found under ${ANDROID_HOME}/build-tools." >&2 exit 1 @@ -81,9 +81,7 @@ if [[ ! -x "${BT_DIR}/zipalign" || ! -x "${BT_DIR}/apksigner" ]]; then fi APK_GLOB="${APK_GLOB:-android/app/build/outputs/apk/release/*-unsigned.apk}" -shopt -s nullglob -APKS=( ${APK_GLOB} ) -shopt -u nullglob +mapfile -t APKS < <(compgen -G "${APK_GLOB}" || true) if [[ ${#APKS[@]} -eq 0 ]]; then echo "No unsigned APKs matched: ${APK_GLOB}" >&2 exit 1 diff --git a/scripts/unify-backend-plain-files.sh b/scripts/unify-backend-plain-files.sh index 89b16f01..364887f0 100755 --- a/scripts/unify-backend-plain-files.sh +++ b/scripts/unify-backend-plain-files.sh @@ -5,8 +5,8 @@ # 1. Every file must exist in BOTH trees (no unique-to-one-arch files). # 2. Every non-Mach-O file must be byte-identical across trees. # -# Python bytecode (.pyc inside library.zip) is architecture-independent; -# only timestamps and zip metadata cause SHA differences. +# Python bytecode (.pyc inside library.zip) is architecture-independent. +# Only timestamps and zip metadata cause SHA differences. set -euo pipefail @@ -82,14 +82,14 @@ while IFS= read -r -d '' rel; do unified=$((unified + 1)) continue fi - # cx_Freeze bundles pure-Python modules into lib/library.zip; native + # cx_Freeze bundles pure-Python modules into lib/library.zip. Native # extensions are always written to the filesystem separately (they # can't be dlopen'd from inside a zip), so this archive's *contents* # are pure CPython bytecode just like loose .pyc files. Its raw bytes # almost always differ across two independent builds (each entry's # own PEP 552 header + the zip's own per-entry timestamps), so only # trust a blind copy once we've confirmed both slices bundled the - # same set of modules; a differing member list would mean the two + # same set of modules. A differing member list would mean the two # Python environments actually resolved different dependencies. if [[ "$(basename "$rel")" == "library.zip" ]]; then # Exclude *.dist-info provenance files that record *how* a package