Files
vphone-cli/scripts/fetch_debs.sh
T
zqxwce 084e239c36 fix: resolve all paths correctly for the bundled / brew-installed app
A whole-codebase audit surfaced path bugs that only bite the bundled .app —
especially when brew puts vphone-cli on $PATH via a symlink, so the process
launches by a bare name from an arbitrary CWD:

- HIGH (crash): CommandLine.arguments[0] was used to locate the running binary
  and the resource base (VPhoneResources.resolve default, vm launch bootBinary,
  vm create selfExe). Under a bare-name PATH launch argv[0] is just
  "vphone-cli", which URL(fileURLWithPath:) resolves against the CWD (e.g.
  $HOME/vphone-cli) — so `vm launch` errored "not found" and `vm create` couldn't
  respawn to boot. Add VPhoneResources.runningExecutable() using
  Bundle.main.executableURL (the kernel-provided path, correct regardless of
  argv[0]/CWD/symlink) and route all three through it. One helper fixes every
  .resolve() consumer.

- MEDIUM (silent): the extra-deb feature resolved its cache + manifest under the
  read-only bundle (Resources/debs, Resources/debs.list). Honor VPHONE_DEBS_DIR
  (a writable ~/.vphone/debs the app now sets, mirroring IPSW_DIR/VPHONE_SEAL_DIR)
  and bundle debs.list.

- LOW (cosmetic): fw_prepare read ../README.md (absent in the bundle → firmwares
  labeled "Not Tested"). Bundle README.md.

Verified: Bundle.main.executableURL yields the real binary under a bare-name
symlink launch (argv[0] → $HOME); build clean; 79 VPhoneCore tests pass.
2026-07-28 15:21:29 +03:00

86 lines
2.5 KiB
Bash
Executable File

#!/bin/zsh
# fetch_debs.sh — Download debs from a URL manifest into a cache dir.
# Skips files already cached; leaves manually-added debs alone. A failed
# download is reported and skipped, never fatal (always exits 0).
#
# Usage: fetch_debs.sh [cache_dir] [manifest_file]
# defaults: <repo>/debs and <repo>/debs.list
set -uo pipefail
[[ -n "${_VPHONE_PATH:-}" ]] && export PATH="$_VPHONE_PATH"
SCRIPT_DIR="${0:a:h}"
REPO_ROOT="${SCRIPT_DIR:h}"
# VPHONE_DEBS_DIR (set by the app to a writable ~/.vphone/debs) keeps the cache
# out of the read-only .app bundle; the manifest is bundled next to this script's
# repo/Resources root, so $REPO_ROOT/debs.list resolves in both dev and .app.
CACHE_DIR="${1:-${VPHONE_DEBS_DIR:-$REPO_ROOT/debs}}"
MANIFEST="${2:-$REPO_ROOT/debs.list}"
mkdir -p "$CACHE_DIR"
deb_filename_from_url() {
local url="$1"
url="${url%%\#*}"
url="${url%%\?*}"
print -r -- "${url##*/}"
}
downloaded=0
cached=0
failed=0
if [[ -f "$MANIFEST" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
line="${line#"${line%%[![:space:]]*}"}"
line="${line%"${line##*[![:space:]]}"}"
[[ -z "$line" || "$line" == \#* ]] && continue
name="$(deb_filename_from_url "$line")"
if [[ "$name" != *.deb ]]; then
echo " [!] ERROR: URL does not resolve to a .deb filename, skipping: $line" >&2
failed=$((failed + 1))
continue
fi
dest="$CACHE_DIR/$name"
if [[ -s "$dest" ]]; then
echo " [=] Cached: $name"
cached=$((cached + 1))
continue
fi
echo " [>] Downloading: $line"
tmp="$dest.download"
if curl -fL --retry 2 --connect-timeout 20 \
--speed-limit 1024 --speed-time 30 -o "$tmp" "$line"; then
mv -f "$tmp" "$dest"
echo " [+] Downloaded: $name"
downloaded=$((downloaded + 1))
else
rc=$?
rm -f "$tmp"
echo " [!] ERROR: download failed (curl exit $rc), skipping: $line" >&2
failed=$((failed + 1))
fi
done < "$MANIFEST"
else
echo " [=] No manifest at $MANIFEST (skipping downloads)"
fi
total=0
for f in "$CACHE_DIR"/*.deb(N); do
total=$((total + 1))
done
echo " [i] debs: $total in cache ($downloaded downloaded, $cached already cached, $failed failed)"
# Return the cache to the invoking user when run under sudo.
if [[ "$(id -u)" == "0" && -n "${SUDO_USER:-}" ]]; then
chown -R "$SUDO_USER" "$CACHE_DIR" 2>/dev/null || true
fi
exit 0