🔒 Repository is read-only – file editing is disabled.

PaganLinux/ui.sh main

146 linii Raw ← Powrót
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
# =============================================================================
# ui.sh — Wspólny interfejs użytkownika dla buildera PaganOS
# =============================================================================
# Zapewnia:
#   • spinner + czas trwania podczas budowy pakietu  (tryb TTY)
#   • logi per-pakiet w $UI_LOG_DIR (zawsze)
#   • licznik postępu [N/TOTAL] i listę nieudanych pakietów
#   • czytelne podsumowanie na końcu budowy
# W trybie non-TTY (CI, pipe) zachowuje proste linie + pełny log per pakiet.
# =============================================================================

[[ -n "${UI_LOADED:-}" ]] && return 0
UI_LOADED=1

# ---- kolory (jeśli nie zdefiniowane przez skrypt źródłowy) ----
: "${RED:=\033[0;31m}" "${GREEN:=\033[0;32m}" "${YELLOW:=\033[1;33m}"
: "${BLUE:=\033[0;34m}" "${MAGENTA:=\033[0;35m}" "${CYAN:=\033[0;36m}"
: "${BOLD:=\033[1m}" "${DIM:=\033[2m}" "${NC:=\033[0m}"

# ---- konfiguracja ----
UI_TTY=0; [[ -t 1 ]] && UI_TTY=1
UI_START_EPOCH=$(date +%s)
UI_PKG_N=0
UI_PKG_TOTAL=0
UI_LOG_DIR="${UI_LOG_DIR:-/var/log/pagan-pkgs}"
UI_TAIL_LINES="${UI_TAIL_LINES:-15}"
UI_FAILED=()

SPIN=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')

ui_init() {
    mkdir -p "$UI_LOG_DIR" 2>/dev/null || true
}

ui_fmt_duration() {
    local s="${1:-0}" h m
    h=$((s / 3600)); m=$(((s % 3600) / 60)); s=$((s % 60))
    printf '%02d:%02d:%02d' "$h" "$m" "$s"
}

# Nadpisuje bieżącą linię statusu (tylko TTY)
_ui_status() {
    [[ $UI_TTY -ne 1 ]] && return 0
    printf '\r\033[K%s' "$*"
}

_ui_clear_status() {
    [[ $UI_TTY -ne 1 ]] && return 0
    printf '\r\033[K'
}

# Resetuje licznik postępu dla nowego rozdziału
ui_set_total() {
    UI_PKG_TOTAL="${1:-0}"
    UI_PKG_N=0
}

# Pokazuje ostatnie N linii logu pakietu (po błędzie)
_ui_tail() {
    local log="$1" n="${2:-15}"
    [[ -f "$log" ]] || return 0
    echo -e "  ${DIM}└─ Ostatnie linie z: ${log}${NC}"
    tail -n "$n" "$log" | sed 's/^/      /'
}

# Uruchamia komendę budowy z capture outputu do logu per-pakiet.
# Zwraca kod wyjścia; po sukcesie drukuje ✓, po błędzie ✗ + tail logu.
ui_build_eval() {
    local label="$1" log="$2" cmd="$3"
    local start_epoch rc el i
    start_epoch=$(date +%s)

    local counter
    if [[ $UI_PKG_TOTAL -gt 0 ]]; then
        counter="[${UI_PKG_N}/${UI_PKG_TOTAL}]"
    else
        counter="[#${UI_PKG_N}]"
    fi

    if [[ $UI_TTY -eq 1 ]]; then
        ( eval "$cmd" ) > "$log" 2>&1 &
        local pid=$!
        i=0
        while kill -0 "$pid" 2>/dev/null; do
            el=$(( $(date +%s) - start_epoch ))
            _ui_status "  ${SPIN[i % ${#SPIN[@]}]} ${counter} ${label}   [$(ui_fmt_duration "$el")]"
            i=$((i + 1))
            sleep 0.2
        done
        rc=0; wait "$pid" || rc=$?
        _ui_clear_status
    else
        echo "  ▶ ${counter} ${label}"
        ( eval "$cmd" ) > "$log" 2>&1
        rc=$?
    fi

    el=$(( $(date +%s) - start_epoch ))
    if [[ $rc -eq 0 ]]; then
        echo -e "  ${GREEN}${NC} ${counter} ${label}   [$(ui_fmt_duration "$el")]"
    else
        echo -e "  ${RED}${NC} ${counter} ${label}   [$(ui_fmt_duration "$el")]"
        UI_FAILED+=("$label")
        _ui_tail "$log" "$UI_TAIL_LINES"
    fi
    return "$rc"
}

# Linia pominięcia pakietu (resume)
ui_skip() {
    local label="$1"
    local counter
    if [[ $UI_PKG_TOTAL -gt 0 ]]; then
        counter="[${UI_PKG_N}/${UI_PKG_TOTAL}]"
    else
        counter="[#${UI_PKG_N}]"
    fi
    echo -e "  ${DIM}${NC} ${counter} ${label}  ${DIM}(już zbudowany)${NC}"
}

# Podsumowanie końcowe
ui_summary() {
    local total_sec elapsed
    total_sec=$(( $(date +%s) - UI_START_EPOCH ))
    elapsed=$(ui_fmt_duration "$total_sec")

    echo ""
    echo -e "${BOLD}════════════════════════════════════════════════════════════════════${NC}"
    echo -e "${BOLD}  PODSUMOWANIE BUDOWY    (czas: ${elapsed})${NC}"
    echo -e "${BOLD}════════════════════════════════════════════════════════════════════${NC}"
    echo -e "  ${GREEN}✓ Zbudowano:${NC}  ${PKG_BUILT}"
    echo -e "  ${RED}✗ Błędy:${NC}      ${PKG_FAILED}"
    echo -e "  ${DIM}⏭ Pominięto:${NC}  ${PKG_SKIPPED}"
    echo -e "  ${CYAN}Log główny:${NC}    ${LOG_FILE}"
    echo -e "  ${CYAN}Raport:${NC}        ${SUMMARY_FILE}"
    echo -e "  ${CYAN}Logi pakietów:${NC} ${UI_LOG_DIR}"
    if [[ ${#UI_FAILED[@]} -gt 0 ]]; then
        echo ""
        echo -e "  ${RED}Nieudane pakiety:${NC}"
        local p
        for p in "${UI_FAILED[@]}"; do
            echo -e "    ${RED}${NC} $p"
        done
    fi
    echo -e "${BOLD}════════════════════════════════════════════════════════════════════${NC}"
}