From 77cde5d012d67e26af2629d39991af6b5f175633 Mon Sep 17 00:00:00 2001 From: delta-cloud-208e Date: Sun, 8 Mar 2026 10:40:39 +0000 Subject: [PATCH] fix(codex): rewrite install script as self-contained for curl pipe usage - Script no longer depends on local update-codex.sh or SCRIPT_DIR files - Downloads Codex binary directly from GitHub releases - Downloads patcher + config from gitea repo - Sets env vars system-wide (/etc/environment + /etc/profile.d/) - Proper error handling with set -euo pipefail Co-Authored-By: Claude Opus 4.6 --- codex/ucodex_install.sh | 143 ++++++++++++++++++++++++++++++---------- 1 file changed, 107 insertions(+), 36 deletions(-) diff --git a/codex/ucodex_install.sh b/codex/ucodex_install.sh index 396d691..aff1c7f 100755 --- a/codex/ucodex_install.sh +++ b/codex/ucodex_install.sh @@ -1,11 +1,16 @@ -#!/bin/bash +#!/usr/bin/env bash # UnlimitedCoding — Codex CLI Installer # Downloads Codex binary from GitHub + applies config patches # # Usage: -# curl -fsSL https://git.sensey24.ru/.../ucodex_install.sh | sudo bash +# curl -fsSL -H "Authorization: token TOKEN" \ +# https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/codex/ucodex_install.sh \ +# -o /tmp/ucodex_install.sh && sudo bash /tmp/ucodex_install.sh +set -euo pipefail -set -e +GITEA_TOKEN="${GITEA_TOKEN:-cadffcb0a6a3be728ac1ff619bb40c86588f6837}" +REPO_RAW="https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/codex" +GITHUB_API="https://api.github.com/repos/openai/codex/releases/latest" RED='\033[0;31m' GREEN='\033[0;32m' @@ -14,54 +19,111 @@ CYAN='\033[0;36m' BOLD='\033[1m' NC='\033[0m' -echo -e "${BOLD}=== UnlimitedCoding — Codex CLI Installer ===${NC}" +log() { echo -e "${GREEN}[+]${NC} $*"; } +err() { echo -e "${RED}[!]${NC} $*" >&2; } +info() { echo -e "${CYAN}[i]${NC} $*"; } +warn() { echo -e "${YELLOW}[~]${NC} $*"; } -# Check prerequisites -for cmd in python3 curl; do +echo -e "${BOLD}" +echo " +--------------------------------------+" +echo " | Codex CLI — Installer |" +echo " +--------------------------------------+" +echo -e "${NC}" + +# ---- Check prerequisites ---- + +for cmd in python3 curl tar; do if ! command -v "$cmd" &>/dev/null; then - echo -e "${RED}Error: $cmd is required but not found${NC}" + err "$cmd is required but not found" exit 1 fi done -# Check Python version (need 3.11+ for tomllib) PY_VER=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") PY_MAJOR=$(echo "$PY_VER" | cut -d. -f1) PY_MINOR=$(echo "$PY_VER" | cut -d. -f2) if [ "$PY_MAJOR" -lt 3 ] || ([ "$PY_MAJOR" -eq 3 ] && [ "$PY_MINOR" -lt 11 ]); then - echo -e "${RED}Error: Python 3.11+ required (found $PY_VER)${NC}" + err "Python 3.11+ required (found $PY_VER)" exit 1 fi +log "Python3 $PY_VER" -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# ---- Step 1: Install Codex binary from GitHub ---- -# Step 1: Install/update Codex binary echo -e "\n${BOLD}Step 1: Installing Codex CLI binary...${NC}" -if [ -f "$SCRIPT_DIR/update-codex.sh" ]; then - bash "$SCRIPT_DIR/update-codex.sh" + +ARCH=$(uname -m) +case "$ARCH" in + x86_64) BINARY_SUFFIX="x86_64-unknown-linux-musl" ;; + aarch64|arm64) BINARY_SUFFIX="aarch64-unknown-linux-musl" ;; + *) err "Unsupported architecture: $ARCH"; exit 1 ;; +esac + +LATEST_VER=$(curl -s "$GITHUB_API" | grep -oP '"tag_name":\s*"rust-v\K[0-9]+\.[0-9]+\.[0-9]+' | head -1) +if [ -z "$LATEST_VER" ]; then + err "Could not fetch latest version from GitHub" + exit 1 +fi +info "Latest version: $LATEST_VER ($BINARY_SUFFIX)" + +OLD_VER="not installed" +if command -v codex &>/dev/null; then + OLD_VER=$(codex --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown") + info "Current version: $OLD_VER" +fi + +if [ "$OLD_VER" = "$LATEST_VER" ]; then + log "Already up to date ($LATEST_VER)" else - echo -e "${RED}update-codex.sh not found${NC}" - exit 1 + DOWNLOAD_URL="https://github.com/openai/codex/releases/download/rust-v${LATEST_VER}/codex-${BINARY_SUFFIX}.tar.gz" + TEMP_BIN=$(mktemp -d) + + info "Downloading codex v${LATEST_VER}..." + curl -L -# -o "$TEMP_BIN/codex.tar.gz" "$DOWNLOAD_URL" + tar -xzf "$TEMP_BIN/codex.tar.gz" -C "$TEMP_BIN" + + BINARY_FILE=$(find "$TEMP_BIN" -maxdepth 1 -name 'codex*' -type f ! -name '*.gz' | head -1) + if [ -z "$BINARY_FILE" ]; then + err "Binary not found in archive" + rm -rf "$TEMP_BIN" + exit 1 + fi + + pkill -9 -x "codex" 2>/dev/null || true + CODEX_PATH=$(which codex 2>/dev/null || echo "/usr/local/bin/codex") + chmod +x "$BINARY_FILE" + mv -f "$BINARY_FILE" "$CODEX_PATH" + rm -rf "$TEMP_BIN" + hash -r 2>/dev/null || true + + NEW_VER=$(codex --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown") + log "Binary installed: $OLD_VER → $NEW_VER" fi -# Step 2: Apply config patches +# ---- Step 2: Download and apply patches ---- + echo -e "\n${BOLD}Step 2: Applying config patches...${NC}" -if [ ! -f "$SCRIPT_DIR/codex_config.json" ]; then - echo -e "${YELLOW}codex_config.json not found, copying example...${NC}" - cp "$SCRIPT_DIR/codex_config.example.json" "$SCRIPT_DIR/codex_config.json" - echo -e "${YELLOW}Edit codex_config.json with your API endpoint and key, then re-run.${NC}" - exit 1 -fi -python3 "$SCRIPT_DIR/codex_patcher.py" --apply --config "$SCRIPT_DIR/codex_config.json" +INSTALL_DIR=$(mktemp -d) +cleanup() { rm -rf "$INSTALL_DIR" 2>/dev/null || true; } +trap cleanup EXIT + +info "Downloading patcher..." +curl -fsSL -H "Authorization: token ${GITEA_TOKEN}" "$REPO_RAW/codex_patcher.py" -o "$INSTALL_DIR/codex_patcher.py" +curl -fsSL -H "Authorization: token ${GITEA_TOKEN}" "$REPO_RAW/codex_config.json" -o "$INSTALL_DIR/codex_config.json" + +info "Applying patches..." +python3 "$INSTALL_DIR/codex_patcher.py" --apply --config "$INSTALL_DIR/codex_config.json" +log "Patches applied" + +# ---- Step 3: Set env vars system-wide (all users, all sessions) ---- -# Step 3: Set env vars system-wide (all users, all sessions) echo -e "\n${BOLD}Step 3: Setting environment variables...${NC}" -API_KEY=$(python3 -c "import json; print(json.load(open('$SCRIPT_DIR/codex_config.json'))['api_key'])") -BASE_URL=$(python3 -c "import json; print(json.load(open('$SCRIPT_DIR/codex_config.json'))['base_url'])") +API_KEY=$(python3 -c "import json; print(json.load(open('$INSTALL_DIR/codex_config.json'))['api_key'])") +BASE_URL=$(python3 -c "import json; print(json.load(open('$INSTALL_DIR/codex_config.json'))['base_url'])") -# Write to /etc/environment (system-wide, all users) +# Write to /etc/environment (all users, all sessions including cron) ETC_ENV="/etc/environment" for kv in "OPENAI_API_KEY=\"$API_KEY\"" "OPENAI_BASE_URL=\"${BASE_URL}/v1\""; do KEY="${kv%%=*}" @@ -71,25 +133,34 @@ for kv in "OPENAI_API_KEY=\"$API_KEY\"" "OPENAI_BASE_URL=\"${BASE_URL}/v1\""; do echo "$kv" >> "$ETC_ENV" fi done -echo -e " ${GREEN}Env vars written to $ETC_ENV (all users)${NC}" +log "Env vars written to $ETC_ENV (all users)" -# Also write to /etc/profile.d/ so vars are exported in login shells +# Write to /etc/profile.d/ for export in login shells cat > /etc/profile.d/codex-env.sh << ENVEOF export OPENAI_API_KEY="$API_KEY" export OPENAI_BASE_URL="${BASE_URL}/v1" ENVEOF chmod 644 /etc/profile.d/codex-env.sh -echo -e " ${GREEN}Export script created: /etc/profile.d/codex-env.sh${NC}" +log "Export script created: /etc/profile.d/codex-env.sh" -# Export for current session too +# Export for current session export OPENAI_API_KEY="$API_KEY" export OPENAI_BASE_URL="${BASE_URL}/v1" -# Step 4: Validate -echo -e "\n${BOLD}Step 4: Validating...${NC}" -python3 "$SCRIPT_DIR/update_codex_patcher.py" --validate +# ---- Step 4: Verify ---- -echo -e "\n${GREEN}=== Installation complete! ===${NC}" +echo -e "\n${BOLD}Step 4: Verifying...${NC}" + +if command -v codex &>/dev/null; then + VER=$(codex --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown") + log "Codex CLI v$VER" +else + err "codex binary not found in PATH" + exit 1 +fi + +echo "" +echo -e "${GREEN}${BOLD}=== Installation complete! ===${NC}" echo -e "Run: ${CYAN}codex${NC} to start" -echo -e "${YELLOW}Note: Env vars are set system-wide. New shells will pick them up automatically.${NC}" +echo -e "${YELLOW}Note: Env vars are set system-wide. New shells pick them up automatically.${NC}" echo -e "${YELLOW}For current shell: source /etc/profile.d/codex-env.sh${NC}"