Merge pull request #428 from mas-cli/monterey

🐛 Allow redownloads on macOS 12 Monterey
This commit is contained in:
Ben Chatelain 2021-11-03 19:32:02 -06:00 committed by GitHub
commit 9da3c3a1f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 61 additions and 29 deletions

View file

@ -101,6 +101,7 @@ $ mas lucky twitter
> Please note that this command will not allow you to install (or even purchase) an app for the first time:
use the `purchase` command in that case.
> ⛔ The `purchase` command is not supported as of macOS 10.15 Catalina. Please see [Known Issues](#%EF%B8%8F-known-issues).
```bash
$ mas purchase 768053424
@ -148,6 +149,8 @@ Xcode (8.0)
### 🚏📥 Sign-in
> ⛔ The `signin` command is not supported as of macOS 10.13 High Sierra. Please see [Known Issues](#%EF%B8%8F-known-issues).
To sign into the Mac App Store for the first time run `mas signin`.
```bash
@ -156,11 +159,8 @@ $ mas signin mas@example.com
Password:
```
> ⚠️ Due to breaking changes in the underlying API that mas uses to interact with the Mac App Store,
> the `signin` command has been temporarily disabled on macOS 10.13+ ⛔.
> For more information on this issue, see [#164](https://github.com/mas-cli/mas/issues/164).
If you experience issues signing in this way, you can ask to signin using a graphical dialog (provided by Mac App Store application):
If you experience issues signing in this way, you can ask to sign in using a graphical dialog
(provided by Mac App Store application):
```bash
$ mas signin --dialog mas@example.com
@ -182,6 +182,22 @@ Use `mas signout` to sign out from the Mac App Store.
then your Mac App Store apps will be included in the Brewfile created. See the [homebrew-bundle]
docs for more details.
## ⚠️ Known Issues
Over time, Apple has changed the APIs used by `mas` to manage App Store apps, limiting its capabilities. Please sign in
or purchase apps using the App Store app instead. Subsequent redownloads can be performed with `mas install`.
- ⛔️ The `signin` command is not supported as of macOS 10.13 High Sierra. [#164](https://github.com/mas-cli/mas/issues/164)
- ⛔️ The `purchase` command is not supported as of macOS 10.15 Catalina. [#289](https://github.com/mas-cli/mas/issues/289)
- ⛔️ The `account` command is not supported as of macOS 12 Monterey. [#417](https://github.com/mas-cli/mas/issues/417)
The versions `mas` sees from the app bundles on your Mac don't always match the versions reported by the App Store for
the same app bundles. This leads to some confusion when the `outdated` and `upgrade` commands differ in behavior from
what is shown as outdated in the App Store app. Further confusing matters, there is often some delay due to CDN
propagatioon and caching between the time a new app version is released to the App Store, and the time it appears
available in the App Store app or via the `mas` command. These issues cause symptoms like
[#384](https://github.com/mas-cli/mas/issues/384) and [#387](https://github.com/mas-cli/mas/issues/387).
## 💥 When something doesn't work
If you see this error, it's probably because you haven't installed the app through the App Store yet.

View file

@ -63,12 +63,20 @@ private func downloadWithRetries(
/// Only works for free apps. Defaults to false.
/// - Returns: A promise the completes when the download is complete.
private func download(_ appID: UInt64, purchase: Bool = false) -> Promise<Void> {
guard let account = ISStoreAccount.primaryAccount else {
return Promise(error: MASError.notSignedIn)
}
var storeAccount: ISStoreAccount?
if #available(macOS 12, *) {
// Monterey obscured the user's account information, but still allows
// redownloads without passing it to SSPurchase.
// https://github.com/mas-cli/mas/issues/417
} else {
guard let account = ISStoreAccount.primaryAccount else {
return Promise(error: MASError.notSignedIn)
}
guard let storeAccount = account as? ISStoreAccount else {
fatalError("Unable to cast StoreAccount to ISStoreAccount")
storeAccount = account as? ISStoreAccount
guard storeAccount != nil else {
fatalError("Unable to cast StoreAccount to ISStoreAccount")
}
}
return Promise<SSPurchase> { seal in

View file

@ -13,7 +13,7 @@ typealias SSPurchaseCompletion =
(_ purchase: SSPurchase?, _ completed: Bool, _ error: Error?, _ response: SSPurchaseResponse?) -> Void
extension SSPurchase {
convenience init(adamId: UInt64, account: ISStoreAccount, purchase: Bool = false) {
convenience init(adamId: UInt64, account: ISStoreAccount?, purchase: Bool = false) {
self.init()
var parameters: [String: Any] = [
@ -40,8 +40,11 @@ extension SSPurchase {
.joined(separator: "&")
itemIdentifier = adamId
accountIdentifier = account.dsID
appleID = account.identifier
if let account = account {
accountIdentifier = account.dsID
appleID = account.identifier
}
// Not sure if this is needed, but lets use it here.
if purchase {

View file

@ -18,6 +18,12 @@ public struct AccountCommand: CommandProtocol {
/// Runs the command.
public func run(_: Options) -> Result<Void, MASError> {
if #available(macOS 12, *) {
// Account information is no longer available as of Monterey.
// https://github.com/mas-cli/mas/issues/417
return .failure(.notSupported)
}
if let account = ISStoreAccount.primaryAccount {
print(String(describing: account.identifier))
} else {

View file

@ -29,6 +29,12 @@ public struct PurchaseCommand: CommandProtocol {
/// Runs the command.
public func run(_ options: Options) -> Result<Void, MASError> {
if #available(macOS 10.15, *) {
// Purchases are no longer possible as of Catalina.
// https://github.com/mas-cli/mas/issues/289
return .failure(.notSupported)
}
// Try to download applications with given identifiers and collect results
let appIds = options.appIds.filter { appId in
if let product = appLibrary.installedApp(forId: appId) {

View file

@ -20,7 +20,9 @@ public struct SignInCommand: CommandProtocol {
/// Runs the command.
public func run(_ options: Options) -> Result<Void, MASError> {
if #available(macOS 10.13, *) {
return .failure(.signInDisabled)
// Signing in is no longer possible as of High Sierra.
// https://github.com/mas-cli/mas/issues/164
return .failure(.notSupported)
}
guard ISStoreAccount.primaryAccount == nil else {

View file

@ -9,8 +9,9 @@
import Foundation
public enum MASError: Error, Equatable {
case notSupported
case notSignedIn
case signInDisabled
case signInFailed(error: NSError?)
case alreadySignedIn
@ -38,12 +39,11 @@ extension MASError: CustomStringConvertible {
case .notSignedIn:
return "Not signed in"
case .signInDisabled:
case .notSupported:
return """
The 'signin' command has been disabled on this macOS version. \
Please sign into the Mac App Store app manually.
For more info see: \
https://github.com/mas-cli/mas/issues/164
This command is not supported on this macOS version due to changes in macOS. \
For more information see: \
https://github.com/mas-cli/mas#known-issues
"""
case .signInFailed(let error):

View file

@ -7,19 +7,10 @@
//
import Commandant
import Foundation
import MasKit
MasKit.initialize()
let monterey = OperatingSystemVersion(majorVersion: 12, minorVersion: 0, patchVersion: 0)
if ProcessInfo.processInfo.isOperatingSystemAtLeast(monterey) {
printWarning(
"mas is not yet functional on macOS Monterey (12) due to changes in macOS frameworks. "
+ "To track progress or to *contribute* to fixing this issue, please see: "
+ "https://github.com/mas-cli/mas/issues/417")
}
let registry = CommandRegistry<MASError>()
let helpCommand = HelpCommand(registry: registry)