323 lines
8.2 KiB
Bash
Executable File
323 lines
8.2 KiB
Bash
Executable File
#!/bin/bash
|
||
# XCodeCLI Setup Launcher (macOS / Linux)
|
||
# 一站式安装和配置 Claude Code, Gemini CLI, Codex
|
||
|
||
set -e
|
||
|
||
# ========== 颜色定义 ==========
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[0;33m'
|
||
BLUE='\033[0;34m'
|
||
CYAN='\033[0;36m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# ========== 输出函数 ==========
|
||
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||
success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||
warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
||
error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||
|
||
# ========== 工具配置(兼容 bash 3.x)==========
|
||
TOOL_NAMES_1="Claude Code"
|
||
TOOL_NAMES_2="Gemini CLI"
|
||
TOOL_NAMES_3="Codex"
|
||
|
||
TOOL_CMDS_1="claude"
|
||
TOOL_CMDS_2="gemini"
|
||
TOOL_CMDS_3="codex"
|
||
|
||
TOOL_PKGS_1="@anthropic-ai/claude-code"
|
||
TOOL_PKGS_2="@google/gemini-cli@latest"
|
||
TOOL_PKGS_3="@openai/codex"
|
||
|
||
TOOL_URLS_1="https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/ClaudeCode/setup-claude-code.sh"
|
||
TOOL_URLS_2="https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/GeminiCLI/setup-gemini.sh"
|
||
TOOL_URLS_3="https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/codex/setup-codex.sh"
|
||
|
||
# Helper functions to get tool properties
|
||
get_tool_name() { eval echo \"\$TOOL_NAMES_$1\"; }
|
||
get_tool_cmd() { eval echo \"\$TOOL_CMDS_$1\"; }
|
||
get_tool_pkg() { eval echo \"\$TOOL_PKGS_$1\"; }
|
||
get_tool_url() { eval echo \"\$TOOL_URLS_$1\"; }
|
||
|
||
# ========== 帮助信息 ==========
|
||
show_help() {
|
||
cat << 'EOF'
|
||
XCodeCLI Setup Launcher (macOS / Linux)
|
||
一站式安装和配置 Claude Code, Gemini CLI, Codex
|
||
|
||
Usage: ./setup.sh [OPTIONS]
|
||
|
||
Options:
|
||
--key <KEY> 预设 API 密钥(必填)
|
||
--help 显示此帮助信息
|
||
|
||
一行命令快速使用:
|
||
API_KEY='YOUR_API_KEY' bash -c "$(curl -fsSL https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/setup.sh)"
|
||
EOF
|
||
exit 0
|
||
}
|
||
|
||
# ========== 命令检测 ==========
|
||
command_exists() {
|
||
command -v "$1" &> /dev/null
|
||
}
|
||
|
||
# ========== 获取包管理器 ==========
|
||
get_package_manager() {
|
||
if command_exists node; then
|
||
local node_version=$(node --version 2>/dev/null | sed 's/v//')
|
||
info "检测到 Node.js v$node_version"
|
||
echo "npm"
|
||
return 0
|
||
fi
|
||
|
||
if command_exists bun; then
|
||
local bun_version=$(bun --version 2>/dev/null)
|
||
info "检测到 Bun v$bun_version"
|
||
echo "bun"
|
||
return 0
|
||
fi
|
||
|
||
return 1
|
||
}
|
||
|
||
# ========== 安装 Bun ==========
|
||
install_bun() {
|
||
echo ""
|
||
warning "未检测到 Node.js 或 Bun"
|
||
info "推荐安装 Bun(轻量级 JavaScript 运行时)"
|
||
echo ""
|
||
echo -e " 安装命令: ${CYAN}curl -fsSL https://bun.sh/install | bash${NC}"
|
||
echo ""
|
||
|
||
read -p "是否立即安装 Bun? (Y/n) " -n 1 -r
|
||
echo ""
|
||
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
||
return 1
|
||
fi
|
||
|
||
info "正在安装 Bun..."
|
||
if curl -fsSL https://bun.sh/install | bash; then
|
||
# 刷新 PATH
|
||
export BUN_INSTALL="$HOME/.bun"
|
||
export PATH="$BUN_INSTALL/bin:$PATH"
|
||
|
||
if command_exists bun; then
|
||
success "Bun 安装成功!"
|
||
return 0
|
||
else
|
||
warning "Bun 可能已安装,但需要重新打开终端才能生效"
|
||
info "请重新打开终端后再运行此脚本"
|
||
return 1
|
||
fi
|
||
else
|
||
error "Bun 安装失败"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# ========== 安装工具 ==========
|
||
install_tool() {
|
||
local tool_num=$1
|
||
local pm=$2
|
||
local tool_name=$(get_tool_name "$tool_num")
|
||
local tool_pkg=$(get_tool_pkg "$tool_num")
|
||
|
||
info "安装 $tool_name..."
|
||
local install_cmd=""
|
||
if [[ "$pm" == "npm" ]]; then
|
||
install_cmd="npm install -g $tool_pkg"
|
||
else
|
||
install_cmd="bun add -g $tool_pkg"
|
||
fi
|
||
|
||
echo -e " 执行: ${CYAN}$install_cmd${NC}"
|
||
|
||
if eval "$install_cmd"; then
|
||
hash -r 2>/dev/null || true
|
||
success "$tool_name 安装成功!"
|
||
return 0
|
||
else
|
||
error "$tool_name 安装失败"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# ========== 配置工具 ==========
|
||
configure_tool() {
|
||
local tool_num=$1
|
||
local api_key=$2
|
||
local tool_name=$(get_tool_name "$tool_num")
|
||
local setup_url=$(get_tool_url "$tool_num")
|
||
|
||
info "配置 $tool_name..."
|
||
|
||
if API_KEY="$api_key" bash -c "$(curl -fsSL "$setup_url")"; then
|
||
success "$tool_name 配置完成!"
|
||
return 0
|
||
else
|
||
error "$tool_name 配置失败"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# ========== 显示状态 ==========
|
||
show_status() {
|
||
echo ""
|
||
echo -e "${CYAN}========================================${NC}"
|
||
echo -e "${CYAN} XCodeCLI Setup Launcher${NC}"
|
||
echo -e "${CYAN}========================================${NC}"
|
||
echo ""
|
||
echo -e "获取 API 密钥: ${CYAN}https://api2.xcodecli.com/console/token${NC}"
|
||
echo -e "步骤: 添加令牌 → 输入令牌名称 → 提交"
|
||
echo ""
|
||
echo -e "${YELLOW}工具安装状态:${NC}"
|
||
echo ""
|
||
|
||
for i in 1 2 3; do
|
||
local tool_name=$(get_tool_name "$i")
|
||
local tool_cmd=$(get_tool_cmd "$i")
|
||
local status
|
||
local color
|
||
|
||
if command_exists "$tool_cmd"; then
|
||
status="[已安装]"
|
||
color="${GREEN}"
|
||
else
|
||
status="[未安装]"
|
||
color="${RED}"
|
||
fi
|
||
|
||
printf " [%d] %-12s %b%s%b\n" "$i" "$tool_name" "$color" "$status" "$NC"
|
||
done
|
||
echo ""
|
||
echo -e " [${CYAN}a${NC}] 配置全部工具"
|
||
echo -e " [${CYAN}0${NC}] 退出"
|
||
echo ""
|
||
}
|
||
|
||
# ========== 主函数 ==========
|
||
main() {
|
||
local api_key="${API_KEY:-}"
|
||
|
||
# 解析参数
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
--key)
|
||
api_key="$2"
|
||
shift 2
|
||
;;
|
||
--help|-h)
|
||
show_help
|
||
;;
|
||
*)
|
||
shift
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# 显示状态
|
||
show_status
|
||
|
||
# 选择要配置的工具
|
||
echo -e "${YELLOW}请选择要配置的工具 (1/2/3/a/0):${NC}"
|
||
read -r choice
|
||
|
||
# 退出
|
||
if [[ "$choice" == "0" ]]; then
|
||
info "再见!"
|
||
exit 0
|
||
fi
|
||
|
||
# 验证选择
|
||
local tools_to_configure=""
|
||
if [[ "$choice" == "a" || "$choice" == "A" ]]; then
|
||
tools_to_configure="1 2 3"
|
||
elif [[ "$choice" =~ ^[1-3]$ ]]; then
|
||
tools_to_configure="$choice"
|
||
else
|
||
error "无效的选择"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查 API Key
|
||
if [[ -z "$api_key" ]]; then
|
||
echo ""
|
||
echo -e "${YELLOW}请输入 API 密钥:${NC}"
|
||
read -r api_key
|
||
if [[ -z "$api_key" ]]; then
|
||
error "API 密钥不能为空"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
info "API 密钥: ${api_key:0:8}..."
|
||
echo ""
|
||
|
||
# 获取包管理器
|
||
local pm=$(get_package_manager)
|
||
if [[ -z "$pm" ]]; then
|
||
if ! install_bun; then
|
||
exit 1
|
||
fi
|
||
pm=$(get_package_manager)
|
||
if [[ -z "$pm" ]]; then
|
||
error "仍未检测到可用的包管理器"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
echo ""
|
||
echo -e "${CYAN}========================================${NC}"
|
||
echo -e "${CYAN} 开始安装和配置工具${NC}"
|
||
echo -e "${CYAN}========================================${NC}"
|
||
echo ""
|
||
|
||
local failed=0
|
||
local total=$(echo $tools_to_configure | wc -w | tr -d ' ')
|
||
local current=0
|
||
|
||
# 安装和配置选中的工具
|
||
for i in $tools_to_configure; do
|
||
current=$((current + 1))
|
||
local tool_name=$(get_tool_name "$i")
|
||
local tool_cmd=$(get_tool_cmd "$i")
|
||
|
||
echo ""
|
||
echo -e "${YELLOW}>>> [$current/$total] $tool_name${NC}"
|
||
echo ""
|
||
|
||
# 检测是否已安装
|
||
if ! command_exists "$tool_cmd"; then
|
||
if ! install_tool "$i" "$pm"; then
|
||
failed=$((failed + 1))
|
||
continue
|
||
fi
|
||
else
|
||
info "$tool_name 已安装,跳过安装步骤"
|
||
fi
|
||
|
||
# 配置工具
|
||
if ! configure_tool "$i" "$api_key"; then
|
||
failed=$((failed + 1))
|
||
fi
|
||
done
|
||
|
||
# 显示结果
|
||
echo ""
|
||
echo -e "${CYAN}========================================${NC}"
|
||
echo -e "${CYAN} 配置完成${NC}"
|
||
echo -e "${CYAN}========================================${NC}"
|
||
echo ""
|
||
|
||
if [[ $failed -eq 0 ]]; then
|
||
success "所有选中的工具配置成功!"
|
||
else
|
||
warning "有 $failed 个工具配置失败"
|
||
fi
|
||
}
|
||
|
||
main "$@"
|