mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 18:07:06 +01:00
The capture half -- dump_packages, pull_apks, pull_sdcard, dump_settings
and dump_focus_state -- moves into lib/backup_capture.sh. SDCARD_DIRS goes
with pull_sdcard, its only reader: left behind it would be a global the
entry script never reads (SC2034), and the hook runs shellcheck without -x
so each file has to stand alone.
This code decides what a phone backup actually contains and had no test at
all. It has one now, against a fake device mocking adb_cmd -- the single
boundary all five functions cross. 22 assertions, 52/52 lines, and 13
mutations all killed. One of those mutations reintroduces the stdin-
draining bug pull_apks' own comment documents (it pulled 1 of 54 packages
before it was fixed); the suite catches it.
Nine of the ten functions moved verbatim per verify_shell_split.sh.
dump_focus_state is the exception and the tool correctly says so: its
`{ ... } >file` group hid a line kcov instruments but bash never reports,
and rewriting it as individual redirects drew SC2129 instead. One printf
satisfies both. Its rendered focus-state.md was diffed against HEAD's
output on the same inputs -- byte-identical.
Same for three multi-line literals (SDCARD_DIRS and two mapfile process
substitutions), which were stuck at 1/N covered for the same reason.
phone_backup.sh is PC-side and in neither deploy list, so no list edits.
--help exits 0; --verify on an empty dir exits 1 naming the four missing
files, matching HEAD exactly. Over-cap count 22 -> 21.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
120 lines
4.8 KiB
Bash
Executable File
120 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# lib/backup_capture.sh — the capture half of phone_backup.sh: package lists,
|
|
# third-party APKs, shared-storage directories, settings dumps and the
|
|
# focus-mode state. Each function is handed the output directory to fill.
|
|
#
|
|
# Sourced by phone_backup.sh, which owns adb_common.sh (adb_cmd, adb_shell,
|
|
# _info, _warn). SDCARD_DIRS lives here rather than in the entry script
|
|
# because pull_sdcard is its only reader, and a file must not assign a global
|
|
# it never reads (SC2034) — shellcheck runs without -x, so each file stands
|
|
# alone.
|
|
|
|
# Directories pulled wholesale from shared storage. Anything not
|
|
# listed here is not backed up, so keep the list honest.
|
|
# Written on one line rather than one entry per line: kcov instruments a
|
|
# multi-line literal's continuation lines but bash only ever reports the
|
|
# statement at its first line, so a list spanning N lines is permanently
|
|
# stuck at 1/N covered however thoroughly it is tested.
|
|
readonly SDCARD_DIRS=(DCIM Pictures Download Documents Movies Music Signal RunnerUp)
|
|
|
|
dump_packages() {
|
|
local dir="$1"
|
|
adb_cmd shell pm list packages | sed 's/^package://' | tr -d '\r' |
|
|
sort >"${dir}/packages-all.txt"
|
|
adb_cmd shell pm list packages -3 | sed 's/^package://' | tr -d '\r' |
|
|
sort >"${dir}/packages-third-party.txt"
|
|
# Packages removed for user 0 read as uninstalled here; recorded
|
|
# separately so a restore knows what was deliberately purged.
|
|
adb_cmd shell pm list packages -u | sed 's/^package://' | tr -d '\r' |
|
|
sort >"${dir}/packages-including-removed.txt"
|
|
comm -13 "${dir}/packages-all.txt" "${dir}/packages-including-removed.txt" \
|
|
>"${dir}/packages-removed-for-user0.txt"
|
|
_info "Packages: $(wc -l <"${dir}/packages-third-party.txt") third-party, $(wc -l <"${dir}/packages-removed-for-user0.txt") removed for user 0"
|
|
}
|
|
|
|
pull_apks() {
|
|
local dir="$1" pkg="" path="" n=0 base=""
|
|
local -a pkgs=() paths=()
|
|
mkdir -p "${dir}/apks"
|
|
|
|
# Read the list into an array FIRST. Iterating the file with
|
|
# `while read < file` breaks after one package, because `adb`
|
|
# inside the loop inherits and drains that same stdin -- measured:
|
|
# it pulled 1 of 54 before this was fixed.
|
|
mapfile -t pkgs <"${dir}/packages-third-party.txt"
|
|
|
|
for pkg in "${pkgs[@]}"; do
|
|
[[ -n "${pkg}" ]] || continue
|
|
# A split app reports several paths (base + split_config.*).
|
|
# All of them are needed for a working offline reinstall, so
|
|
# each package gets its own directory rather than one file.
|
|
mapfile -t paths < <(adb_cmd shell pm path "${pkg}" 2>/dev/null | sed 's/^package://' | tr -d '\r')
|
|
[[ "${#paths[@]}" -gt 0 ]] || {
|
|
_warn "no APK path for ${pkg}"
|
|
continue
|
|
}
|
|
mkdir -p "${dir}/apks/${pkg}"
|
|
for path in "${paths[@]}"; do
|
|
[[ -n "${path}" ]] || continue
|
|
base="$(basename "${path}")"
|
|
adb_cmd pull "${path}" "${dir}/apks/${pkg}/${base}" >/dev/null 2>&1 ||
|
|
_warn "could not pull ${base} for ${pkg}"
|
|
done
|
|
n=$((n + 1))
|
|
done
|
|
_info "APKs pulled: ${n} packages, $(find "${dir}/apks" -name '*.apk' | wc -l) files"
|
|
}
|
|
|
|
pull_sdcard() {
|
|
local dir="$1" d=""
|
|
mkdir -p "${dir}/sdcard"
|
|
for d in "${SDCARD_DIRS[@]}"; do
|
|
if adb_cmd shell "test -d /sdcard/${d}" 2>/dev/null; then
|
|
_info "Pulling /sdcard/${d}"
|
|
adb_cmd pull "/sdcard/${d}" "${dir}/sdcard/" >/dev/null 2>&1 ||
|
|
_warn "partial or failed pull: ${d}"
|
|
fi
|
|
done
|
|
# Same stdin caveat as pull_apks: collect first, pull second.
|
|
local -a kdbx_paths=()
|
|
mapfile -t kdbx_paths < <(adb_cmd shell 'find /sdcard -iname "*.kdbx" 2>/dev/null' | tr -d '\r')
|
|
local kdbx=""
|
|
for kdbx in "${kdbx_paths[@]}"; do
|
|
[[ -n "${kdbx}" ]] || continue
|
|
_info "Pulling KeePass database: ${kdbx}"
|
|
mkdir -p "${dir}/sdcard/keepass"
|
|
adb_cmd pull "${kdbx}" "${dir}/sdcard/keepass/" >/dev/null 2>&1 || true
|
|
done
|
|
}
|
|
|
|
dump_settings() {
|
|
local dir="$1" ns=""
|
|
for ns in system secure global; do
|
|
adb_cmd shell settings list "${ns}" | tr -d '\r' | sort \
|
|
>"${dir}/settings-${ns}.txt"
|
|
done
|
|
_info "Settings captured (system/secure/global)"
|
|
}
|
|
|
|
dump_focus_state() {
|
|
local dir="$1"
|
|
local out="${dir}/focus-state.md" rethink="no" purged=""
|
|
|
|
# Built as one printf rather than a `{ ... } >file` group of many: kcov
|
|
# counts the group's closing brace as an instrumented line that bash never
|
|
# reports, and a run of individual redirects instead draws SC2129. One
|
|
# statement satisfies both, and the repo forbids suppressing either.
|
|
grep -qx 'com.celzero.bravedns' "${dir}/packages-all.txt" && rethink="yes"
|
|
purged="$(cat "${dir}/packages-removed-for-user0.txt")"
|
|
|
|
printf '%s\n%s\n\n%s\n%s\n\n%s%s\n%s\n%s\n' \
|
|
'# Focus-mode state at backup time' \
|
|
'# Restore with: phone_focus_mode/distraction_purge.sh' \
|
|
'## Packages removed for user 0' \
|
|
"${purged}" \
|
|
'## RethinkDNS installed: ' "${rethink}" \
|
|
'## uBlock filters live in the Firefox profile and CANNOT be' \
|
|
'## backed up from adb; see docs/youtube-block-unrooted.md' \
|
|
>"${out}"
|
|
}
|