Última atividade 3 weeks ago

Interactive developer environment bootstrapper for Zsh/Bash with repeatable workstation setup helpers.

Revisão b825b83a2bd6c378f2b9a5a965d3ee25f3ddd8b0

README.md Bruto

Strict Developer Environment Installer

A robust, idempotent, and interactive bash script to bootstrap your macOS, Linux, or WSL development environment.

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).

✨ Key Features

  • 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).
  • Idempotent: Safe to run multiple times. It intelligently checks if a tool is already installed before attempting to download it.
  • 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.
  • Auto-Path Management: Intelligently injects paths into a dedicated ~/.pathrc (or your .bashrc/.zshrc) without mangling your config files.
  • Architecture Aware: Automatically detects if you are running on Intel (x86_64) or Apple Silicon/ARM (aarch64/arm64) and downloads the correct binaries.

🚀 Usage

You can launch the interactive installer directly from your terminal with a single command:

bash -c "$(curl -fsSL https://opengist.rmrf.online/weehong/af1c64c143a44ffbb0a1632dd6a32af1/raw/HEAD/menu.sh)"

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).

🛠️ Included Tools

Core Runtimes & Managers

  • Build Tools: GCC, Make, Git, Curl, Unzip, and core libraries.
  • Homebrew: (Optional) Installed officially.
  • NVM (Node Version Manager): Includes interactive prompt to install LTS or Latest Node.js immediately.
  • Python 3: Fetches the latest stable .pkg for Mac or compiles strictly from source for Linux.
  • Go: Fetches the latest tarball and installs system-wide to /usr/local/go.
  • SDKMAN: For managing Java, Kotlin, and Gradle.
  • .NET: Installed via Microsoft's official script.

Cloud & Infrastructure

  • Docker: Downloads the official .dmg (macOS) or runs the official get.docker.com script (Linux) with auto-group assignment.
  • AWS CLI: Fetches the official binaries directly from Amazon.
  • Google Cloud CLI (gcloud): Official Google setup script.
  • Firebase CLI: Standalone binary (no Node.js required natively).

Dev Tools & Security

  • GitHub CLI (gh): Downloaded directly from GitHub Releases to /usr/local/bin.
  • Infisical CLI: Downloaded directly from GitHub Releases for secret management.

AI & Agentic Tools

  • Claude Code CLI: Anthropic's official agent.
  • OpenCode: AI agent orchestration.
  • OpenAI Codex CLI: Required NVM/Node.js to run.

⚠️ Important Notes & Troubleshooting

  • 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.
  • 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.
  • 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.

Built for developers who want total control over their toolchain.

