diff --git a/Sources/mas/Commands/Install.swift b/Sources/mas/Commands/Install.swift index 88c2688..1ba12b0 100644 --- a/Sources/mas/Commands/Install.swift +++ b/Sources/mas/Commands/Install.swift @@ -29,8 +29,8 @@ extension Mas { func run(appLibrary: AppLibrary) throws { // Try to download applications with given identifiers and collect results let appIDs = appIDs.filter { appID in - if let product = appLibrary.installedApp(withAppID: appID), !force { - printWarning("\(product.appName) is already installed") + if let appName = appLibrary.installedApps(withAppID: appID).first?.appName, !force { + printWarning("\(appName) is already installed") return false } diff --git a/Sources/mas/Commands/Lucky.swift b/Sources/mas/Commands/Lucky.swift index 16c7948..296dde7 100644 --- a/Sources/mas/Commands/Lucky.swift +++ b/Sources/mas/Commands/Lucky.swift @@ -58,8 +58,8 @@ extension Mas { /// - Throws: Any error that occurs while attempting to install the app. private func install(appID: AppID, appLibrary: AppLibrary) throws { // Try to download applications with given identifiers and collect results - if let product = appLibrary.installedApp(withAppID: appID), !force { - printWarning("\(product.appName) is already installed") + if let appName = appLibrary.installedApps(withAppID: appID).first?.appName, !force { + printWarning("\(appName) is already installed") } else { do { try downloadAll([appID]).wait() diff --git a/Sources/mas/Commands/Purchase.swift b/Sources/mas/Commands/Purchase.swift index 841d26d..58a7a48 100644 --- a/Sources/mas/Commands/Purchase.swift +++ b/Sources/mas/Commands/Purchase.swift @@ -26,8 +26,8 @@ extension Mas { func run(appLibrary: AppLibrary) throws { // Try to download applications with given identifiers and collect results let appIDs = appIDs.filter { appID in - if let product = appLibrary.installedApp(withAppID: appID) { - printWarning("\(product.appName) has already been purchased.") + if let appName = appLibrary.installedApps(withAppID: appID).first?.appName { + printWarning("\(appName) has already been purchased.") return false } diff --git a/Sources/mas/Commands/Uninstall.swift b/Sources/mas/Commands/Uninstall.swift index 632c84b..afb4b12 100644 --- a/Sources/mas/Commands/Uninstall.swift +++ b/Sources/mas/Commands/Uninstall.swift @@ -7,8 +7,7 @@ // import ArgumentParser -import CommerceKit -import StoreFoundation +import Foundation extension Mas { /// Command which uninstalls apps managed by the Mac App Store. @@ -29,16 +28,21 @@ extension Mas { } func run(appLibrary: AppLibrary) throws { - guard let product = appLibrary.installedApp(withAppID: appID) else { + let installedApps = appLibrary.installedApps(withAppID: appID) + guard !installedApps.isEmpty else { throw MASError.notInstalled } if dryRun { - printInfo("\(product.appName) \(product.bundlePath)") + for installedApp in installedApps { + printInfo("\(installedApp.appName) \(installedApp.bundlePath)") + } printInfo("(not removed, dry run)") } else { do { - try appLibrary.uninstallApp(app: product) + for installedApp in installedApps { + try appLibrary.uninstallApp(app: installedApp) + } } catch { throw MASError.uninstallFailed } diff --git a/Sources/mas/Commands/Upgrade.swift b/Sources/mas/Commands/Upgrade.swift index 4b3740b..83c4788 100644 --- a/Sources/mas/Commands/Upgrade.swift +++ b/Sources/mas/Commands/Upgrade.swift @@ -58,14 +58,14 @@ extension Mas { let apps = appIDs.isEmpty ? appLibrary.installedApps - : appIDs.compactMap { appID in + : appIDs.flatMap { appID in if let appID = AppID(appID) { - // argument is an AppID, lookup app by id using argument - return appLibrary.installedApp(withAppID: appID) + // argument is an AppID, lookup apps by id using argument + return appLibrary.installedApps(withAppID: appID) } - // argument is not an AppID, lookup app by name using argument - return appLibrary.installedApp(named: appID) + // argument is not an AppID, lookup apps by name using argument + return appLibrary.installedApps(named: appID) } let promises = apps.map { installedApp in diff --git a/Sources/mas/Controllers/AppLibrary.swift b/Sources/mas/Controllers/AppLibrary.swift index d05e180..9bcebc7 100644 --- a/Sources/mas/Controllers/AppLibrary.swift +++ b/Sources/mas/Controllers/AppLibrary.swift @@ -22,20 +22,20 @@ protocol AppLibrary { /// Common logic extension AppLibrary { - /// Finds an app for appID. + /// Finds all installed instances of apps whose app ID is `appID`. /// - /// - Parameter appID: app ID for app. - /// - Returns: SoftwareProduct of app if found; nil otherwise. - func installedApp(withAppID appID: AppID) -> SoftwareProduct? { + /// - Parameter appID: app ID for app(s). + /// - Returns: [SoftwareProduct] of matching apps. + func installedApps(withAppID appID: AppID) -> [SoftwareProduct] { let appID = NSNumber(value: appID) - return installedApps.first { $0.itemIdentifier == appID } + return installedApps.filter { $0.itemIdentifier == appID } } - /// Finds an app by name. + /// Finds all installed instances of apps whose name is `appName`. /// - /// - Parameter appName: Full title of an app. - /// - Returns: Software Product of app if found; nil otherwise. - func installedApp(named appName: String) -> SoftwareProduct? { - installedApps.first { $0.appName == appName } + /// - Parameter appName: Full name of app(s). + /// - Returns: [SoftwareProduct] of matching apps. + func installedApps(named appName: String) -> [SoftwareProduct] { + installedApps.filter { $0.appName == appName } } }