#!/bin/sh set -eu APP_NAME="Lumide" APP_ID="io.sofluffy.lumide" REPO="SoFluffyOS/lumide" API_ROOT="https://api.github.com/repos/$REPO/releases" INSTALL_ROOT="${LUMIDE_INSTALL_DIR:-$HOME/.local/opt/lumide}" BIN_DIR="${LUMIDE_BIN_DIR:-$HOME/.local/bin}" XDG_DATA_HOME_DIR="${XDG_DATA_HOME:-$HOME/.local/share}" DESKTOP_DIR="$XDG_DATA_HOME_DIR/applications" ICON_DIR="$XDG_DATA_HOME_DIR/icons/hicolor/512x512/apps" VERSION="${LUMIDE_VERSION:-latest}" say() { printf '%s\n' "$1" } fail() { printf 'Error: %s\n' "$1" >&2 exit 1 } need_cmd() { command -v "$1" >/dev/null 2>&1 || fail "missing required command '$1'" } detect_arch() { case "$(uname -m)" in x86_64|amd64) printf 'x86_64' ;; aarch64|arm64) printf 'arm64' ;; *) fail "unsupported architecture '$(uname -m)'" ;; esac } need_cmd curl need_cmd mktemp need_cmd install need_cmd sed extract_asset_url() { sed -n 's/.*"browser_download_url":[[:space:]]*"\([^"]*\)".*/\1/p' | sed 's#\\/#/#g' } github_curl() { TOKEN="${GITHUB_TOKEN:-${LUMIDE_GITHUB_TOKEN:-}}" if [ -n "$TOKEN" ]; then curl -fsSL -H "User-Agent: Lumide-Installer" -H "Accept: application/vnd.github+json" -H "Authorization: Bearer $TOKEN" "$@" else curl -fsSL -H "User-Agent: Lumide-Installer" -H "Accept: application/vnd.github+json" "$@" fi } ARCH=$(detect_arch) if [ "$VERSION" = "latest" ]; then RELEASE_API_URL="$API_ROOT/latest" else RELEASE_API_URL="$API_ROOT/tags/$VERSION" fi TMP_DIR=$(mktemp -d) cleanup() { rm -rf "$TMP_DIR" } trap cleanup EXIT INT TERM say "Resolving Linux release asset for $ARCH" CURL_ERR_FILE="$TMP_DIR/curl_err.log" if ! RELEASE_JSON=$(github_curl "$RELEASE_API_URL" 2>"$CURL_ERR_FILE"); then if grep -q "403" "$CURL_ERR_FILE" 2>/dev/null; then fail "GitHub API returned 403 Forbidden. This usually happens if you hit GitHub API rate limits. Try setting GITHUB_TOKEN environment variable (e.g. GITHUB_TOKEN=your_token ./install.sh)." fi if [ -s "$CURL_ERR_FILE" ]; then fail "Failed to fetch release info from GitHub API ($RELEASE_API_URL): $(cat "$CURL_ERR_FILE")" else fail "Failed to fetch release info from GitHub API ($RELEASE_API_URL)." fi fi DOWNLOAD_URL=$( printf '%s' "$RELEASE_JSON" \ | tr ',' '\n' \ | extract_asset_url \ | grep "/Lumide-Linux-.*-$ARCH\.zip$" \ | head -n 1 \ || true ) if [ -z "$DOWNLOAD_URL" ]; then DOWNLOAD_URL=$( printf '%s' "$RELEASE_JSON" \ | tr ',' '\n' \ | extract_asset_url \ | grep "/Lumide-Linux-.*-$ARCH\.tar\.gz$" \ | head -n 1 \ || true ) fi [ -n "$DOWNLOAD_URL" ] || fail "no Linux release asset found for architecture '$ARCH' in GitHub release '$VERSION'" ASSET_NAME=$(basename "$DOWNLOAD_URL") say "Downloading $DOWNLOAD_URL" if ! curl -fL -H "User-Agent: Lumide-Installer" "$DOWNLOAD_URL" -o "$TMP_DIR/$ASSET_NAME"; then fail "Failed to download release asset from $DOWNLOAD_URL" fi say "Extracting archive" case "$ASSET_NAME" in *.zip) need_cmd unzip unzip -q "$TMP_DIR/$ASSET_NAME" -d "$TMP_DIR" ;; *.tar.gz) need_cmd tar tar -xzf "$TMP_DIR/$ASSET_NAME" -C "$TMP_DIR" ;; *) fail "unsupported archive format: $ASSET_NAME" ;; esac PACKAGE_DIR="$TMP_DIR/$APP_NAME" [ -x "$PACKAGE_DIR/$APP_NAME" ] || fail "archive does not contain $APP_NAME/$APP_NAME" [ -f "$PACKAGE_DIR/share/applications/$APP_ID.desktop" ] || fail "archive is missing desktop metadata" [ -f "$PACKAGE_DIR/share/icons/hicolor/512x512/apps/$APP_ID.png" ] || fail "archive is missing app icon" mkdir -p "$(dirname "$INSTALL_ROOT")" "$BIN_DIR" "$DESKTOP_DIR" "$ICON_DIR" rm -rf "$INSTALL_ROOT" mv "$PACKAGE_DIR" "$INSTALL_ROOT" ln -sfn "$INSTALL_ROOT/$APP_NAME" "$BIN_DIR/lumide" # Patch the desktop file with absolute paths # We use a temporary file to avoid issues with sed -i portability sed -e "s|^Exec=.*|Exec=$INSTALL_ROOT/$APP_NAME %F|g" \ -e "s|^Icon=.*|Icon=$ICON_DIR/$APP_ID.png|g" \ "$INSTALL_ROOT/share/applications/$APP_ID.desktop" > "$TMP_DIR/$APP_ID.desktop" install -m 0644 "$TMP_DIR/$APP_ID.desktop" "$DESKTOP_DIR/$APP_ID.desktop" install -m 0644 "$INSTALL_ROOT/share/icons/hicolor/512x512/apps/$APP_ID.png" "$ICON_DIR/$APP_ID.png" if command -v update-desktop-database >/dev/null 2>&1; then update-desktop-database "$DESKTOP_DIR" >/dev/null 2>&1 || true fi if command -v gtk-update-icon-cache >/dev/null 2>&1; then gtk-update-icon-cache "$XDG_DATA_HOME_DIR/icons/hicolor" >/dev/null 2>&1 || true fi say "Lumide installed to $INSTALL_ROOT" say "CLI symlink: $BIN_DIR/lumide" case ":$PATH:" in *":$BIN_DIR:"*) ;; *) say "Add $BIN_DIR to PATH to launch Lumide from the terminal." ;; esac