menu.sh Bruto
1#!/usr/bin/env bash
2
3# =======================================================
4# 1. BOOTSTRAPPER: PREFER ZSH, FALLBACK TO BASH
5# =======================================================
6if [ -z "${_PREFER_ZSH_BOOTSTRAPPED:-}" ]; then
7 export _PREFER_ZSH_BOOTSTRAPPED=1
8 if command -v zsh >/dev/null 2>&1; then
9 exec zsh "$0" "$@"
10 elif command -v bash >/dev/null 2>&1; then
11 exec bash "$0" "$@"
12 else
13 echo "Error: Neither Zsh nor Bash is installed. Exiting."
14 exit 1
15 fi
16fi
17
18set -u
19
20# =======================================================
21# 2. CROSS-SHELL NORMALIZATION
22# =======================================================
23if [ -n "${ZSH_VERSION:-}" ]; then
24 # Zsh: Enable Bash-like word splitting for unquoted variables (menu input)
25 setopt shwordsplit 2>/dev/null || true
26 CURRENT_SHELL="zsh"
27 PROFILE_FILE="$HOME/.zshrc"
28elif [ -n "${BASH_VERSION:-}" ]; then
29 # Bash
30 CURRENT_SHELL="bash"
31 PROFILE_FILE="$HOME/.bashrc"
32else
33 # Fallback POSIX
34 CURRENT_SHELL="sh"
35 PROFILE_FILE="$HOME/.profile"
36fi
37
38# =======================================================
39# COLORS & LOGGING
40# =======================================================
41GREEN="\033[0;32m"
42RED="\033[0;31m"
43YELLOW="\033[1;33m"
44BLUE="\033[0;34m"
45NC="\033[0m"
46
47log() { printf "${GREEN}▶ %s${NC}\n" "$*"; }
48warn() { printf "${YELLOW}⚠ %s${NC}\n" "$*"; }
49err() { printf "${RED}✖ %s${NC}\n" "$*"; }
50info() { printf "${BLUE}ℹ %s${NC}\n" "$*"; }
51
52# =======================================================
53# HELPERS & SYSTEM DETECTION
54# =======================================================
55require_cmd() { command -v "$1" >/dev/null 2>&1; }
56
57add_to_path_config() {
58 local label=$1
59 local path_line=$2
60 local target_file="${3:-$PROFILE_FILE}"
61
62 if [[ -f "$target_file" ]]; then
63 if ! grep -q "$label" "$target_file"; then
64 printf "\n# %s\n%s\n" "$label" "$path_line" >> "$target_file"
65 log "Added $label to $target_file"
66 fi
67 else
68 printf "\n# %s\n%s\n" "$label" "$path_line" >> "$PROFILE_FILE"
69 log "Added $label to shell profile ($PROFILE_FILE)."
70 fi
71}
72
73detect_os_arch() {
74 ARCH=$(uname -m)
75 case "$ARCH" in
76 x86_64|amd64) SYS_ARCH="amd64"; MAC_ARCH="x86_64"; AWS_ARCH="x86_64" ;;
77 aarch64|arm64) SYS_ARCH="arm64"; MAC_ARCH="arm64"; AWS_ARCH="aarch64" ;;
78 *) err "Unsupported architecture: $ARCH"; exit 1 ;;
79 esac
80
81 if [[ "$OSTYPE" == "darwin"* ]]; then
82 OS="macOS"
83 OS_LOWER="darwin"
84 elif grep -qi microsoft /proc/version 2>/dev/null; then
85 OS="WSL"
86 OS_LOWER="linux"
87 elif [[ -f /etc/os-release ]]; then
88 . /etc/os-release
89 [[ "$ID" == "ubuntu" || "$ID_LIKE" == *"ubuntu"* ]] && OS="Ubuntu" || OS="Linux"
90 OS_LOWER="linux"
91 else
92 OS="Unknown"
93 OS_LOWER="unknown"
94 fi
95 log "Detected: $OS ($ARCH) running $CURRENT_SHELL"
96}
97
98detect_os_arch
99
100# =======================================================
101# CORE RUNTIMES & MANAGERS
102# =======================================================
103
104install_build_tools() {
105 log "Installing Build Essentials & Core Dependencies..."
106 case "$OS" in
107 Ubuntu|WSL) sudo apt-get update && sudo apt-get install -y build-essential curl wget git jq unzip libssl-dev zlib1g-dev libffi-dev libsqlite3-dev ;;
108 macOS) xcode-select --install || warn "Xcode tools already installed" ;;
109 *) warn "Manual installation required for $OS." ;;
110 esac
111}
112
113install_brew() {
114 if require_cmd brew; then warn "Homebrew already installed"; return; fi
115 log "Installing Homebrew from Official Source..."
116
117 # Homebrew's installer specifically requires Bash execution, regardless of current shell
118 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
119
120 if [[ "$OS_LOWER" == "linux" ]]; then
121 add_to_path_config "HOMEBREW" 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"'
122 elif [[ "$MAC_ARCH" == "arm64" ]]; then
123 add_to_path_config "HOMEBREW" 'eval "$(/opt/homebrew/bin/brew shellenv)"'
124 else
125 add_to_path_config "HOMEBREW" 'eval "$(/usr/local/bin/brew shellenv)"'
126 fi
127}
128
129install_nvm() {
130 export NVM_DIR="$HOME/.nvm"
131
132 if [ -d "$NVM_DIR" ]; then
133 warn "NVM is already installed."
134 else
135 log "Installing NVM via $CURRENT_SHELL..."
136 curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | $CURRENT_SHELL
137 fi
138
139 [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
140
141 printf "\n${YELLOW}Which version of Node.js would you like to install?${NC}\n"
142 printf " 1) LTS (Long Term Support - Recommended for stability)\n"
143 printf " 2) Latest (Current features - Recommended for testing new APIs)\n"
144 printf " 3) Skip installing Node.js right now\n"
145
146 printf "Select (1/2/3): "
147 read node_choice
148
149 case "$node_choice" in
150 2) log "Installing Latest Node.js..."; nvm install node; nvm alias default node; nvm use node ;;
151 3) log "Skipping Node.js installation." ;;
152 *) log "Installing Latest LTS Node.js..."; nvm install --lts; nvm alias default 'lts/*'; nvm use --lts ;;
153 esac
154}
155
156install_python() {
157 log "Fetching latest stable Python version..."
158
159 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\}')
160 [[ -z "$LATEST_PY" ]] && LATEST_PY="3.12.3"
161
162 log "Detected Stable Version: $LATEST_PY"
163
164 if [[ "$OS" == "macOS" ]]; then
165 log "Downloading official macOS package..."
166 PKG_URL="https://www.python.org/ftp/python/${LATEST_PY}/python-${LATEST_PY}-macos11.pkg"
167 curl -fsSL -o /tmp/python.pkg "$PKG_URL"
168
169 log "Running installer..."
170 sudo installer -pkg /tmp/python.pkg -target /
171 rm /tmp/python.pkg
172 else
173 log "Installing build dependencies (zlib, ssl, etc)..."
174 sudo apt-get update && sudo apt-get install -y build-essential zlib1g-dev libssl-dev libffi-dev libsqlite3-dev
175
176 SRC_URL="https://www.python.org/ftp/python/${LATEST_PY}/Python-${LATEST_PY}.tgz"
177
178 log "Downloading $SRC_URL..."
179 curl -fSL -o /tmp/Python.tgz "$SRC_URL" || err "Failed to download Python source from $SRC_URL"
180
181 cd /tmp && tar -xzf Python.tgz && cd "Python-${LATEST_PY}"
182
183 log "Configuring build (with ensurepip)..."
184 ./configure --enable-optimizations --with-ensurepip=install
185
186 log "Compiling Python (this may take a few minutes)..."
187 sudo make altinstall
188
189 PY_MINOR=$(echo "$LATEST_PY" | cut -d. -f1,2)
190
191 log "Setting up symlinks..."
192 sudo ln -sf /usr/local/bin/python${PY_MINOR} /usr/local/bin/python3
193
194 if [[ -f "/usr/local/bin/pip${PY_MINOR}" ]]; then
195 sudo ln -sf /usr/local/bin/pip${PY_MINOR} /usr/local/bin/pip3
196 log "Successfully linked pip3!"
197 else
198 err "pip${PY_MINOR} was not generated during the build!"
199 fi
200
201 cd ~ && sudo rm -rf /tmp/Python*
202 fi
203
204 log "Python $LATEST_PY installation sequence finished!"
205}
206
207install_go() {
208 log "Fetching latest Go version from official source..."
209 LATEST_GO=$(curl -sL https://go.dev/VERSION?m=text | head -n 1)
210 TAR_FILE="${LATEST_GO}.${OS_LOWER}-${SYS_ARCH}.tar.gz"
211
212 log "Downloading $TAR_FILE..."
213 curl -fsSL -o /tmp/go.tar.gz "https://go.dev/dl/$TAR_FILE"
214
215 log "Installing to /usr/local/go..."
216 sudo rm -rf /usr/local/go
217 sudo tar -C /usr/local -xzf /tmp/go.tar.gz
218 rm /tmp/go.tar.gz
219 add_to_path_config "GO_BIN" 'export PATH="$PATH:/usr/local/go/bin"'
220}
221
222install_sdkman() {
223 if [ -d "$HOME/.sdkman" ]; then warn "SDKMAN already exists"; return; fi
224 log "Installing SDKMAN via $CURRENT_SHELL..."
225 curl -s "https://get.sdkman.io" | $CURRENT_SHELL
226}
227
228install_dotnet() {
229 log "Installing .NET from official script..."
230 curl -fsSL https://dot.net/v1/dotnet-install.sh | $CURRENT_SHELL
231 add_to_path_config "DOTNET_TOOLS" 'export PATH="$PATH:$HOME/.dotnet/tools"'
232}
233
234# =======================================================
235# CLOUD & INFRASTRUCTURE
236# =======================================================
237
238install_docker() {
239 if require_cmd docker; then log "Docker exists"; else
240 log "Installing Docker from official source..."
241
242 if [[ "$OS" == "macOS" ]]; then
243 [[ "$SYS_ARCH" == "arm64" ]] && DOCKER_MAC_ARCH="arm64" || DOCKER_MAC_ARCH="amd64"
244 DMG_URL="https://desktop.docker.com/mac/main/${DOCKER_MAC_ARCH}/Docker.dmg"
245 curl -fsSL -o /tmp/Docker.dmg "$DMG_URL"
246 hdiutil attach /tmp/Docker.dmg -nobrowse -mountpoint /Volumes/Docker
247 sudo cp -a /Volumes/Docker/Docker.app /Applications/
248 hdiutil detach /Volumes/Docker
249 rm /tmp/Docker.dmg
250
251 log "Starting Docker Desktop..."
252 open /Applications/Docker.app
253 log "Please complete the setup in the Docker Desktop UI."
254 else
255 curl -fsSL https://get.docker.com | sudo sh
256 fi
257 fi
258
259 if [[ "$OS" != "macOS" ]]; then
260 log "Applying Linux post-install actions..."
261
262 sudo groupadd -f docker
263 sudo usermod -aG docker "$USER"
264
265 if command -v systemctl >/dev/null 2>&1; then
266 sudo systemctl enable --now docker.service
267 sudo systemctl enable --now containerd.service
268 elif [[ "$OS" == "WSL" ]]; then
269 sudo service docker start
270 fi
271
272 if [[ -S /var/run/docker.sock ]]; then
273 log "Fixing ownership of /var/run/docker.sock..."
274 sudo chown root:docker /var/run/docker.sock
275 sudo chmod 660 /var/run/docker.sock
276 fi
277
278 log "Added $USER to the docker group."
279 log "CRITICAL: To apply group changes immediately, run: newgrp docker"
280 fi
281}
282
283install_aws() {
284 if require_cmd aws; then warn "AWS CLI exists"; return; fi
285 log "Installing AWS CLI directly from Amazon..."
286
287 if [[ "$OS" == "macOS" ]]; then
288 curl -fsSL -o /tmp/AWSCLIV2.pkg "https://awscli.amazonaws.com/AWSCLIV2.pkg"
289 sudo installer -pkg /tmp/AWSCLIV2.pkg -target /
290 rm /tmp/AWSCLIV2.pkg
291 else
292 if ! require_cmd unzip; then
293 err "unzip is required. Please install 'Build Tools' (Option 1) first."
294 return 1
295 fi
296 curl -fsSL -o /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-${AWS_ARCH}.zip"
297 cd /tmp && unzip -q awscliv2.zip && sudo ./aws/install
298 rm -rf /tmp/awscliv2.zip /tmp/aws
299 fi
300}
301
302install_gcloud() {
303 if require_cmd gcloud; then warn "Google Cloud CLI exists"; return; fi
304 log "Installing Google Cloud CLI..."
305 curl -fsSL https://sdk.cloud.google.com | $CURRENT_SHELL -s -- --disable-prompts
306
307 if [[ "$CURRENT_SHELL" == "zsh" ]]; then
308 add_to_path_config "GCLOUD" '[ -f "$HOME/google-cloud-sdk/path.zsh.inc" ] && source "$HOME/google-cloud-sdk/path.zsh.inc"'
309 else
310 add_to_path_config "GCLOUD" '[ -f "$HOME/google-cloud-sdk/path.bash.inc" ] && source "$HOME/google-cloud-sdk/path.bash.inc"'
311 fi
312}
313
314install_firebase() {
315 if require_cmd firebase; then warn "Firebase CLI exists"; return; fi
316 log "Installing Firebase CLI via NPM to ensure ARM64 compatibility..."
317
318 if ! require_cmd npm; then
319 err "NPM not found. Please install NVM (Option 3) first."
320 return 1
321 fi
322
323 npm install -g firebase-tools
324}
325
326# =======================================================
327# DEV TOOLS & SECURITY
328# =======================================================
329
330install_gh() {
331 if require_cmd gh; then warn "GitHub CLI exists"; return; fi
332 log "Fetching latest GitHub CLI version..."
333 LATEST_GH=$(curl -s https://api.github.com/repos/cli/cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
334 TAR_NAME="gh_${LATEST_GH}_${OS_LOWER}_${SYS_ARCH}"
335
336 curl -fsSL -o /tmp/gh.tar.gz "https://github.com/cli/cli/releases/download/v${LATEST_GH}/${TAR_NAME}.tar.gz"
337 tar -xzf /tmp/gh.tar.gz -C /tmp
338 sudo mv "/tmp/${TAR_NAME}/bin/gh" /usr/local/bin/
339 sudo rm -rf "/tmp/${TAR_NAME}" /tmp/gh.tar.gz
340}
341
342install_infisical() {
343 if require_cmd infisical; then warn "Infisical CLI exists"; return; fi
344 log "Installing Infisical CLI via NPM..."
345
346 if ! require_cmd npm; then
347 err "NPM not found. Please install NVM (Option 3) first."
348 return 1
349 fi
350
351 npm install -g @infisical/cli
352}
353
354# =======================================================
355# AI & AGENTIC TOOLS
356# =======================================================
357
358install_claude() { log "Installing Claude Code..."; curl -fsSL https://claude.ai/install.sh | $CURRENT_SHELL; }
359install_opencode() { log "Installing OpenCode..."; curl -fsSL https://opencode.ai/install | $CURRENT_SHELL; }
360
361install_codex() {
362 log "Installing @openai/codex..."
363 if ! require_cmd npm; then err "Node.js/NPM is required. Install NVM (3) first."; return 1; fi
364 npm i -g @openai/codex
365}
366
367# =======================================================
368# MENU LOGIC
369# =======================================================
370show_menu() {
371 clear
372 printf "${BLUE}==================================================${NC}\n"
373 printf "${GREEN} DEVELOPER ENVIRONMENT INSTALLER (Polyglot) ${NC}\n"
374 printf "${BLUE}==================================================${NC}\n"
375 printf "${YELLOW}--- Core Runtimes & Managers ---${NC}\n"
376 printf " 1) Build Tools (GCC/Make)\n"
377 printf " 2) Homebrew (Optional)\n"
378 printf " 3) NVM (Node.js)\n"
379 printf " 4) Python 3 (Official API)\n"
380 printf " 5) Go (Official -> /usr/local)\n"
381 printf " 6) SDKMAN (Java/Kotlin)\n"
382 printf " 7) .NET (Official Script)\n"
383 printf "${YELLOW}--- Cloud & Infrastructure ---${NC}\n"
384 printf " 8) Docker (Official DMG/sh)\n"
385 printf " 9) AWS CLI (Official Bin)\n"
386 printf " 10) Google Cloud CLI (gcloud)\n"
387 printf " 11) Firebase CLI (NPM/ARM64 Safe)\n"
388 printf "${YELLOW}--- Dev Tools & Security ---${NC}\n"
389 printf " 12) GitHub CLI (Official Bin)\n"
390 printf " 13) Infisical (Official Bin)\n"
391 printf "${YELLOW}--- AI & Agentic Tools ---${NC}\n"
392 printf " 14) Claude Code CLI\n"
393 printf " 15) OpenCode (opencode.ai)\n"
394 printf " 16) OpenAI Codex CLI\n"
395 printf "${BLUE}==================================================${NC}\n"
396 printf " 99) Quit\n"
397 printf "${BLUE}==================================================${NC}\n"
398}
399
400while true; do
401 show_menu
402
403 # Bulletproof prompt for both Bash and Zsh
404 printf "Select options (space-separated): "
405 read input
406
407 # Thanks to 'setopt shwordsplit' in Zsh, this behaves perfectly across both shells
408 for choice in $input; do
409 case "$choice" in
410 1) install_build_tools ;;
411 2) install_brew ;;
412 3) install_nvm ;;
413 4) install_python ;;
414 5) install_go ;;
415 6) install_sdkman ;;
416 7) install_dotnet ;;
417 8) install_docker ;;
418 9) install_aws ;;
419 10) install_gcloud ;;
420 11) install_firebase ;;
421 12) install_gh ;;
422 13) install_infisical ;;
423 14) install_claude ;;
424 15) install_opencode ;;
425 16) install_codex ;;
426 99) log "Exiting..."; exit 0 ;;
427 *) warn "Option $choice not valid." ;;
428 esac
429 done
430
431 printf "Press Enter to continue..."
432 read dummy
433done