-
-
Notifications
You must be signed in to change notification settings - Fork 235
Expand file tree
/
Copy pathbuild.sh
More file actions
executable file
·393 lines (341 loc) · 15.1 KB
/
Copy pathbuild.sh
File metadata and controls
executable file
·393 lines (341 loc) · 15.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
#!/bin/zsh
# FadCam Build Script with TUI & Progress Bar
# Interactive menu when run without arguments
set -e
# Clear screen immediately
clear
export JAVA_HOME="/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home"
# ANSI Colors (Red Theme)
RED='\033[0;31m'
DARK_RED='\033[38;5;52m'
BRIGHT_RED='\033[1;31m'
WHITE='\033[1;37m'
GRAY='\033[0;37m'
DIM_GRAY='\033[2;37m'
RESET='\033[0m'
CLEAR='\033c'
BOLD='\033[1m'
# Cursor control
HIDE_CURSOR='\033[?25l'
SHOW_CURSOR='\033[?25h'
SAVE_POS='\033[s'
RESTORE_POS='\033[u'
CLEAR_LINE='\033[2K'
MOVE_UP='\033[1A'
# Progress bar function
progress_bar() {
local current=$1
local total=$2
local width=40
local percent=$((current * 100 / total))
local filled=$((current * width / total))
local empty=$((width - filled))
printf "${RED}["
printf "${BRIGHT_RED}"
printf "%${filled}s" | tr ' ' '█'
printf "${DARK_RED}"
printf "%${empty}s" | tr ' ' '░'
printf "${RED}]${RESET} ${percent}%% (${current}/${total})"
}
# TUI Box drawing
draw_box() {
local width=$1
local title=$2
printf "${RED}┌$(printf '─%.0s' {1..$((width-2))})┐${RESET}\n"
if [ -n "$title" ]; then
printf "${RED}│${RESET} ${BRIGHT_RED}${BOLD}${title}${RESET}${RED}│${RESET}\n"
printf "${RED}├$(printf '─%.0s' {1..$((width-2))})┤${RESET}\n"
fi
}
close_box() {
local width=$1
printf "${RED}└$(printf '─%.0s' {1..$((width-2))})┘${RESET}\n"
}
# Print header
print_header() {
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
echo -e "${BRIGHT_RED}${BOLD}$1${RESET}"
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
}
# Print status
print_status() {
echo -e "$1 $2"
}
# Show help
show_help() {
clear
echo ""
echo -e "${BRIGHT_RED}${BOLD}╔══════════════════════════════════════╗${RESET}"
echo -e "${BRIGHT_RED}${BOLD}║ 🔴 FadCam Build Manager 🔴 ║${RESET}"
echo -e "${BRIGHT_RED}${BOLD}╚══════════════════════════════════════╝${RESET}"
echo ""
echo -e "${BRIGHT_RED}${BOLD}Usage:${RESET}"
echo -e "${WHITE} ./build.sh${RESET}${DIM_GRAY} # Interactive menu${RESET}"
echo -e "${WHITE} ./build.sh debug true${RESET}${DIM_GRAY} # Build & install debug APK${RESET}"
echo -e "${WHITE} ./build.sh release true${RESET}${DIM_GRAY} # Build & install release APK${RESET}"
echo -e "${WHITE} ./build.sh debug false${RESET}${DIM_GRAY} # Build debug APK only${RESET}"
echo -e "${WHITE} ./build.sh release false${RESET}${DIM_GRAY} # Build release APK only${RESET}"
echo -e "${WHITE} ./build.sh --help${RESET}${DIM_GRAY} # Show this help${RESET}"
echo ""
echo -e "${BRIGHT_RED}${BOLD}Menu Options (Interactive Mode):${RESET}"
echo -e "${BRIGHT_RED}[1]${RESET} ${WHITE}Build & Install Debug${RESET}${DIM_GRAY} (default)${RESET}"
echo -e "${BRIGHT_RED}[2]${RESET} ${WHITE}Build & Install Release${RESET}"
echo -e "${BRIGHT_RED}[3]${RESET} ${WHITE}Build Only (Debug)${RESET}"
echo -e "${BRIGHT_RED}[4]${RESET} ${WHITE}Build Only (Release)${RESET}"
echo -e "${BRIGHT_RED}[5]${RESET} ${WHITE}Clean Build Cache${RESET}"
echo -e "${BRIGHT_RED}[?]${RESET} ${WHITE}Show Help${RESET}"
echo -e "${BRIGHT_RED}[0]${RESET} ${WHITE}Exit${RESET}"
echo ""
echo -e "${BRIGHT_RED}${BOLD}Examples:${RESET}"
echo -e "${DIM_GRAY} • Build and test debug: ./build.sh debug true${RESET}"
echo -e "${DIM_GRAY} • Build for release: ./build.sh release false${RESET}"
echo -e "${DIM_GRAY} • Clean cache first, then build: use menu [5] then [1]${RESET}"
echo ""
}
# Show interactive menu
show_menu() {
clear
echo ""
echo -e "${BRIGHT_RED}${BOLD}╔══════════════════════════════════════╗${RESET}"
echo -e "${BRIGHT_RED}${BOLD}║ 🔴 FadCam Build Manager 🔴 ║${RESET}"
echo -e "${BRIGHT_RED}${BOLD}╚══════════════════════════════════════╝${RESET}"
echo ""
echo -e "${RED}Available Options:${RESET}"
echo ""
echo -e "${BRIGHT_RED}[1]${RESET} ${WHITE}Build & Install Debug${RESET}${DIM_GRAY} (default)${RESET}"
echo -e "${BRIGHT_RED}[2]${RESET} ${WHITE}Build & Install Release${RESET}"
echo -e "${BRIGHT_RED}[3]${RESET} ${WHITE}Build Only (Debug)${RESET}"
echo -e "${BRIGHT_RED}[4]${RESET} ${WHITE}Build Only (Release)${RESET}"
echo -e "${BRIGHT_RED}[5]${RESET} ${WHITE}Clean Build Cache${RESET}"
echo -e "${BRIGHT_RED}[?]${RESET} ${WHITE}Help${RESET}"
echo -e "${BRIGHT_RED}[0]${RESET} ${WHITE}Exit${RESET}"
echo ""
echo -en "${RED}Choose option (default 1): ${RESET}"
}
# Execute build
execute_build() {
local BUILD_TYPE=$1
local INSTALL=$2
local ACTION_NAME=$3
if [ "$BUILD_TYPE" = "debug" ]; then
GRADLE_TASK="assembleDefaultDebug"
APK_PATTERN="*debug.apk"
else
GRADLE_TASK="assembleDefaultRelease"
APK_PATTERN="*release.apk"
fi
print_header "$ACTION_NAME"
echo -e "${RED}Task:${RESET} ${WHITE}${GRADLE_TASK}${RESET}"
echo -e "${RED}Install:${RESET} ${WHITE}${INSTALL}${RESET}"
echo ""
# Build with real output
print_status "🔨" "Building APK..."
echo ""
# Run actual build and capture output
local BUILD_LOG=$(mktemp)
local BUILD_START=$(date +%s)
local LAST_LINE_COUNT=0
local LAST_PROGRESS_LINE=""
# Start build in background and monitor output
./gradlew "$GRADLE_TASK" --no-daemon --warning-mode=summary > "$BUILD_LOG" 2>&1 &
local BUILD_PID=$!
# Show live output and progress bar while building
while kill -0 $BUILD_PID 2>/dev/null; do
sleep 1.5
# Show last 2 lines of output that haven't been shown yet
if [ -f "$BUILD_LOG" ]; then
local current_lines=$(wc -l < "$BUILD_LOG")
if [ $current_lines -gt $LAST_LINE_COUNT ]; then
# Show up to 2 new lines
local start_line=$((LAST_LINE_COUNT + 1))
local end_line=$current_lines
local show_lines=$((end_line - start_line + 1))
if [ $show_lines -gt 2 ]; then
start_line=$((end_line - 1))
show_lines=2
fi
if [ $show_lines -gt 0 ]; then
# Erase previous progress line before printing new output
if [ -n "$LAST_PROGRESS_LINE" ]; then
printf "\r\033[0K"
fi
sed -n "${start_line},${end_line}p" "$BUILD_LOG" | while read -r line; do
if [ -n "$line" ] && [[ ! "$line" =~ ^[[:space:]]*$ ]]; then
echo -e "${DIM_GRAY} $line${RESET}"
fi
done
fi
LAST_LINE_COUNT=$current_lines
fi
# Show progress bar estimate on same line (without newline)
local elapsed=$(($(date +%s) - BUILD_START))
local progress=$((elapsed * 100 / 45)) # Estimate ~45s build
if [ $progress -gt 95 ]; then progress=95; fi
# Create progress bar with correct character count
local filled=$((progress / 2)) # 0-50 characters
local empty=$((50 - filled))
local bar=$(printf "%-${filled}s" | tr ' ' '█')
local empty_bar=$(printf "%-${empty}s" | tr ' ' '░')
# Print progress line with carriage return to update same line
printf "\r${RED}[${BRIGHT_RED}${bar}${DARK_RED}${empty_bar}${RED}]${RESET} ${progress}%% (${progress}/100)\033[0K"
LAST_PROGRESS_LINE="shown"
fi
done
wait $BUILD_PID
local BUILD_EXIT=$?
local BUILD_END=$(date +%s)
local BUILD_TIME=$((BUILD_END - BUILD_START))
# Final progress bar at 100%
printf "\r${RED}[${BRIGHT_RED}$(printf '%-50s' | tr ' ' '█')${RED}]${RESET} 100%% (100/100)\033[0K\n"
echo ""
if [ $BUILD_EXIT -eq 0 ]; then
print_status "✅" "Build completed in ${BUILD_TIME}s"
echo ""
else
print_status "❌" "Build FAILED after ${BUILD_TIME}s"
echo ""
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
echo -e "${BRIGHT_RED}Build Output:${RESET}"
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
cat "$BUILD_LOG"
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
rm -f "$BUILD_LOG"
return 1
fi
rm -f "$BUILD_LOG"
# Find APK
APK_PATH=$(find app/build/outputs/apk -name "$APK_PATTERN" -type f 2>/dev/null | head -1)
if [ -z "$APK_PATH" ]; then
print_status "❌" "APK not found in output directory"
echo -e "${DIM_GRAY}Expected to find: app/build/outputs/apk/**/$APK_PATTERN${RESET}"
echo ""
return 1
fi
APK_DIR=$(dirname "$APK_PATH")
APK_NAME=$(basename "$APK_PATH")
APK_SIZE=$(ls -lh "$APK_PATH" | awk '{print $5}')
# Show APK info
print_header "📦 APK Information"
print_status "📁" "Directory: ${BRIGHT_RED}${APK_DIR#$(pwd)/}${RESET}"
print_status "📄" "Filename: ${BRIGHT_RED}${APK_NAME}${RESET}"
print_status "💾" "Size: ${BRIGHT_RED}${APK_SIZE}${RESET}"
echo ""
# Install if requested using Gradle (professional Android approach)
if [ "$INSTALL" = "true" ]; then
# Capitalize first letter of BUILD_TYPE for Gradle task (e.g., debug -> Debug)
local BUILD_TYPE_UPPER=$(echo "$BUILD_TYPE" | tr '[:lower:]' '[:upper:]' | cut -c1)$(echo "$BUILD_TYPE" | cut -c2-)
# Show device info using standard adb approach
local DEVICE_COUNT=$(adb devices | grep -E '^[a-zA-Z0-9].*[[:space:]]device$' | wc -l)
if [ $DEVICE_COUNT -eq 0 ]; then
print_status "⚠️" "No connected devices found"
echo ""
return 0
fi
print_status "📱" "Connected Devices: ${BRIGHT_RED}${DEVICE_COUNT}${RESET}"
adb devices | grep -E '^[a-zA-Z0-9].*[[:space:]]device$' | while read -r device _; do
local DEVICE_MODEL=$(adb -s "$device" shell getprop ro.product.model 2>/dev/null || echo "Unknown")
local DEVICE_VERSION=$(adb -s "$device" shell getprop ro.build.version.release 2>/dev/null || echo "?")
echo -e " ${BRIGHT_RED}[${device:0:16}]${RESET} ${WHITE}${DEVICE_MODEL}${RESET} - ${GRAY}Android ${DEVICE_VERSION}${RESET}"
done
echo ""
print_status "📥" "Installing to all connected devices..."
# Use gradle's standard install task (Android official way)
local INSTALL_TASK="app:installDefault${BUILD_TYPE_UPPER}"
if ./gradlew "$INSTALL_TASK" --no-daemon 2>&1 | tail -3; then
print_status "✅" "Installation successful on ${BRIGHT_RED}${DEVICE_COUNT}${RESET} device(s)"
# Launch using Android's official am start command (not gradle run which doesn't exist)
echo ""
print_status "🚀" "Launching app on all devices..."
local PACKAGE_NAME="com.fadcam.beta"
[ "$BUILD_TYPE" = "release" ] && PACKAGE_NAME="com.fadcam"
# Use am start with proper activity path - this is the Android standard
adb devices | grep -E '^[a-zA-Z0-9].*[[:space:]]device$' | while read -r device _; do
# Launch the app (Android's official way) - note: full class path needed
if adb -s "$device" shell am start -W -n "${PACKAGE_NAME}/com.fadcam.SplashActivity" 2>/dev/null; then
echo -e " ${BRIGHT_RED}[${device:0:16}]${RESET} ✅ Launched successfully"
else
echo -e " ${BRIGHT_RED}[${device:0:16}]${RESET} ⚠️ Launch may have failed"
fi
done
else
print_status "❌" "Installation failed"
echo ""
return 1
fi
else
print_status "💡" "APK ready: ${BRIGHT_RED}${APK_PATH}${RESET}"
fi
echo ""
print_header "✨ Build Complete!"
echo ""
return 0
}
# Main logic
if [ $# -eq 0 ]; then
# Interactive menu mode
while true; do
show_menu
read -r choice
choice=${choice:-1}
case $choice in
1|"")
execute_build "debug" "true" "🔴 Debug Build & Install"
;;
2)
execute_build "release" "true" "🔴 Release Build & Install"
;;
3)
execute_build "debug" "false" "🔴 Debug Build Only"
;;
4)
execute_build "release" "false" "🔴 Release Build Only"
;;
5)
print_header "🔴 Cleaning Build Cache"
print_status "🧹" "Clearing Gradle cache..."
./gradlew clean --quiet --no-daemon
print_status "✅" "Cache cleaned"
echo ""
;;
"?"|h|H)
show_help
echo -en "${RED}Press Enter to continue...${RESET}"
read
;;
0)
echo -e "${RED}Goodbye!${RESET}"
exit 0
;;
*)
print_status "❌" "Invalid option. Please try again."
sleep 2
;;
esac
if [[ "$choice" =~ ^[0-5]$ ]]; then
if [ $choice -ne 5 ] && [ $choice -ne 0 ]; then
echo -en "${RED}Press Enter to continue...${RESET}"
read
fi
elif [[ "$choice" == "?" || "$choice" == "h" || "$choice" == "H" ]]; then
# Help option, continue to next menu iteration
:
fi
done
else
# Direct execution mode or help
if [ "$1" = "--help" ] || [ "$1" = "-h" ] || [ "$1" = "help" ]; then
show_help
else
BUILD_TYPE=${1:-debug}
INSTALL=${2:-true}
if [ "$BUILD_TYPE" = "debug" ]; then
ACTION_NAME="🔴 Debug Build"
else
ACTION_NAME="🔴 Release Build"
fi
if [ "$INSTALL" = "true" ]; then
ACTION_NAME="$ACTION_NAME & Install"
fi
execute_build "$BUILD_TYPE" "$INSTALL" "$ACTION_NAME"
fi
fi