diff --git a/cmd/lazy-update-manager/main.go b/cmd/lazy-update-manager/main.go index 5d10cde..1f45fea 100644 --- a/cmd/lazy-update-manager/main.go +++ b/cmd/lazy-update-manager/main.go @@ -288,20 +288,64 @@ func defaultConfigPath() string { } func tryElectronApp() error { - // Try to find and launch the Electron app - cmd := exec.Command("npm", "start") + projectDir := electronProjectDir() + if projectDir == "" { + return errors.New("LazyUpdateManager project directory not found – set LAZY_UPDATE_MANAGER_DIR or run from the project folder") + } + + electronBin := filepath.Join(projectDir, "node_modules", ".bin", "electron") + if _, err := os.Stat(electronBin); err != nil { + electronBin = "electron" + } + + cmd := exec.Command(electronBin, projectDir) + cmd.Dir = projectDir cmd.Stdout = nil cmd.Stderr = nil cmd.Stdin = nil - if err := cmd.Run(); err != nil { - // Try electron directly - cmd = exec.Command("electron", ".") - cmd.Stdout = nil - cmd.Stderr = nil - cmd.Stdin = nil - return cmd.Run() + return cmd.Run() +} + +func electronProjectDir() string { + if d := os.Getenv("LAZY_UPDATE_MANAGER_DIR"); d != "" { + if hasElectronMain(d) { + return d + } } - return nil + + if d, err := os.Getwd(); err == nil && hasElectronMain(d) { + return d + } + + exe, err := os.Executable() + if err != nil { + return "" + } + exeDir := filepath.Dir(exe) + + // binary in ~/Projekte/LazyUpdateManager/bin/ + if p := filepath.Dir(exeDir); hasElectronMain(p) { + return p + } + + // binary in ~/.local/bin/, project is at configured location + if p := filepath.Join(exeDir, "..", "Projekte", "LazyUpdateManager"); hasElectronMain(p) { + return p + } + + // relative to $HOME + if home, err := os.UserHomeDir(); err == nil { + if p := filepath.Join(home, "Projekte", "LazyUpdateManager"); hasElectronMain(p) { + return p + } + } + + return "" +} + +func hasElectronMain(dir string) bool { + info, err := os.Stat(filepath.Join(dir, "electron", "main.cjs")) + return err == nil && !info.IsDir() } func usage() { diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..2ba796d --- /dev/null +++ b/install.sh @@ -0,0 +1,246 @@ +#!/usr/bin/env bash +set -euo pipefail + +BINARY="lazy-update-manager" +PREFIX="${PREFIX:-$HOME/.local}" +PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" +VERSION="$(git describe --tags --always --dirty 2>/dev/null || echo dev)" +BUILD_TIME="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" + +RED='\033[0;31m' +GREEN='\033[0;32m' +CYAN='\033[0;36m' +NC='\033[0m' + +info() { echo -e "${CYAN}::${NC} $*"; } +ok() { echo -e "${GREEN} ->${NC} $*"; } +error() { echo -e "${RED} ->${NC} $*" >&2; } + +cleanup() { + if [ -n "${TMP_CONFIG:-}" ]; then + rm -f "$TMP_CONFIG" + fi +} +trap cleanup EXIT + +check_deps() { + local missing=false + for cmd in go node npm; do + if ! command -v "$cmd" &>/dev/null; then + error "$cmd ist nicht installiert" + missing=true + fi + done + if [ "$missing" = true ]; then + error "Installiere die fehlenden Abhängigkeiten und versuche es erneut." + exit 1 + fi + ok "Alle Abhängigkeiten vorhanden (go $(go version | grep -oP '\d+\.\d+' | head -1), node $(node -v), npm $(npm -v))" +} + +build_backend() { + info "Baue Go-Backend (Version: $VERSION, Build: $BUILD_TIME)" + mkdir -p "$PROJECT_DIR/bin" + go build -buildvcs=false \ + -ldflags "-X 'lazy-update-manager/internal/version.Version=$VERSION' -X 'lazy-update-manager/internal/version.BuildTime=$BUILD_TIME'" \ + -o "$PROJECT_DIR/bin/$BINARY" "$PROJECT_DIR/cmd/lazy-update-manager" + ok "Backend gebaut: bin/$BINARY" +} + +install_npm() { + info "Installiere npm-Abhängigkeiten (Electron)" + npm install --prefix "$PROJECT_DIR" + + if [ ! -f "$PROJECT_DIR/node_modules/electron/path.txt" ]; then + info "Electron-Binary fehlt – versuche manuelle Installation" + ELECTRON_CACHE="$HOME/.cache/electron" + ELECTRON_DIR="$PROJECT_DIR/node_modules/electron" + if [ -d "$ELECTRON_CACHE" ]; then + CACHE_DIR=$(ls -t "$ELECTRON_CACHE" | head -1) + ZIP_FILE=$(ls "$ELECTRON_CACHE/$CACHE_DIR"/*.zip 2>/dev/null | head -1) + if [ -n "$ZIP_FILE" ] && [ -f "$ZIP_FILE" ]; then + rm -rf "$ELECTRON_DIR/dist" + mkdir -p "$ELECTRON_DIR/dist" + unzip -q "$ZIP_FILE" -d "$ELECTRON_DIR/dist/" + printf 'electron' > "$ELECTRON_DIR/path.txt" + chmod +x "$ELECTRON_DIR/dist/electron" + ok "Electron-Binary manuell installiert (${ZIP_FILE##*/})" + fi + fi + if [ ! -f "$ELECTRON_DIR/path.txt" ]; then + error "Electron-Binary konnte nicht installiert werden" + error "Versuche: rm -rf node_modules && npm install" + exit 1 + fi + fi + + ok "npm-Abhängigkeiten installiert" +} + +install_binary() { + info "Installiere Binary nach $PREFIX/bin" + mkdir -p "$PREFIX/bin" + command install -Dm755 "$PROJECT_DIR/bin/$BINARY" "$PREFIX/bin/$BINARY" + ok "Binary installiert: $PREFIX/bin/$BINARY" +} + +install_electron_launcher() { + info "Installiere Electron-Launcher nach $PREFIX/bin" + mkdir -p "$PREFIX/bin" + cat > "$PREFIX/bin/lazy-update-manager-electron" <<'LAUNCHER' +#!/bin/sh +export LAZY_UPDATE_MANAGER_DIR="__PROJECT_DIR__" +cd "$LAZY_UPDATE_MANAGER_DIR" || exit 1 +exec ./node_modules/.bin/electron . +LAUNCHER + sed -i "s|__PROJECT_DIR__|$PROJECT_DIR|g" "$PREFIX/bin/lazy-update-manager-electron" + chmod +x "$PREFIX/bin/lazy-update-manager-electron" + ok "Electron-Launcher installiert: $PREFIX/bin/lazy-update-manager-electron" +} + +install_desktop_file() { + info "Installiere Desktop-Eintrag" + mkdir -p "$PREFIX/share/applications" + cat > "$PREFIX/share/applications/lazy-update-manager.desktop" </dev/null || { + # fallback: jq or sed + if command -v jq &>/dev/null; then + jq '.prefer_electron = true' "$CONFIG_FILE" > "$tmp" && cp "$tmp" "$CONFIG_FILE" + else + info "Konnte Config nicht automatisch aktualisieren, setze prefer_electron manuell" + fi + } + if [ -f "$tmp" ]; then + cp "$tmp" "$CONFIG_FILE" && rm -f "$tmp" + fi + else + cat > "$CONFIG_FILE" </dev/null; then + info "Aktiviere Timer" + systemctl --user daemon-reload 2>/dev/null || true + systemctl --user enable --now lazy-update-manager.timer 2>/dev/null || true + ok "Timer aktiviert: systemctl --user status lazy-update-manager.timer" + else + info "systemctl nicht verfügbar. Manuell aktivieren:" + info " systemctl --user daemon-reload" + info " systemctl --user enable --now lazy-update-manager.timer" + fi +} + +build_electron_dist() { + info "Baue Electron-Desktop-Pakete" + npm run --prefix "$PROJECT_DIR" dist + ok "Electron-Pakete gebaut: dist/" +} + +run_install() { + echo -e "${CYAN}========================================${NC}" + echo -e "${CYAN} LazyUpdateManager Installer${NC}" + echo -e "${CYAN}========================================${NC}" + echo "" + + check_deps + echo "" + install_npm + echo "" + build_backend + echo "" + install_binary + echo "" + install_electron_launcher + echo "" + install_desktop_file + echo "" + enable_electron_config + echo "" + install_systemd + echo "" + echo -e "${GREEN}========================================${NC}" + echo -e "${GREEN} Installation abgeschlossen!${NC}" + echo -e "${GREEN}========================================${NC}" + echo "" + echo "Desktop-App starten: $PREFIX/bin/lazy-update-manager-electron" + echo "Web-Oberfläche starten: $PREFIX/bin/$BINARY gui web" + echo "Updates prüfen: $PREFIX/bin/$BINARY check" + echo "Status anzeigen: $PREFIX/bin/$BINARY status" + echo "" +} + +build_electron() { + check_deps + install_npm + build_backend + build_electron_dist + echo "" + echo -e "${GREEN}Electron-Pakete erstellt in: $PROJECT_DIR/dist/${NC}" +} + +usage() { + cat <