weehong gist felülvizsgálása 6 days ago. Revízióhoz ugrás
1 file changed, 45 insertions, 260 deletions
menu.sh
| @@ -5,9 +5,9 @@ | |||
| 5 | 5 | # ======================================================= | |
| 6 | 6 | if [ -z "${_PREFER_ZSH_BOOTSTRAPPED:-}" ]; then | |
| 7 | 7 | export _PREFER_ZSH_BOOTSTRAPPED=1 | |
| 8 | - | ||
| 8 | + | ||
| 9 | 9 | # Only attempt to re-execute if $0 is an actual file on disk. | |
| 10 | - | # This prevents the 'can't open input file' error when running | |
| 10 | + | # This prevents the 'can't open input file' error when running | |
| 11 | 11 | # from memory via `bash -c "$(curl ...)"` or `zsh -c`. | |
| 12 | 12 | if [ -f "$0" ]; then | |
| 13 | 13 | if command -v zsh >/dev/null 2>&1; then | |
| @@ -61,7 +61,7 @@ add_to_path_config() { | |||
| 61 | 61 | local label=$1 | |
| 62 | 62 | local path_line=$2 | |
| 63 | 63 | local target_file="${3:-$PROFILE_FILE}" | |
| 64 | - | ||
| 64 | + | ||
| 65 | 65 | if [[ -f "$target_file" ]]; then | |
| 66 | 66 | if ! grep -q "$label" "$target_file"; then | |
| 67 | 67 | printf "\n# %s\n%s\n" "$label" "$path_line" >> "$target_file" | |
| @@ -71,8 +71,8 @@ add_to_path_config() { | |||
| 71 | 71 | printf "\n# %s\n%s\n" "$label" "$path_line" >> "$PROFILE_FILE" | |
| 72 | 72 | log "Added $label to shell profile ($PROFILE_FILE)." | |
| 73 | 73 | fi | |
| 74 | - | ||
| 75 | - | # Instantly evaluate the path line so the current script session | |
| 74 | + | ||
| 75 | + | # Instantly evaluate the path line so the current script session | |
| 76 | 76 | # can immediately use the newly installed tool in subsequent steps. | |
| 77 | 77 | eval "$path_line" 2>/dev/null || true | |
| 78 | 78 | } | |
| @@ -120,10 +120,10 @@ install_build_tools() { | |||
| 120 | 120 | install_brew() { | |
| 121 | 121 | if require_cmd brew; then warn "Homebrew already installed"; return; fi | |
| 122 | 122 | log "Installing Homebrew from Official Source..." | |
| 123 | - | ||
| 123 | + | ||
| 124 | 124 | # Homebrew's installer specifically requires Bash execution, regardless of current shell | |
| 125 | 125 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | |
| 126 | - | ||
| 126 | + | ||
| 127 | 127 | if [[ "$OS_LOWER" == "linux" ]]; then | |
| 128 | 128 | add_to_path_config "HOMEBREW" 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' | |
| 129 | 129 | elif [[ "$MAC_ARCH" == "arm64" ]]; then | |
| @@ -135,46 +135,46 @@ install_brew() { | |||
| 135 | 135 | ||
| 136 | 136 | install_nvm() { | |
| 137 | 137 | # 1. Temporarily disable 'unbound variable' strictness for NVM | |
| 138 | - | set +u | |
| 139 | - | ||
| 138 | + | set +u | |
| 139 | + | ||
| 140 | 140 | export NVM_DIR="$HOME/.nvm" | |
| 141 | - | ||
| 142 | - | if [ -d "$NVM_DIR" ]; then | |
| 141 | + | ||
| 142 | + | if [ -d "$NVM_DIR" ]; then | |
| 143 | 143 | warn "NVM is already installed." | |
| 144 | 144 | else | |
| 145 | 145 | log "Installing NVM via $CURRENT_SHELL..." | |
| 146 | 146 | curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | $CURRENT_SHELL | |
| 147 | 147 | fi | |
| 148 | - | ||
| 148 | + | ||
| 149 | 149 | [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" | |
| 150 | - | ||
| 150 | + | ||
| 151 | 151 | printf "\n${YELLOW}Which version of Node.js would you like to install?${NC}\n" | |
| 152 | 152 | printf " 1) LTS (Long Term Support - Recommended for stability)\n" | |
| 153 | 153 | printf " 2) Latest (Current features - Recommended for testing new APIs)\n" | |
| 154 | 154 | printf " 3) Skip installing Node.js right now\n" | |
| 155 | - | ||
| 156 | - | printf "Select (1/2/3): " | |
| 155 | + | ||
| 156 | + | printf "Select (1/2/3): " | |
| 157 | 157 | read node_choice | |
| 158 | 158 | ||
| 159 | 159 | case "$node_choice" in | |
| 160 | - | 2) | |
| 160 | + | 2) | |
| 161 | 161 | log "Installing Latest Node.js..." | |
| 162 | 162 | nvm install node | |
| 163 | 163 | nvm alias default node | |
| 164 | 164 | nvm use node | |
| 165 | - | ||
| 165 | + | ||
| 166 | 166 | log "Disabling npm logs..." | |
| 167 | 167 | npm config set logs-max 0 | |
| 168 | 168 | ;; | |
| 169 | - | 3) | |
| 170 | - | log "Skipping Node.js installation." | |
| 169 | + | 3) | |
| 170 | + | log "Skipping Node.js installation." | |
| 171 | 171 | ;; | |
| 172 | - | *) | |
| 172 | + | *) | |
| 173 | 173 | log "Installing Latest LTS Node.js..." | |
| 174 | 174 | nvm install --lts | |
| 175 | 175 | nvm alias default 'lts/*' | |
| 176 | 176 | nvm use --lts | |
| 177 | - | ||
| 177 | + | ||
| 178 | 178 | log "Disabling npm logs..." | |
| 179 | 179 | npm config set logs-max 0 | |
| 180 | 180 | ;; | |
| @@ -204,7 +204,7 @@ install_python() { | |||
| 204 | 204 | err "Failed to download Python macOS package from $PKG_URL" | |
| 205 | 205 | return 1 | |
| 206 | 206 | } | |
| 207 | - | ||
| 207 | + | ||
| 208 | 208 | log "Running installer..." | |
| 209 | 209 | sudo installer -pkg /tmp/python.pkg -target / || { | |
| 210 | 210 | err "Python macOS installer failed." | |
| @@ -257,14 +257,14 @@ install_go() { | |||
| 257 | 257 | add_to_path_config "GO_BIN" 'export PATH="$PATH:/usr/local/go/bin"' | |
| 258 | 258 | return 0 | |
| 259 | 259 | fi | |
| 260 | - | ||
| 260 | + | ||
| 261 | 261 | log "Downloading $TAR_FILE..." | |
| 262 | 262 | curl -fsSL -o /tmp/go.tar.gz "https://go.dev/dl/$TAR_FILE" || { | |
| 263 | 263 | err "Failed to download $TAR_FILE." | |
| 264 | 264 | rm -f /tmp/go.tar.gz | |
| 265 | 265 | return 1 | |
| 266 | 266 | } | |
| 267 | - | ||
| 267 | + | ||
| 268 | 268 | log "Installing to /usr/local/go..." | |
| 269 | 269 | if ! sudo rm -rf /usr/local/go || ! sudo tar -C /usr/local -xzf /tmp/go.tar.gz; then | |
| 270 | 270 | err "Go installation failed. Run this installer from an interactive terminal so sudo can authenticate." | |
| @@ -278,8 +278,8 @@ install_go() { | |||
| 278 | 278 | ||
| 279 | 279 | install_sdkman() { | |
| 280 | 280 | if [ -d "$HOME/.sdkman" ]; then warn "SDKMAN already exists"; return; fi | |
| 281 | - | ||
| 282 | - | # SDKMAN explicitly blocks macOS's default Bash 3.2. | |
| 281 | + | ||
| 282 | + | # SDKMAN explicitly blocks macOS's default Bash 3.2. | |
| 283 | 283 | # If we are trapped in Bash < 4, force the installer to use Zsh. | |
| 284 | 284 | if [[ "$CURRENT_SHELL" == "bash" && "${BASH_VERSINFO[0]:-0}" -lt 4 ]]; then | |
| 285 | 285 | log "Outdated Bash detected. Installing SDKMAN via Zsh..." | |
| @@ -296,210 +296,13 @@ install_dotnet() { | |||
| 296 | 296 | add_to_path_config "DOTNET_TOOLS" 'export PATH="$PATH:$HOME/.dotnet/tools"' | |
| 297 | 297 | } | |
| 298 | 298 | ||
| 299 | - | # Prints the major Java version of the given java binary, or fails. | |
| 300 | - | # Handles both "21.0.4" and legacy "1.8.0_xxx" style version strings | |
| 301 | - | # (legacy ones report as 1, which correctly counts as too old). | |
| 302 | - | java_major() { | |
| 303 | - | local out | |
| 304 | - | out=$("$1" -version 2>&1) || return 1 | |
| 305 | - | printf '%s\n' "$out" | sed -nE 's/.*version "([0-9]+).*/\1/p' | head -1 | |
| 306 | - | } | |
| 307 | - | ||
| 308 | - | # The Android command line tools (sdkmanager, avdmanager) are Java programs | |
| 309 | - | # and need JDK 17 or newer. On macOS, /usr/bin/java is a stub that exists even | |
| 310 | - | # when no JDK is installed, so `command -v java` is not enough: we must run it. | |
| 311 | - | ensure_android_java() { | |
| 312 | - | local major home jbr | |
| 313 | - | ||
| 314 | - | # Pick up an SDKMAN managed JDK if SDKMAN is installed. | |
| 315 | - | if [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]]; then | |
| 316 | - | set +u; source "$HOME/.sdkman/bin/sdkman-init.sh"; set -u | |
| 317 | - | fi | |
| 318 | - | ||
| 319 | - | major=$(java_major java 2>/dev/null) | |
| 320 | - | if [[ -n "$major" ]] && (( major >= 17 )); then | |
| 321 | - | log "Using Java $major for the Android SDK tools." | |
| 322 | - | return 0 | |
| 323 | - | fi | |
| 324 | - | ||
| 325 | - | if [[ "$OS" == "macOS" ]]; then | |
| 326 | - | # A JDK registered with macOS (Temurin, Zulu, Oracle .pkg installers). | |
| 327 | - | home=$(/usr/libexec/java_home -v 17+ 2>/dev/null || true) | |
| 328 | - | if [[ -n "$home" && -x "$home/bin/java" ]]; then | |
| 329 | - | export JAVA_HOME="$home" | |
| 330 | - | export PATH="$JAVA_HOME/bin:$PATH" | |
| 331 | - | log "Using the JDK at $JAVA_HOME" | |
| 332 | - | return 0 | |
| 333 | - | fi | |
| 334 | - | ||
| 335 | - | # The JDK bundled inside Android Studio (not registered with macOS). | |
| 336 | - | jbr="/Applications/Android Studio.app/Contents/jbr/Contents/Home" | |
| 337 | - | if [[ -x "$jbr/bin/java" ]]; then | |
| 338 | - | add_to_path_config "ANDROID_STUDIO_JBR" 'export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" | |
| 339 | - | export PATH="$JAVA_HOME/bin:$PATH"' | |
| 340 | - | log "Using the JDK bundled with Android Studio." | |
| 341 | - | return 0 | |
| 342 | - | fi | |
| 343 | - | fi | |
| 344 | - | ||
| 345 | - | # Nothing usable: provision a JDK through SDKMAN. | |
| 346 | - | if [[ ! -s "$HOME/.sdkman/bin/sdkman-init.sh" ]]; then | |
| 347 | - | log "No Java 17+ found. Installing SDKMAN to provide a JDK..." | |
| 348 | - | install_sdkman | |
| 349 | - | fi | |
| 350 | - | ||
| 351 | - | if [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]]; then | |
| 352 | - | log "Installing the default Temurin JDK through SDKMAN..." | |
| 353 | - | set +u | |
| 354 | - | source "$HOME/.sdkman/bin/sdkman-init.sh" | |
| 355 | - | yes | sdk install java | |
| 356 | - | # Re-source so the freshly installed JDK lands on PATH and JAVA_HOME. | |
| 357 | - | source "$HOME/.sdkman/bin/sdkman-init.sh" | |
| 358 | - | set -u | |
| 359 | - | ||
| 360 | - | major=$(java_major java 2>/dev/null) | |
| 361 | - | if [[ -n "$major" ]] && (( major >= 17 )); then | |
| 362 | - | log "Using Java $major for the Android SDK tools." | |
| 363 | - | return 0 | |
| 364 | - | fi | |
| 365 | - | fi | |
| 366 | - | ||
| 367 | - | err "Java 17 or newer is required by the Android SDK tools, but none could be set up." | |
| 368 | - | err "Install a JDK (for example: sdk install java), open a new terminal, then rerun Option 8." | |
| 369 | - | return 1 | |
| 370 | - | } | |
| 371 | - | ||
| 372 | - | # Prints the download URL of the newest Android command line tools zip. | |
| 373 | - | # Tries the Android Studio download page first, then falls back to Google's | |
| 374 | - | # SDK repository manifest, which is a stable machine readable source. | |
| 375 | - | latest_cmdline_tools_url() { | |
| 376 | - | local tools_os=$1 file | |
| 377 | - | ||
| 378 | - | file=$(curl -fsSL --compressed https://developer.android.com/studio 2>/dev/null \ | |
| 379 | - | | grep -oE "commandlinetools-${tools_os}-[0-9]+_latest\.zip" \ | |
| 380 | - | | head -1) | |
| 381 | - | ||
| 382 | - | if [[ -z "$file" ]]; then | |
| 383 | - | file=$(curl -fsSL --compressed https://dl.google.com/android/repository/repository2-3.xml 2>/dev/null \ | |
| 384 | - | | grep -oE "commandlinetools-${tools_os}-[0-9]+_latest\.zip" \ | |
| 385 | - | | sort -t- -k3 -n \ | |
| 386 | - | | tail -1) | |
| 387 | - | fi | |
| 388 | - | ||
| 389 | - | [[ -n "$file" ]] && printf 'https://dl.google.com/android/repository/%s\n' "$file" | |
| 390 | - | } | |
| 391 | - | ||
| 392 | - | install_android() { | |
| 393 | - | log "Installing Android SDK command-line tools..." | |
| 394 | - | ||
| 395 | - | if ! require_cmd unzip; then | |
| 396 | - | err "unzip is required. Please install 'Build Tools' (Option 1) first." | |
| 397 | - | return 1 | |
| 398 | - | fi | |
| 399 | - | ||
| 400 | - | if [[ "$OS_LOWER" == "linux" && "$SYS_ARCH" != "amd64" ]]; then | |
| 401 | - | err "Google's Android command-line tools installer supports Linux x86_64 only." | |
| 402 | - | return 1 | |
| 403 | - | fi | |
| 404 | - | ||
| 405 | - | if [[ "$OS" == "macOS" ]]; then | |
| 406 | - | TOOLS_OS="mac" | |
| 407 | - | elif [[ "$OS_LOWER" == "linux" ]]; then | |
| 408 | - | TOOLS_OS="linux" | |
| 409 | - | else | |
| 410 | - | err "Android SDK installation is not supported for $OS." | |
| 411 | - | return 1 | |
| 412 | - | fi | |
| 413 | - | ||
| 414 | - | # sdkmanager is a Java program, so fail fast before downloading anything. | |
| 415 | - | ensure_android_java || return 1 | |
| 416 | - | ||
| 417 | - | ANDROID_HOME="$HOME/Android/Sdk" | |
| 418 | - | ANDROID_SDK_ROOT="$ANDROID_HOME" | |
| 419 | - | export ANDROID_HOME ANDROID_SDK_ROOT | |
| 420 | - | ||
| 421 | - | mkdir -p "$ANDROID_HOME/cmdline-tools" | |
| 422 | - | ||
| 423 | - | log "Finding latest Android command-line tools from Google..." | |
| 424 | - | TOOLS_URL=$(latest_cmdline_tools_url "$TOOLS_OS") | |
| 425 | - | ||
| 426 | - | if [[ -z "$TOOLS_URL" ]]; then | |
| 427 | - | err "Could not find the Android command-line tools download URL." | |
| 428 | - | return 1 | |
| 429 | - | fi | |
| 430 | - | ||
| 431 | - | log "Downloading $TOOLS_URL..." | |
| 432 | - | rm -rf /tmp/android-cmdline-tools /tmp/android-cmdline-tools.zip | |
| 433 | - | mkdir -p /tmp/android-cmdline-tools | |
| 434 | - | if ! curl -fsSL -o /tmp/android-cmdline-tools.zip "$TOOLS_URL" || \ | |
| 435 | - | ! unzip -q /tmp/android-cmdline-tools.zip -d /tmp/android-cmdline-tools; then | |
| 436 | - | err "Failed to download or extract the Android command-line tools." | |
| 437 | - | rm -rf /tmp/android-cmdline-tools /tmp/android-cmdline-tools.zip | |
| 438 | - | return 1 | |
| 439 | - | fi | |
| 440 | - | ||
| 441 | - | rm -rf "$ANDROID_HOME/cmdline-tools/latest" | |
| 442 | - | mkdir -p "$ANDROID_HOME/cmdline-tools/latest" | |
| 443 | - | mv /tmp/android-cmdline-tools/cmdline-tools/* "$ANDROID_HOME/cmdline-tools/latest/" | |
| 444 | - | rm -rf /tmp/android-cmdline-tools /tmp/android-cmdline-tools.zip | |
| 445 | - | ||
| 446 | - | local tools_bin="$ANDROID_HOME/cmdline-tools/latest/bin" | |
| 447 | - | ||
| 448 | - | if [[ -x "$tools_bin/android" ]]; then | |
| 449 | - | # Current cmdline-tools ship the Android CLI ('android'), and | |
| 450 | - | # 'android sdk' replaces the deprecated sdkmanager. It is left | |
| 451 | - | # interactive on purpose so any license prompt reaches you. | |
| 452 | - | log "Installing Android SDK packages with Android CLI..." | |
| 453 | - | if ! "$tools_bin/android" --sdk="$ANDROID_HOME" sdk install \ | |
| 454 | - | cmdline-tools/latest \ | |
| 455 | - | platform-tools \ | |
| 456 | - | emulator \ | |
| 457 | - | platforms/android-36 \ | |
| 458 | - | build-tools/36.0.0; then | |
| 459 | - | err "Android CLI failed to install the SDK packages. See the error above." | |
| 460 | - | return 1 | |
| 461 | - | fi | |
| 462 | - | elif [[ -x "$tools_bin/sdkmanager" ]]; then | |
| 463 | - | # Older cmdline-tools without the Android CLI: use sdkmanager. | |
| 464 | - | warn "Android CLI not found in cmdline-tools. Falling back to sdkmanager." | |
| 465 | - | SDKMANAGER="$tools_bin/sdkmanager" | |
| 466 | - | ||
| 467 | - | # stdout is silenced, stderr is kept so Java or network errors stay visible. | |
| 468 | - | log "Accepting Android SDK licenses..." | |
| 469 | - | if ! yes | "$SDKMANAGER" --sdk_root="$ANDROID_HOME" --licenses >/dev/null; then | |
| 470 | - | err "sdkmanager could not run. See the error above." | |
| 471 | - | return 1 | |
| 472 | - | fi | |
| 473 | - | ||
| 474 | - | log "Installing Android SDK packages..." | |
| 475 | - | if ! "$SDKMANAGER" --sdk_root="$ANDROID_HOME" \ | |
| 476 | - | "cmdline-tools;latest" \ | |
| 477 | - | "platform-tools" \ | |
| 478 | - | "emulator" \ | |
| 479 | - | "platforms;android-36" \ | |
| 480 | - | "build-tools;36.0.0"; then | |
| 481 | - | err "Failed to install Android SDK packages." | |
| 482 | - | return 1 | |
| 483 | - | fi | |
| 484 | - | else | |
| 485 | - | err "Neither Android CLI nor sdkmanager was found in $tools_bin." | |
| 486 | - | return 1 | |
| 487 | - | fi | |
| 488 | - | ||
| 489 | - | add_to_path_config "ANDROID_SDK" 'export ANDROID_HOME="$HOME/Android/Sdk" | |
| 490 | - | export ANDROID_SDK_ROOT="$ANDROID_HOME" | |
| 491 | - | export PATH="$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator"' | |
| 492 | - | ||
| 493 | - | log "Android SDK installation sequence finished!" | |
| 494 | - | } | |
| 495 | - | ||
| 496 | 299 | # ======================================================= | |
| 497 | 300 | # CLOUD & INFRASTRUCTURE | |
| 498 | 301 | # ======================================================= | |
| 499 | 302 | ||
| 500 | 303 | install_docker() { | |
| 501 | 304 | log "Checking Docker status..." | |
| 502 | - | ||
| 305 | + | ||
| 503 | 306 | # 1. Install if missing | |
| 504 | 307 | if ! require_cmd docker; then | |
| 505 | 308 | log "Installing Docker from official source..." | |
| @@ -511,7 +314,7 @@ install_docker() { | |||
| 511 | 314 | sudo cp -a /Volumes/Docker/Docker.app /Applications/ | |
| 512 | 315 | hdiutil detach /Volumes/Docker | |
| 513 | 316 | rm /tmp/Docker.dmg | |
| 514 | - | ||
| 317 | + | ||
| 515 | 318 | log "Starting Docker Desktop..." | |
| 516 | 319 | open /Applications/Docker.app | |
| 517 | 320 | log "Please complete the setup in the Docker Desktop UI." | |
| @@ -525,11 +328,11 @@ install_docker() { | |||
| 525 | 328 | # 2. Aggressively enforce Linux permissions | |
| 526 | 329 | if [[ "$OS" != "macOS" ]]; then | |
| 527 | 330 | log "Applying strict Linux post-install actions..." | |
| 528 | - | ||
| 331 | + | ||
| 529 | 332 | # Ensure docker group exists and user is added | |
| 530 | 333 | sudo groupadd -f docker | |
| 531 | 334 | sudo usermod -aG docker "$USER" | |
| 532 | - | ||
| 335 | + | ||
| 533 | 336 | # Ensure services are enabled and running | |
| 534 | 337 | if command -v systemctl >/dev/null 2>&1; then | |
| 535 | 338 | sudo systemctl enable --now docker.service | |
| @@ -606,7 +409,7 @@ install_aws() { | |||
| 606 | 409 | sudo installer -pkg /tmp/AWSCLIV2.pkg -target / | |
| 607 | 410 | rm /tmp/AWSCLIV2.pkg | |
| 608 | 411 | else | |
| 609 | - | if ! require_cmd unzip; then | |
| 412 | + | if ! require_cmd unzip; then | |
| 610 | 413 | err "unzip is required. Please install 'Build Tools' (Option 1) first." | |
| 611 | 414 | return 1 | |
| 612 | 415 | fi | |
| @@ -623,7 +426,7 @@ install_gcloud() { | |||
| 623 | 426 | log "Installing Google Cloud CLI to $gcloud_dir..." | |
| 624 | 427 | curl -fsSL https://sdk.cloud.google.com | sudo bash -s -- --disable-prompts --install-dir=/opt | |
| 625 | 428 | sudo chown -R "$(id -u):$(id -g)" "$gcloud_dir" | |
| 626 | - | ||
| 429 | + | ||
| 627 | 430 | if [[ "$CURRENT_SHELL" == "zsh" ]]; then | |
| 628 | 431 | add_to_path_config "GCLOUD" '[ -f "/opt/google-cloud-sdk/path.zsh.inc" ] && source "/opt/google-cloud-sdk/path.zsh.inc"' | |
| 629 | 432 | else | |
| @@ -634,12 +437,12 @@ install_gcloud() { | |||
| 634 | 437 | install_firebase() { | |
| 635 | 438 | if require_cmd firebase; then warn "Firebase CLI exists"; return; fi | |
| 636 | 439 | log "Installing Firebase CLI via NPM to ensure ARM64 compatibility..." | |
| 637 | - | ||
| 440 | + | ||
| 638 | 441 | if ! require_cmd npm; then | |
| 639 | 442 | err "NPM not found. Please install NVM (Option 3) first." | |
| 640 | 443 | return 1 | |
| 641 | 444 | fi | |
| 642 | - | ||
| 445 | + | ||
| 643 | 446 | npm install -g firebase-tools | |
| 644 | 447 | } | |
| 645 | 448 | ||
| @@ -652,7 +455,7 @@ install_gh() { | |||
| 652 | 455 | log "Fetching latest GitHub CLI version..." | |
| 653 | 456 | LATEST_GH=$(curl -s https://api.github.com/repos/cli/cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') | |
| 654 | 457 | TAR_NAME="gh_${LATEST_GH}_${OS_LOWER}_${SYS_ARCH}" | |
| 655 | - | ||
| 458 | + | ||
| 656 | 459 | curl -fsSL -o /tmp/gh.tar.gz "https://github.com/cli/cli/releases/download/v${LATEST_GH}/${TAR_NAME}.tar.gz" | |
| 657 | 460 | tar -xzf /tmp/gh.tar.gz -C /tmp | |
| 658 | 461 | sudo mv "/tmp/${TAR_NAME}/bin/gh" /usr/local/bin/ | |
| @@ -662,12 +465,12 @@ install_gh() { | |||
| 662 | 465 | install_infisical() { | |
| 663 | 466 | if require_cmd infisical; then warn "Infisical CLI exists"; return; fi | |
| 664 | 467 | log "Installing Infisical CLI via NPM..." | |
| 665 | - | ||
| 666 | - | if ! require_cmd npm; then | |
| 468 | + | ||
| 469 | + | if ! require_cmd npm; then | |
| 667 | 470 | err "NPM not found. Please install NVM (Option 3) first." | |
| 668 | 471 | return 1 | |
| 669 | 472 | fi | |
| 670 | - | ||
| 473 | + | ||
| 671 | 474 | npm install -g @infisical/cli | |
| 672 | 475 | } | |
| 673 | 476 | ||
| @@ -749,21 +552,6 @@ update_all() { | |||
| 749 | 552 | curl -fsSL https://dot.net/v1/dotnet-install.sh | $CURRENT_SHELL | |
| 750 | 553 | fi | |
| 751 | 554 | ||
| 752 | - | local android_sdk="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-$HOME/Android/Sdk}}" | |
| 753 | - | local android_bin="$android_sdk/cmdline-tools/latest/bin" | |
| 754 | - | if [[ -x "$android_bin/android" ]]; then | |
| 755 | - | log "Updating Android SDK packages with Android CLI..." | |
| 756 | - | "$android_bin/android" --sdk="$android_sdk" sdk update || \ | |
| 757 | - | warn "Android CLI could not update the SDK. See the error above." | |
| 758 | - | elif [[ -x "$android_bin/sdkmanager" ]]; then | |
| 759 | - | if ensure_android_java; then | |
| 760 | - | yes | "$android_bin/sdkmanager" --licenses >/dev/null || true | |
| 761 | - | "$android_bin/sdkmanager" --update | |
| 762 | - | else | |
| 763 | - | warn "Skipping the Android SDK update because no usable Java was found." | |
| 764 | - | fi | |
| 765 | - | fi | |
| 766 | - | ||
| 767 | 555 | if require_cmd docker; then | |
| 768 | 556 | if [[ "$OS" == "macOS" ]]; then | |
| 769 | 557 | docker desktop update || warn "Update Docker Desktop from its application menu." | |
| @@ -842,8 +630,6 @@ show_menu() { | |||
| 842 | 630 | printf " 5) Go\n" | |
| 843 | 631 | printf " 6) SDKMAN (Java/Kotlin/Gradle)\n" | |
| 844 | 632 | printf " 7) .NET\n" | |
| 845 | - | printf "${YELLOW}--- Mobile Development ---${NC}\n" | |
| 846 | - | printf " 8) Android SDK (CLI + Platform Tools)\n" | |
| 847 | 633 | printf "${YELLOW}--- Containers & Infrastructure ---${NC}\n" | |
| 848 | 634 | printf " 9) Docker\n" | |
| 849 | 635 | printf " 13) Portainer (Docker UI)\n" | |
| @@ -869,7 +655,7 @@ show_menu() { | |||
| 869 | 655 | ||
| 870 | 656 | while true; do | |
| 871 | 657 | show_menu | |
| 872 | - | ||
| 658 | + | ||
| 873 | 659 | # Bulletproof prompt for both Bash and Zsh | |
| 874 | 660 | printf "Select options (space-separated): " | |
| 875 | 661 | if ! read input; then | |
| @@ -877,7 +663,7 @@ while true; do | |||
| 877 | 663 | warn "Input closed. Exiting installer." | |
| 878 | 664 | exit 0 | |
| 879 | 665 | fi | |
| 880 | - | ||
| 666 | + | ||
| 881 | 667 | # Thanks to 'setopt shwordsplit' in Zsh, this behaves perfectly across both shells | |
| 882 | 668 | for choice in $input; do | |
| 883 | 669 | case "$choice" in | |
| @@ -888,7 +674,6 @@ while true; do | |||
| 888 | 674 | 5) install_go ;; | |
| 889 | 675 | 6) install_sdkman ;; | |
| 890 | 676 | 7) install_dotnet ;; | |
| 891 | - | 8) install_android ;; | |
| 892 | 677 | 9) install_docker ;; | |
| 893 | 678 | 10) install_aws ;; | |
| 894 | 679 | 11) install_gcloud ;; | |
| @@ -902,20 +687,20 @@ while true; do | |||
| 902 | 687 | 19) update_all ;; | |
| 903 | 688 | 20) install_augment ;; | |
| 904 | 689 | 21) install_coderabbit ;; | |
| 905 | - | 99) | |
| 690 | + | 99) | |
| 906 | 691 | log "Installation complete! Refreshing terminal environment..." | |
| 907 | - | ||
| 692 | + | ||
| 908 | 693 | # If on Linux, forcefully inherit the new docker group without needing a logout | |
| 909 | 694 | if [[ "$OS" != "macOS" ]] && command -v sg >/dev/null 2>&1; then | |
| 910 | 695 | exec sg docker -c "exec ${SHELL:-zsh}" | |
| 911 | 696 | else | |
| 912 | - | exec "${SHELL:-zsh}" | |
| 697 | + | exec "${SHELL:-zsh}" | |
| 913 | 698 | fi | |
| 914 | 699 | ;; | |
| 915 | 700 | *) warn "Option $choice not valid." ;; | |
| 916 | 701 | esac | |
| 917 | 702 | done | |
| 918 | - | ||
| 919 | - | printf "Press Enter to continue..." | |
| 703 | + | ||
| 704 | + | printf "Press Enter to continue..." | |
| 920 | 705 | read dummy || exit 0 | |
| 921 | 706 | done | |
weehong gist felülvizsgálása 6 days ago. Revízióhoz ugrás
1 file changed, 4 insertions, 2 deletions
menu.sh
| @@ -677,7 +677,9 @@ install_infisical() { | |||
| 677 | 677 | ||
| 678 | 678 | install_claude() { log "Installing Claude Code..."; curl -fsSL https://claude.ai/install.sh | $CURRENT_SHELL; } | |
| 679 | 679 | ||
| 680 | - | install_opencode() { log "Installing OpenCode..."; curl -fsSL https://opencode.ai/install | $CURRENT_SHELL; } | |
| 680 | + | # opencode.ai/install now serves the v1 branch; OpenCode 2 has its own installer. | |
| 681 | + | # It installs to ~/.opencode/bin and is documented to run under bash. | |
| 682 | + | install_opencode() { log "Installing OpenCode 2..."; curl -fsSL https://opencode.ai/v2/install | bash; } | |
| 681 | 683 | ||
| 682 | 684 | install_codex() { | |
| 683 | 685 | log "Installing @openai/codex..." | |
| @@ -814,7 +816,7 @@ update_all() { | |||
| 814 | 816 | require_cmd infisical && npm install -g @infisical/cli@latest | |
| 815 | 817 | require_cmd claude && { curl -fsSL https://claude.ai/install.sh | $CURRENT_SHELL; } | |
| 816 | 818 | require_cmd codex && npm install -g @openai/codex@latest | |
| 817 | - | require_cmd opencode && { curl -fsSL https://opencode.ai/install | $CURRENT_SHELL; } | |
| 819 | + | require_cmd opencode && { curl -fsSL https://opencode.ai/v2/install | bash; } | |
| 818 | 820 | require_cmd auggie && npm install -g @augmentcode/auggie@latest | |
| 819 | 821 | if require_cmd coderabbit || require_cmd cr; then | |
| 820 | 822 | curl -fsSL https://cli.coderabbit.ai/install.sh | sh | |
weehong gist felülvizsgálása 6 days ago. Revízióhoz ugrás
1 file changed, 48 insertions, 24 deletions
menu.sh
| @@ -443,27 +443,46 @@ install_android() { | |||
| 443 | 443 | mv /tmp/android-cmdline-tools/cmdline-tools/* "$ANDROID_HOME/cmdline-tools/latest/" | |
| 444 | 444 | rm -rf /tmp/android-cmdline-tools /tmp/android-cmdline-tools.zip | |
| 445 | 445 | ||
| 446 | - | SDKMANAGER="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" | |
| 447 | - | if [[ ! -x "$SDKMANAGER" ]]; then | |
| 448 | - | err "sdkmanager was not installed correctly." | |
| 449 | - | return 1 | |
| 450 | - | fi | |
| 451 | - | ||
| 452 | - | # stdout is silenced, stderr is kept so Java or network errors stay visible. | |
| 453 | - | log "Accepting Android SDK licenses..." | |
| 454 | - | if ! yes | "$SDKMANAGER" --sdk_root="$ANDROID_HOME" --licenses >/dev/null; then | |
| 455 | - | err "sdkmanager could not run. See the error above." | |
| 456 | - | return 1 | |
| 457 | - | fi | |
| 446 | + | local tools_bin="$ANDROID_HOME/cmdline-tools/latest/bin" | |
| 447 | + | ||
| 448 | + | if [[ -x "$tools_bin/android" ]]; then | |
| 449 | + | # Current cmdline-tools ship the Android CLI ('android'), and | |
| 450 | + | # 'android sdk' replaces the deprecated sdkmanager. It is left | |
| 451 | + | # interactive on purpose so any license prompt reaches you. | |
| 452 | + | log "Installing Android SDK packages with Android CLI..." | |
| 453 | + | if ! "$tools_bin/android" --sdk="$ANDROID_HOME" sdk install \ | |
| 454 | + | cmdline-tools/latest \ | |
| 455 | + | platform-tools \ | |
| 456 | + | emulator \ | |
| 457 | + | platforms/android-36 \ | |
| 458 | + | build-tools/36.0.0; then | |
| 459 | + | err "Android CLI failed to install the SDK packages. See the error above." | |
| 460 | + | return 1 | |
| 461 | + | fi | |
| 462 | + | elif [[ -x "$tools_bin/sdkmanager" ]]; then | |
| 463 | + | # Older cmdline-tools without the Android CLI: use sdkmanager. | |
| 464 | + | warn "Android CLI not found in cmdline-tools. Falling back to sdkmanager." | |
| 465 | + | SDKMANAGER="$tools_bin/sdkmanager" | |
| 466 | + | ||
| 467 | + | # stdout is silenced, stderr is kept so Java or network errors stay visible. | |
| 468 | + | log "Accepting Android SDK licenses..." | |
| 469 | + | if ! yes | "$SDKMANAGER" --sdk_root="$ANDROID_HOME" --licenses >/dev/null; then | |
| 470 | + | err "sdkmanager could not run. See the error above." | |
| 471 | + | return 1 | |
| 472 | + | fi | |
| 458 | 473 | ||
| 459 | - | log "Installing Android SDK packages..." | |
| 460 | - | if ! "$SDKMANAGER" --sdk_root="$ANDROID_HOME" \ | |
| 461 | - | "cmdline-tools;latest" \ | |
| 462 | - | "platform-tools" \ | |
| 463 | - | "emulator" \ | |
| 464 | - | "platforms;android-36" \ | |
| 465 | - | "build-tools;36.0.0"; then | |
| 466 | - | err "Failed to install Android SDK packages." | |
| 474 | + | log "Installing Android SDK packages..." | |
| 475 | + | if ! "$SDKMANAGER" --sdk_root="$ANDROID_HOME" \ | |
| 476 | + | "cmdline-tools;latest" \ | |
| 477 | + | "platform-tools" \ | |
| 478 | + | "emulator" \ | |
| 479 | + | "platforms;android-36" \ | |
| 480 | + | "build-tools;36.0.0"; then | |
| 481 | + | err "Failed to install Android SDK packages." | |
| 482 | + | return 1 | |
| 483 | + | fi | |
| 484 | + | else | |
| 485 | + | err "Neither Android CLI nor sdkmanager was found in $tools_bin." | |
| 467 | 486 | return 1 | |
| 468 | 487 | fi | |
| 469 | 488 | ||
| @@ -728,11 +747,16 @@ update_all() { | |||
| 728 | 747 | curl -fsSL https://dot.net/v1/dotnet-install.sh | $CURRENT_SHELL | |
| 729 | 748 | fi | |
| 730 | 749 | ||
| 731 | - | local sdkmanager="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-$HOME/Android/Sdk}}/cmdline-tools/latest/bin/sdkmanager" | |
| 732 | - | if [[ -x "$sdkmanager" ]]; then | |
| 750 | + | local android_sdk="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-$HOME/Android/Sdk}}" | |
| 751 | + | local android_bin="$android_sdk/cmdline-tools/latest/bin" | |
| 752 | + | if [[ -x "$android_bin/android" ]]; then | |
| 753 | + | log "Updating Android SDK packages with Android CLI..." | |
| 754 | + | "$android_bin/android" --sdk="$android_sdk" sdk update || \ | |
| 755 | + | warn "Android CLI could not update the SDK. See the error above." | |
| 756 | + | elif [[ -x "$android_bin/sdkmanager" ]]; then | |
| 733 | 757 | if ensure_android_java; then | |
| 734 | - | yes | "$sdkmanager" --licenses >/dev/null || true | |
| 735 | - | "$sdkmanager" --update | |
| 758 | + | yes | "$android_bin/sdkmanager" --licenses >/dev/null || true | |
| 759 | + | "$android_bin/sdkmanager" --update | |
| 736 | 760 | else | |
| 737 | 761 | warn "Skipping the Android SDK update because no usable Java was found." | |
| 738 | 762 | fi | |
weehong gist felülvizsgálása 6 days ago. Revízióhoz ugrás
1 file changed, 127 insertions, 18 deletions
menu.sh
| @@ -296,6 +296,99 @@ install_dotnet() { | |||
| 296 | 296 | add_to_path_config "DOTNET_TOOLS" 'export PATH="$PATH:$HOME/.dotnet/tools"' | |
| 297 | 297 | } | |
| 298 | 298 | ||
| 299 | + | # Prints the major Java version of the given java binary, or fails. | |
| 300 | + | # Handles both "21.0.4" and legacy "1.8.0_xxx" style version strings | |
| 301 | + | # (legacy ones report as 1, which correctly counts as too old). | |
| 302 | + | java_major() { | |
| 303 | + | local out | |
| 304 | + | out=$("$1" -version 2>&1) || return 1 | |
| 305 | + | printf '%s\n' "$out" | sed -nE 's/.*version "([0-9]+).*/\1/p' | head -1 | |
| 306 | + | } | |
| 307 | + | ||
| 308 | + | # The Android command line tools (sdkmanager, avdmanager) are Java programs | |
| 309 | + | # and need JDK 17 or newer. On macOS, /usr/bin/java is a stub that exists even | |
| 310 | + | # when no JDK is installed, so `command -v java` is not enough: we must run it. | |
| 311 | + | ensure_android_java() { | |
| 312 | + | local major home jbr | |
| 313 | + | ||
| 314 | + | # Pick up an SDKMAN managed JDK if SDKMAN is installed. | |
| 315 | + | if [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]]; then | |
| 316 | + | set +u; source "$HOME/.sdkman/bin/sdkman-init.sh"; set -u | |
| 317 | + | fi | |
| 318 | + | ||
| 319 | + | major=$(java_major java 2>/dev/null) | |
| 320 | + | if [[ -n "$major" ]] && (( major >= 17 )); then | |
| 321 | + | log "Using Java $major for the Android SDK tools." | |
| 322 | + | return 0 | |
| 323 | + | fi | |
| 324 | + | ||
| 325 | + | if [[ "$OS" == "macOS" ]]; then | |
| 326 | + | # A JDK registered with macOS (Temurin, Zulu, Oracle .pkg installers). | |
| 327 | + | home=$(/usr/libexec/java_home -v 17+ 2>/dev/null || true) | |
| 328 | + | if [[ -n "$home" && -x "$home/bin/java" ]]; then | |
| 329 | + | export JAVA_HOME="$home" | |
| 330 | + | export PATH="$JAVA_HOME/bin:$PATH" | |
| 331 | + | log "Using the JDK at $JAVA_HOME" | |
| 332 | + | return 0 | |
| 333 | + | fi | |
| 334 | + | ||
| 335 | + | # The JDK bundled inside Android Studio (not registered with macOS). | |
| 336 | + | jbr="/Applications/Android Studio.app/Contents/jbr/Contents/Home" | |
| 337 | + | if [[ -x "$jbr/bin/java" ]]; then | |
| 338 | + | add_to_path_config "ANDROID_STUDIO_JBR" 'export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" | |
| 339 | + | export PATH="$JAVA_HOME/bin:$PATH"' | |
| 340 | + | log "Using the JDK bundled with Android Studio." | |
| 341 | + | return 0 | |
| 342 | + | fi | |
| 343 | + | fi | |
| 344 | + | ||
| 345 | + | # Nothing usable: provision a JDK through SDKMAN. | |
| 346 | + | if [[ ! -s "$HOME/.sdkman/bin/sdkman-init.sh" ]]; then | |
| 347 | + | log "No Java 17+ found. Installing SDKMAN to provide a JDK..." | |
| 348 | + | install_sdkman | |
| 349 | + | fi | |
| 350 | + | ||
| 351 | + | if [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]]; then | |
| 352 | + | log "Installing the default Temurin JDK through SDKMAN..." | |
| 353 | + | set +u | |
| 354 | + | source "$HOME/.sdkman/bin/sdkman-init.sh" | |
| 355 | + | yes | sdk install java | |
| 356 | + | # Re-source so the freshly installed JDK lands on PATH and JAVA_HOME. | |
| 357 | + | source "$HOME/.sdkman/bin/sdkman-init.sh" | |
| 358 | + | set -u | |
| 359 | + | ||
| 360 | + | major=$(java_major java 2>/dev/null) | |
| 361 | + | if [[ -n "$major" ]] && (( major >= 17 )); then | |
| 362 | + | log "Using Java $major for the Android SDK tools." | |
| 363 | + | return 0 | |
| 364 | + | fi | |
| 365 | + | fi | |
| 366 | + | ||
| 367 | + | err "Java 17 or newer is required by the Android SDK tools, but none could be set up." | |
| 368 | + | err "Install a JDK (for example: sdk install java), open a new terminal, then rerun Option 8." | |
| 369 | + | return 1 | |
| 370 | + | } | |
| 371 | + | ||
| 372 | + | # Prints the download URL of the newest Android command line tools zip. | |
| 373 | + | # Tries the Android Studio download page first, then falls back to Google's | |
| 374 | + | # SDK repository manifest, which is a stable machine readable source. | |
| 375 | + | latest_cmdline_tools_url() { | |
| 376 | + | local tools_os=$1 file | |
| 377 | + | ||
| 378 | + | file=$(curl -fsSL --compressed https://developer.android.com/studio 2>/dev/null \ | |
| 379 | + | | grep -oE "commandlinetools-${tools_os}-[0-9]+_latest\.zip" \ | |
| 380 | + | | head -1) | |
| 381 | + | ||
| 382 | + | if [[ -z "$file" ]]; then | |
| 383 | + | file=$(curl -fsSL --compressed https://dl.google.com/android/repository/repository2-3.xml 2>/dev/null \ | |
| 384 | + | | grep -oE "commandlinetools-${tools_os}-[0-9]+_latest\.zip" \ | |
| 385 | + | | sort -t- -k3 -n \ | |
| 386 | + | | tail -1) | |
| 387 | + | fi | |
| 388 | + | ||
| 389 | + | [[ -n "$file" ]] && printf 'https://dl.google.com/android/repository/%s\n' "$file" | |
| 390 | + | } | |
| 391 | + | ||
| 299 | 392 | install_android() { | |
| 300 | 393 | log "Installing Android SDK command-line tools..." | |
| 301 | 394 | ||
| @@ -309,12 +402,6 @@ install_android() { | |||
| 309 | 402 | return 1 | |
| 310 | 403 | fi | |
| 311 | 404 | ||
| 312 | - | ANDROID_HOME="$HOME/Android/Sdk" | |
| 313 | - | ANDROID_SDK_ROOT="$ANDROID_HOME" | |
| 314 | - | export ANDROID_HOME ANDROID_SDK_ROOT | |
| 315 | - | ||
| 316 | - | mkdir -p "$ANDROID_HOME/cmdline-tools" | |
| 317 | - | ||
| 318 | 405 | if [[ "$OS" == "macOS" ]]; then | |
| 319 | 406 | TOOLS_OS="mac" | |
| 320 | 407 | elif [[ "$OS_LOWER" == "linux" ]]; then | |
| @@ -324,21 +411,32 @@ install_android() { | |||
| 324 | 411 | return 1 | |
| 325 | 412 | fi | |
| 326 | 413 | ||
| 414 | + | # sdkmanager is a Java program, so fail fast before downloading anything. | |
| 415 | + | ensure_android_java || return 1 | |
| 416 | + | ||
| 417 | + | ANDROID_HOME="$HOME/Android/Sdk" | |
| 418 | + | ANDROID_SDK_ROOT="$ANDROID_HOME" | |
| 419 | + | export ANDROID_HOME ANDROID_SDK_ROOT | |
| 420 | + | ||
| 421 | + | mkdir -p "$ANDROID_HOME/cmdline-tools" | |
| 422 | + | ||
| 327 | 423 | log "Finding latest Android command-line tools from Google..." | |
| 328 | - | TOOLS_URL=$(curl -fsSL https://developer.android.com/studio \ | |
| 329 | - | | grep -o "https://dl.google.com/android/repository/commandlinetools-${TOOLS_OS}-[0-9]*_latest.zip" \ | |
| 330 | - | | head -1) | |
| 424 | + | TOOLS_URL=$(latest_cmdline_tools_url "$TOOLS_OS") | |
| 331 | 425 | ||
| 332 | 426 | if [[ -z "$TOOLS_URL" ]]; then | |
| 333 | 427 | err "Could not find the Android command-line tools download URL." | |
| 334 | 428 | return 1 | |
| 335 | 429 | fi | |
| 336 | 430 | ||
| 337 | - | log "Downloading Android command-line tools..." | |
| 431 | + | log "Downloading $TOOLS_URL..." | |
| 338 | 432 | rm -rf /tmp/android-cmdline-tools /tmp/android-cmdline-tools.zip | |
| 339 | 433 | mkdir -p /tmp/android-cmdline-tools | |
| 340 | - | curl -fsSL -o /tmp/android-cmdline-tools.zip "$TOOLS_URL" | |
| 341 | - | unzip -q /tmp/android-cmdline-tools.zip -d /tmp/android-cmdline-tools | |
| 434 | + | if ! curl -fsSL -o /tmp/android-cmdline-tools.zip "$TOOLS_URL" || \ | |
| 435 | + | ! unzip -q /tmp/android-cmdline-tools.zip -d /tmp/android-cmdline-tools; then | |
| 436 | + | err "Failed to download or extract the Android command-line tools." | |
| 437 | + | rm -rf /tmp/android-cmdline-tools /tmp/android-cmdline-tools.zip | |
| 438 | + | return 1 | |
| 439 | + | fi | |
| 342 | 440 | ||
| 343 | 441 | rm -rf "$ANDROID_HOME/cmdline-tools/latest" | |
| 344 | 442 | mkdir -p "$ANDROID_HOME/cmdline-tools/latest" | |
| @@ -351,16 +449,23 @@ install_android() { | |||
| 351 | 449 | return 1 | |
| 352 | 450 | fi | |
| 353 | 451 | ||
| 452 | + | # stdout is silenced, stderr is kept so Java or network errors stay visible. | |
| 354 | 453 | log "Accepting Android SDK licenses..." | |
| 355 | - | yes | "$SDKMANAGER" --sdk_root="$ANDROID_HOME" --licenses >/dev/null || true | |
| 454 | + | if ! yes | "$SDKMANAGER" --sdk_root="$ANDROID_HOME" --licenses >/dev/null; then | |
| 455 | + | err "sdkmanager could not run. See the error above." | |
| 456 | + | return 1 | |
| 457 | + | fi | |
| 356 | 458 | ||
| 357 | 459 | log "Installing Android SDK packages..." | |
| 358 | - | "$SDKMANAGER" --sdk_root="$ANDROID_HOME" \ | |
| 460 | + | if ! "$SDKMANAGER" --sdk_root="$ANDROID_HOME" \ | |
| 359 | 461 | "cmdline-tools;latest" \ | |
| 360 | 462 | "platform-tools" \ | |
| 361 | 463 | "emulator" \ | |
| 362 | 464 | "platforms;android-36" \ | |
| 363 | - | "build-tools;36.0.0" | |
| 465 | + | "build-tools;36.0.0"; then | |
| 466 | + | err "Failed to install Android SDK packages." | |
| 467 | + | return 1 | |
| 468 | + | fi | |
| 364 | 469 | ||
| 365 | 470 | add_to_path_config "ANDROID_SDK" 'export ANDROID_HOME="$HOME/Android/Sdk" | |
| 366 | 471 | export ANDROID_SDK_ROOT="$ANDROID_HOME" | |
| @@ -625,8 +730,12 @@ update_all() { | |||
| 625 | 730 | ||
| 626 | 731 | local sdkmanager="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-$HOME/Android/Sdk}}/cmdline-tools/latest/bin/sdkmanager" | |
| 627 | 732 | if [[ -x "$sdkmanager" ]]; then | |
| 628 | - | yes | "$sdkmanager" --licenses >/dev/null || true | |
| 629 | - | "$sdkmanager" --update | |
| 733 | + | if ensure_android_java; then | |
| 734 | + | yes | "$sdkmanager" --licenses >/dev/null || true | |
| 735 | + | "$sdkmanager" --update | |
| 736 | + | else | |
| 737 | + | warn "Skipping the Android SDK update because no usable Java was found." | |
| 738 | + | fi | |
| 630 | 739 | fi | |
| 631 | 740 | ||
| 632 | 741 | if require_cmd docker; then | |
| @@ -783,4 +892,4 @@ while true; do | |||
| 783 | 892 | ||
| 784 | 893 | printf "Press Enter to continue..." | |
| 785 | 894 | read dummy || exit 0 | |
| 786 | - | done | |
| 895 | + | done | |
weehong gist felülvizsgálása 1 week ago. Revízióhoz ugrás
Nincsenek változtatások
weehong gist felülvizsgálása 2 months ago. Revízióhoz ugrás
1 file changed, 1 insertion, 1 deletion
README.md
| @@ -17,7 +17,7 @@ This script follows a **"Strict Official Source"** philosophy. It fetches binari | |||
| 17 | 17 | You can launch the interactive installer directly from your terminal with a single command: | |
| 18 | 18 | ||
| 19 | 19 | ```bash | |
| 20 | - | zsh -c "$(curl -fsSL https://tinyurl.com/4rskc9e7)" | |
| 20 | + | bash -c "$(curl -fsSL https://tinyurl.com/4rskc9e7)" | |
| 21 | 21 | ``` | |
| 22 | 22 | ||
| 23 | 23 | Once the menu loads, simply **follow the interactive prompts**. You can select multiple tools at once by entering space-separated numbers (e.g., `1 3 8 12`). | |
Vernon Wee Hong KOH gist felülvizsgálása 2 months ago. Revízióhoz ugrás
2 files changed, 34 insertions, 16 deletions
README.md
| @@ -9,7 +9,7 @@ This script follows a **"Strict Official Source"** philosophy. It fetches binari | |||
| 9 | 9 | * **Zero-Brew Dependency:** By default, it bypasses Homebrew entirely, using official APIs, release pages, and signed OS repositories (Homebrew is available as an optional install). | |
| 10 | 10 | * **Idempotent:** Safe to run multiple times. It intelligently checks if a tool is already installed before attempting to download it. | |
| 11 | 11 | * **Dynamic Versioning:** Uses official APIs (like GitHub Releases or `go.dev/VERSION`) when maintainers publish versioned binaries. OS-packaged tools track the supported distribution version and security updates. | |
| 12 | - | * **Auto-Path Management:** Intelligently injects paths into a dedicated `~/.pathrc` (or your `.bashrc`/`.zshrc`) without mangling your config files. | |
| 12 | + | * **Auto-Path Management:** Consistently writes installed-tool paths to `~/.zshrc`, regardless of which shell launches the installer. | |
| 13 | 13 | * **Architecture Aware:** Automatically detects if you are running on Intel (`x86_64`) or Apple Silicon/ARM (`aarch64`/`arm64`) and downloads the correct binaries. | |
| 14 | 14 | ||
| 15 | 15 | ## 🚀 Usage | |
| @@ -17,7 +17,7 @@ This script follows a **"Strict Official Source"** philosophy. It fetches binari | |||
| 17 | 17 | You can launch the interactive installer directly from your terminal with a single command: | |
| 18 | 18 | ||
| 19 | 19 | ```bash | |
| 20 | - | bash -c "$(curl -fsSL https://tinyurl.com/4rskc9e7)" | |
| 20 | + | zsh -c "$(curl -fsSL https://tinyurl.com/4rskc9e7)" | |
| 21 | 21 | ``` | |
| 22 | 22 | ||
| 23 | 23 | Once the menu loads, simply **follow the interactive prompts**. You can select multiple tools at once by entering space-separated numbers (e.g., `1 3 8 12`). | |
| @@ -64,7 +64,7 @@ Choose **19) Update All Installed Software** to update every detected tool in th | |||
| 64 | 64 | ||
| 65 | 65 | ## ⚠️ Important Notes & Troubleshooting | |
| 66 | 66 | ||
| 67 | - | * **Restart Your Shell:** After running the script for the first time, you should restart your terminal or run `source ~/.bashrc` (or `~/.zshrc`) to ensure all new PATH variables (like NVM, Go, or .NET) take effect. | |
| 67 | + | * **Restart Your Shell:** After running the script for the first time, restart your terminal or run `source ~/.zshrc` to ensure all new PATH variables (like NVM, Go, or .NET) take effect. | |
| 68 | 68 | * **Docker Permissions (Linux):** The script automatically adds your user to the `docker` group. You will need to log out and log back in for this to take effect. | |
| 69 | 69 | * **AWS CLI on Linux:** Ensure you install **Build Tools (Option 1)** first if you are on a fresh Linux install, as the AWS installer requires `unzip` to extract the payload. | |
| 70 | 70 | * **Python Version on Linux:** Python follows the version supported by your distribution rather than the newest python.org patch release. This keeps installation precompiled, vendor-supported, and eligible for normal OS security updates. | |
menu.sh
| @@ -24,21 +24,18 @@ fi | |||
| 24 | 24 | set -u | |
| 25 | 25 | ||
| 26 | 26 | # ======================================================= | |
| 27 | - | # 2. CROSS-SHELL NORMALIZATION | |
| 27 | + | # 2. SHELL NORMALIZATION | |
| 28 | 28 | # ======================================================= | |
| 29 | + | PROFILE_FILE="$HOME/.zshrc" | |
| 30 | + | ||
| 29 | 31 | if [ -n "${ZSH_VERSION:-}" ]; then | |
| 30 | 32 | # Zsh: Enable Bash-like word splitting for unquoted variables (menu input) | |
| 31 | 33 | setopt shwordsplit 2>/dev/null || true | |
| 32 | 34 | CURRENT_SHELL="zsh" | |
| 33 | - | PROFILE_FILE="$HOME/.zshrc" | |
| 34 | 35 | elif [ -n "${BASH_VERSION:-}" ]; then | |
| 35 | - | # Bash | |
| 36 | 36 | CURRENT_SHELL="bash" | |
| 37 | - | PROFILE_FILE="$HOME/.bashrc" | |
| 38 | 37 | else | |
| 39 | - | # Fallback POSIX | |
| 40 | 38 | CURRENT_SHELL="sh" | |
| 41 | - | PROFILE_FILE="$HOME/.profile" | |
| 42 | 39 | fi | |
| 43 | 40 | ||
| 44 | 41 | # ======================================================= | |
| @@ -249,17 +246,34 @@ install_python() { | |||
| 249 | 246 | ||
| 250 | 247 | install_go() { | |
| 251 | 248 | log "Fetching latest Go version from official source..." | |
| 252 | - | LATEST_GO=$(curl -sL https://go.dev/VERSION?m=text | head -n 1) | |
| 249 | + | LATEST_GO=$(curl -fsSL 'https://go.dev/VERSION?m=text' | head -n 1) || { | |
| 250 | + | err "Could not determine the latest Go version." | |
| 251 | + | return 1 | |
| 252 | + | } | |
| 253 | 253 | TAR_FILE="${LATEST_GO}.${OS_LOWER}-${SYS_ARCH}.tar.gz" | |
| 254 | + | ||
| 255 | + | if [[ -x /usr/local/go/bin/go ]] && [[ "$(/usr/local/go/bin/go version)" == "go version $LATEST_GO "* ]]; then | |
| 256 | + | warn "$LATEST_GO is already installed." | |
| 257 | + | add_to_path_config "GO_BIN" 'export PATH="$PATH:/usr/local/go/bin"' | |
| 258 | + | return 0 | |
| 259 | + | fi | |
| 254 | 260 | ||
| 255 | 261 | log "Downloading $TAR_FILE..." | |
| 256 | - | curl -fsSL -o /tmp/go.tar.gz "https://go.dev/dl/$TAR_FILE" | |
| 262 | + | curl -fsSL -o /tmp/go.tar.gz "https://go.dev/dl/$TAR_FILE" || { | |
| 263 | + | err "Failed to download $TAR_FILE." | |
| 264 | + | rm -f /tmp/go.tar.gz | |
| 265 | + | return 1 | |
| 266 | + | } | |
| 257 | 267 | ||
| 258 | 268 | log "Installing to /usr/local/go..." | |
| 259 | - | sudo rm -rf /usr/local/go | |
| 260 | - | sudo tar -C /usr/local -xzf /tmp/go.tar.gz | |
| 261 | - | rm /tmp/go.tar.gz | |
| 269 | + | if ! sudo rm -rf /usr/local/go || ! sudo tar -C /usr/local -xzf /tmp/go.tar.gz; then | |
| 270 | + | err "Go installation failed. Run this installer from an interactive terminal so sudo can authenticate." | |
| 271 | + | rm -f /tmp/go.tar.gz | |
| 272 | + | return 1 | |
| 273 | + | fi | |
| 274 | + | rm -f /tmp/go.tar.gz | |
| 262 | 275 | add_to_path_config "GO_BIN" 'export PATH="$PATH:/usr/local/go/bin"' | |
| 276 | + | log "$(/usr/local/go/bin/go version) installed successfully." | |
| 263 | 277 | } | |
| 264 | 278 | ||
| 265 | 279 | install_sdkman() { | |
| @@ -723,7 +737,11 @@ while true; do | |||
| 723 | 737 | ||
| 724 | 738 | # Bulletproof prompt for both Bash and Zsh | |
| 725 | 739 | printf "Select options (space-separated): " | |
| 726 | - | read input | |
| 740 | + | if ! read input; then | |
| 741 | + | printf "\n" | |
| 742 | + | warn "Input closed. Exiting installer." | |
| 743 | + | exit 0 | |
| 744 | + | fi | |
| 727 | 745 | ||
| 728 | 746 | # Thanks to 'setopt shwordsplit' in Zsh, this behaves perfectly across both shells | |
| 729 | 747 | for choice in $input; do | |
| @@ -764,5 +782,5 @@ while true; do | |||
| 764 | 782 | done | |
| 765 | 783 | ||
| 766 | 784 | printf "Press Enter to continue..." | |
| 767 | - | read dummy | |
| 785 | + | read dummy || exit 0 | |
| 768 | 786 | done | |
Vernon Wee Hong KOH gist felülvizsgálása 2 months ago. Revízióhoz ugrás
2 files changed, 23 insertions
README.md
| @@ -59,6 +59,8 @@ Choose **19) Update All Installed Software** to update every detected tool in th | |||
| 59 | 59 | * **Claude Code CLI:** Anthropic's official agent. | |
| 60 | 60 | * **OpenAI Codex CLI:** Required NVM/Node.js to run. | |
| 61 | 61 | * **OpenCode:** AI agent orchestration installed from the official OpenCode installer. | |
| 62 | + | * **Augment Code CLI (Auggie):** Installed from Augment's official NPM package; requires Node.js 20 or later. | |
| 63 | + | * **CodeRabbit CLI:** Local AI code reviews installed from CodeRabbit's official installer. | |
| 62 | 64 | ||
| 63 | 65 | ## ⚠️ Important Notes & Troubleshooting | |
| 64 | 66 | ||
menu.sh
| @@ -547,6 +547,19 @@ install_codex() { | |||
| 547 | 547 | npm i -g @openai/codex | |
| 548 | 548 | } | |
| 549 | 549 | ||
| 550 | + | install_augment() { | |
| 551 | + | if require_cmd auggie; then warn "Augment Code CLI exists"; return; fi | |
| 552 | + | log "Installing Augment Code CLI (Auggie)..." | |
| 553 | + | if ! require_cmd npm; then err "Node.js 20+/NPM is required. Install NVM (3) first."; return 1; fi | |
| 554 | + | npm install -g @augmentcode/auggie | |
| 555 | + | } | |
| 556 | + | ||
| 557 | + | install_coderabbit() { | |
| 558 | + | if require_cmd coderabbit || require_cmd cr; then warn "CodeRabbit CLI exists"; return; fi | |
| 559 | + | log "Installing CodeRabbit CLI..." | |
| 560 | + | curl -fsSL https://cli.coderabbit.ai/install.sh | sh | |
| 561 | + | } | |
| 562 | + | ||
| 550 | 563 | update_all() { | |
| 551 | 564 | log "Updating all installed software from official sources..." | |
| 552 | 565 | ||
| @@ -655,6 +668,10 @@ update_all() { | |||
| 655 | 668 | require_cmd claude && { curl -fsSL https://claude.ai/install.sh | $CURRENT_SHELL; } | |
| 656 | 669 | require_cmd codex && npm install -g @openai/codex@latest | |
| 657 | 670 | require_cmd opencode && { curl -fsSL https://opencode.ai/install | $CURRENT_SHELL; } | |
| 671 | + | require_cmd auggie && npm install -g @augmentcode/auggie@latest | |
| 672 | + | if require_cmd coderabbit || require_cmd cr; then | |
| 673 | + | curl -fsSL https://cli.coderabbit.ai/install.sh | sh | |
| 674 | + | fi | |
| 658 | 675 | ||
| 659 | 676 | log "Finished updating installed software. Review any warnings or errors above." | |
| 660 | 677 | } | |
| @@ -693,6 +710,8 @@ show_menu() { | |||
| 693 | 710 | printf " 16) Claude Code CLI\n" | |
| 694 | 711 | printf " 17) OpenAI Codex CLI\n" | |
| 695 | 712 | printf " 18) OpenCode\n" | |
| 713 | + | printf " 20) Augment Code CLI (Auggie)\n" | |
| 714 | + | printf " 21) CodeRabbit CLI\n" | |
| 696 | 715 | printf "${BLUE}==================================================${NC}\n" | |
| 697 | 716 | printf " 19) Update All Installed Software\n" | |
| 698 | 717 | printf " 99) Quit & Refresh Shell\n" | |
| @@ -728,6 +747,8 @@ while true; do | |||
| 728 | 747 | 17) install_codex ;; | |
| 729 | 748 | 18) install_opencode ;; | |
| 730 | 749 | 19) update_all ;; | |
| 750 | + | 20) install_augment ;; | |
| 751 | + | 21) install_coderabbit ;; | |
| 731 | 752 | 99) | |
| 732 | 753 | log "Installation complete! Refreshing terminal environment..." | |
| 733 | 754 | ||
weehong gist felülvizsgálása 2 months ago. Revízióhoz ugrás
2 files changed, 116 insertions
README.md
| @@ -22,6 +22,8 @@ bash -c "$(curl -fsSL https://tinyurl.com/4rskc9e7)" | |||
| 22 | 22 | ||
| 23 | 23 | Once the menu loads, simply **follow the interactive prompts**. You can select multiple tools at once by entering space-separated numbers (e.g., `1 3 8 12`). | |
| 24 | 24 | ||
| 25 | + | Choose **19) Update All Installed Software** to update every detected tool in the menu from its official source. Tools that are not installed are skipped. | |
| 26 | + | ||
| 25 | 27 | ## 🛠️ Included Tools | |
| 26 | 28 | ||
| 27 | 29 | ### Essentials & Package Managers | |
menu.sh
| @@ -547,6 +547,118 @@ install_codex() { | |||
| 547 | 547 | npm i -g @openai/codex | |
| 548 | 548 | } | |
| 549 | 549 | ||
| 550 | + | update_all() { | |
| 551 | + | log "Updating all installed software from official sources..." | |
| 552 | + | ||
| 553 | + | if require_cmd apt-get; then | |
| 554 | + | sudo apt-get update && sudo apt-get install -y --only-upgrade \ | |
| 555 | + | build-essential curl wget git jq unzip libssl-dev zlib1g-dev libffi-dev libsqlite3-dev \ | |
| 556 | + | python3 python3-pip python3-venv | |
| 557 | + | elif require_cmd dnf; then | |
| 558 | + | sudo dnf upgrade -y python3 python3-pip | |
| 559 | + | elif require_cmd zypper; then | |
| 560 | + | sudo zypper --non-interactive update python3 python3-pip | |
| 561 | + | elif require_cmd pacman; then | |
| 562 | + | sudo pacman -Syu --noconfirm python python-pip | |
| 563 | + | elif require_cmd apk; then | |
| 564 | + | sudo apk upgrade | |
| 565 | + | fi | |
| 566 | + | ||
| 567 | + | if [[ "$OS" == "macOS" ]] && require_cmd python3; then | |
| 568 | + | install_python | |
| 569 | + | fi | |
| 570 | + | ||
| 571 | + | require_cmd brew && { brew update && brew upgrade; } | |
| 572 | + | ||
| 573 | + | if [[ -s "$HOME/.nvm/nvm.sh" ]]; then | |
| 574 | + | set +u | |
| 575 | + | export NVM_DIR="$HOME/.nvm" | |
| 576 | + | LATEST_NVM=$(curl -fsSL https://api.github.com/repos/nvm-sh/nvm/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') | |
| 577 | + | curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${LATEST_NVM}/install.sh" | PROFILE=/dev/null $CURRENT_SHELL | |
| 578 | + | \. "$NVM_DIR/nvm.sh" | |
| 579 | + | nvm install --lts --reinstall-packages-from=current | |
| 580 | + | nvm alias default 'lts/*' | |
| 581 | + | nvm use --lts | |
| 582 | + | set -u | |
| 583 | + | fi | |
| 584 | + | ||
| 585 | + | require_cmd go && install_go | |
| 586 | + | ||
| 587 | + | if [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]]; then | |
| 588 | + | set +u | |
| 589 | + | source "$HOME/.sdkman/bin/sdkman-init.sh" | |
| 590 | + | sdk selfupdate force | |
| 591 | + | sdk upgrade | |
| 592 | + | set -u | |
| 593 | + | fi | |
| 594 | + | ||
| 595 | + | if require_cmd dotnet; then | |
| 596 | + | curl -fsSL https://dot.net/v1/dotnet-install.sh | $CURRENT_SHELL | |
| 597 | + | fi | |
| 598 | + | ||
| 599 | + | local sdkmanager="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-$HOME/Android/Sdk}}/cmdline-tools/latest/bin/sdkmanager" | |
| 600 | + | if [[ -x "$sdkmanager" ]]; then | |
| 601 | + | yes | "$sdkmanager" --licenses >/dev/null || true | |
| 602 | + | "$sdkmanager" --update | |
| 603 | + | fi | |
| 604 | + | ||
| 605 | + | if require_cmd docker; then | |
| 606 | + | if [[ "$OS" == "macOS" ]]; then | |
| 607 | + | docker desktop update || warn "Update Docker Desktop from its application menu." | |
| 608 | + | else | |
| 609 | + | curl -fsSL https://get.docker.com | sudo sh | |
| 610 | + | fi | |
| 611 | + | fi | |
| 612 | + | ||
| 613 | + | if require_cmd docker && docker ps -a --format '{{.Names}}' | grep -Fxq portainer; then | |
| 614 | + | log "Updating Portainer CE..." | |
| 615 | + | docker pull portainer/portainer-ce:sts && \ | |
| 616 | + | docker stop portainer && \ | |
| 617 | + | docker rm portainer && \ | |
| 618 | + | docker run -d \ | |
| 619 | + | -p 8000:8000 \ | |
| 620 | + | -p 9443:9443 \ | |
| 621 | + | --name portainer \ | |
| 622 | + | --restart=always \ | |
| 623 | + | -v /var/run/docker.sock:/var/run/docker.sock \ | |
| 624 | + | -v portainer_data:/data \ | |
| 625 | + | portainer/portainer-ce:sts | |
| 626 | + | fi | |
| 627 | + | ||
| 628 | + | if require_cmd aws; then | |
| 629 | + | if [[ "$OS" == "macOS" ]]; then | |
| 630 | + | curl -fsSL -o /tmp/AWSCLIV2.pkg https://awscli.amazonaws.com/AWSCLIV2.pkg && \ | |
| 631 | + | sudo installer -pkg /tmp/AWSCLIV2.pkg -target / | |
| 632 | + | rm -f /tmp/AWSCLIV2.pkg | |
| 633 | + | elif require_cmd unzip; then | |
| 634 | + | curl -fsSL -o /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-${AWS_ARCH}.zip" && \ | |
| 635 | + | rm -rf /tmp/aws && unzip -q /tmp/awscliv2.zip -d /tmp && \ | |
| 636 | + | sudo /tmp/aws/install --update | |
| 637 | + | rm -rf /tmp/aws /tmp/awscliv2.zip | |
| 638 | + | fi | |
| 639 | + | fi | |
| 640 | + | ||
| 641 | + | require_cmd gcloud && gcloud components update --quiet | |
| 642 | + | require_cmd firebase && npm install -g firebase-tools@latest | |
| 643 | + | ||
| 644 | + | if require_cmd gh; then | |
| 645 | + | log "Updating GitHub CLI..." | |
| 646 | + | LATEST_GH=$(curl -s https://api.github.com/repos/cli/cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') | |
| 647 | + | TAR_NAME="gh_${LATEST_GH}_${OS_LOWER}_${SYS_ARCH}" | |
| 648 | + | curl -fsSL -o /tmp/gh.tar.gz "https://github.com/cli/cli/releases/download/v${LATEST_GH}/${TAR_NAME}.tar.gz" && \ | |
| 649 | + | tar -xzf /tmp/gh.tar.gz -C /tmp && \ | |
| 650 | + | sudo mv "/tmp/${TAR_NAME}/bin/gh" /usr/local/bin/ | |
| 651 | + | sudo rm -rf "/tmp/${TAR_NAME}" /tmp/gh.tar.gz | |
| 652 | + | fi | |
| 653 | + | ||
| 654 | + | require_cmd infisical && npm install -g @infisical/cli@latest | |
| 655 | + | require_cmd claude && { curl -fsSL https://claude.ai/install.sh | $CURRENT_SHELL; } | |
| 656 | + | require_cmd codex && npm install -g @openai/codex@latest | |
| 657 | + | require_cmd opencode && { curl -fsSL https://opencode.ai/install | $CURRENT_SHELL; } | |
| 658 | + | ||
| 659 | + | log "Finished updating installed software. Review any warnings or errors above." | |
| 660 | + | } | |
| 661 | + | ||
| 550 | 662 | # ======================================================= | |
| 551 | 663 | # MENU LOGIC | |
| 552 | 664 | # ======================================================= | |
| @@ -582,6 +694,7 @@ show_menu() { | |||
| 582 | 694 | printf " 17) OpenAI Codex CLI\n" | |
| 583 | 695 | printf " 18) OpenCode\n" | |
| 584 | 696 | printf "${BLUE}==================================================${NC}\n" | |
| 697 | + | printf " 19) Update All Installed Software\n" | |
| 585 | 698 | printf " 99) Quit & Refresh Shell\n" | |
| 586 | 699 | printf "${BLUE}==================================================${NC}\n" | |
| 587 | 700 | } | |
| @@ -614,6 +727,7 @@ while true; do | |||
| 614 | 727 | 16) install_claude ;; | |
| 615 | 728 | 17) install_codex ;; | |
| 616 | 729 | 18) install_opencode ;; | |
| 730 | + | 19) update_all ;; | |
| 617 | 731 | 99) | |
| 618 | 732 | log "Installation complete! Refreshing terminal environment..." | |
| 619 | 733 | ||
weehong gist felülvizsgálása 2 months ago. Revízióhoz ugrás
2 files changed, 43 insertions, 63 deletions
README.md
| @@ -2,13 +2,13 @@ | |||
| 2 | 2 | ||
| 3 | 3 | A robust, idempotent, and interactive bash script to bootstrap your macOS, Linux, or WSL development environment. | |
| 4 | 4 | ||
| 5 | - | Unlike standard setup scripts that rely heavily on package managers like Homebrew or Apt (which can introduce bloat, dependency hell, or outdated packages), this script is designed with a **"Strict Official Source"** philosophy. It dynamically fetches the absolute latest binaries and pre-compiled releases directly from the official maintainers (e.g., GitHub API, Python.org, Amazon). | |
| 5 | + | This script follows a **"Strict Official Source"** philosophy. It fetches binaries and installers directly from official maintainers, or from the operating system vendor's signed repositories when upstream does not publish native binaries for that platform. | |
| 6 | 6 | ||
| 7 | 7 | ## ✨ Key Features | |
| 8 | 8 | ||
| 9 | - | * **Zero-Brew Dependency:** By default, it bypasses Homebrew entirely, fetching tools directly from official APIs and release pages (Homebrew is available as an optional install). | |
| 9 | + | * **Zero-Brew Dependency:** By default, it bypasses Homebrew entirely, using official APIs, release pages, and signed OS repositories (Homebrew is available as an optional install). | |
| 10 | 10 | * **Idempotent:** Safe to run multiple times. It intelligently checks if a tool is already installed before attempting to download it. | |
| 11 | - | * **Dynamic Versioning:** Pings official APIs (like GitHub Releases or `go.dev/VERSION`) to ensure you are downloading the exact latest version at the time of execution. | |
| 11 | + | * **Dynamic Versioning:** Uses official APIs (like GitHub Releases or `go.dev/VERSION`) when maintainers publish versioned binaries. OS-packaged tools track the supported distribution version and security updates. | |
| 12 | 12 | * **Auto-Path Management:** Intelligently injects paths into a dedicated `~/.pathrc` (or your `.bashrc`/`.zshrc`) without mangling your config files. | |
| 13 | 13 | * **Architecture Aware:** Automatically detects if you are running on Intel (`x86_64`) or Apple Silicon/ARM (`aarch64`/`arm64`) and downloads the correct binaries. | |
| 14 | 14 | ||
| @@ -30,7 +30,7 @@ Once the menu loads, simply **follow the interactive prompts**. You can select m | |||
| 30 | 30 | ||
| 31 | 31 | ### Languages & Runtimes | |
| 32 | 32 | * **NVM (Node Version Manager):** Includes interactive prompt to install LTS or Latest Node.js immediately. | |
| 33 | - | * **Python 3:** Fetches the latest stable `.pkg` for Mac or compiles strictly from source for Linux. | |
| 33 | + | * **Python 3:** Fetches Python.org's latest stable `.pkg` for macOS. Linux and WSL install precompiled Python, pip, and venv from the signed OS-vendor repository without source compilation or third-party repositories. | |
| 34 | 34 | * **Go:** Fetches the latest tarball and installs system-wide to `/usr/local/go`. | |
| 35 | 35 | * **SDKMAN:** For managing Java, Kotlin, and Gradle. | |
| 36 | 36 | * **.NET:** Installed via Microsoft's official script. | |
| @@ -63,6 +63,7 @@ Once the menu loads, simply **follow the interactive prompts**. You can select m | |||
| 63 | 63 | * **Restart Your Shell:** After running the script for the first time, you should restart your terminal or run `source ~/.bashrc` (or `~/.zshrc`) to ensure all new PATH variables (like NVM, Go, or .NET) take effect. | |
| 64 | 64 | * **Docker Permissions (Linux):** The script automatically adds your user to the `docker` group. You will need to log out and log back in for this to take effect. | |
| 65 | 65 | * **AWS CLI on Linux:** Ensure you install **Build Tools (Option 1)** first if you are on a fresh Linux install, as the AWS installer requires `unzip` to extract the payload. | |
| 66 | + | * **Python Version on Linux:** Python follows the version supported by your distribution rather than the newest python.org patch release. This keeps installation precompiled, vendor-supported, and eligible for normal OS security updates. | |
| 66 | 67 | ||
| 67 | 68 | --- | |
| 68 | 69 | *Built for developers who want total control over their toolchain.* | |
menu.sh
| @@ -188,22 +188,19 @@ install_nvm() { | |||
| 188 | 188 | } | |
| 189 | 189 | ||
| 190 | 190 | install_python() { | |
| 191 | - | log "Fetching latest stable Python version..." | |
| 192 | - | ||
| 193 | - | LATEST_PY=$( | |
| 194 | - | curl -fsSL --compressed https://www.python.org/downloads/ | | |
| 195 | - | sed -nE 's/.*Download Python ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' | | |
| 196 | - | head -1 | |
| 197 | - | ) | |
| 198 | - | ||
| 199 | - | if [[ -z "$LATEST_PY" ]]; then | |
| 200 | - | err "Could not detect the latest stable Python version from python.org." | |
| 201 | - | return 1 | |
| 202 | - | fi | |
| 203 | - | ||
| 204 | - | log "Detected Stable Version: $LATEST_PY" | |
| 205 | - | ||
| 206 | 191 | if [[ "$OS" == "macOS" ]]; then | |
| 192 | + | log "Fetching latest stable Python version..." | |
| 193 | + | LATEST_PY=$( | |
| 194 | + | curl -fsSL --compressed https://www.python.org/downloads/ | | |
| 195 | + | sed -nE 's/.*Download Python ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' | | |
| 196 | + | head -1 | |
| 197 | + | ) | |
| 198 | + | if [[ -z "$LATEST_PY" ]]; then | |
| 199 | + | err "Could not detect the latest stable Python version from python.org." | |
| 200 | + | return 1 | |
| 201 | + | fi | |
| 202 | + | ||
| 203 | + | log "Detected Stable Version: $LATEST_PY" | |
| 207 | 204 | log "Downloading official macOS package..." | |
| 208 | 205 | PKG_URL="https://www.python.org/ftp/python/${LATEST_PY}/python-${LATEST_PY}-macos11.pkg" | |
| 209 | 206 | curl -fsSL --compressed -o /tmp/python.pkg "$PKG_URL" || { | |
| @@ -219,53 +216,35 @@ install_python() { | |||
| 219 | 216 | } | |
| 220 | 217 | rm /tmp/python.pkg | |
| 221 | 218 | else | |
| 222 | - | log "Installing build dependencies (zlib, ssl, etc)..." | |
| 223 | - | sudo apt-get update && sudo apt-get install -y build-essential zlib1g-dev libssl-dev libffi-dev libsqlite3-dev || { | |
| 224 | - | err "Failed to install Python build dependencies." | |
| 225 | - | return 1 | |
| 226 | - | } | |
| 227 | - | ||
| 228 | - | SRC_URL="https://www.python.org/ftp/python/${LATEST_PY}/Python-${LATEST_PY}.tgz" | |
| 229 | - | ||
| 230 | - | log "Downloading $SRC_URL..." | |
| 231 | - | curl -fSL --compressed -o /tmp/Python.tgz "$SRC_URL" || { | |
| 232 | - | err "Failed to download Python source from $SRC_URL" | |
| 233 | - | return 1 | |
| 234 | - | } | |
| 235 | - | ||
| 236 | - | cd /tmp && tar -xzf Python.tgz && cd "Python-${LATEST_PY}" || { | |
| 237 | - | err "Failed to extract Python source archive." | |
| 238 | - | return 1 | |
| 239 | - | } | |
| 240 | - | ||
| 241 | - | log "Configuring build (with ensurepip)..." | |
| 242 | - | ./configure --enable-optimizations --with-ensurepip=install || { | |
| 243 | - | err "Python configure step failed." | |
| 244 | - | return 1 | |
| 245 | - | } | |
| 246 | - | ||
| 247 | - | log "Compiling Python (this may take a few minutes)..." | |
| 248 | - | sudo make altinstall || { | |
| 249 | - | err "Python build/install step failed." | |
| 250 | - | return 1 | |
| 251 | - | } | |
| 252 | - | ||
| 253 | - | PY_MINOR=$(echo "$LATEST_PY" | cut -d. -f1,2) | |
| 254 | - | ||
| 255 | - | log "Setting up symlinks..." | |
| 256 | - | sudo ln -sf /usr/local/bin/python${PY_MINOR} /usr/local/bin/python3 | |
| 257 | - | ||
| 258 | - | if [[ -f "/usr/local/bin/pip${PY_MINOR}" ]]; then | |
| 259 | - | sudo ln -sf /usr/local/bin/pip${PY_MINOR} /usr/local/bin/pip3 | |
| 260 | - | log "Successfully linked pip3!" | |
| 219 | + | log "Installing precompiled Python from the official OS repository..." | |
| 220 | + | if require_cmd apt-get; then | |
| 221 | + | sudo apt-get update && \ | |
| 222 | + | sudo apt-get install -y python3 python3-pip python3-venv | |
| 223 | + | elif require_cmd dnf; then | |
| 224 | + | sudo dnf install -y python3 python3-pip | |
| 225 | + | elif require_cmd zypper; then | |
| 226 | + | sudo zypper --non-interactive install python3 python3-pip | |
| 227 | + | elif require_cmd pacman; then | |
| 228 | + | sudo pacman -Sy --needed python python-pip | |
| 229 | + | elif require_cmd apk; then | |
| 230 | + | sudo apk add python3 py3-pip py3-virtualenv | |
| 261 | 231 | else | |
| 262 | - | err "pip${PY_MINOR} was not generated during the build!" | |
| 232 | + | err "No supported official OS package manager found for Python." | |
| 233 | + | return 1 | |
| 263 | 234 | fi | |
| 264 | - | ||
| 265 | - | cd ~ && sudo rm -rf /tmp/Python* | |
| 266 | 235 | fi | |
| 267 | - | ||
| 268 | - | log "Python $LATEST_PY installation sequence finished!" | |
| 236 | + | ||
| 237 | + | require_cmd python3 || { err "python3 was not installed successfully."; return 1; } | |
| 238 | + | python3 -m pip --version >/dev/null 2>&1 || { | |
| 239 | + | err "pip is unavailable for the installed Python." | |
| 240 | + | return 1 | |
| 241 | + | } | |
| 242 | + | python3 -m venv --help >/dev/null 2>&1 || { | |
| 243 | + | err "venv is unavailable for the installed Python." | |
| 244 | + | return 1 | |
| 245 | + | } | |
| 246 | + | ||
| 247 | + | log "$(python3 --version) installed with pip and venv support." | |
| 269 | 248 | } | |
| 270 | 249 | ||
| 271 | 250 | install_go() { | |