mirror of
https://github.com/Lakr233/vphone-cli.git
synced 2026-09-02 02:34:29 +00:00
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.
86 lines
2.5 KiB
Bash
Executable File
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
|