feat: add android-fs5 CLI toolset
- fs5 entrypoint with status, push, pull, app, shell, logs commands - lib/adb.sh: ADB wrapper functions with idempotency and --force guards - lib/output.sh: human + JSON output formatting via Python - 33 bats tests (6 status, 9 transfer, 7 app, 5 shell, 6 logs) — all passing - Zero shellcheck warnings - .env-based config (device serial, log path) - Spec-Driven Development artifacts in specs/001-android-fs5-management/ Device: exone GmbH FS5 (RD51QE202392, Android 9)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env bash
|
||||
# lib/output.sh — Human and JSON output formatting for android-fs5
|
||||
# shellcheck shell=bash
|
||||
|
||||
# ANSI colors (disabled when not a terminal)
|
||||
if [[ -t 1 ]]; then
|
||||
_RED='\033[0;31m'
|
||||
_GREEN='\033[0;32m'
|
||||
_YELLOW='\033[1;33m'
|
||||
_CYAN='\033[0;36m'
|
||||
_RESET='\033[0m'
|
||||
else
|
||||
_RED='' _GREEN='' _YELLOW='' _CYAN='' _RESET=''
|
||||
fi
|
||||
|
||||
# out_human MSG — print informational message to stdout
|
||||
out_human() {
|
||||
echo -e "${_CYAN}${1}${_RESET}"
|
||||
}
|
||||
|
||||
# out_success MSG — print success message with checkmark
|
||||
out_success() {
|
||||
echo -e "${_GREEN}✓ ${1}${_RESET}"
|
||||
}
|
||||
|
||||
# out_warn MSG — print warning to stdout
|
||||
out_warn() {
|
||||
echo -e "${_YELLOW}⚠ ${1}${_RESET}"
|
||||
}
|
||||
|
||||
# out_error MSG — print error message to stderr
|
||||
out_error() {
|
||||
echo -e "${_RED}✗ ${1}${_RESET}" >&2
|
||||
}
|
||||
|
||||
# out_json KEY=VALUE ... — emit a JSON object from key=value pairs
|
||||
# Usage: out_json serial="RD51QE202392" model="FS5" battery_level=85
|
||||
out_json() {
|
||||
local -a pairs=("$@")
|
||||
python3 - "${pairs[@]}" <<'PYEOF'
|
||||
import sys, json
|
||||
|
||||
data = {}
|
||||
for arg in sys.argv[1:]:
|
||||
if '=' in arg:
|
||||
key, _, val = arg.partition('=')
|
||||
# Attempt numeric conversion
|
||||
try:
|
||||
if '.' in val:
|
||||
data[key] = float(val)
|
||||
else:
|
||||
data[key] = int(val)
|
||||
except ValueError:
|
||||
# Boolean strings
|
||||
if val.lower() == 'true':
|
||||
data[key] = True
|
||||
elif val.lower() == 'false':
|
||||
data[key] = False
|
||||
else:
|
||||
data[key] = val
|
||||
|
||||
print(json.dumps(data, indent=2))
|
||||
PYEOF
|
||||
}
|
||||
Reference in New Issue
Block a user