diff --git a/meshchatx.rsm b/meshchatx.rsm index 523462e5..10934b12 100644 Binary files a/meshchatx.rsm and b/meshchatx.rsm differ 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