Ultima attività 3 weeks ago

Interactive developer environment bootstrapper using official upstream downloads and signed OS-vendor packages.

weehong ha revisionato questo gist 1 month ago. Vai alla revisione

1 file changed, 1 insertion, 1 deletion

README.md

@@ -17,7 +17,7 @@ Unlike standard setup scripts that rely heavily on package managers like Homebre
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://opengist.resetrix.work/weehong/af1c64c143a44ffbb0a1632dd6a32af1/raw/HEAD/menu.sh)"
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`).

weehong ha revisionato questo gist 1 month ago. Vai alla revisione

1 file changed, 6 insertions

menu.sh

@@ -137,6 +137,9 @@ install_brew() {
137 137 }
138 138
139 139 install_nvm() {
140 + # 1. Temporarily disable 'unbound variable' strictness for NVM
141 + set +u
142 +
140 143 export NVM_DIR="$HOME/.nvm"
141 144
142 145 if [ -d "$NVM_DIR" ]; then
@@ -179,6 +182,9 @@ install_nvm() {
179 182 npm config set logs-max 0
180 183 ;;
181 184 esac
185 +
186 + # 2. Re-enable 'unbound variable' strictness for the rest of your script
187 + set -u
182 188 }
183 189
184 190 install_python() {

weehong ha revisionato questo gist 1 month ago. Vai alla revisione

1 file changed, 1 insertion, 1 deletion

README.md

@@ -17,7 +17,7 @@ Unlike standard setup scripts that rely heavily on package managers like Homebre
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://opengist.rmrf.online/weehong/af1c64c143a44ffbb0a1632dd6a32af1/raw/HEAD/menu.sh)"
20 + bash -c "$(curl -fsSL https://opengist.resetrix.work/weehong/af1c64c143a44ffbb0a1632dd6a32af1/raw/HEAD/menu.sh)"
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 ha revisionato questo gist 2 months ago. Vai alla revisione

1 file changed, 39 insertions, 9 deletions

menu.sh

@@ -184,35 +184,65 @@ install_nvm() {
184 184 install_python() {
185 185 log "Fetching latest stable Python version..."
186 186
187 - LATEST_PY=$(curl -s https://www.python.org/downloads/ | grep -o 'Download Python 3\.[0-9]\{1,2\}\.[0-9]\{1,2\}' | head -1 | grep -o '3\.[0-9]\{1,2\}\.[0-9]\{1,2\}')
188 - [[ -z "$LATEST_PY" ]] && LATEST_PY="3.12.3"
187 + LATEST_PY=$(
188 + curl -fsSL --compressed https://www.python.org/downloads/ |
189 + sed -nE 's/.*Download Python ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' |
190 + head -1
191 + )
192 +
193 + if [[ -z "$LATEST_PY" ]]; then
194 + err "Could not detect the latest stable Python version from python.org."
195 + return 1
196 + fi
189 197
190 198 log "Detected Stable Version: $LATEST_PY"
191 199
192 200 if [[ "$OS" == "macOS" ]]; then
193 201 log "Downloading official macOS package..."
194 202 PKG_URL="https://www.python.org/ftp/python/${LATEST_PY}/python-${LATEST_PY}-macos11.pkg"
195 - curl -fsSL -o /tmp/python.pkg "$PKG_URL"
203 + curl -fsSL --compressed -o /tmp/python.pkg "$PKG_URL" || {
204 + err "Failed to download Python macOS package from $PKG_URL"
205 + return 1
206 + }
196 207
197 208 log "Running installer..."
198 - sudo installer -pkg /tmp/python.pkg -target /
209 + sudo installer -pkg /tmp/python.pkg -target / || {
210 + err "Python macOS installer failed."
211 + rm -f /tmp/python.pkg
212 + return 1
213 + }
199 214 rm /tmp/python.pkg
200 215 else
201 216 log "Installing build dependencies (zlib, ssl, etc)..."
202 - sudo apt-get update && sudo apt-get install -y build-essential zlib1g-dev libssl-dev libffi-dev libsqlite3-dev
217 + sudo apt-get update && sudo apt-get install -y build-essential zlib1g-dev libssl-dev libffi-dev libsqlite3-dev || {
218 + err "Failed to install Python build dependencies."
219 + return 1
220 + }
203 221
204 222 SRC_URL="https://www.python.org/ftp/python/${LATEST_PY}/Python-${LATEST_PY}.tgz"
205 223
206 224 log "Downloading $SRC_URL..."
207 - curl -fSL -o /tmp/Python.tgz "$SRC_URL" || err "Failed to download Python source from $SRC_URL"
225 + curl -fSL --compressed -o /tmp/Python.tgz "$SRC_URL" || {
226 + err "Failed to download Python source from $SRC_URL"
227 + return 1
228 + }
208 229
209 - cd /tmp && tar -xzf Python.tgz && cd "Python-${LATEST_PY}"
230 + cd /tmp && tar -xzf Python.tgz && cd "Python-${LATEST_PY}" || {
231 + err "Failed to extract Python source archive."
232 + return 1
233 + }
210 234
211 235 log "Configuring build (with ensurepip)..."
212 - ./configure --enable-optimizations --with-ensurepip=install
236 + ./configure --enable-optimizations --with-ensurepip=install || {
237 + err "Python configure step failed."
238 + return 1
239 + }
213 240
214 241 log "Compiling Python (this may take a few minutes)..."
215 - sudo make altinstall
242 + sudo make altinstall || {
243 + err "Python build/install step failed."
244 + return 1
245 + }
216 246
217 247 PY_MINOR=$(echo "$LATEST_PY" | cut -d. -f1,2)
218 248

weehong ha revisionato questo gist 2 months ago. Vai alla revisione

Nessuna modifica

weehong ha revisionato questo gist 2 months ago. Vai alla revisione

1 file changed, 94 insertions, 19 deletions

menu.sh

@@ -267,6 +267,79 @@ install_dotnet() {
267 267 add_to_path_config "DOTNET_TOOLS" 'export PATH="$PATH:$HOME/.dotnet/tools"'
268 268 }
269 269
270 + install_android() {
271 + log "Installing Android SDK command-line tools..."
272 +
273 + if ! require_cmd unzip; then
274 + err "unzip is required. Please install 'Build Tools' (Option 1) first."
275 + return 1
276 + fi
277 +
278 + if [[ "$OS_LOWER" == "linux" && "$SYS_ARCH" != "amd64" ]]; then
279 + err "Google's Android command-line tools installer supports Linux x86_64 only."
280 + return 1
281 + fi
282 +
283 + ANDROID_HOME="$HOME/Android/Sdk"
284 + ANDROID_SDK_ROOT="$ANDROID_HOME"
285 + export ANDROID_HOME ANDROID_SDK_ROOT
286 +
287 + mkdir -p "$ANDROID_HOME/cmdline-tools"
288 +
289 + if [[ "$OS" == "macOS" ]]; then
290 + TOOLS_OS="mac"
291 + elif [[ "$OS_LOWER" == "linux" ]]; then
292 + TOOLS_OS="linux"
293 + else
294 + err "Android SDK installation is not supported for $OS."
295 + return 1
296 + fi
297 +
298 + log "Finding latest Android command-line tools from Google..."
299 + TOOLS_URL=$(curl -fsSL https://developer.android.com/studio \
300 + | grep -o "https://dl.google.com/android/repository/commandlinetools-${TOOLS_OS}-[0-9]*_latest.zip" \
301 + | head -1)
302 +
303 + if [[ -z "$TOOLS_URL" ]]; then
304 + err "Could not find the Android command-line tools download URL."
305 + return 1
306 + fi
307 +
308 + log "Downloading Android command-line tools..."
309 + rm -rf /tmp/android-cmdline-tools /tmp/android-cmdline-tools.zip
310 + mkdir -p /tmp/android-cmdline-tools
311 + curl -fsSL -o /tmp/android-cmdline-tools.zip "$TOOLS_URL"
312 + unzip -q /tmp/android-cmdline-tools.zip -d /tmp/android-cmdline-tools
313 +
314 + rm -rf "$ANDROID_HOME/cmdline-tools/latest"
315 + mkdir -p "$ANDROID_HOME/cmdline-tools/latest"
316 + mv /tmp/android-cmdline-tools/cmdline-tools/* "$ANDROID_HOME/cmdline-tools/latest/"
317 + rm -rf /tmp/android-cmdline-tools /tmp/android-cmdline-tools.zip
318 +
319 + SDKMANAGER="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager"
320 + if [[ ! -x "$SDKMANAGER" ]]; then
321 + err "sdkmanager was not installed correctly."
322 + return 1
323 + fi
324 +
325 + log "Accepting Android SDK licenses..."
326 + yes | "$SDKMANAGER" --sdk_root="$ANDROID_HOME" --licenses >/dev/null || true
327 +
328 + log "Installing Android SDK packages..."
329 + "$SDKMANAGER" --sdk_root="$ANDROID_HOME" \
330 + "cmdline-tools;latest" \
331 + "platform-tools" \
332 + "emulator" \
333 + "platforms;android-36" \
334 + "build-tools;36.0.0"
335 +
336 + add_to_path_config "ANDROID_SDK" 'export ANDROID_HOME="$HOME/Android/Sdk"
337 + export ANDROID_SDK_ROOT="$ANDROID_HOME"
338 + export PATH="$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator"'
339 +
340 + log "Android SDK installation sequence finished!"
341 + }
342 +
270 343 # =======================================================
271 344 # CLOUD & INFRASTRUCTURE
272 345 # =======================================================
@@ -428,18 +501,19 @@ show_menu() {
428 501 printf " 5) Go (Official -> /usr/local)\n"
429 502 printf " 6) SDKMAN (Java/Kotlin)\n"
430 503 printf " 7) .NET (Official Script)\n"
504 + printf " 8) Android SDK (CLI + Platform Tools)\n"
431 505 printf "${YELLOW}--- Cloud & Infrastructure ---${NC}\n"
432 - printf " 8) Docker (Official DMG/sh)\n"
433 - printf " 9) AWS CLI (Official Bin)\n"
434 - printf " 10) Google Cloud CLI (gcloud)\n"
435 - printf " 11) Firebase CLI (NPM/ARM64 Safe)\n"
506 + printf " 9) Docker (Official DMG/sh)\n"
507 + printf " 10) AWS CLI (Official Bin)\n"
508 + printf " 11) Google Cloud CLI (gcloud)\n"
509 + printf " 12) Firebase CLI (NPM/ARM64 Safe)\n"
436 510 printf "${YELLOW}--- Dev Tools & Security ---${NC}\n"
437 - printf " 12) GitHub CLI (Official Bin)\n"
438 - printf " 13) Infisical (Official Bin)\n"
511 + printf " 13) GitHub CLI (Official Bin)\n"
512 + printf " 14) Infisical (Official Bin)\n"
439 513 printf "${YELLOW}--- AI & Agentic Tools ---${NC}\n"
440 - printf " 14) Claude Code CLI\n"
441 - printf " 15) OpenCode (opencode.ai)\n"
442 - printf " 16) OpenAI Codex CLI\n"
514 + printf " 15) Claude Code CLI\n"
515 + printf " 16) OpenCode (opencode.ai)\n"
516 + printf " 17) OpenAI Codex CLI\n"
443 517 printf "${BLUE}==================================================${NC}\n"
444 518 printf " 99) Quit & Refresh Shell\n"
445 519 printf "${BLUE}==================================================${NC}\n"
@@ -462,15 +536,16 @@ while true; do
462 536 5) install_go ;;
463 537 6) install_sdkman ;;
464 538 7) install_dotnet ;;
465 - 8) install_docker ;;
466 - 9) install_aws ;;
467 - 10) install_gcloud ;;
468 - 11) install_firebase ;;
469 - 12) install_gh ;;
470 - 13) install_infisical ;;
471 - 14) install_claude ;;
472 - 15) install_opencode ;;
473 - 16) install_codex ;;
539 + 8) install_android ;;
540 + 9) install_docker ;;
541 + 10) install_aws ;;
542 + 11) install_gcloud ;;
543 + 12) install_firebase ;;
544 + 13) install_gh ;;
545 + 14) install_infisical ;;
546 + 15) install_claude ;;
547 + 16) install_opencode ;;
548 + 17) install_codex ;;
474 549 99)
475 550 log "Installation complete! Refreshing terminal environment..."
476 551
@@ -487,4 +562,4 @@ while true; do
487 562
488 563 printf "Press Enter to continue..."
489 564 read dummy
490 - done
565 + done

weehong ha revisionato questo gist 3 months ago. Vai alla revisione

1 file changed, 26 insertions, 9 deletions

menu.sh

@@ -272,9 +272,11 @@ install_dotnet() {
272 272 # =======================================================
273 273
274 274 install_docker() {
275 - if require_cmd docker; then log "Docker exists"; else
275 + log "Checking Docker status..."
276 +
277 + # 1. Install if missing
278 + if ! require_cmd docker; then
276 279 log "Installing Docker from official source..."
277 -
278 280 if [[ "$OS" == "macOS" ]]; then
279 281 [[ "$SYS_ARCH" == "arm64" ]] && DOCKER_MAC_ARCH="arm64" || DOCKER_MAC_ARCH="amd64"
280 282 DMG_URL="https://desktop.docker.com/mac/main/${DOCKER_MAC_ARCH}/Docker.dmg"
@@ -290,29 +292,39 @@ install_docker() {
290 292 else
291 293 curl -fsSL https://get.docker.com | sudo sh
292 294 fi
295 + else
296 + warn "Docker is already installed. Enforcing permissions..."
293 297 fi
294 298
299 + # 2. Aggressively enforce Linux permissions
295 300 if [[ "$OS" != "macOS" ]]; then
296 - log "Applying Linux post-install actions..."
301 + log "Applying strict Linux post-install actions..."
297 302
303 + # Ensure docker group exists and user is added
298 304 sudo groupadd -f docker
299 305 sudo usermod -aG docker "$USER"
300 306
307 + # Ensure services are enabled and running
301 308 if command -v systemctl >/dev/null 2>&1; then
302 309 sudo systemctl enable --now docker.service
303 - sudo systemctl enable --now containerd.service
310 + sudo systemctl enable --now docker.socket containerd.service 2>/dev/null || true
304 311 elif [[ "$OS" == "WSL" ]]; then
305 312 sudo service docker start
306 313 fi
307 314
315 + # Give the system a second to generate the socket file
316 + sleep 2
317 +
318 + # Lock in ownership and permissions on the socket
308 319 if [[ -S /var/run/docker.sock ]]; then
309 - log "Fixing ownership of /var/run/docker.sock..."
320 + log "Securing /var/run/docker.sock..."
310 321 sudo chown root:docker /var/run/docker.sock
311 322 sudo chmod 660 /var/run/docker.sock
323 + else
324 + warn "Docker socket not found. The service may have failed to start."
312 325 fi
313 326
314 - log "Added $USER to the docker group."
315 - log "CRITICAL: To apply group changes immediately, run: newgrp docker"
327 + log "Added $USER to the docker group and secured the socket."
316 328 fi
317 329 }
318 330
@@ -461,8 +473,13 @@ while true; do
461 473 16) install_codex ;;
462 474 99)
463 475 log "Installation complete! Refreshing terminal environment..."
464 - # $SHELL holds the user's actual default terminal (e.g., /bin/zsh)
465 - exec "${SHELL:-zsh}"
476 +
477 + # If on Linux, forcefully inherit the new docker group without needing a logout
478 + if [[ "$OS" != "macOS" ]] && command -v sg >/dev/null 2>&1; then
479 + exec sg docker -c "exec ${SHELL:-zsh}"
480 + else
481 + exec "${SHELL:-zsh}"
482 + fi
466 483 ;;
467 484 *) warn "Option $choice not valid." ;;
468 485 esac

weehong ha revisionato questo gist 3 months ago. Vai alla revisione

1 file changed, 2 insertions, 1 deletion

menu.sh

@@ -461,7 +461,8 @@ while true; do
461 461 16) install_codex ;;
462 462 99)
463 463 log "Installation complete! Refreshing terminal environment..."
464 - exec "$CURRENT_SHELL"
464 + # $SHELL holds the user's actual default terminal (e.g., /bin/zsh)
465 + exec "${SHELL:-zsh}"
465 466 ;;
466 467 *) warn "Option $choice not valid." ;;
467 468 esac

weehong ha revisionato questo gist 3 months ago. Vai alla revisione

1 file changed, 30 insertions, 5 deletions

menu.sh

@@ -74,6 +74,10 @@ add_to_path_config() {
74 74 printf "\n# %s\n%s\n" "$label" "$path_line" >> "$PROFILE_FILE"
75 75 log "Added $label to shell profile ($PROFILE_FILE)."
76 76 fi
77 +
78 + # Instantly evaluate the path line so the current script session
79 + # can immediately use the newly installed tool in subsequent steps.
80 + eval "$path_line" 2>/dev/null || true
77 81 }
78 82
79 83 detect_os_arch() {
@@ -153,9 +157,27 @@ install_nvm() {
153 157 read node_choice
154 158
155 159 case "$node_choice" in
156 - 2) log "Installing Latest Node.js..."; nvm install node; nvm alias default node; nvm use node ;;
157 - 3) log "Skipping Node.js installation." ;;
158 - *) log "Installing Latest LTS Node.js..."; nvm install --lts; nvm alias default 'lts/*'; nvm use --lts ;;
160 + 2)
161 + log "Installing Latest Node.js..."
162 + nvm install node
163 + nvm alias default node
164 + nvm use node
165 +
166 + log "Disabling npm logs..."
167 + npm config set logs-max 0
168 + ;;
169 + 3)
170 + log "Skipping Node.js installation."
171 + ;;
172 + *)
173 + log "Installing Latest LTS Node.js..."
174 + nvm install --lts
175 + nvm alias default 'lts/*'
176 + nvm use --lts
177 +
178 + log "Disabling npm logs..."
179 + npm config set logs-max 0
180 + ;;
159 181 esac
160 182 }
161 183
@@ -407,7 +429,7 @@ show_menu() {
407 429 printf " 15) OpenCode (opencode.ai)\n"
408 430 printf " 16) OpenAI Codex CLI\n"
409 431 printf "${BLUE}==================================================${NC}\n"
410 - printf " 99) Quit\n"
432 + printf " 99) Quit & Refresh Shell\n"
411 433 printf "${BLUE}==================================================${NC}\n"
412 434 }
413 435
@@ -437,7 +459,10 @@ while true; do
437 459 14) install_claude ;;
438 460 15) install_opencode ;;
439 461 16) install_codex ;;
440 - 99) log "Exiting..."; exit 0 ;;
462 + 99)
463 + log "Installation complete! Refreshing terminal environment..."
464 + exec "$CURRENT_SHELL"
465 + ;;
441 466 *) warn "Option $choice not valid." ;;
442 467 esac
443 468 done

weehong ha revisionato questo gist 3 months ago. Vai alla revisione

1 file changed, 10 insertions, 2 deletions

menu.sh

@@ -227,8 +227,16 @@ install_go() {
227 227
228 228 install_sdkman() {
229 229 if [ -d "$HOME/.sdkman" ]; then warn "SDKMAN already exists"; return; fi
230 - log "Installing SDKMAN via $CURRENT_SHELL..."
231 - curl -s "https://get.sdkman.io" | $CURRENT_SHELL
230 +
231 + # SDKMAN explicitly blocks macOS's default Bash 3.2.
232 + # If we are trapped in Bash < 4, force the installer to use Zsh.
233 + if [[ "$CURRENT_SHELL" == "bash" && "${BASH_VERSINFO[0]:-0}" -lt 4 ]]; then
234 + log "Outdated Bash detected. Installing SDKMAN via Zsh..."
235 + curl -s "https://get.sdkman.io" | zsh
236 + else
237 + log "Installing SDKMAN via $CURRENT_SHELL..."
238 + curl -s "https://get.sdkman.io" | $CURRENT_SHELL
239 + fi
232 240 }
233 241
234 242 install_dotnet() {