-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·502 lines (465 loc) · 16 KB
/
setup.sh
File metadata and controls
executable file
·502 lines (465 loc) · 16 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
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
#!/bin/bash
# ADT Flutter Tools — interaktivní setup.
# Spusťte před prvním použitím aplikace: ./setup.sh
# Detekuje OS + dostupné package managery a nabídne instalaci toho, co chybí.
# Když je víc možností (např. brew + npm pro firebase), zeptá se, kterou chcete.
set -u
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
DIM='\033[2m'
NC='\033[0m'
MISSING=()
INSTALLED=()
SKIPPED=()
# ---------------------------------------------------------------------------
# Detekce OS a distribuce
# ---------------------------------------------------------------------------
OS_TYPE="unknown"
LINUX_DISTRO=""
case "$OSTYPE" in
linux-gnu*) OS_TYPE="linux" ;;
darwin*) OS_TYPE="macos" ;;
cygwin|msys|win32) OS_TYPE="windows" ;;
esac
if [ "$OS_TYPE" = "linux" ] && [ -r /etc/os-release ]; then
# shellcheck disable=SC1091
. /etc/os-release
LINUX_DISTRO="${ID:-}"
fi
echo -e "${BLUE}=== ADT Flutter Tools — setup ===${NC}"
echo -e "Systém: ${YELLOW}$OS_TYPE${NC}${LINUX_DISTRO:+ (${LINUX_DISTRO})}"
# ---------------------------------------------------------------------------
# Detekce dostupných package managerů
# ---------------------------------------------------------------------------
has() { command -v "$1" &> /dev/null; }
HAS_BREW=0; has brew && HAS_BREW=1
HAS_NPM=0; has npm && HAS_NPM=1
HAS_GEM=0; has gem && HAS_GEM=1
HAS_APT=0; has apt-get && HAS_APT=1
HAS_DNF=0; has dnf && HAS_DNF=1
HAS_PACMAN=0; has pacman && HAS_PACMAN=1
HAS_ZYPPER=0; has zypper && HAS_ZYPPER=1
HAS_SNAP=0; has snap && HAS_SNAP=1
HAS_WINGET=0; has winget && HAS_WINGET=1
HAS_SCOOP=0; has scoop && HAS_SCOOP=1
HAS_CHOCO=0; has choco && HAS_CHOCO=1
HAS_GIT=0; has git && HAS_GIT=1
HAS_DART=0; has dart && HAS_DART=1
AVAILABLE_MGRS=()
[ $HAS_BREW -eq 1 ] && AVAILABLE_MGRS+=("brew")
[ $HAS_NPM -eq 1 ] && AVAILABLE_MGRS+=("npm")
[ $HAS_GEM -eq 1 ] && AVAILABLE_MGRS+=("gem")
[ $HAS_APT -eq 1 ] && AVAILABLE_MGRS+=("apt")
[ $HAS_DNF -eq 1 ] && AVAILABLE_MGRS+=("dnf")
[ $HAS_PACMAN -eq 1 ] && AVAILABLE_MGRS+=("pacman")
[ $HAS_ZYPPER -eq 1 ] && AVAILABLE_MGRS+=("zypper")
[ $HAS_SNAP -eq 1 ] && AVAILABLE_MGRS+=("snap")
[ $HAS_WINGET -eq 1 ] && AVAILABLE_MGRS+=("winget")
[ $HAS_SCOOP -eq 1 ] && AVAILABLE_MGRS+=("scoop")
[ $HAS_CHOCO -eq 1 ] && AVAILABLE_MGRS+=("choco")
if [ ${#AVAILABLE_MGRS[@]} -gt 0 ]; then
echo -e "Dostupné nástroje: ${DIM}${AVAILABLE_MGRS[*]}${NC}"
fi
echo
# ---------------------------------------------------------------------------
# Interaktivní helpery (čtou z /dev/tty, aby šlo skript pipe-ovat)
# ---------------------------------------------------------------------------
ask_yn() {
# ask_yn "Otázka" [default_y|default_n]
local prompt="$1"
local default="${2:-default_n}"
local hint="[y/N]"
[ "$default" = "default_y" ] && hint="[Y/n]"
local ans
echo -ne "${BLUE}${prompt} ${hint}: ${NC}"
read -r ans < /dev/tty || ans=""
if [ -z "$ans" ]; then
[ "$default" = "default_y" ] && return 0 || return 1
fi
[[ "$ans" =~ ^[YyAa]$ ]]
}
choose_one() {
# choose_one "Otázka" "opt1" "opt2" ...
# Vrací zvolenou hodnotu přes globální REPLY_CHOICE.
local prompt="$1"; shift
local opts=("$@")
local i
echo -e "${BLUE}${prompt}${NC}"
for i in "${!opts[@]}"; do
echo -e " ${YELLOW}$((i+1)))${NC} ${opts[$i]}"
done
echo -e " ${YELLOW}0)${NC} přeskočit"
local ans
while true; do
echo -ne "${BLUE}Volba [1-${#opts[@]}, 0=přeskočit]: ${NC}"
read -r ans < /dev/tty || ans=""
if [[ "$ans" =~ ^[0-9]+$ ]]; then
if [ "$ans" -eq 0 ]; then
REPLY_CHOICE=""
return 1
fi
if [ "$ans" -ge 1 ] && [ "$ans" -le "${#opts[@]}" ]; then
REPLY_CHOICE="${opts[$((ans-1))]}"
return 0
fi
fi
echo -e "${YELLOW}Neplatná volba.${NC}"
done
}
run_cmd() {
# run_cmd "popis" cmd args...
local desc="$1"; shift
echo -e "${DIM}\$ $*${NC}"
if "$@"; then
echo -e "${GREEN}✓ $desc${NC}"
return 0
else
echo -e "${RED}✗ $desc selhalo${NC}"
return 1
fi
}
run_shell() {
# run_shell "popis" "shell expression" — pro pipe / sudo / složené příkazy
local desc="$1"; shift
echo -e "${DIM}\$ $*${NC}"
if bash -c "$*"; then
echo -e "${GREEN}✓ $desc${NC}"
return 0
else
echo -e "${RED}✗ $desc selhalo${NC}"
return 1
fi
}
needs_sudo_for_npm_global() {
[ $HAS_NPM -eq 1 ] || return 1
[ "$OS_TYPE" = "windows" ] && return 1
local prefix
prefix=$(npm config get prefix 2>/dev/null || echo "")
[ -n "$prefix" ] && [ ! -w "$prefix/lib/node_modules" ] && [ ! -w "$prefix/lib" ]
}
# ---------------------------------------------------------------------------
# Generická per-dep instalace
# Každá fce vrací 0 pokud je nakonec nainstalováno, 1 jinak.
# ---------------------------------------------------------------------------
# --- GIT ---
check_git() {
echo -n "Git... "
if has git; then
echo -e "${GREEN}OK${NC} ($(git --version))"
return 0
fi
echo -e "${RED}CHYBÍ${NC}"
return 1
}
install_git() {
local opts=()
case "$OS_TYPE" in
macos)
opts+=("xcode-select --install (Apple Command Line Tools)")
[ $HAS_BREW -eq 1 ] && opts+=("brew install git")
;;
linux)
[ $HAS_APT -eq 1 ] && opts+=("sudo apt-get install -y git")
[ $HAS_DNF -eq 1 ] && opts+=("sudo dnf install -y git")
[ $HAS_PACMAN -eq 1 ] && opts+=("sudo pacman -S --noconfirm git")
[ $HAS_ZYPPER -eq 1 ] && opts+=("sudo zypper install -y git")
;;
windows)
[ $HAS_WINGET -eq 1 ] && opts+=("winget install --id Git.Git -e --silent")
[ $HAS_SCOOP -eq 1 ] && opts+=("scoop install git")
[ $HAS_CHOCO -eq 1 ] && opts+=("choco install -y git")
;;
esac
if [ ${#opts[@]} -eq 0 ]; then
echo -e "${YELLOW}Žádný známý package manager není dostupný.${NC}"
echo -e "${YELLOW}-> Stáhněte ručně: https://git-scm.com/downloads${NC}"
return 1
fi
if ! choose_one "Jak nainstalovat Git?" "${opts[@]}"; then
return 1
fi
run_shell "Instalace Git" "$REPLY_CHOICE" || return 1
has git
}
# --- FLUTTER ---
check_flutter() {
echo -n "Flutter SDK... "
if has flutter; then
local ver
ver=$(flutter --version 2>/dev/null | head -n 1)
echo -e "${GREEN}OK${NC} ($ver)"
return 0
fi
echo -e "${RED}CHYBÍ${NC}"
return 1
}
install_flutter_via_git() {
local target="$HOME/flutter"
if [ -d "$target" ]; then
echo -e "${YELLOW}$target už existuje. Přeskakuji klonování.${NC}"
else
run_cmd "Klonování Flutter SDK do $target" \
git clone --depth 1 -b stable https://github.com/flutter/flutter.git "$target" || return 1
fi
# Přidání do PATH (pro aktuální session i shell rc)
export PATH="$target/bin:$PATH"
local rc=""
case "${SHELL##*/}" in
zsh) rc="$HOME/.zshrc" ;;
bash) rc="$HOME/.bashrc" ;;
esac
if [ -n "$rc" ] && [ -f "$rc" ] && ! grep -q "flutter/bin" "$rc"; then
if ask_yn "Přidat 'export PATH=\"$target/bin:\$PATH\"' do $rc?" default_y; then
echo "" >> "$rc"
echo "# Flutter SDK (přidáno ADT Flutter Tools setup)" >> "$rc"
echo "export PATH=\"$target/bin:\$PATH\"" >> "$rc"
echo -e "${GREEN}✓ Přidáno do $rc${NC}"
echo -e "${YELLOW}Otevřete nový terminál nebo: source $rc${NC}"
fi
fi
has flutter
}
install_flutter() {
local opts=()
case "$OS_TYPE" in
macos)
[ $HAS_BREW -eq 1 ] && opts+=("brew install --cask flutter")
;;
linux)
[ $HAS_SNAP -eq 1 ] && opts+=("sudo snap install flutter --classic")
;;
windows)
[ $HAS_WINGET -eq 1 ] && opts+=("winget install --id Google.Flutter -e --silent")
[ $HAS_SCOOP -eq 1 ] && opts+=("scoop bucket add extras; scoop install flutter")
[ $HAS_CHOCO -eq 1 ] && opts+=("choco install -y flutter")
;;
esac
# Univerzální fallback: git clone (vyžaduje git)
if [ $HAS_GIT -eq 1 ] || has git; then
opts+=("git clone do ~/flutter (oficiální postup, ~1 GB)")
fi
if [ ${#opts[@]} -eq 0 ]; then
echo -e "${YELLOW}Není dostupný žádný způsob instalace.${NC}"
echo -e "${YELLOW}-> Návod: https://docs.flutter.dev/get-started/install${NC}"
return 1
fi
if ! choose_one "Jak nainstalovat Flutter SDK? (~1 GB stažení)" "${opts[@]}"; then
return 1
fi
if [[ "$REPLY_CHOICE" == git\ clone* ]]; then
install_flutter_via_git
else
run_shell "Instalace Flutter" "$REPLY_CHOICE" || return 1
has flutter
fi
}
# --- FIREBASE CLI ---
check_firebase() {
echo -n "Firebase CLI... "
if has firebase; then
echo -e "${GREEN}OK${NC} ($(firebase --version))"
return 0
fi
echo -e "${YELLOW}NENALEZENO${NC}"
return 1
}
install_firebase() {
local opts=()
if [ $HAS_BREW -eq 1 ] && [ "$OS_TYPE" = "macos" ]; then
opts+=("brew install firebase-cli")
fi
if [ $HAS_NPM -eq 1 ]; then
if needs_sudo_for_npm_global; then
opts+=("sudo npm install -g firebase-tools")
else
opts+=("npm install -g firebase-tools")
fi
fi
case "$OS_TYPE" in
windows)
[ $HAS_WINGET -eq 1 ] && opts+=("winget install --id Google.FirebaseCLI -e --silent")
[ $HAS_SCOOP -eq 1 ] && opts+=("scoop install firebase-cli")
[ $HAS_CHOCO -eq 1 ] && opts+=("choco install -y firebase-tools")
;;
esac
if [ ${#opts[@]} -eq 0 ]; then
echo -e "${YELLOW}-> Pro instalaci nejdřív Node.js (npm): https://nodejs.org/${NC}"
return 1
fi
echo -e "${DIM}Firebase CLI je potřeba jen pro nahrávání symbolů na Crashlytics. Bez něj build funguje.${NC}"
if ! choose_one "Jak nainstalovat Firebase CLI?" "${opts[@]}"; then
return 1
fi
run_shell "Instalace Firebase CLI" "$REPLY_CHOICE" || return 1
has firebase
}
# --- PYTHON 3 ---
PYTHON_CMD=""
detect_python() {
if has python3; then
PYTHON_CMD="python3"
elif has python; then
local ver
ver=$(python --version 2>&1 | awk '{print $2}' | cut -d. -f1)
[ "$ver" = "3" ] && PYTHON_CMD="python"
fi
}
check_python() {
echo -n "Python 3... "
detect_python
if [ -n "$PYTHON_CMD" ]; then
echo -e "${GREEN}OK${NC} ($($PYTHON_CMD --version 2>&1))"
return 0
fi
echo -e "${RED}CHYBÍ${NC}"
return 1
}
install_python() {
local opts=()
case "$OS_TYPE" in
macos)
[ $HAS_BREW -eq 1 ] && opts+=("brew install python")
;;
linux)
[ $HAS_APT -eq 1 ] && opts+=("sudo apt-get install -y python3 python3-tk")
[ $HAS_DNF -eq 1 ] && opts+=("sudo dnf install -y python3 python3-tkinter")
[ $HAS_PACMAN -eq 1 ] && opts+=("sudo pacman -S --noconfirm python tk")
[ $HAS_ZYPPER -eq 1 ] && opts+=("sudo zypper install -y python3 python3-tk")
;;
windows)
[ $HAS_WINGET -eq 1 ] && opts+=("winget install --id Python.Python.3.12 -e --silent")
[ $HAS_SCOOP -eq 1 ] && opts+=("scoop install python")
[ $HAS_CHOCO -eq 1 ] && opts+=("choco install -y python")
;;
esac
if [ ${#opts[@]} -eq 0 ]; then
echo -e "${YELLOW}-> Stáhněte Python 3: https://www.python.org/downloads/${NC}"
return 1
fi
if ! choose_one "Jak nainstalovat Python 3?" "${opts[@]}"; then
return 1
fi
run_shell "Instalace Python 3" "$REPLY_CHOICE" || return 1
detect_python
[ -n "$PYTHON_CMD" ]
}
# --- TKINTER ---
check_tkinter() {
echo -n "Tkinter (GUI modul)... "
if [ -z "$PYTHON_CMD" ]; then
echo -e "${YELLOW}přeskočeno (chybí Python)${NC}"
return 1
fi
if $PYTHON_CMD -c "import tkinter" &> /dev/null; then
echo -e "${GREEN}OK${NC}"
return 0
fi
echo -e "${RED}CHYBÍ${NC}"
return 1
}
install_tkinter() {
local opts=()
case "$OS_TYPE" in
macos)
[ $HAS_BREW -eq 1 ] && opts+=("brew install python-tk")
;;
linux)
[ $HAS_APT -eq 1 ] && opts+=("sudo apt-get install -y python3-tk")
[ $HAS_DNF -eq 1 ] && opts+=("sudo dnf install -y python3-tkinter")
[ $HAS_PACMAN -eq 1 ] && opts+=("sudo pacman -S --noconfirm tk")
[ $HAS_ZYPPER -eq 1 ] && opts+=("sudo zypper install -y python3-tk")
;;
windows)
echo -e "${YELLOW}Na Windows je tkinter součástí python.org installeru — přeinstalujte Python a zaškrtněte 'tcl/tk and IDLE'.${NC}"
return 1
;;
esac
if [ ${#opts[@]} -eq 0 ]; then
echo -e "${YELLOW}Žádná známá cesta instalace. Reinstall Pythonu z balíčku obsahujícího tk.${NC}"
return 1
fi
if ! choose_one "Jak nainstalovat Tkinter?" "${opts[@]}"; then
return 1
fi
run_shell "Instalace Tkinter" "$REPLY_CHOICE" || return 1
$PYTHON_CMD -c "import tkinter" &> /dev/null
}
# --- COCOAPODS (jen macOS) ---
check_cocoapods() {
echo -n "CocoaPods... "
if has pod; then
echo -e "${GREEN}OK${NC} ($(pod --version))"
return 0
fi
echo -e "${YELLOW}NENALEZENO${NC}"
return 1
}
install_cocoapods() {
local opts=()
[ $HAS_BREW -eq 1 ] && opts+=("brew install cocoapods")
[ $HAS_GEM -eq 1 ] && opts+=("sudo gem install cocoapods")
if [ ${#opts[@]} -eq 0 ]; then
echo -e "${YELLOW}-> Návod: https://guides.cocoapods.org/using/getting-started.html${NC}"
return 1
fi
echo -e "${DIM}CocoaPods je potřeba jen pro iOS buildy.${NC}"
if ! choose_one "Jak nainstalovat CocoaPods?" "${opts[@]}"; then
return 1
fi
run_shell "Instalace CocoaPods" "$REPLY_CHOICE" || return 1
has pod
}
# ---------------------------------------------------------------------------
# Spojovací logika: check + případná instalace
# ---------------------------------------------------------------------------
ensure() {
# ensure <name> <check_fn> <install_fn>
local name="$1" check_fn="$2" install_fn="$3"
if $check_fn; then
return 0
fi
if ask_yn "Nainstalovat $name nyní?" default_y; then
if $install_fn; then
INSTALLED+=("$name")
return 0
else
MISSING+=("$name")
return 1
fi
else
SKIPPED+=("$name")
return 1
fi
}
# ---------------------------------------------------------------------------
# Hlavní průchod
# ---------------------------------------------------------------------------
ensure "Git" check_git install_git
ensure "Flutter SDK" check_flutter install_flutter
ensure "Firebase CLI" check_firebase install_firebase
ensure "Python 3" check_python install_python
ensure "Tkinter" check_tkinter install_tkinter
if [ "$OS_TYPE" = "macos" ]; then
ensure "CocoaPods" check_cocoapods install_cocoapods
fi
echo
echo -e "${BLUE}=== Souhrn ===${NC}"
[ ${#INSTALLED[@]} -gt 0 ] && echo -e "${GREEN}Nainstalováno:${NC} ${INSTALLED[*]}"
[ ${#SKIPPED[@]} -gt 0 ] && echo -e "${YELLOW}Přeskočeno:${NC} ${SKIPPED[*]}"
[ ${#MISSING[@]} -gt 0 ] && echo -e "${RED}Stále chybí:${NC} ${MISSING[*]}"
# Kritické závislosti pro běh aplikace: Python 3 + Tkinter.
# Flutter je potřeba pro buildy. Firebase / CocoaPods jen pro některé funkce.
CRITICAL_MISSING=0
for dep in "${MISSING[@]:-}" "${SKIPPED[@]:-}"; do
case "$dep" in
"Python 3"|"Tkinter") CRITICAL_MISSING=1 ;;
esac
done
if [ $CRITICAL_MISSING -eq 1 ]; then
echo -e "${RED}Bez Pythonu 3 + Tkinteru aplikace nepoběží.${NC}"
exit 1
fi
echo -e "${GREEN}Hotovo. Aplikaci můžete spustit.${NC}"
exit 0