Removed ArchUpdateService
This commit is contained in:
parent
7d2eaa46e6
commit
5079fc78d3
1 changed files with 0 additions and 704 deletions
|
|
@ -1,704 +0,0 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
|
||||
Singleton {
|
||||
id: updateService
|
||||
|
||||
// ============================================================================
|
||||
// CORE PROPERTIES
|
||||
// ============================================================================
|
||||
|
||||
// Package data
|
||||
property var repoPackages: []
|
||||
property var aurPackages: []
|
||||
property var selectedPackages: []
|
||||
property int selectedPackagesCount: 0
|
||||
property string allUpdatesOutput: ""
|
||||
|
||||
// Update state
|
||||
property bool updateInProgress: false
|
||||
property bool updateFailed: false
|
||||
property string lastUpdateError: ""
|
||||
property bool checkFailed: false
|
||||
property string lastCheckError: ""
|
||||
|
||||
// Monitoring state
|
||||
property string capturedErrorText: ""
|
||||
property string capturedSuccessText: ""
|
||||
|
||||
// Computed properties
|
||||
readonly property bool aurBusy: checkAurUpdatesProcess.running || checkAurOnlyProcess.running
|
||||
readonly property int updates: repoPackages.length
|
||||
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
|
||||
readonly property bool canPoll: (Date.now() - lastPollTime) > pollCooldownMs
|
||||
|
||||
// ============================================================================
|
||||
// TIMERS
|
||||
// ============================================================================
|
||||
|
||||
// Refresh timer for post-update polling
|
||||
Timer {
|
||||
id: refreshTimer
|
||||
interval: 5000
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
doPoll()
|
||||
}
|
||||
}
|
||||
|
||||
// Timer to mark update as complete - with error handling
|
||||
Timer {
|
||||
id: updateCompleteTimer
|
||||
interval: 30000 // Increased to 30 seconds to allow more time
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
checkForUpdateFailures()
|
||||
}
|
||||
}
|
||||
|
||||
// Timer to check if update processes are still running
|
||||
Timer {
|
||||
id: updateMonitorTimer
|
||||
interval: 2000
|
||||
repeat: true
|
||||
running: updateInProgress
|
||||
onTriggered: {
|
||||
// Check if any update-related processes might still be running
|
||||
checkUpdateStatus()
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// MONITORING PROCESSES
|
||||
// ============================================================================
|
||||
|
||||
// Process to monitor update completion
|
||||
Process {
|
||||
id: updateStatusProcess
|
||||
command: ["pgrep", "-f", "(yay|paru).*(-S|-Syu)"]
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode !== 0 && updateInProgress) {
|
||||
// No update processes found, update likely completed
|
||||
updateInProgress = false
|
||||
updateMonitorTimer.stop()
|
||||
errorCheckTimer.stop()
|
||||
successCheckTimer.stop()
|
||||
|
||||
// Don't stop the complete timer - let it handle failures
|
||||
// If the update actually failed, the timer will trigger and set updateFailed = true
|
||||
|
||||
// Refresh package lists after a short delay
|
||||
Qt.callLater(() => {
|
||||
doPoll()
|
||||
}, 2000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process to check for errors in log file (only when update is in progress)
|
||||
Process {
|
||||
id: errorCheckProcess
|
||||
command: ["sh", "-c", "if [ -f /tmp/archupdater_output.log ]; then grep -i 'failed to build\\|could not resolve\\|unable to satisfy\\|failed to install\\|failed to upgrade\\|error:' /tmp/archupdater_output.log | grep -v 'ERROR_DETECTED' | tail -1; fi"]
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode === 0 && updateInProgress && capturedErrorText.trim() !== "") {
|
||||
// Error found in log
|
||||
updateInProgress = false
|
||||
updateFailed = true
|
||||
updateCompleteTimer.stop()
|
||||
updateMonitorTimer.stop()
|
||||
errorCheckTimer.stop()
|
||||
successCheckTimer.stop()
|
||||
lastUpdateError = "Build or update error detected"
|
||||
|
||||
// Refresh to check actual state
|
||||
Qt.callLater(() => {
|
||||
doPoll()
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
capturedErrorText = text || ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process to check for successful completion
|
||||
Process {
|
||||
id: successCheckProcess
|
||||
command: ["sh", "-c", "if [ -f /tmp/archupdater_output.log ]; then grep -i 'Update complete!\\|:: Running post-transaction hooks\\|:: Processing package changes\\|upgrading.*\\.\\.\\.\\|installing.*\\.\\.\\.\\|removing.*\\.\\.\\.' /tmp/archupdater_output.log | tail -1; fi"]
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode === 0 && updateInProgress && capturedSuccessText.trim() !== "") {
|
||||
// Success indicators found
|
||||
updateInProgress = false
|
||||
updateFailed = false
|
||||
updateCompleteTimer.stop()
|
||||
updateMonitorTimer.stop()
|
||||
errorCheckTimer.stop()
|
||||
successCheckTimer.stop()
|
||||
lastUpdateError = ""
|
||||
|
||||
// Refresh to check actual state
|
||||
Qt.callLater(() => {
|
||||
doPoll()
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
capturedSuccessText = text || ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Timer to check for success more frequently when update is in progress
|
||||
Timer {
|
||||
id: successCheckTimer
|
||||
interval: 5000 // Check every 5 seconds
|
||||
repeat: true
|
||||
running: updateInProgress
|
||||
onTriggered: {
|
||||
if (updateInProgress && !successCheckProcess.running) {
|
||||
successCheckProcess.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Timer to check for errors more frequently when update is in progress
|
||||
Timer {
|
||||
id: errorCheckTimer
|
||||
interval: 5000 // Check every 5 seconds
|
||||
repeat: true
|
||||
running: updateInProgress
|
||||
onTriggered: {
|
||||
if (updateInProgress && !errorCheckProcess.running) {
|
||||
errorCheckProcess.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// MONITORING FUNCTIONS
|
||||
// ============================================================================
|
||||
function checkUpdateStatus() {
|
||||
if (updateInProgress && !updateStatusProcess.running) {
|
||||
updateStatusProcess.running = true
|
||||
}
|
||||
}
|
||||
|
||||
function checkForUpdateFailures() {
|
||||
updateInProgress = false
|
||||
updateFailed = true
|
||||
updateCompleteTimer.stop()
|
||||
updateMonitorTimer.stop()
|
||||
|
||||
// Refresh to check actual state after a delay
|
||||
Qt.callLater(() => {
|
||||
doPoll()
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
// Initial check
|
||||
Component.onCompleted: {
|
||||
// Start AUR helper detection
|
||||
getAurHelper()
|
||||
|
||||
// Set up a fallback timer in case detection takes too long
|
||||
Qt.callLater(() => {
|
||||
if (cachedAurHelper === "" && !yayCheckProcess.running && !paruCheckProcess.running) {
|
||||
// No AUR helper found after reasonable time and processes have finished
|
||||
checkFailed = true
|
||||
lastCheckError = "No AUR helper found (yay or paru not installed)"
|
||||
Logger.warn("ArchUpdater", "No AUR helper found (yay or paru)")
|
||||
}
|
||||
}, 5000) // 5 second fallback
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PACKAGE CHECKING PROCESSES
|
||||
// ============================================================================
|
||||
|
||||
// Process for checking all updates with AUR helper (repo + AUR)
|
||||
Process {
|
||||
id: checkAurUpdatesProcess
|
||||
command: []
|
||||
onExited: function (exitCode) {
|
||||
// For both yay and paru: exit code 0 = updates available, exit code 1 = no updates
|
||||
if (exitCode !== 0 && exitCode !== 1) {
|
||||
Logger.warn("ArchUpdater", "AUR helper check failed (code:", exitCode, ")")
|
||||
checkFailed = true
|
||||
lastCheckError = "Failed to check for updates (exit code: " + exitCode + ")"
|
||||
aurPackages = []
|
||||
repoPackages = []
|
||||
}
|
||||
// Don't clear checkFailed here - wait for the second process to complete
|
||||
}
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
allUpdatesOutput = text
|
||||
// Now get AUR-only updates to compare
|
||||
checkAurOnlyProcess.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process for checking AUR-only updates (to separate from repo updates)
|
||||
Process {
|
||||
id: checkAurOnlyProcess
|
||||
command: []
|
||||
onExited: function (exitCode) {
|
||||
// For both yay and paru: exit code 0 = updates available, exit code 1 = no updates
|
||||
if (exitCode !== 0 && exitCode !== 1) {
|
||||
Logger.warn("ArchUpdater", "AUR helper AUR-only check failed (code:", exitCode, ")")
|
||||
checkFailed = true
|
||||
lastCheckError = "Failed to check AUR updates (exit code: " + exitCode + ")"
|
||||
aurPackages = []
|
||||
repoPackages = []
|
||||
} else {
|
||||
// Only clear checkFailed if both processes succeeded
|
||||
// Check if the first process also succeeded (no error was set)
|
||||
if (!checkFailed) {
|
||||
checkFailed = false
|
||||
lastCheckError = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
parseAllUpdatesOutput(allUpdatesOutput, text)
|
||||
Logger.log("ArchUpdater", "found", repoPackages.length, "repo package(s) and", aurPackages.length, "AUR package(s) to upgrade")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PARSING FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
// Generic package parsing function
|
||||
function parsePackageOutput(output, source) {
|
||||
const lines = output.trim().split('\n').filter(line => line.trim())
|
||||
const packages = []
|
||||
|
||||
for (const line of lines) {
|
||||
const m = line.match(/^(\S+)\s+([^\s]+)\s+->\s+([^\s]+)$/)
|
||||
if (m) {
|
||||
packages.push({
|
||||
"name": m[1],
|
||||
"oldVersion": m[2],
|
||||
"newVersion": m[3],
|
||||
"description": `${m[1]} ${m[2]} -> ${m[3]}`,
|
||||
"source": source
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Only update if we have new data or if this is a fresh check
|
||||
if (packages.length > 0 || output.trim() === "") {
|
||||
if (source === "repo") {
|
||||
repoPackages = packages
|
||||
} else {
|
||||
aurPackages = packages
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse all updates output (repo + AUR packages)
|
||||
function parseAllUpdatesOutput(allOutput, aurOnlyOutput) {
|
||||
const allLines = allOutput.trim().split('\n').filter(line => line.trim())
|
||||
const aurOnlyLines = aurOnlyOutput.trim().split('\n').filter(line => line.trim())
|
||||
|
||||
// Create a set of AUR package names for quick lookup
|
||||
const aurPackageNames = new Set()
|
||||
for (const line of aurOnlyLines) {
|
||||
const m = line.match(/^(\S+)\s+([^\s]+)\s+->\s+([^\s]+)$/)
|
||||
if (m) {
|
||||
aurPackageNames.add(m[1])
|
||||
}
|
||||
}
|
||||
|
||||
const repoPackages = []
|
||||
const aurPackages = []
|
||||
|
||||
for (const line of allLines) {
|
||||
const m = line.match(/^(\S+)\s+([^\s]+)\s+->\s+([^\s]+)$/)
|
||||
if (m) {
|
||||
const packageInfo = {
|
||||
"name": m[1],
|
||||
"oldVersion": m[2],
|
||||
"newVersion": m[3],
|
||||
"description": `${m[1]} ${m[2]} -> ${m[3]}`
|
||||
}
|
||||
|
||||
// Check if this package is in the AUR-only list
|
||||
if (aurPackageNames.has(m[1])) {
|
||||
packageInfo.source = "aur"
|
||||
aurPackages.push(packageInfo)
|
||||
} else {
|
||||
packageInfo.source = "repo"
|
||||
repoPackages.push(packageInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the package lists
|
||||
if (repoPackages.length > 0 || aurPackages.length > 0 || allOutput.trim() === "") {
|
||||
updateService.repoPackages = repoPackages
|
||||
updateService.aurPackages = aurPackages
|
||||
}
|
||||
}
|
||||
|
||||
function doPoll() {
|
||||
// Prevent excessive polling
|
||||
if (aurBusy || !canPoll) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if we have a cached AUR helper
|
||||
if (cachedAurHelper !== "") {
|
||||
// Clear error state when helper is available
|
||||
if (checkFailed && lastCheckError.includes("No AUR helper found")) {
|
||||
checkFailed = false
|
||||
lastCheckError = ""
|
||||
}
|
||||
|
||||
checkAurUpdatesProcess.command = [cachedAurHelper, "-Qu"]
|
||||
checkAurOnlyProcess.command = [cachedAurHelper, getAurOnlyFlag()]
|
||||
|
||||
// Start AUR updates check (includes both repo and AUR packages)
|
||||
checkAurUpdatesProcess.running = true
|
||||
lastPollTime = Date.now()
|
||||
} else {
|
||||
// AUR helper detection is still in progress or failed
|
||||
// Try to detect again if not already in progress
|
||||
if (!yayCheckProcess.running && !paruCheckProcess.running) {
|
||||
getAurHelper()
|
||||
}
|
||||
Logger.warn("ArchUpdater", "AUR helper detection in progress or failed")
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// UPDATE FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
// Helper function to generate update command with error detection
|
||||
function generateUpdateCommand(baseCommand) {
|
||||
return baseCommand + " 2>&1 | tee /tmp/archupdater_output.log; if [ $? -ne 0 ]; then echo 'ERROR_DETECTED'; fi; echo 'Update complete! Press Enter to close...'; read -p 'Press Enter to continue...'"
|
||||
}
|
||||
|
||||
// Update all packages (repo + AUR)
|
||||
function runUpdate() {
|
||||
if (totalUpdates === 0) {
|
||||
doPoll()
|
||||
return
|
||||
}
|
||||
|
||||
// Reset any previous error states
|
||||
updateFailed = false
|
||||
lastUpdateError = ""
|
||||
updateInProgress = true
|
||||
capturedErrorText = ""
|
||||
capturedSuccessText = ""
|
||||
|
||||
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")
|
||||
Quickshell.execDetached([terminal, "-e", "bash", "-c", command])
|
||||
} else if (cachedAurHelper === "") {
|
||||
// No AUR helper found
|
||||
updateInProgress = false
|
||||
updateFailed = true
|
||||
lastUpdateError = "No AUR helper found (yay or paru not installed)"
|
||||
Logger.warn("ArchUpdater", "No AUR helper found for update")
|
||||
}
|
||||
|
||||
// Start monitoring and timeout timers
|
||||
refreshTimer.start()
|
||||
updateCompleteTimer.start()
|
||||
updateMonitorTimer.start()
|
||||
}
|
||||
|
||||
// Update selected packages
|
||||
function runSelectiveUpdate() {
|
||||
if (selectedPackages.length === 0)
|
||||
return
|
||||
|
||||
// Reset any previous error states
|
||||
updateFailed = false
|
||||
lastUpdateError = ""
|
||||
updateInProgress = true
|
||||
capturedErrorText = ""
|
||||
capturedSuccessText = ""
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// Update all packages with AUR helper (handles both repo and AUR)
|
||||
if (selectedPackages.length > 0) {
|
||||
if (cachedAurHelper !== "") {
|
||||
const packageList = selectedPackages.join(" ")
|
||||
|
||||
// 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
|
||||
lastUpdateError = "No AUR helper found (yay or paru not installed)"
|
||||
Logger.warn("ArchUpdater", "No AUR helper found for packages:", selectedPackages.join(", "))
|
||||
}
|
||||
}
|
||||
|
||||
// Start monitoring and timeout timers
|
||||
refreshTimer.start()
|
||||
updateCompleteTimer.start()
|
||||
updateMonitorTimer.start()
|
||||
}
|
||||
|
||||
// Reset update state (useful for manual recovery)
|
||||
function resetUpdateState() {
|
||||
// Clear all update states
|
||||
updateInProgress = false
|
||||
updateFailed = false
|
||||
lastUpdateError = ""
|
||||
checkFailed = false
|
||||
lastCheckError = ""
|
||||
updateCompleteTimer.stop()
|
||||
updateMonitorTimer.stop()
|
||||
refreshTimer.stop()
|
||||
errorCheckTimer.stop()
|
||||
successCheckTimer.stop()
|
||||
|
||||
// Refresh to get current state
|
||||
doPoll()
|
||||
}
|
||||
|
||||
// Manual refresh function (bypasses cooldown)
|
||||
function forceRefresh() {
|
||||
// Prevent multiple simultaneous refreshes
|
||||
if (aurBusy) {
|
||||
return
|
||||
}
|
||||
|
||||
// Clear error states when refreshing
|
||||
updateFailed = false
|
||||
lastUpdateError = ""
|
||||
checkFailed = false
|
||||
lastCheckError = ""
|
||||
|
||||
// Check if we have a cached AUR helper
|
||||
if (cachedAurHelper !== "") {
|
||||
// Clear error state when helper is available
|
||||
if (checkFailed && lastCheckError.includes("No AUR helper found")) {
|
||||
checkFailed = false
|
||||
lastCheckError = ""
|
||||
}
|
||||
|
||||
checkAurUpdatesProcess.command = [cachedAurHelper, "-Qu"]
|
||||
checkAurOnlyProcess.command = [cachedAurHelper, getAurOnlyFlag()]
|
||||
|
||||
// Force refresh by bypassing cooldown
|
||||
checkAurUpdatesProcess.running = true
|
||||
lastPollTime = Date.now()
|
||||
} else {
|
||||
// AUR helper detection is still in progress or failed
|
||||
// Try to detect again if not already in progress
|
||||
if (!yayCheckProcess.running && !paruCheckProcess.running) {
|
||||
getAurHelper()
|
||||
}
|
||||
Logger.warn("ArchUpdater", "AUR helper detection in progress or failed")
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// UTILITY PROCESSES
|
||||
// ============================================================================
|
||||
|
||||
// Process for checking yay availability
|
||||
Process {
|
||||
id: yayCheckProcess
|
||||
command: ["which", "yay"]
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode === 0) {
|
||||
cachedAurHelper = "yay"
|
||||
Logger.log("ArchUpdater", "Found yay AUR helper (preferred)")
|
||||
// Clear error state when helper is found
|
||||
if (checkFailed && lastCheckError.includes("No AUR helper found")) {
|
||||
checkFailed = false
|
||||
lastCheckError = ""
|
||||
}
|
||||
// Trigger initial check when helper is found
|
||||
triggerInitialCheck()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process for checking paru availability
|
||||
Process {
|
||||
id: paruCheckProcess
|
||||
command: ["which", "paru"]
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode === 0) {
|
||||
// Only use paru if yay wasn't found (yay is preferred)
|
||||
if (cachedAurHelper === "") {
|
||||
cachedAurHelper = "paru"
|
||||
Logger.log("ArchUpdater", "Found paru AUR helper")
|
||||
// Clear error state when helper is found
|
||||
if (checkFailed && lastCheckError.includes("No AUR helper found")) {
|
||||
checkFailed = false
|
||||
lastCheckError = ""
|
||||
}
|
||||
// Trigger initial check when helper is found
|
||||
triggerInitialCheck()
|
||||
} else {
|
||||
Logger.log("ArchUpdater", "Found paru but using", cachedAurHelper, "(preferred)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cached AUR helper detection
|
||||
property string cachedAurHelper: ""
|
||||
|
||||
// Helper function to detect AUR helper
|
||||
function getAurHelper() {
|
||||
// Return cached result if available
|
||||
if (cachedAurHelper !== "") {
|
||||
return cachedAurHelper
|
||||
}
|
||||
|
||||
// Check for AUR helpers using Process objects
|
||||
Logger.log("ArchUpdater", "Detecting AUR helper...")
|
||||
|
||||
// Start the detection processes
|
||||
yayCheckProcess.running = true
|
||||
paruCheckProcess.running = true
|
||||
|
||||
// Return empty string to indicate no helper found yet
|
||||
// The processes will update cachedAurHelper when they complete
|
||||
return ""
|
||||
}
|
||||
|
||||
// Helper function to get the correct AUR-only flag for the detected helper
|
||||
function getAurOnlyFlag() {
|
||||
if (cachedAurHelper === "yay") {
|
||||
return "-Qua"
|
||||
} else if (cachedAurHelper === "paru") {
|
||||
return "-Qua" // paru uses the same flag but different exit code behavior
|
||||
}
|
||||
return "-Qua" // fallback
|
||||
}
|
||||
|
||||
// Helper function to trigger the initial package check
|
||||
function triggerInitialCheck() {
|
||||
// Only trigger if this is the first time (no packages have been checked yet)
|
||||
if (repoPackages.length === 0 && aurPackages.length === 0 && !aurBusy) {
|
||||
// Clear any previous error state
|
||||
checkFailed = false
|
||||
lastCheckError = ""
|
||||
|
||||
// Wait a bit for the system to be ready before the first check
|
||||
Qt.callLater(() => {
|
||||
checkAurUpdatesProcess.command = [cachedAurHelper, "-Qu"]
|
||||
checkAurOnlyProcess.command = [cachedAurHelper, getAurOnlyFlag()]
|
||||
checkAurUpdatesProcess.running = true
|
||||
lastPollTime = Date.now()
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PACKAGE SELECTION FUNCTIONS
|
||||
// ============================================================================
|
||||
function togglePackageSelection(packageName) {
|
||||
const index = selectedPackages.indexOf(packageName)
|
||||
if (index > -1) {
|
||||
selectedPackages.splice(index, 1)
|
||||
} else {
|
||||
selectedPackages.push(packageName)
|
||||
}
|
||||
selectedPackagesCount = selectedPackages.length
|
||||
}
|
||||
|
||||
function selectAllPackages() {
|
||||
selectedPackages = [...repoPackages.map(pkg => pkg.name), ...aurPackages.map(pkg => pkg.name)]
|
||||
selectedPackagesCount = selectedPackages.length
|
||||
}
|
||||
|
||||
function deselectAllPackages() {
|
||||
selectedPackages = []
|
||||
selectedPackagesCount = 0
|
||||
}
|
||||
|
||||
function isPackageSelected(packageName) {
|
||||
return selectedPackages.indexOf(packageName) > -1
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// REFRESH FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
// ============================================================================
|
||||
// UTILITY FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
// Notification helper
|
||||
function notify(title, body) {
|
||||
Quickshell.execDetached(["notify-send", "-a", "UpdateService", "-i", "system-software-update", title, body])
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// AUTO-POLL TIMER
|
||||
// ============================================================================
|
||||
|
||||
// Auto-poll every 15 minutes (respects cooldown)
|
||||
Timer {
|
||||
interval: 15 * 60 * 1000 // 15 minutes
|
||||
repeat: true
|
||||
running: true
|
||||
onTriggered: {
|
||||
if (!updateInProgress && canPoll) {
|
||||
doPoll()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue