Ctrl K
ComunidadGuías…

install.sh

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash
set -euo pipefail

# Depsilo one-liner install script.
# Usage: curl -fsSL https://depsilo.com/install.sh | bash

REPO="depsilo/depsilo"
BIN="depsilo"
INSTALL_DIR="${DEPSILO_INSTALL_DIR:-/usr/local/bin}"
VERSION="${DEPSILO_VERSION:-latest}"

# --- helpers ---
RED='\033[0;31m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'

info()  { printf "${CYAN}→${NC} %s\n" "$*"; }
ok()    { printf "${GREEN}✓${NC} %s\n" "$*"; }
err()   { printf "${RED}✗${NC} %s\n" "$*" >&2; exit 1; }

DOWNLOAD_TOOL=""

select_downloader() {
    if command -v curl >/dev/null 2>&1; then
        DOWNLOAD_TOOL="curl"
    elif command -v wget >/dev/null 2>&1; then
        DOWNLOAD_TOOL="wget"
    else
        err "Neither curl nor wget found. Install one of them first."
    fi
}

fetch_stdout() {
    case "$DOWNLOAD_TOOL" in
        curl) curl -fsSL "$1" ;;
        wget) wget -qO- "$1" ;;
        *) err "Download tool was not initialized" ;;
    esac
}

download_file() {
    local url="$1"
    local destination="$2"
    case "$DOWNLOAD_TOOL" in
        curl) curl -fsSL "$url" -o "$destination" ;;
        wget) wget -q "$url" -O "$destination" ;;
        *) err "Download tool was not initialized" ;;
    esac
}

archive_binary_name() {
    if [ "$1" = "windows" ]; then
        printf '%s.exe\n' "$BIN"
    else
        printf '%s\n' "$BIN"
    fi
}

print_install_success() {
    local version="$1"
    local install_path="$2"

    ok "Depsilo ${version} installed"
    printf '\n  %s\n\n' "$install_path"
    printf "${BOLD}Get started:${NC}\n\n"
    printf '  depsilo serve\n\n'
    printf "${BOLD}Then open:${NC}\n\n"
    printf '  http://127.0.0.1:23333\n\n'
    printf "${BOLD}Docs:${NC}\n\n"
    printf '  https://github.com/depsilo/depsilo#quick-start\n'
}

verify_checksum() {
    local archive="$1"
    local checksum_file="$2"
    local checksum_line

    [ -s "$checksum_file" ] || err "Checksum file is missing or empty"
    checksum_line=$(awk -v archive="$archive" '
        NF >= 2 {
            name = $2
            sub(/^\*/, "", name)
            if (name == archive) {
                print $1 "  " archive
                exit
            }
        }
    ' "$checksum_file")
    [ -n "$checksum_line" ] || err "No checksum found for ${archive}"

    if command -v sha256sum >/dev/null 2>&1; then
        printf '%s\n' "$checksum_line" | sha256sum -c - >/dev/null 2>&1 \
            || err "Checksum verification failed for ${archive}"
    elif command -v shasum >/dev/null 2>&1; then
        printf '%s\n' "$checksum_line" | shasum -a 256 -c - >/dev/null 2>&1 \
            || err "Checksum verification failed for ${archive}"
    else
        err "Checksum verification requires sha256sum or shasum"
    fi
    info "Checksum verified"
}

# resolve_latest_version prints the newest release tag. It prefers the
# releases/latest redirect because the unauthenticated REST API allows only 60
# requests per hour per IP — shared NATs, CI runners, and offices exhaust that
# easily, and a rate-limited API must not break the documented one-liner. The
# API stays as a fallback for downloaders or networks where HEAD/redirects are
# unavailable.
resolve_latest_version() {
    local effective tag release_json
    if [ "$DOWNLOAD_TOOL" = "curl" ]; then
        effective=$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
            "https://github.com/${REPO}/releases/latest" 2>/dev/null || true)
        case "$effective" in
            */releases/tag/*)
                printf '%s\n' "${effective##*/}"
                return 0
                ;;
        esac
    fi
    release_json=$(fetch_stdout "https://api.github.com/repos/${REPO}/releases/latest") || return 1
    tag=$(printf '%s\n' "$release_json" \
        | sed -nE 's/.*"tag_name"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p' \
        | head -1)
    [ -n "$tag" ] || return 1
    printf '%s\n' "$tag"
}

