186 lines
5.5 KiB
Bash
Executable File
186 lines
5.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
ROOT="$(cd "$(dirname "$0")" && pwd)"
|
||
AAB_DIR="$ROOT/build/app/outputs/bundle/release"
|
||
FLUTTER="/opt/flutter/bin/flutter"
|
||
JAVA_HOME="/root/.sdkman/candidates/java/21.0.11-amzn"
|
||
|
||
# ── colors ──
|
||
R=$'\033[0;31m' G=$'\033[0;32m' Y=$'\033[1;33m'
|
||
C=$'\033[0;36m' B=$'\033[1m' N=$'\033[0m'
|
||
|
||
bar="━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
blen=${#bar}
|
||
|
||
# ── helpers ──
|
||
CURSOR_ON='\033[?25h'
|
||
CURSOR_OFF='\033[?25l'
|
||
cleanup() { printf "$CURSOR_ON" >/dev/tty; exit; }
|
||
trap cleanup EXIT INT TERM
|
||
|
||
# ── arrow selector ──
|
||
select_arrow() {
|
||
local opts=("$@")
|
||
local sel=0 key i n=${#opts[@]}
|
||
local tty=/dev/tty
|
||
|
||
for i in "${!opts[@]}"; do
|
||
if [ "$i" -eq "$sel" ]; then
|
||
printf " ${C}❯ ${opts[$i]}${N}\n" >"$tty"
|
||
else
|
||
printf " ${opts[$i]}\n" >"$tty"
|
||
fi
|
||
done
|
||
printf '\033[%dA' "$n" >"$tty"
|
||
printf "$CURSOR_OFF" >"$tty"
|
||
|
||
while true; do
|
||
IFS= read -rsn1 key <"$tty"
|
||
if [[ $key == $'\x1b' ]]; then
|
||
read -rsn2 -t 0.01 key <"$tty" || key=''
|
||
case "$key" in
|
||
'[A') (( sel > 0 )) && (( sel-- )) ;;
|
||
'[B') (( sel < n - 1 )) && (( sel++ )) ;;
|
||
esac
|
||
elif [[ -z "$key" || "$key" == $'\n' || "$key" == $'\r' ]]; then
|
||
printf '\033[%dA\033[J' "$n" >"$tty"
|
||
printf "$CURSOR_ON" >"$tty"
|
||
printf '%s\n' "${opts[$sel]}"
|
||
return 0
|
||
fi
|
||
|
||
for i in "${!opts[@]}"; do
|
||
if [ "$i" -eq "$sel" ]; then
|
||
printf "\033[2K\r ${C}❯ ${opts[$i]}${N}\n" >"$tty"
|
||
else
|
||
printf "\033[2K\r ${opts[$i]}\n" >"$tty"
|
||
fi
|
||
done
|
||
printf '\033[%dA' "$n" >"$tty"
|
||
done
|
||
}
|
||
|
||
# ── progress bar ──
|
||
progress() {
|
||
local pct=$1 msg=$2
|
||
local filled=$(( pct * blen / 100 ))
|
||
local empty=$(( blen - filled ))
|
||
printf "\r${C}[${bar:0:filled}${N}${bar:0:empty}${C}]${N} %3d%% %s\033[K" "$pct" "$msg"
|
||
}
|
||
|
||
# ── ── ── ── ── ── ── ── ──
|
||
clear
|
||
cat <<EOF
|
||
${B}═══════════════════════════════════════${N}
|
||
${B} Factura del Hogar — Release Builder ${N}
|
||
${B}═══════════════════════════════════════${N}
|
||
|
||
EOF
|
||
|
||
# ── verify project ──
|
||
if [ ! -f "$ROOT/pubspec.yaml" ] || ! grep -q "flutter" "$ROOT/pubspec.yaml" 2>/dev/null; then
|
||
echo -e "${R}✗ Not a Flutter project root.${N}"
|
||
exit 1
|
||
fi
|
||
|
||
NAME=$(grep "^name:" "$ROOT/pubspec.yaml" | head -1 | awk '{print $2}' | tr -d '"')
|
||
VERSION=$(grep "^version:" "$ROOT/pubspec.yaml" | head -1 | awk '{print $2}')
|
||
|
||
printf " Project ${C}%s${N}\n" "$NAME"
|
||
printf " Version ${C}%s${N}\n" "$VERSION"
|
||
printf " Output ${C}%s${N}\n" "$AAB_DIR"
|
||
echo
|
||
|
||
# ── confirm with arrows ──
|
||
echo -e " ${Y}Build release for Play Store?${N}"
|
||
CHOICE=$(select_arrow "Yes" "No")
|
||
if [ "$CHOICE" != "Yes" ]; then
|
||
echo -e "${Y}Canceled.${N}"
|
||
exit 0
|
||
fi
|
||
|
||
export JAVA_HOME="$JAVA_HOME"
|
||
|
||
# ── clean ──
|
||
progress 3 "Cleaning..."
|
||
"$FLUTTER" clean > /dev/null 2>&1 || true
|
||
progress 6 "Cleaning... done"
|
||
|
||
# ── pub get ──
|
||
progress 8 "Dependencies..."
|
||
"$FLUTTER" pub get > /dev/null 2>&1
|
||
progress 12 "Dependencies... done"
|
||
|
||
# ── build AAB ──
|
||
progress 12 "Building release AAB..."
|
||
BUILD_OUTPUT=$("$FLUTTER" build appbundle --release 2>&1) || {
|
||
echo -e "\n${R}✗ Build failed:${N}"
|
||
echo "$BUILD_OUTPUT"
|
||
exit 1
|
||
}
|
||
progress 75 "AAB built successfully"
|
||
|
||
# ── native debug symbols ──
|
||
SYMBOLS_DIR="$ROOT/build/app/intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib"
|
||
progress 78 "Packaging symbols..."
|
||
if [ -d "$SYMBOLS_DIR" ]; then
|
||
cd "$SYMBOLS_DIR"
|
||
rm -f "$AAB_DIR/native-debug-symbols.zip"
|
||
zip -r "$AAB_DIR/native-debug-symbols.zip" . > /dev/null 2>&1
|
||
cd "$ROOT"
|
||
progress 95 "Symbols packaged"
|
||
else
|
||
echo -e "\n${Y}⚠ No native libs found${N}"
|
||
fi
|
||
|
||
# ── verify ──
|
||
progress 98 "Verifying..."
|
||
sleep 0.2
|
||
progress 100 "Complete!"
|
||
echo
|
||
|
||
# ── results ──
|
||
AAB_FILE="$AAB_DIR/app-release.aab"
|
||
SYM_FILE="$AAB_DIR/native-debug-symbols.zip"
|
||
size_aab=$(du -sh "$AAB_FILE" 2>/dev/null | cut -f1)
|
||
size_sym=$(du -sh "$SYM_FILE" 2>/dev/null | cut -f1)
|
||
|
||
cat <<EOF
|
||
|
||
${B}═══════════════════════════════════════${N}
|
||
${G}✓ Build successful!${N}
|
||
|
||
${C}App Bundle${N} $AAB_FILE
|
||
${C}Debug Symbols${N} ${SYM_FILE}
|
||
${C}Version${N} $VERSION
|
||
${C}AAB size${N} ${size_aab:-N/A}
|
||
${C}Symbols size${N} ${size_sym:-N/A}
|
||
|
||
EOF
|
||
|
||
# ── move prompt with arrows ──
|
||
echo -e " ${B}Move files to another location?${N}"
|
||
MOVE_CHOICE=$(select_arrow "No" "Yes")
|
||
if [ "$MOVE_CHOICE" = "Yes" ]; then
|
||
read -rp " Destination: " DEST
|
||
DEST="${DEST/#\~/$HOME}"
|
||
if [ -d "$DEST" ]; then
|
||
cp "$AAB_FILE" "$DEST/" 2>/dev/null \
|
||
&& echo -e " ${G}✓ AAB copied${N}" \
|
||
|| echo -e " ${R}✗ Failed to copy AAB${N}"
|
||
if [ -f "$SYM_FILE" ]; then
|
||
cp "$SYM_FILE" "$DEST/" 2>/dev/null \
|
||
&& echo -e " ${G}✓ Symbols copied${N}" \
|
||
|| echo -e " ${R}✗ Failed to copy symbols${N}"
|
||
fi
|
||
else
|
||
echo -e " ${R}✗ Directory not found: $DEST${N}"
|
||
fi
|
||
fi
|
||
|
||
echo
|
||
echo -e "${B}═══════════════════════════════════════${N}"
|
||
echo -e "${G}Ready to upload to Play Console!${N}"
|
||
echo -e "${B}═══════════════════════════════════════${N}"
|