From 1ecc3d974460013bcf11872e8e96f5cf9d41c370 Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Sun, 31 Aug 2025 16:41:52 +0200 Subject: [PATCH] Fix ArchUpdater to be able to use ghostty ArchUpdaterService: add separate ghostty command ArchUpdater: Change color of symbol if no terminal/aur helper is found, edited tooltip ArchUpdaterPanel: Add proper error message if TERMINAL or aur helper was not found --- Modules/ArchUpdaterPanel/ArchUpdaterPanel.qml | 98 ++++++++++- Modules/Bar/Widgets/ArchUpdater.qml | 19 ++- Services/ArchUpdaterService.qml | 153 ++++-------------- 3 files changed, 139 insertions(+), 131 deletions(-) diff --git a/Modules/ArchUpdaterPanel/ArchUpdaterPanel.qml b/Modules/ArchUpdaterPanel/ArchUpdaterPanel.qml index 2457776..c282e11 100644 --- a/Modules/ArchUpdaterPanel/ArchUpdaterPanel.qml +++ b/Modules/ArchUpdaterPanel/ArchUpdaterPanel.qml @@ -66,11 +66,12 @@ NPanel { Layout.fillWidth: true } - // Update summary (only show when packages are available) + // Update summary (only show when packages are available and terminal is configured) NText { visible: !ArchUpdaterService.updateInProgress && !ArchUpdaterService.updateFailed && !ArchUpdaterService.checkFailed && !ArchUpdaterService.aurBusy - && ArchUpdaterService.totalUpdates > 0 + && ArchUpdaterService.totalUpdates > 0 && ArchUpdaterService.terminalAvailable + && ArchUpdaterService.aurHelperAvailable text: ArchUpdaterService.totalUpdates + " package" + (ArchUpdaterService.totalUpdates !== 1 ? "s" : "") + " can be updated" font.pointSize: Style.fontSizeL * scaling font.weight: Style.fontWeightMedium @@ -78,11 +79,12 @@ NPanel { Layout.fillWidth: true } - // Package selection info (only show when not updating and have packages) + // Package selection info (only show when not updating and have packages and terminal is configured) NText { visible: !ArchUpdaterService.updateInProgress && !ArchUpdaterService.updateFailed && !ArchUpdaterService.checkFailed && !ArchUpdaterService.aurBusy - && ArchUpdaterService.totalUpdates > 0 + && ArchUpdaterService.totalUpdates > 0 && ArchUpdaterService.terminalAvailable + && ArchUpdaterService.aurHelperAvailable text: ArchUpdaterService.selectedPackagesCount + " of " + ArchUpdaterService.totalUpdates + " packages selected" font.pointSize: Style.fontSizeS * scaling color: Color.mOnSurfaceVariant @@ -129,12 +131,88 @@ NPanel { } // Spacer } + // Terminal not available state + Item { + Layout.fillWidth: true + Layout.fillHeight: true + visible: !ArchUpdaterService.terminalAvailable && !ArchUpdaterService.updateInProgress + && !ArchUpdaterService.updateFailed + + ColumnLayout { + anchors.centerIn: parent + spacing: Style.marginM * scaling + + NIcon { + text: "terminal" + font.pointSize: Style.fontSizeXXXL * scaling + color: Color.mError + Layout.alignment: Qt.AlignHCenter + } + + NText { + text: "Terminal not configured" + font.pointSize: Style.fontSizeL * scaling + color: Color.mOnSurface + Layout.alignment: Qt.AlignHCenter + } + + NText { + text: "The TERMINAL environment variable is not set. Please set it to your preferred terminal (e.g., kitty, alacritty, foot) in your shell configuration." + font.pointSize: Style.fontSizeNormal * scaling + color: Color.mOnSurfaceVariant + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + Layout.maximumWidth: 280 * scaling + } + } + } + + // AUR helper not available state + Item { + Layout.fillWidth: true + Layout.fillHeight: true + visible: ArchUpdaterService.terminalAvailable && !ArchUpdaterService.aurHelperAvailable + && !ArchUpdaterService.updateInProgress && !ArchUpdaterService.updateFailed + && !ArchUpdaterService.checkFailed && !ArchUpdaterService.aurBusy + + ColumnLayout { + anchors.centerIn: parent + spacing: Style.marginM * scaling + + NIcon { + text: "package" + font.pointSize: Style.fontSizeXXXL * scaling + color: Color.mError + Layout.alignment: Qt.AlignHCenter + } + + NText { + text: "AUR helper not found" + font.pointSize: Style.fontSizeL * scaling + color: Color.mOnSurface + Layout.alignment: Qt.AlignHCenter + } + + NText { + text: "No AUR helper (yay or paru) is installed. Please install either yay or paru to manage AUR packages. yay is recommended." + font.pointSize: Style.fontSizeNormal * scaling + color: Color.mOnSurfaceVariant + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.Wrap + Layout.maximumWidth: 280 * scaling + } + } + } + // Check failed state (AUR down, network issues, etc.) Item { Layout.fillWidth: true Layout.fillHeight: true visible: ArchUpdaterService.checkFailed && !ArchUpdaterService.updateInProgress - && !ArchUpdaterService.updateFailed + && !ArchUpdaterService.updateFailed && ArchUpdaterService.terminalAvailable + && ArchUpdaterService.aurHelperAvailable ColumnLayout { anchors.centerIn: parent @@ -237,7 +315,8 @@ NPanel { Layout.fillHeight: true visible: !ArchUpdaterService.updateInProgress && !ArchUpdaterService.updateFailed && !ArchUpdaterService.checkFailed && !ArchUpdaterService.aurBusy - && ArchUpdaterService.totalUpdates === 0 + && ArchUpdaterService.totalUpdates === 0 && ArchUpdaterService.terminalAvailable + && ArchUpdaterService.aurHelperAvailable ColumnLayout { anchors.centerIn: parent @@ -274,6 +353,7 @@ NPanel { Layout.fillWidth: true Layout.fillHeight: true visible: ArchUpdaterService.aurBusy && !ArchUpdaterService.updateInProgress && !ArchUpdaterService.updateFailed + && ArchUpdaterService.terminalAvailable && ArchUpdaterService.aurHelperAvailable ColumnLayout { anchors.centerIn: parent @@ -308,7 +388,8 @@ NPanel { NBox { visible: !ArchUpdaterService.updateInProgress && !ArchUpdaterService.updateFailed && !ArchUpdaterService.checkFailed && !ArchUpdaterService.aurBusy - && ArchUpdaterService.totalUpdates > 0 + && ArchUpdaterService.totalUpdates > 0 && ArchUpdaterService.terminalAvailable + && ArchUpdaterService.aurHelperAvailable Layout.fillWidth: true Layout.fillHeight: true @@ -396,7 +477,8 @@ NPanel { // Action buttons (only show when not updating) RowLayout { visible: !ArchUpdaterService.updateInProgress && !ArchUpdaterService.updateFailed - && !ArchUpdaterService.checkFailed + && !ArchUpdaterService.checkFailed && ArchUpdaterService.terminalAvailable + && ArchUpdaterService.aurHelperAvailable Layout.fillWidth: true spacing: Style.marginL * scaling diff --git a/Modules/Bar/Widgets/ArchUpdater.qml b/Modules/Bar/Widgets/ArchUpdater.qml index e405ecf..2e5b4f7 100644 --- a/Modules/Bar/Widgets/ArchUpdater.qml +++ b/Modules/Bar/Widgets/ArchUpdater.qml @@ -16,10 +16,21 @@ NIconButton { colorBg: Color.mSurfaceVariant colorBorder: Color.transparent colorBorderHover: Color.transparent - colorFg: (ArchUpdaterService.totalUpdates === 0) ? Color.mOnSurface : Color.mPrimary + colorFg: { + if (!ArchUpdaterService.terminalAvailable || !ArchUpdaterService.aurHelperAvailable) { + return Color.mError + } + return (ArchUpdaterService.totalUpdates === 0) ? Color.mOnSurface : Color.mPrimary + } // Icon states icon: { + if (!ArchUpdaterService.terminalAvailable) { + return "terminal" + } + if (!ArchUpdaterService.aurHelperAvailable) { + return "package" + } if (ArchUpdaterService.aurBusy) { return "sync" } @@ -31,6 +42,12 @@ NIconButton { // Tooltip with repo vs AUR breakdown and sample lists tooltipText: { + if (!ArchUpdaterService.terminalAvailable) { + return "Terminal not configured\nSet TERMINAL environment variable" + } + if (!ArchUpdaterService.aurHelperAvailable) { + return "AUR helper not found\nInstall yay or paru" + } if (ArchUpdaterService.aurBusy) { return "Checking for updates…" } diff --git a/Services/ArchUpdaterService.qml b/Services/ArchUpdaterService.qml index 30e72b7..38c6e99 100644 --- a/Services/ArchUpdaterService.qml +++ b/Services/ArchUpdaterService.qml @@ -32,6 +32,14 @@ Singleton { readonly property int aurUpdates: aurPackages.length readonly property int totalUpdates: updates + aurUpdates + // Terminal validation + readonly property bool terminalAvailable: Quickshell.env("TERMINAL") !== "" + readonly property string terminalError: "TERMINAL environment variable not set" + + // AUR helper validation + readonly property bool aurHelperAvailable: cachedAurHelper !== "" + readonly property string aurHelperError: "No AUR helper found (yay or paru not installed)" + // Polling cooldown (prevent excessive polling) property int lastPollTime: 0 readonly property int pollCooldownMs: 5 * 60 * 1000 // 5 minutes @@ -360,16 +368,9 @@ Singleton { function doPoll() { // Prevent excessive polling if (aurBusy || !canPoll) { - if (aurBusy) { - Logger.log("ArchUpdater", "Poll skipped - already checking for updates") - } else { - Logger.log("ArchUpdater", "Poll skipped - cooldown period active") - } return } - Logger.log("ArchUpdater", "Automatic poll triggered") - // Check if we have a cached AUR helper if (cachedAurHelper !== "") { // Clear error state when helper is available @@ -381,9 +382,6 @@ Singleton { checkAurUpdatesProcess.command = [cachedAurHelper, "-Qu"] checkAurOnlyProcess.command = [cachedAurHelper, getAurOnlyFlag()] - Logger.log("ArchUpdater", "Poll commands:", cachedAurHelper + " -Qu", "and", - cachedAurHelper + " " + getAurOnlyFlag()) - // Start AUR updates check (includes both repo and AUR packages) checkAurUpdatesProcess.running = true lastPollTime = Date.now() @@ -391,7 +389,6 @@ Singleton { // AUR helper detection is still in progress or failed // Try to detect again if not already in progress if (!yayCheckProcess.running && !paruCheckProcess.running) { - Logger.log("ArchUpdater", "No AUR helper cached, starting detection...") getAurHelper() } Logger.warn("ArchUpdater", "AUR helper detection in progress or failed") @@ -410,7 +407,6 @@ Singleton { // Update all packages (repo + AUR) function runUpdate() { if (totalUpdates === 0) { - Logger.log("ArchUpdater", "No updates available, polling for updates...") doPoll() return } @@ -419,16 +415,20 @@ Singleton { updateFailed = false lastUpdateError = "" updateInProgress = true - Logger.log("ArchUpdater", "Starting full system update...") - const terminal = Quickshell.env("TERMINAL") || "xterm" + const terminal = Quickshell.env("TERMINAL") + if (!terminal) { + updateInProgress = false + updateFailed = true + lastUpdateError = "TERMINAL environment variable not set" + ToastService.showWarning("ArchUpdater", "TERMINAL environment variable not set") + return + } // Check if we have an AUR helper for full system update if (cachedAurHelper !== "" && (aurUpdates > 0 || updates > 0)) { // Use AUR helper for full system update (handles both repo and AUR) const command = generateUpdateCommand(cachedAurHelper + " -Syu") - Logger.log("ArchUpdater", "Full update command:", cachedAurHelper + " -Syu") - Logger.log("ArchUpdater", "Executing in terminal:", terminal) Quickshell.execDetached([terminal, "-e", "bash", "-c", command]) } else if (cachedAurHelper === "") { // No AUR helper found @@ -453,60 +453,29 @@ Singleton { updateFailed = false lastUpdateError = "" updateInProgress = true - Logger.log("ArchUpdater", "Starting selective update for", selectedPackages.length, "packages") - const terminal = Quickshell.env("TERMINAL") || "xterm" - - // Split selected packages by source - const repoPkgs = [] - const aurPkgs = [] - - for (const pkgName of selectedPackages) { - const repoPkg = repoPackages.find(p => p.name === pkgName) - if (repoPkg && repoPkg.source === "repo") { - repoPkgs.push(pkgName) - } - - const aurPkg = aurPackages.find(p => p.name === pkgName) - if (aurPkg && aurPkg.source === "aur") { - aurPkgs.push(pkgName) - } + const terminal = Quickshell.env("TERMINAL") + if (!terminal) { + updateInProgress = false + updateFailed = true + lastUpdateError = "TERMINAL environment variable not set" + ToastService.showWarning("ArchUpdater", "TERMINAL environment variable not set") + return } - Logger.log("ArchUpdater", "Package source analysis:") - Logger.log("ArchUpdater", " - Repo packages:", repoPkgs) - Logger.log("ArchUpdater", " - AUR packages:", aurPkgs) - Logger.log("ArchUpdater", " - Total repo packages available:", repoPackages.length) - Logger.log("ArchUpdater", " - Total AUR packages available:", aurPackages.length) - // Update all packages with AUR helper (handles both repo and AUR) if (selectedPackages.length > 0) { if (cachedAurHelper !== "") { const packageList = selectedPackages.join(" ") - const command = generateUpdateCommand(cachedAurHelper + " -S " + packageList) - Logger.log("ArchUpdater", "Selective update command:", cachedAurHelper + " -S " + packageList) - Logger.log("ArchUpdater", "Selected packages:", selectedPackages) - Logger.log("ArchUpdater", "Terminal:", terminal) - Logger.log("ArchUpdater", "AUR helper version check - running:", cachedAurHelper + " --version") - // Log system info for debugging - Logger.log("ArchUpdater", "System info for debugging:") - Logger.log("ArchUpdater", " - AUR helper:", cachedAurHelper) - Logger.log("ArchUpdater", " - Terminal:", terminal) - Logger.log("ArchUpdater", " - Total updates available:", totalUpdates) - Logger.log("ArchUpdater", " - Package source breakdown:") - Logger.log("ArchUpdater", " * Repo packages:", repoPkgs.length, ":", repoPkgs) - Logger.log("ArchUpdater", " * AUR packages:", aurPkgs.length, ":", aurPkgs) - Logger.log("ArchUpdater", " - Base command:", cachedAurHelper + " -S " + packageList) - Logger.log("ArchUpdater", " - Full wrapped command:", command) - Logger.log("ArchUpdater", " - Terminal command array:", [terminal, "-e", "bash", "-c", command]) - - // Test: Try without the wrapper first to see if that's the issue - Logger.log("ArchUpdater", "TESTING: Executing command without wrapper to isolate issue") - Quickshell.execDetached([terminal, "-e", "bash", "-c", cachedAurHelper + " -S " + packageList]) - - // Original wrapped command (commented out for testing) - // Quickshell.execDetached([terminal, "-e", "bash", "-c", command]) + // Handle ghostty terminal differently due to command parsing issues + if (terminal.includes("ghostty")) { + const simpleCommand = cachedAurHelper + " -S " + packageList + Quickshell.execDetached([terminal, "-e", simpleCommand]) + } else { + const command = generateUpdateCommand(cachedAurHelper + " -S " + packageList) + Quickshell.execDetached([terminal, "-e", "bash", "-c", command]) + } } else { updateInProgress = false updateFailed = true @@ -523,8 +492,6 @@ Singleton { // Reset update state (useful for manual recovery) function resetUpdateState() { - Logger.log("ArchUpdater", "Reset update state triggered") - // Clear all update states updateInProgress = false updateFailed = false @@ -545,12 +512,9 @@ Singleton { function forceRefresh() { // Prevent multiple simultaneous refreshes if (aurBusy) { - Logger.log("ArchUpdater", "Refresh skipped - already checking for updates") return } - Logger.log("ArchUpdater", "Manual refresh triggered") - // Clear error states when refreshing updateFailed = false lastUpdateError = "" @@ -568,9 +532,6 @@ Singleton { checkAurUpdatesProcess.command = [cachedAurHelper, "-Qu"] checkAurOnlyProcess.command = [cachedAurHelper, getAurOnlyFlag()] - Logger.log("ArchUpdater", "Refresh commands:", cachedAurHelper + " -Qu", "and", - cachedAurHelper + " " + getAurOnlyFlag()) - // Force refresh by bypassing cooldown checkAurUpdatesProcess.running = true lastPollTime = Date.now() @@ -578,7 +539,6 @@ Singleton { // AUR helper detection is still in progress or failed // Try to detect again if not already in progress if (!yayCheckProcess.running && !paruCheckProcess.running) { - Logger.log("ArchUpdater", "No AUR helper cached, starting detection...") getAurHelper() } Logger.warn("ArchUpdater", "AUR helper detection in progress or failed") @@ -602,8 +562,6 @@ Singleton { checkFailed = false lastCheckError = "" } - // Log diagnostics - logAurHelperDiagnostics() // Trigger initial check when helper is found triggerInitialCheck() } @@ -625,8 +583,6 @@ Singleton { checkFailed = false lastCheckError = "" } - // Log diagnostics - logAurHelperDiagnostics() // Trigger initial check when helper is found triggerInitialCheck() } else { @@ -636,37 +592,6 @@ Singleton { } } - // Process for checking AUR helper version - Process { - id: versionCheckProcess - command: [] - onExited: function (exitCode) { - if (exitCode === 0) { - Logger.log("ArchUpdater", " - Version check successful") - } else { - Logger.log("ArchUpdater", " - Version check failed") - } - } - } - - // Process for checking AUR helper location - Process { - id: locationCheckProcess - command: [] - onExited: function (exitCode) { - if (exitCode === 0) { - Logger.log("ArchUpdater", " - Location check successful") - } else { - Logger.log("ArchUpdater", " - Location check failed") - } - } - stdout: StdioCollector { - onStreamFinished: { - Logger.log("ArchUpdater", " - Location:", text.trim()) - } - } - } - // Cached AUR helper detection property string cachedAurHelper: "" @@ -699,22 +624,6 @@ Singleton { return "-Qua" // fallback } - // Helper function to log AUR helper diagnostic info - function logAurHelperDiagnostics() { - if (cachedAurHelper !== "") { - Logger.log("ArchUpdater", "AUR Helper Diagnostics:") - Logger.log("ArchUpdater", " - Helper:", cachedAurHelper) - - // Check version using existing process - versionCheckProcess.command = [cachedAurHelper, "--version"] - versionCheckProcess.running = true - - // Check location using existing process - locationCheckProcess.command = ["which", cachedAurHelper] - locationCheckProcess.running = true - } - } - // Helper function to trigger the initial package check function triggerInitialCheck() { // Only trigger if this is the first time (no packages have been checked yet)