diff --git a/plugins/clone-app/skills/clone-app/scripts/download-apk.sh b/plugins/clone-app/skills/clone-app/scripts/download-apk.sh new file mode 100755 index 0000000..55a653f --- /dev/null +++ b/plugins/clone-app/skills/clone-app/scripts/download-apk.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +set -euo pipefail + +package="${1:-}" +out_dir="${2:-}" +curl_bin="${CLONE_APP_CURL:-curl}" + +if [[ -z "$package" || -z "$out_dir" ]]; then + echo "ERROR: usage: download-apk.sh " >&2 + exit 1 +fi + +mkdir -p "$out_dir" +tmp_file="$out_dir/app.download" +url="https://d.apkpure.com/b/APK/${package}?version=latest" + +ok=0 +for attempt in 1 2 3; do + if "$curl_bin" -L --fail "$url" --output "$tmp_file" 2>/dev/null; then + ok=1; break + fi + echo "download attempt $attempt failed, retrying..." >&2 + sleep 1 +done + +if [[ "$ok" -ne 1 ]]; then + echo "ERROR: failed to download $package after 3 attempts from $url" >&2 + rm -f "$tmp_file" + exit 1 +fi + +# Decide extension: both APK and XAPK are ZIPs. XAPK = zip containing manifest.json + >=2 .apk entries. +ext="apk" +if entries="$(unzip -Z1 "$tmp_file" 2>/dev/null)"; then + apk_count="$(grep -c '\.apk$' <<<"$entries" || true)" + if grep -q '^manifest\.json$' <<<"$entries" && [[ "$apk_count" -ge 1 ]]; then + ext="xapk" + fi +fi + +final="$out_dir/app.$ext" +mv "$tmp_file" "$final" +echo "$final" diff --git a/plugins/clone-app/tests/test-download-apk.sh b/plugins/clone-app/tests/test-download-apk.sh new file mode 100644 index 0000000..18560ce --- /dev/null +++ b/plugins/clone-app/tests/test-download-apk.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -uo pipefail +SCRIPT="$(dirname "$0")/../skills/clone-app/scripts/download-apk.sh" +fail=0 +check() { [[ "$2" == "$3" ]] && echo "PASS: $1" || { echo "FAIL: $1 — expected '$2' got '$3'"; fail=1; }; } + +tmp="$(mktemp -d)" + +# Stub curl: writes a minimal zip containing manifest.json + two apk entries → xapk +cat > "$tmp/fakecurl-xapk.sh" <<'EOF' +#!/usr/bin/env bash +out=""; prev="" +for a in "$@"; do [[ "$prev" == "--output" ]] && out="$a"; prev="$a"; done +workdir="$(mktemp -d)" +echo '{}' > "$workdir/manifest.json" +echo 'a' > "$workdir/base.apk"; echo 'b' > "$workdir/config.apk" +( cd "$workdir" && zip -q -r "$out" . ) +exit 0 +EOF +chmod +x "$tmp/fakecurl-xapk.sh" + +path="$(CLONE_APP_CURL="$tmp/fakecurl-xapk.sh" bash "$SCRIPT" com.example.app "$tmp/out" 2>/dev/null)"; rc=$? +check "xapk exit 0" "0" "$rc" +check "xapk extension" "xapk" "${path##*.}" + +# Stub curl that always fails → exit 1 after retries +cat > "$tmp/fakecurl-fail.sh" <<'EOF' +#!/usr/bin/env bash +exit 22 +EOF +chmod +x "$tmp/fakecurl-fail.sh" +out2="$(CLONE_APP_CURL="$tmp/fakecurl-fail.sh" bash "$SCRIPT" com.example.app "$tmp/out2" 2>/dev/null)"; rc2=$? +check "fail exit 1" "1" "$rc2" + +rm -rf "$tmp" +exit $fail