Остання активність 3 weeks ago

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

Версія a5a4360f924a7822b073853a4db07fa43ddbbbc2

README.md Неформатований

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 Неформатований
1#!/usr/bin/env bash
2set -u
3
4# =============================
5# COLORS & LOGGING
6# =============================
7GREEN="\033[0;32m"
8RED="\033[0;31m"
9YELLOW="\033[1;33m"
10BLUE="\033[0;34m"
11NC="\033[0m"
12
13log() { echo -e "${GREEN}$*${NC}"; }
14warn() { echo -e "${YELLOW}$*${NC}"; }
15err() { echo -e "${RED}$*${NC}"; }
16info() { echo -e "${BLUE}$*${NC}"; }
17
18# =============================
19# HELPERS & SYSTEM DETECTION
20# =============================
21require_cmd() { command -v "$1" >/dev/null 2>&1; }
22
23add_to_path_config() {
24 local label=$1
25 local path_line=$2
26 local target_file="${3:-$HOME/.pathrc}"
27
28 if [[ -f "$target_file" ]]; then
29 if ! grep -q "$label" "$target_file"; then
30 echo -e "\n# $label\n$path_line" >> "$target_file"
31 log "Added $label to $target_file"
32 fi
33 else
34 echo -e "\n# $label\n$path_line" >> "$HOME/.bashrc"
35 [[ -f "$HOME/.zshrc" ]] && echo -e "\n# $label\n$path_line" >> "$HOME/.zshrc"
36 log "Added $label to shell profiles."
37 fi
38}
39
40detect_os_arch() {
41 ARCH=$(uname -m)
42 case "$ARCH" in
43 x86_64|amd64) SYS_ARCH="amd64"; MAC_ARCH="x86_64"; AWS_ARCH="x86_64" ;;
44 aarch64|arm64) SYS_ARCH="arm64"; MAC_ARCH="arm64"; AWS_ARCH="aarch64" ;;
45 *) err "Unsupported architecture: $ARCH"; exit 1 ;;
46 esac
47
48 if [[ "$OSTYPE" == "darwin"* ]]; then
49 OS="macOS"
50 OS_LOWER="darwin"
51 elif grep -qi microsoft /proc/version 2>/dev/null; then
52 OS="WSL"
53 OS_LOWER="linux"
54 elif [[ -f /etc/os-release ]]; then
55 . /etc/os-release
56 [[ "$ID" == "ubuntu" || "$ID_LIKE" == *"ubuntu"* ]] && OS="Ubuntu" || OS="Linux"
57 OS_LOWER="linux"
58 else
59 OS="Unknown"
60 OS_LOWER="unknown"
61 fi
62 log "Detected: $OS ($ARCH)"
63}
64
65detect_os_arch
66
67# =============================
68# CORE RUNTIMES & MANAGERS
69# =============================
70
71install_build_tools() {
72 log "Installing Build Essentials & Core Dependencies..."
73 case "$OS" in
74 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 ;;
75 macOS) xcode-select --install || warn "Xcode tools already installed" ;;
76 *) warn "Manual installation required for $OS." ;;
77 esac
78}
79
80install_brew() {
81 if require_cmd brew; then warn "Homebrew already installed"; return; fi
82 log "Installing Homebrew from Official Source..."
83 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
84
85 if [[ "$OS_LOWER" == "linux" ]]; then
86 add_to_path_config "HOMEBREW" 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"'
87 elif [[ "$MAC_ARCH" == "arm64" ]]; then
88 add_to_path_config "HOMEBREW" 'eval "$(/opt/homebrew/bin/brew shellenv)"'
89 else
90 add_to_path_config "HOMEBREW" 'eval "$(/usr/local/bin/brew shellenv)"'
91 fi
92}
93
94install_nvm() {
95 export NVM_DIR="$HOME/.nvm"
96
97 if [ -d "$NVM_DIR" ]; then
98 warn "NVM is already installed."
99 else
100 log "Installing NVM..."
101 curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
102 fi
103
104 # Load NVM for the current session to ensure the 'nvm' command is available immediately
105 [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
106
107 echo -e "\n${YELLOW}Which version of Node.js would you like to install?${NC}"
108 echo " 1) LTS (Long Term Support - Recommended for stability)"
109 echo " 2) Latest (Current features - Recommended for testing new APIs)"
110 echo " 3) Skip installing Node.js right now"
111 read -p "Select (1/2/3): " node_choice
112
113 case "$node_choice" in
114 2)
115 log "Installing Latest Node.js..."
116 nvm install node
117 nvm alias default node
118 nvm use node
119 ;;
120 3)
121 log "Skipping Node.js installation."
122 ;;
123 *)
124 log "Installing Latest LTS Node.js..."
125 nvm install --lts
126 nvm alias default 'lts/*'
127 nvm use --lts
128 ;;
129 esac
130}
131
132install_python() {
133 log "Fetching latest Python 3 version from official API..."
134 LATEST_PY=$(curl -s https://api.github.com/repos/python/cpython/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
135 [[ -z "$LATEST_PY" ]] && LATEST_PY="3.12.3"
136
137 log "Installing Python $LATEST_PY directly from Python.org..."
138 if [[ "$OS" == "macOS" ]]; then
139 PKG_URL="https://www.python.org/ftp/python/${LATEST_PY}/python-${LATEST_PY}-macos11.pkg"
140 curl -fsSL -o /tmp/python.pkg "$PKG_URL"
141 sudo installer -pkg /tmp/python.pkg -target /
142 rm /tmp/python.pkg
143 else
144 SRC_URL="https://www.python.org/ftp/python/${LATEST_PY}/Python-${LATEST_PY}.tgz"
145 curl -fsSL -o /tmp/Python.tgz "$SRC_URL"
146 cd /tmp && tar -xzf Python.tgz && cd "Python-${LATEST_PY}"
147 ./configure --enable-optimizations
148 sudo make altinstall
149
150 PY_MINOR=$(echo "$LATEST_PY" | cut -d. -f1,2)
151 log "Symlinking python${PY_MINOR} to python3..."
152 sudo ln -sf /usr/local/bin/python${PY_MINOR} /usr/local/bin/python3
153 sudo ln -sf /usr/local/bin/pip${PY_MINOR} /usr/local/bin/pip3
154
155 cd ~ && sudo rm -rf /tmp/Python*
156 fi
157}
158
159install_go() {
160 log "Fetching latest Go version from official source..."
161 LATEST_GO=$(curl -sL https://go.dev/VERSION?m=text | head -n 1)
162 TAR_FILE="${LATEST_GO}.${OS_LOWER}-${SYS_ARCH}.tar.gz"
163
164 log "Downloading $TAR_FILE..."
165 curl -fsSL -o /tmp/go.tar.gz "https://go.dev/dl/$TAR_FILE"
166
167 log "Installing to /usr/local/go..."
168 sudo rm -rf /usr/local/go
169 sudo tar -C /usr/local -xzf /tmp/go.tar.gz
170 rm /tmp/go.tar.gz
171 add_to_path_config "GO_BIN" 'export PATH="$PATH:/usr/local/go/bin"'
172}
173
174install_sdkman() {
175 if [ -d "$HOME/.sdkman" ]; then warn "SDKMAN already exists"; return; fi
176 log "Installing SDKMAN..."
177 curl -s "https://get.sdkman.io" | bash
178}
179
180install_dotnet() {
181 log "Installing .NET from official script..."
182 curl -fsSL https://dot.net/v1/dotnet-install.sh | bash
183 add_to_path_config "DOTNET_TOOLS" 'export PATH="$PATH:$HOME/.dotnet/tools"'
184}
185
186# =============================
187# CLOUD & INFRASTRUCTURE
188# =============================
189
190install_docker() {
191 if require_cmd docker; then log "Docker exists"; return; fi
192 log "Installing Docker from official source..."
193
194 if [[ "$OS" == "macOS" ]]; then
195 [[ "$SYS_ARCH" == "arm64" ]] && DOCKER_MAC_ARCH="arm64" || DOCKER_MAC_ARCH="amd64"
196 DMG_URL="https://desktop.docker.com/mac/main/${DOCKER_MAC_ARCH}/Docker.dmg"
197 curl -fsSL -o /tmp/Docker.dmg "$DMG_URL"
198 hdiutil attach /tmp/Docker.dmg -nobrowse -mountpoint /Volumes/Docker
199 sudo cp -a /Volumes/Docker/Docker.app /Applications/
200 hdiutil detach /Volumes/Docker
201 rm /tmp/Docker.dmg
202 else
203 curl -fsSL https://get.docker.com | sudo sh
204 sudo usermod -aG docker "$USER"
205 log "Added $USER to docker group. You may need to logout/login."
206 fi
207}
208
209install_aws() {
210 if require_cmd aws; then warn "AWS CLI exists"; return; fi
211 log "Installing AWS CLI directly from Amazon..."
212
213 if [[ "$OS" == "macOS" ]]; then
214 curl -fsSL -o /tmp/AWSCLIV2.pkg "https://awscli.amazonaws.com/AWSCLIV2.pkg"
215 sudo installer -pkg /tmp/AWSCLIV2.pkg -target /
216 rm /tmp/AWSCLIV2.pkg
217 else
218 if ! require_cmd unzip; then
219 err "unzip is required. Please install 'Build Tools' (Option 1) first."
220 return 1
221 fi
222 curl -fsSL -o /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-${AWS_ARCH}.zip"
223 cd /tmp && unzip -q awscliv2.zip && sudo ./aws/install
224 rm -rf /tmp/awscliv2.zip /tmp/aws
225 fi
226}
227
228install_gcloud() {
229 if require_cmd gcloud; then warn "Google Cloud CLI exists"; return; fi
230 log "Installing Google Cloud CLI..."
231 curl -fsSL https://sdk.cloud.google.com | bash -s -- --disable-prompts
232 add_to_path_config "GCLOUD" 'source "$HOME/google-cloud-sdk/path.bash.inc"'
233}
234
235install_firebase() {
236 if require_cmd firebase; then warn "Firebase CLI exists"; return; fi
237 log "Installing Standalone Firebase CLI..."
238 curl -sL https://firebase.tools | bash
239}
240
241# =============================
242# DEV TOOLS & SECURITY
243# =============================
244
245install_gh() {
246 if require_cmd gh; then warn "GitHub CLI exists"; return; fi
247 log "Fetching latest GitHub CLI version..."
248 LATEST_GH=$(curl -s https://api.github.com/repos/cli/cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
249 TAR_NAME="gh_${LATEST_GH}_${OS_LOWER}_${SYS_ARCH}"
250
251 curl -fsSL -o /tmp/gh.tar.gz "https://github.com/cli/cli/releases/download/v${LATEST_GH}/${TAR_NAME}.tar.gz"
252 tar -xzf /tmp/gh.tar.gz -C /tmp
253 sudo mv "/tmp/${TAR_NAME}/bin/gh" /usr/local/bin/
254 sudo rm -rf "/tmp/${TAR_NAME}" /tmp/gh.tar.gz
255}
256
257install_infisical() {
258 if require_cmd infisical; then warn "Infisical exists"; return; fi
259 log "Fetching latest Infisical binary from GitHub Releases..."
260 LATEST_INF=$(curl -s https://api.github.com/repos/Infisical/infisical-cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
261 TAR_FILE="infisical_${LATEST_INF}_${OS_LOWER}_${SYS_ARCH}.tar.gz"
262
263 curl -fsSL -o /tmp/infisical.tar.gz "https://github.com/Infisical/infisical-cli/releases/download/v${LATEST_INF}/${TAR_FILE}"
264 tar -xzf /tmp/infisical.tar.gz -C /tmp
265 sudo mv /tmp/infisical /usr/local/bin/
266 rm /tmp/infisical.tar.gz
267}
268
269# =============================
270# AI & AGENTIC TOOLS
271# =============================
272
273install_claude() { log "Installing Claude Code..."; curl -fsSL https://claude.ai/install.sh | bash; }
274install_opencode() { log "Installing OpenCode..."; curl -fsSL https://opencode.ai/install | bash; }
275
276install_codex() {
277 log "Installing @openai/codex..."
278 if ! require_cmd npm; then err "Node.js/NPM is required. Install NVM (3) first."; return 1; fi
279 npm i -g @openai/codex
280}
281
282# =============================
283# MENU LOGIC
284# =============================
285show_menu() {
286 clear
287 echo -e "${BLUE}==================================================${NC}"
288 echo -e "${GREEN} DEVELOPER ENVIRONMENT INSTALLER (Strict) ${NC}"
289 echo -e "${BLUE}==================================================${NC}"
290 echo -e "${YELLOW}--- Core Runtimes & Managers ---${NC}"
291 echo " 1) Build Tools (GCC/Make)"
292 echo " 2) Homebrew (Optional)"
293 echo " 3) NVM (Node.js)"
294 echo " 4) Python 3 (Official API)"
295 echo " 5) Go (Official -> /usr/local)"
296 echo " 6) SDKMAN (Java/Kotlin)"
297 echo " 7) .NET (Official Script)"
298 echo -e "${YELLOW}--- Cloud & Infrastructure ---${NC}"
299 echo " 8) Docker (Official DMG/sh)"
300 echo " 9) AWS CLI (Official Bin)"
301 echo " 10) Google Cloud CLI (gcloud)"
302 echo " 11) Firebase CLI (Standalone)"
303 echo -e "${YELLOW}--- Dev Tools & Security ---${NC}"
304 echo " 12) GitHub CLI (Official Bin)"
305 echo " 13) Infisical (Official Bin)"
306 echo -e "${YELLOW}--- AI & Agentic Tools ---${NC}"
307 echo " 14) Claude Code CLI"
308 echo " 15) OpenCode (opencode.ai)"
309 echo " 16) OpenAI Codex CLI"
310 echo -e "${BLUE}==================================================${NC}"
311 echo " 99) Quit"
312 echo -e "${BLUE}==================================================${NC}"
313}
314
315while true; do
316 show_menu
317 read -p "Select options (space-separated): " input
318 for choice in $input; do
319 case "$choice" in
320 1) install_build_tools ;;
321 2) install_brew ;;
322 3) install_nvm ;;
323 4) install_python ;;
324 5) install_go ;;
325 6) install_sdkman ;;
326 7) install_dotnet ;;
327 8) install_docker ;;
328 9) install_aws ;;
329 10) install_gcloud ;;
330 11) install_firebase ;;
331 12) install_gh ;;
332 13) install_infisical ;;
333 14) install_claude ;;
334 15) install_opencode ;;
335 16) install_codex ;;
336 99) log "Exiting..."; exit 0 ;;
337 *) warn "Option $choice not valid." ;;
338 esac
339 done
340 read -p "Press Enter to continue..."
341done