Compare commits

..

No commits in common. "3d6f39048a59f5232f5a478919f0a26ff7db1f31" and "44705cccae362e10dc6da024f0e7e95078ce8303" have entirely different histories.

View file

@ -47,9 +47,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
/// last known outdated list, shown in the Upgrade All confirmation /// last known outdated list, shown in the Upgrade All confirmation
var cachedOutdated: OutdatedPackages = .none var cachedOutdated: OutdatedPackages = .none
var lastNotifiedOutdated: Set<String> = [] var lastNotifiedOutdated: Set<String> = []
/// packages whose last upgrade attempt failed; reset when an upgrade
/// run starts, displayed once by updateStatus after the run's refetch
var failedUpgrades: [String] = []
let pathMonitor = NWPathMonitor() let pathMonitor = NWPathMonitor()
/// false until the monitor's first update, so the launch refresh waits /// false until the monitor's first update, so the launch refresh waits
@ -357,15 +354,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
statusMenuItem.title = "Upgrading..." statusMenuItem.title = "Upgrading..."
setMenuBarIcon("brewbar-updating") setMenuBarIcon("brewbar-updating")
failedUpgrades = []
runBrew("update") { _, _ in runBrew("update") { _, _ in
// packages that turn outdated only after this brew update are not // packages that turn outdated only after this brew update are not
// in cachedOutdated yet; the final refetch will surface them // in cachedOutdated yet; the final refetch will surface them
let formulaNames = formulae ? self.cachedOutdated.formulae.map(\.name) : []
let caskNames = casks ? self.cachedOutdated.casks.map(\.name) : [] let caskNames = casks ? self.cachedOutdated.casks.map(\.name) : []
let upgradeCasksThenRefresh = {
self.upgradeFormulaeSequentially(formulaNames) {
self.upgradeCasksSequentially(caskNames) { self.upgradeCasksSequentially(caskNames) {
self.cleanupAfterUpgradeIfEnabled { self.cleanupAfterUpgradeIfEnabled {
// a manual upgrade just ran; don't chain an auto-upgrade // a manual upgrade just ran; don't chain an auto-upgrade
@ -373,24 +367,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
} }
} }
} }
}
}
/// Formulae also upgrade one at a time: a single broken formula (no if formulae, !self.cachedOutdated.formulae.isEmpty {
/// bottle for this macOS, deprecated, ) makes brew's batch upgrade self.runBrew("upgrade --formula") { _, _ in
/// error out, taking every other pending formula down with it. upgradeCasksThenRefresh()
func upgradeFormulaeSequentially(_ names: [String], completion: @escaping () -> Void) { }
guard let next = names.first else { } else {
completion() upgradeCasksThenRefresh()
return
}
statusMenuItem.title = "Upgrading \(next)..."
runBrew("upgrade --formula \(next)", askpassMessage: "upgrade \(next)") { _, success in
if !success {
self.failedUpgrades.append(next)
} }
self.upgradeFormulaeSequentially(Array(names.dropFirst()), completion: completion)
} }
} }
@ -414,18 +398,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
/// (An explicitly named cask upgrades even when self-updating, no /// (An explicitly named cask upgrades even when self-updating, no
/// --greedy needed.) /// --greedy needed.)
func upgradeCask(_ name: String, completion: @escaping () -> Void) { func upgradeCask(_ name: String, completion: @escaping () -> Void) {
runBrew("upgrade --cask \(name)", askpassMessage: "upgrade \(name)") { output, success in runBrew("upgrade --cask \(name)", askpassMessage: "upgrade \(name)") { output, _ in
guard output.contains("cannot be upgraded as-is") else { guard output.contains("cannot be upgraded as-is") else {
if !success {
self.failedUpgrades.append(name)
}
completion() completion()
return return
} }
self.runBrew("reinstall --cask --force \(name)", askpassMessage: "reinstall \(name)") { _, reinstalled in self.runBrew("reinstall --cask --force \(name)", askpassMessage: "reinstall \(name)") { _, _ in
if !reinstalled {
self.failedUpgrades.append(name)
}
completion() completion()
} }
} }
@ -529,18 +507,23 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func runAutoUpgrade(formulae: Bool, casks: Bool) { func runAutoUpgrade(formulae: Bool, casks: Bool) {
statusMenuItem.title = "Auto-upgrading..." statusMenuItem.title = "Auto-upgrading..."
setMenuBarIcon("brewbar-updating") setMenuBarIcon("brewbar-updating")
failedUpgrades = []
let formulaNames = formulae ? cachedOutdated.formulae.map(\.name) : []
let caskNames = casks ? cachedOutdated.casks.map(\.name) : [] let caskNames = casks ? cachedOutdated.casks.map(\.name) : []
let upgradeCasksThenRefresh = {
upgradeFormulaeSequentially(formulaNames) {
self.upgradeCasksSequentially(caskNames) { self.upgradeCasksSequentially(caskNames) {
self.cleanupAfterUpgradeIfEnabled { self.cleanupAfterUpgradeIfEnabled {
self.fetchOutdated(allowAutoUpgrade: false) self.fetchOutdated(allowAutoUpgrade: false)
} }
} }
} }
if formulae {
runBrew("upgrade --formula") { _, _ in
upgradeCasksThenRefresh()
}
} else {
upgradeCasksThenRefresh()
}
} }
func updateOutdatedMenu(with outdated: OutdatedPackages) { func updateOutdatedMenu(with outdated: OutdatedPackages) {
@ -569,13 +552,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
} }
func updateStatus(count: Int) { func updateStatus(count: Int) {
// surface what the last upgrade run could not handle brew only if count == 0 {
// reports these in its output, which lands in the logs. Consumed
// here so the next plain refresh shows the normal state again.
if !failedUpgrades.isEmpty {
statusMenuItem.title = "⚠️ Upgrade failed: \(failedUpgrades.joined(separator: ", ")) — see Logs"
failedUpgrades = []
} else if count == 0 {
statusMenuItem.title = "✅ All up to date" statusMenuItem.title = "✅ All up to date"
} else { } else {
statusMenuItem.title = "⚠️ \(count) outdated" statusMenuItem.title = "⚠️ \(count) outdated"
@ -587,7 +564,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
statusMenuItem.title = "Upgrading \(name)..." statusMenuItem.title = "Upgrading \(name)..."
setMenuBarIcon("brewbar-updating") setMenuBarIcon("brewbar-updating")
failedUpgrades = []
let finish = { let finish = {
self.cleanupAfterUpgradeIfEnabled { self.cleanupAfterUpgradeIfEnabled {
@ -600,12 +576,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
if cachedOutdated.casks.contains(where: { $0.name == name }) { if cachedOutdated.casks.contains(where: { $0.name == name }) {
upgradeCask(name, completion: finish) upgradeCask(name, completion: finish)
} else { } else {
runBrew("upgrade \(name)", askpassMessage: "upgrade \(name)") { _, success in runBrew("upgrade \(name)", askpassMessage: "upgrade \(name)") { _, _ in finish() }
if !success {
self.failedUpgrades.append(name)
}
finish()
}
} }
} }