# Keep the verifier sourceable for its shell regression tests without running
# downloads or installation as a side effect. Do not infer this from
# BASH_SOURCE: the documented `curl ... | bash` invocation has no script path.
if [[ "${DEPSILO_INSTALL_SOURCE_ONLY:-0}" == "1" ]]; then
    if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
        return 0
    fi
    exit 0
fi

# --- detect os/arch ---
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)

case "$ARCH" in
    x86_64|amd64)  ARCH="amd64" ;;
    aarch64|arm64) ARCH="arm64" ;;
    *)             err "Unsupported architecture: $ARCH" ;;
esac

case "$OS" in
    linux|darwin) ;;
    mingw*|msys*|cygwin*) OS="windows" ;;
    *) err "Unsupported OS: $OS. Only Linux, macOS, and Windows (Git Bash/WSL) are supported." ;;
esac

select_downloader

# --- fetch latest version ---
if [ "$VERSION" = "latest" ]; then
    info "Fetching latest release..."
    if ! VERSION=$(resolve_latest_version); then
        err "Could not fetch the latest release metadata"
    fi
    if [ -z "$VERSION" ]; then
        err "Could not determine latest version. Try setting DEPSILO_VERSION=vX.Y.Z"
    fi
fi

# Strip leading 'v' for archive name (goreleaser uses clean semver in filenames)
CLEAN_VERSION="${VERSION#v}"

# --- download ---
if [ "$OS" = "windows" ]; then
    ARCHIVE="depsilo_${CLEAN_VERSION}_${OS}_${ARCH}.zip"
else
    ARCHIVE="depsilo_${CLEAN_VERSION}_${OS}_${ARCH}.tar.gz"
fi
ARCHIVE_BIN=$(archive_binary_name "$OS")
INSTALL_BIN="$ARCHIVE_BIN"

URL="https://github.com/${REPO}/releases/download/${VERSION}/${ARCHIVE}"
CHECKSUM_URL="https://github.com/${REPO}/releases/download/${VERSION}/checksums.txt"

info "Downloading Depsilo ${VERSION} for ${OS}/${ARCH}..."
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT

cd "$TMPDIR"

download_file "$URL" "$ARCHIVE" || err "Download failed. Check if release ${VERSION} exists."
download_file "$CHECKSUM_URL" checksums.txt || err "Checksum download failed for ${VERSION}"

# --- verify checksum (fail closed) ---
verify_checksum "$ARCHIVE" checksums.txt

# --- install ---
if [ "$OS" = "windows" ]; then
    unzip -q "$ARCHIVE" || err "Failed to extract archive"
else
    tar xzf "$ARCHIVE" || err "Failed to extract archive"
fi

if [ ! -f "$ARCHIVE_BIN" ]; then
    # The archive may have the binary nested
    BIN_PATH=$(find . -name "$ARCHIVE_BIN" -type f -print -quit 2>/dev/null)
    [ -n "$BIN_PATH" ] || err "Binary not found in archive"
else
    BIN_PATH="./$ARCHIVE_BIN"
fi

chmod +x "$BIN_PATH" 2>/dev/null || true

# --- place binary ---
if [ "$INSTALL_DIR" = "/usr/local/bin" ] && [ ! -w "$INSTALL_DIR" ]; then
    info "Need sudo to install to $INSTALL_DIR"
    sudo mkdir -p "$INSTALL_DIR"
    sudo cp "$BIN_PATH" "$INSTALL_DIR/$INSTALL_BIN"
    sudo chmod +x "$INSTALL_DIR/$INSTALL_BIN"
else
    mkdir -p "$INSTALL_DIR"
    cp "$BIN_PATH" "$INSTALL_DIR/$INSTALL_BIN"
    chmod +x "$INSTALL_DIR/$INSTALL_BIN" 2>/dev/null || true
fi

print_install_success "$VERSION" "${INSTALL_DIR}/${INSTALL_BIN}"