fetchOutdated now uses --json and the typed parser, so cachedOutdated knows formulae from casks. The auto-upgrade trigger checks each kind against its own toggle: an outdated cask no longer starts a pointless "upgrade --formula" run (previously any outdated package triggered whichever auto-upgrades were enabled). runAutoUpgrade takes explicit formulae/casks flags instead of re-reading settings. Bonus from the version info now available: outdated menu items and the Upgrade All confirmation show "name installed → current" instead of bare names. The legacy line parser and its tests are removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
54 lines
1.5 KiB
Swift
54 lines
1.5 KiB
Swift
import Foundation
|
|
|
|
struct OutdatedPackage: Codable, Equatable {
|
|
let name: String
|
|
let installedVersions: [String]
|
|
let currentVersion: String
|
|
|
|
/// Menu label, e.g. "wget 1.21 → 1.22"
|
|
var label: String {
|
|
let installed = installedVersions.joined(separator: ", ")
|
|
return "\(name) \(installed) → \(currentVersion)"
|
|
}
|
|
}
|
|
|
|
struct OutdatedPackages: Codable, Equatable {
|
|
let formulae: [OutdatedPackage]
|
|
let casks: [OutdatedPackage]
|
|
|
|
var all: [OutdatedPackage] {
|
|
formulae + casks
|
|
}
|
|
|
|
var isEmpty: Bool {
|
|
formulae.isEmpty && casks.isEmpty
|
|
}
|
|
|
|
var count: Int {
|
|
formulae.count + casks.count
|
|
}
|
|
|
|
static let none = OutdatedPackages(formulae: [], casks: [])
|
|
}
|
|
|
|
enum BrewParser {
|
|
/// Parses `brew outdated --json` output. Returns .none for anything
|
|
/// undecodable (brew error text, empty output) — same effect as an
|
|
/// empty result, and the raw output is already in the log window.
|
|
static func parseOutdatedJSON(_ output: String) -> OutdatedPackages {
|
|
let decoder = JSONDecoder()
|
|
decoder.keyDecodingStrategy = .convertFromSnakeCase // installed_versions → installedVersions
|
|
|
|
guard let data = output.data(using: .utf8),
|
|
let parsed = try? decoder.decode(OutdatedPackages.self, from: data)
|
|
else {
|
|
return .none
|
|
}
|
|
return parsed
|
|
}
|
|
|
|
static func parseVersion(_ output: String) -> String {
|
|
output.split(separator: "\n").first.map(String.init) ?? "Unknown"
|
|
}
|
|
}
|