From 21808ddce02eeae6f98af418dbc5d989e3eb94ba Mon Sep 17 00:00:00 2001 From: thibaud-lclr Date: Wed, 15 Apr 2026 10:38:58 +0200 Subject: [PATCH] fix(install): keep release-based install in TUI wizard --- install.sh | 156 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 138 insertions(+), 18 deletions(-) diff --git a/install.sh b/install.sh index 11eab47..dd2d83a 100755 --- a/install.sh +++ b/install.sh @@ -2,9 +2,11 @@ set -euo pipefail BINARY_NAME="email-mcp" -MODULE_PATH="email-mcp" DEFAULT_PROFILE="default" PROFILE_ENV="EMAIL_MCP_PROFILE" +RELEASE_BASE_URL="https://gitea.lclr.dev" +RELEASE_REPOSITORY="AI/email-mcp" +INSTALLED_BINARY_PATH="" if [ -t 2 ] && [ -z "${NO_COLOR:-}" ]; then C_RESET="$(printf '\033[0m')" @@ -105,6 +107,11 @@ go_bin_dir() { } resolve_binary_path() { + if [ -n "$INSTALLED_BINARY_PATH" ] && [ -x "$INSTALLED_BINARY_PATH" ]; then + printf "%s\n" "$INSTALLED_BINARY_PATH" + return + fi + if command -v "$BINARY_NAME" >/dev/null 2>&1; then command -v "$BINARY_NAME" return @@ -132,13 +139,134 @@ ensure_cli() { exit 1 } +detect_os() { + case "$(uname -s | tr '[:upper:]' '[:lower:]')" in + linux) printf "linux" ;; + darwin) printf "darwin" ;; + *) + ui_error "OS non supporte: $(uname -s)" + exit 1 + ;; + esac +} + +detect_arch() { + case "$(uname -m)" in + x86_64|amd64) printf "amd64" ;; + aarch64|arm64) printf "arm64" ;; + *) + ui_error "Architecture non supportee: $(uname -m)" + exit 1 + ;; + esac +} + +release_api_url() { + printf "%s/api/v1/repos/%s/releases/latest\n" "${RELEASE_BASE_URL%/}" "$RELEASE_REPOSITORY" +} + +extract_asset_url() { + local json="$1" + local asset_name="$2" + + printf "%s\n" "$json" \ + | grep -o '"browser_download_url":"[^"]*"' \ + | sed 's/"browser_download_url":"//;s/"$//' \ + | sed 's#\\/#/#g' \ + | grep "/${asset_name}$" \ + | head -n 1 +} + +verify_checksum() { + local binary_path="$1" + local checksum_path="$2" + + if command -v sha256sum >/dev/null 2>&1; then + ( cd "$(dirname "$binary_path")" && sha256sum -c "$(basename "$checksum_path")" ) + return + fi + + if command -v shasum >/dev/null 2>&1; then + local expected + local actual + expected="$(awk '{print $1}' "$checksum_path")" + actual="$(shasum -a 256 "$binary_path" | awk '{print $1}')" + if [ "$expected" != "$actual" ]; then + ui_error "Checksum invalide pour $binary_path" + exit 1 + fi + return + fi + + ui_warn "Aucun utilitaire checksum trouve (sha256sum/shasum), verification ignoree." +} + +download_latest_release_binary() { + if ! command -v curl >/dev/null 2>&1; then + ui_error "curl est requis pour telecharger la release." + exit 1 + fi + + local os_name + local arch_name + local ext="" + os_name="$(detect_os)" + arch_name="$(detect_arch)" + if [ "$os_name" = "windows" ]; then + ext=".exe" + fi + + local asset_name + local checksum_name + asset_name="${BINARY_NAME}-${os_name}-${arch_name}${ext}" + checksum_name="${asset_name}.sha256" + + ui_info "Recuperation de la derniere release..." + local release_json + release_json="$(curl -fsSL "$(release_api_url)")" + + local asset_url + asset_url="$(extract_asset_url "$release_json" "$asset_name")" + if [ -z "$asset_url" ]; then + ui_error "Asset introuvable dans la derniere release: $asset_name" + exit 1 + fi + + local checksum_url + checksum_url="$(extract_asset_url "$release_json" "$checksum_name" || true)" + + local tmp_dir + tmp_dir="$(mktemp -d)" + trap 'rm -rf "$tmp_dir"' EXIT INT TERM + + curl -fsSL "$asset_url" -o "$tmp_dir/$asset_name" + chmod +x "$tmp_dir/$asset_name" + + if [ -n "$checksum_url" ]; then + curl -fsSL "$checksum_url" -o "$tmp_dir/$checksum_name" + verify_checksum "$tmp_dir/$asset_name" "$tmp_dir/$checksum_name" + fi + + local target_dir + target_dir="$(prompt "Repertoire d'installation" "$HOME/.local/bin")" + mkdir -p "$target_dir" + install -m 0755 "$tmp_dir/$asset_name" "$target_dir/$BINARY_NAME" + INSTALLED_BINARY_PATH="$target_dir/$BINARY_NAME" + + ui_success "Binaire installe: $INSTALLED_BINARY_PATH" + ui_info "Ajoute ce dossier au PATH si necessaire." +} + install_binary() { if command -v "$BINARY_NAME" >/dev/null 2>&1; then - ui_success "Binaire detecte: $(command -v "$BINARY_NAME")" + INSTALLED_BINARY_PATH="$(command -v "$BINARY_NAME")" + ui_success "Binaire detecte: $INSTALLED_BINARY_PATH" local reinstall - reinstall="$(prompt "Reinstaller via go install ? (y/N)" "N")" + reinstall="$(prompt "Forcer une reinstall depuis la derniere release ? (y/N)" "N")" case "$reinstall" in y|Y|yes|YES) + download_latest_release_binary + return ;; *) return @@ -146,20 +274,7 @@ install_binary() { esac fi - if ! command -v go >/dev/null 2>&1; then - ui_error "Go n'est pas installe. Installe Go ou choisis une configuration manuelle." - exit 1 - fi - - ui_info "Installation du binaire via go install..." - go install "${MODULE_PATH}/cmd/${BINARY_NAME}@latest" - - local bin_dir - bin_dir="$(go_bin_dir)" - if [ -n "$bin_dir" ]; then - ui_success "Binaire installe dans $bin_dir" - ui_info "Ajoute ce dossier au PATH si necessaire." - fi + download_latest_release_binary } run_setup_wizard() { @@ -170,6 +285,11 @@ run_setup_wizard() { local binary_path binary_path="$(resolve_binary_path)" + if [ ! -x "$binary_path" ]; then + ui_error "Binaire introuvable/executable: $binary_path" + exit 1 + fi + ui_info "Lancement de $BINARY_NAME setup" if [ -r /dev/tty ] && [ -w /dev/tty ]; then env "${PROFILE_ENV}=${profile}" "$binary_path" setup < /dev/tty > /dev/tty @@ -331,7 +451,7 @@ JSON print_header() { ui_line printf "%bMCP Install Wizard%b for %b%s%b\n" "$C_BOLD$C_MAGENTA" "$C_RESET" "$C_BOLD" "$BINARY_NAME" "$C_RESET" >&2 - printf "%bFramework module:%b %s\n" "$C_DIM" "$C_RESET" "$MODULE_PATH" >&2 + printf "%bRelease repo:%b %s\n" "$C_DIM" "$C_RESET" "$RELEASE_REPOSITORY" >&2 ui_line printf "Choisis une action:\n" >&2 printf " 1) Installer/mettre a jour le binaire + setup\n" >&2