mirror of
https://github.com/mas-cli/mas
synced 2024-11-22 03:23:08 +00:00
Merge branch 'master' into pkg
This commit is contained in:
commit
6e002b79ce
36 changed files with 522 additions and 136 deletions
|
@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
## [Unreleased]
|
||||
|
||||
- 🐛📦 Fix paths building installer package #195
|
||||
- ♻️ AppLibrary refactor #193
|
||||
|
||||
## [v1.5.0] 🗑 Uninstall - 2018-12-27
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ class Mas < Formula
|
|||
desc "Mac App Store command-line interface"
|
||||
homepage "https://github.com/mas-cli/mas"
|
||||
url "https://github.com/mas-cli/mas.git",
|
||||
:tag => "v1.4.4",
|
||||
:revision => "3660365dd334cd852dd83d42ee016e267821a5de"
|
||||
:tag => "v1.5.0",
|
||||
:revision => "ccaaa74c9593d04dc41fcff40af196fdad49f517"
|
||||
head "https://github.com/mas-cli/mas.git"
|
||||
|
||||
bottle do
|
||||
|
@ -15,9 +15,9 @@ class Mas < Formula
|
|||
sha256 "237fd7270cb8f0d68a33e7ce05671a2e5c269d05d736abb0f66b50215439084e" => :el_capitan
|
||||
end
|
||||
|
||||
depends_on "trash"
|
||||
depends_on "carthage" => :build
|
||||
depends_on :xcode => ["10.1", :build]
|
||||
depends_on "trash"
|
||||
|
||||
def install
|
||||
# Working around build issues in dependencies
|
||||
|
|
|
@ -2,8 +2,8 @@ class Mas < Formula
|
|||
desc "Mac App Store command-line interface"
|
||||
homepage "https://github.com/mas-cli/mas"
|
||||
url "https://github.com/mas-cli/mas.git",
|
||||
:tag => "v1.4.4",
|
||||
:revision => "3660365dd334cd852dd83d42ee016e267821a5de"
|
||||
:tag => "v1.5.0",
|
||||
:revision => "ccaaa74c9593d04dc41fcff40af196fdad49f517"
|
||||
head "https://github.com/mas-cli/mas.git"
|
||||
|
||||
bottle do
|
||||
|
@ -12,9 +12,9 @@ class Mas < Formula
|
|||
sha256 "fc6658113d785a660e3f4d2e4e134ad02fe003ffa7d69271a2c53f503aaae726" => :high_sierra
|
||||
end
|
||||
|
||||
depends_on "trash"
|
||||
depends_on "carthage" => :build
|
||||
depends_on :xcode => ["10.1", :build]
|
||||
depends_on "trash"
|
||||
|
||||
def install
|
||||
# Working around build issues in dependencies
|
||||
|
|
|
@ -8,11 +8,29 @@
|
|||
|
||||
/// Utility for managing installed apps.
|
||||
public protocol AppLibrary {
|
||||
/// Finds an app by ID from the set of installed apps
|
||||
/// Entire set of installed apps.
|
||||
var installedApps: [SoftwareProduct] { get }
|
||||
|
||||
/// Map of app name to ID.
|
||||
var appIdsByName: [String: UInt64] { get }
|
||||
|
||||
/// Finds an app by ID.
|
||||
///
|
||||
/// - Parameter appId: MAS ID for app.
|
||||
/// - Parameter forId: MAS ID for app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
func installedApp(appId: UInt64) -> SoftwareProduct?
|
||||
func installedApp(forId: UInt64) -> SoftwareProduct?
|
||||
|
||||
/// Finds an app by it's bundle identifier.
|
||||
///
|
||||
/// - Parameter forBundleId: Bundle identifier of app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
func installedApp(forBundleId: String) -> SoftwareProduct?
|
||||
|
||||
/// Finds an app by name.
|
||||
///
|
||||
/// - Parameter named: Name of app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
func installedApp(named: String) -> SoftwareProduct?
|
||||
|
||||
/// Uninstalls an app.
|
||||
///
|
||||
|
@ -20,3 +38,34 @@ public protocol AppLibrary {
|
|||
/// - Throws: Error if there is a problem.
|
||||
func uninstallApp(app: SoftwareProduct) throws
|
||||
}
|
||||
|
||||
/// Common logic
|
||||
extension AppLibrary {
|
||||
/// Map of app name to ID.
|
||||
public var appIdsByName: [String: UInt64] {
|
||||
get {
|
||||
var destMap = [String: UInt64]()
|
||||
for product in installedApps {
|
||||
destMap[product.appName] = product.itemIdentifier.uint64Value
|
||||
}
|
||||
return destMap
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds an app by name.
|
||||
///
|
||||
/// - Parameter id: MAS ID for app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
public func installedApp(forId id: UInt64) -> SoftwareProduct? {
|
||||
let appId = NSNumber(value: id)
|
||||
return installedApps.first { $0.itemIdentifier == appId }
|
||||
}
|
||||
|
||||
/// Finds an app by name.
|
||||
///
|
||||
/// - Parameter appName: Full title of an app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
public func installedApp(named appName: String) -> SoftwareProduct? {
|
||||
return installedApps.first { $0.appName == appName }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
//
|
||||
// CKSoftwareMap+AppLookup.swift
|
||||
// mas-cli
|
||||
//
|
||||
// Created by Andrew Griffiths on 20/8/17.
|
||||
// Copyright © 2017 Andrew Griffiths.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import CommerceKit
|
||||
|
||||
private var appIdsByName : [String:UInt64]?
|
||||
|
||||
extension CKSoftwareMap {
|
||||
func appIdWithProductName(_ name: String) -> UInt64? {
|
||||
if appIdsByName == nil {
|
||||
let softwareMap = CKSoftwareMap.shared()
|
||||
var destMap = [String:UInt64]()
|
||||
|
||||
guard let products = softwareMap.allProducts() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
for product in products {
|
||||
destMap[product.appName] = product.itemIdentifier.uint64Value
|
||||
}
|
||||
|
||||
appIdsByName = destMap
|
||||
}
|
||||
|
||||
return appIdsByName?[name]
|
||||
}
|
||||
}
|
||||
|
|
@ -10,17 +10,25 @@ import Commandant
|
|||
import Result
|
||||
import CommerceKit
|
||||
|
||||
/// Installs previously purchased apps from the Mac App Store.
|
||||
public struct InstallCommand: CommandProtocol {
|
||||
public typealias Options = InstallOptions
|
||||
public let verb = "install"
|
||||
public let function = "Install from the Mac App Store"
|
||||
|
||||
public init() {}
|
||||
private let appLibrary: AppLibrary
|
||||
|
||||
/// Designated initializer.
|
||||
///
|
||||
/// - Parameter appLibrary: AppLibrary manager.
|
||||
public init(appLibrary: AppLibrary = MasAppLibrary()) {
|
||||
self.appLibrary = appLibrary
|
||||
}
|
||||
|
||||
public func run(_ options: Options) -> Result<(), MASError> {
|
||||
// Try to download applications with given identifiers and collect results
|
||||
let downloadResults = options.appIds.compactMap { (appId) -> MASError? in
|
||||
if let product = installedApp(appId), !options.forceInstall {
|
||||
if let product = appLibrary.installedApp(forId: appId), !options.forceInstall {
|
||||
printWarning("\(product.appName) is already installed")
|
||||
return nil
|
||||
}
|
||||
|
@ -37,13 +45,6 @@ public struct InstallCommand: CommandProtocol {
|
|||
return .failure(.downloadFailed(error: nil))
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func installedApp(_ appId: UInt64) -> CKSoftwareProduct? {
|
||||
let appId = NSNumber(value: appId)
|
||||
|
||||
let softwareMap = CKSoftwareMap.shared()
|
||||
return softwareMap.allProducts()?.first { $0.itemIdentifier == appId }
|
||||
}
|
||||
}
|
||||
|
||||
public struct InstallOptions: OptionsProtocol {
|
||||
|
|
|
@ -8,18 +8,25 @@
|
|||
|
||||
import Commandant
|
||||
import Result
|
||||
import CommerceKit
|
||||
|
||||
/// Command which lists all installed apps.
|
||||
public struct ListCommand: CommandProtocol {
|
||||
public typealias Options = NoOptions<MASError>
|
||||
public let verb = "list"
|
||||
public let function = "Lists apps from the Mac App Store which are currently installed"
|
||||
|
||||
public init() {}
|
||||
private let appLibrary: AppLibrary
|
||||
|
||||
/// Designated initializer.
|
||||
///
|
||||
/// - Parameter appLibrary: AppLibrary manager.
|
||||
public init(appLibrary: AppLibrary = MasAppLibrary()) {
|
||||
self.appLibrary = appLibrary
|
||||
}
|
||||
|
||||
public func run(_ options: Options) -> Result<(), MASError> {
|
||||
let softwareMap = CKSoftwareMap.shared()
|
||||
guard let products = softwareMap.allProducts() else {
|
||||
let products = appLibrary.installedApps
|
||||
if products.isEmpty {
|
||||
print("No installed apps found")
|
||||
return .success(())
|
||||
}
|
||||
|
|
|
@ -10,19 +10,26 @@ import Commandant
|
|||
import Result
|
||||
import CommerceKit
|
||||
|
||||
/// Command which installs the first search result. This is handy as many MAS titles
|
||||
/// can be long with embedded keywords.
|
||||
public struct LuckyCommand: CommandProtocol {
|
||||
public typealias Options = LuckyOptions
|
||||
public let verb = "lucky"
|
||||
public let function = "Install the first result from the Mac App Store"
|
||||
|
||||
private let appLibrary: AppLibrary
|
||||
private let urlSession: URLSession
|
||||
|
||||
public init(urlSession: URLSession = URLSession.shared) {
|
||||
/// Designated initializer.
|
||||
///
|
||||
/// - Parameter appLibrary: AppLibrary manager.
|
||||
/// - Parameter urlSession: URL session for network communication.
|
||||
public init(appLibrary: AppLibrary = MasAppLibrary(), urlSession: URLSession = URLSession.shared) {
|
||||
self.appLibrary = appLibrary
|
||||
self.urlSession = urlSession
|
||||
}
|
||||
|
||||
public func run(_ options: Options) -> Result<(), MASError> {
|
||||
|
||||
guard let searchURLString = searchURLString(options.appName),
|
||||
let searchJson = urlSession.requestSynchronousJSONWithURLString(searchURLString) as? [String: Any] else {
|
||||
return .failure(.searchFailed)
|
||||
|
@ -34,23 +41,22 @@ public struct LuckyCommand: CommandProtocol {
|
|||
return .failure(.noSearchResultsFound)
|
||||
}
|
||||
|
||||
|
||||
let appId = results[0][ResultKeys.TrackId] as! UInt64
|
||||
|
||||
|
||||
return install(appId, options: options)
|
||||
}
|
||||
|
||||
fileprivate func install(_ appId: UInt64, options: Options) -> Result<(), MASError> {
|
||||
// Try to download applications with given identifiers and collect results
|
||||
let downloadResults = [appId].compactMap { (appId) -> MASError? in
|
||||
if let product = installedApp(appId) , !options.forceInstall {
|
||||
if let product = appLibrary.installedApp(forId: appId), !options.forceInstall {
|
||||
printWarning("\(product.appName) is already installed")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
return download(appId)
|
||||
}
|
||||
|
||||
|
||||
switch downloadResults.count {
|
||||
case 0:
|
||||
return .success(())
|
||||
|
@ -61,13 +67,6 @@ public struct LuckyCommand: CommandProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
fileprivate func installedApp(_ appId: UInt64) -> CKSoftwareProduct? {
|
||||
let appId = NSNumber(value: appId)
|
||||
|
||||
let softwareMap = CKSoftwareMap.shared()
|
||||
return softwareMap.allProducts()?.first { $0.itemIdentifier == appId }
|
||||
}
|
||||
|
||||
func searchURLString(_ appName: String) -> String? {
|
||||
if let urlEncodedAppName = appName.URLEncodedString {
|
||||
return "https://itunes.apple.com/search?entity=macSoftware&term=\(urlEncodedAppName)&attribute=allTrackTerm"
|
||||
|
|
|
@ -10,19 +10,28 @@ import Commandant
|
|||
import Result
|
||||
import CommerceKit
|
||||
|
||||
/// Command which displays a list of installed apps which have available updates
|
||||
/// ready to be installed from the Mac App Store.
|
||||
public struct OutdatedCommand: CommandProtocol {
|
||||
public typealias Options = NoOptions<MASError>
|
||||
public let verb = "outdated"
|
||||
public let function = "Lists pending updates from the Mac App Store"
|
||||
|
||||
public init() {}
|
||||
|
||||
private let appLibrary: AppLibrary
|
||||
|
||||
/// Designated initializer.
|
||||
///
|
||||
/// - Parameter appLibrary: AppLibrary manager.
|
||||
public init(appLibrary: AppLibrary = MasAppLibrary()) {
|
||||
self.appLibrary = appLibrary
|
||||
}
|
||||
|
||||
public func run(_ options: Options) -> Result<(), MASError> {
|
||||
let updateController = CKUpdateController.shared()
|
||||
let updates = updateController?.availableUpdates()
|
||||
let softwareMap = CKSoftwareMap.shared()
|
||||
for update in updates! {
|
||||
if let installed = softwareMap.product(forBundleIdentifier: update.bundleID) {
|
||||
if let installed = appLibrary.installedApp(forBundleId: update.bundleID) {
|
||||
// Display version of installed app compared to available update.
|
||||
print("\(update.itemIdentifier) \(update.title) (\(installed.bundleVersion) -> \(update.bundleVersion))")
|
||||
} else {
|
||||
print("\(update.itemIdentifier) \(update.title) (unknown -> \(update.bundleVersion))")
|
||||
|
|
|
@ -33,7 +33,7 @@ public struct UninstallCommand: CommandProtocol {
|
|||
public func run(_ options: Options) -> Result<(), MASError> {
|
||||
let appId = UInt64(options.appId)
|
||||
|
||||
guard let product = appLibrary.installedApp(appId: appId) else {
|
||||
guard let product = appLibrary.installedApp(forId: appId) else {
|
||||
return .failure(.notInstalled)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,37 +10,40 @@ import Commandant
|
|||
import Result
|
||||
import CommerceKit
|
||||
|
||||
/// Command which upgrades apps with new versions available in the Mac App Store.
|
||||
public struct UpgradeCommand: CommandProtocol {
|
||||
public typealias Options = UpgradeOptions
|
||||
public let verb = "upgrade"
|
||||
public let function = "Upgrade outdated apps from the Mac App Store"
|
||||
|
||||
public init() {}
|
||||
private let appLibrary: AppLibrary
|
||||
|
||||
/// Designated initializer.
|
||||
///
|
||||
/// - Parameter appLibrary: <#appLibrary description#>
|
||||
public init(appLibrary: AppLibrary = MasAppLibrary()) {
|
||||
self.appLibrary = appLibrary
|
||||
}
|
||||
|
||||
public func run(_ options: Options) -> Result<(), MASError> {
|
||||
let updateController = CKUpdateController.shared()
|
||||
|
||||
let updates: [CKUpdate]
|
||||
let apps = options.apps
|
||||
if apps.count > 0 {
|
||||
let softwareMap = CKSoftwareMap.shared()
|
||||
|
||||
// convert input into a list of appId's
|
||||
|
||||
let appIds: [UInt64]
|
||||
|
||||
appIds = apps.compactMap {
|
||||
if let appId = UInt64($0) {
|
||||
return appId
|
||||
}
|
||||
if let appId = softwareMap.appIdWithProductName($0) {
|
||||
if let appId = appLibrary.appIdsByName[$0] {
|
||||
return appId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// check each of those for updates
|
||||
|
||||
updates = appIds.compactMap {
|
||||
updateController?.availableUpdate(withItemIdentifier: $0)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import Commandant
|
||||
import Result
|
||||
|
||||
/// Command which displays the version of the mas tool.
|
||||
public struct VersionCommand: CommandProtocol {
|
||||
public typealias Options = NoOptions<MASError>
|
||||
public let verb = "version"
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.5</string>
|
||||
<string>1.5.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>10500000</string>
|
||||
<string>10501000</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2018 Andrew Naylor. All rights reserved.</string>
|
||||
</dict>
|
||||
|
|
|
@ -13,15 +13,23 @@ public class MasAppLibrary: AppLibrary {
|
|||
/// CommerceKit's singleton manager of installed software.
|
||||
private let softwareMap = CKSoftwareMap.shared()
|
||||
|
||||
/// Array of installed software products.
|
||||
public lazy var installedApps: [SoftwareProduct] = {
|
||||
var appList = [SoftwareProduct]()
|
||||
guard let products = softwareMap.allProducts()
|
||||
else { return appList }
|
||||
appList.append(contentsOf: products)
|
||||
return products
|
||||
}()
|
||||
|
||||
public init() {}
|
||||
|
||||
/// Finds an app by ID from the set of installed apps
|
||||
/// Finds an app using a bundle identifier.
|
||||
///
|
||||
/// - Parameter appId: MAS ID for app.
|
||||
/// - Parameter bundleId: Bundle identifier of app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
public func installedApp(appId: UInt64) -> SoftwareProduct? {
|
||||
let appId = NSNumber(value: appId)
|
||||
return softwareMap.allProducts()?.first { $0.itemIdentifier == appId }
|
||||
public func installedApp(forBundleId bundleId: String) -> SoftwareProduct? {
|
||||
return softwareMap.product(forBundleIdentifier: bundleId)
|
||||
}
|
||||
|
||||
/// Uninstalls an app.
|
||||
|
|
|
@ -10,5 +10,6 @@
|
|||
public protocol SoftwareProduct {
|
||||
var appName: String { get }
|
||||
var bundlePath: String { get set }
|
||||
var bundleVersion: String { get set }
|
||||
var itemIdentifier: NSNumber { get set }
|
||||
}
|
||||
|
|
25
MasKitTests/Commands/AccountCommandSpec.swift
Normal file
25
MasKitTests/Commands/AccountCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// AccountCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class AccountCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("Account command") {
|
||||
it("displays active account") {
|
||||
let cmd = AccountCommand()
|
||||
let result = cmd.run(AccountCommand.Options())
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
MasKitTests/Commands/InfoCommandSpec.swift
Normal file
25
MasKitTests/Commands/InfoCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// InfoCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class InfoCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("Info command") {
|
||||
it("displays app details") {
|
||||
let cmd = InfoCommand()
|
||||
let result = cmd.run(InfoCommand.Options(appId: ""))
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
MasKitTests/Commands/InstallCommandSpec.swift
Normal file
25
MasKitTests/Commands/InstallCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// InstallCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class InstallCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("install command") {
|
||||
it("installs apps") {
|
||||
let cmd = InstallCommand()
|
||||
let result = cmd.run(InstallCommand.Options(appIds: [], forceInstall: false))
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
MasKitTests/Commands/LuckyCommandSpec.swift
Normal file
25
MasKitTests/Commands/LuckyCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// LuckyCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class LuckyCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("lucky command") {
|
||||
it("installs the first app matching a search") {
|
||||
let cmd = LuckyCommand()
|
||||
let result = cmd.run(LuckyCommand.Options(appName: "", forceInstall: false))
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
MasKitTests/Commands/OutdatedCommandSpec.swift
Normal file
25
MasKitTests/Commands/OutdatedCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// OutdatedCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class OutdatedCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("outdated command") {
|
||||
it("displays apps with pending updates") {
|
||||
let cmd = OutdatedCommand()
|
||||
let result = cmd.run(OutdatedCommand.Options())
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
MasKitTests/Commands/ResetCommandSpec.swift
Normal file
25
MasKitTests/Commands/ResetCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// ResetCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class ResetCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("reset command") {
|
||||
it("updates stuff") {
|
||||
let cmd = ResetCommand()
|
||||
let result = cmd.run(ResetCommand.Options(debug: false))
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
MasKitTests/Commands/SearchCommandSpec.swift
Normal file
25
MasKitTests/Commands/SearchCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// SearchCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class SearchCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("search command") {
|
||||
it("updates stuff") {
|
||||
let cmd = SearchCommand()
|
||||
let result = cmd.run(SearchCommand.Options(appName: "", price: false))
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
MasKitTests/Commands/SignInCommandSpec.swift
Normal file
25
MasKitTests/Commands/SignInCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// SignInCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class SignInCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("signn command") {
|
||||
it("updates stuff") {
|
||||
let cmd = SignInCommand()
|
||||
let result = cmd.run(SignInCommand.Options(username: "", password: "", dialog: false))
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
MasKitTests/Commands/SignOutCommandSpec.swift
Normal file
25
MasKitTests/Commands/SignOutCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// SignOutCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class SignOutCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("signout command") {
|
||||
it("updates stuff") {
|
||||
let cmd = SignOutCommand()
|
||||
let result = cmd.run(SignOutCommand.Options())
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ class UninstallCommandSpec: QuickSpec {
|
|||
let app = MockSoftwareProduct(
|
||||
appName: "Some App",
|
||||
bundlePath: "/tmp/Some.app",
|
||||
bundleVersion: "1.0",
|
||||
itemIdentifier: NSNumber(value: appId)
|
||||
)
|
||||
let mockLibrary = MockAppLibrary()
|
||||
|
@ -26,16 +27,17 @@ class UninstallCommandSpec: QuickSpec {
|
|||
context("dry run") {
|
||||
let options = UninstallCommand.Options(appId: appId, dryRun: true)
|
||||
|
||||
beforeEach {
|
||||
mockLibrary.reset()
|
||||
}
|
||||
it("can't remove a missing app") {
|
||||
mockLibrary.apps = []
|
||||
|
||||
let result = uninstall.run(options)
|
||||
expect(result).to(beFailure { error in
|
||||
expect(error) == .notInstalled
|
||||
})
|
||||
}
|
||||
it("finds an app") {
|
||||
mockLibrary.apps.append(app)
|
||||
mockLibrary.installedApps.append(app)
|
||||
|
||||
let result = uninstall.run(options)
|
||||
expect(result).to(beSuccess())
|
||||
|
@ -44,25 +46,25 @@ class UninstallCommandSpec: QuickSpec {
|
|||
context("wet run") {
|
||||
let options = UninstallCommand.Options(appId: appId, dryRun: false)
|
||||
|
||||
beforeEach {
|
||||
mockLibrary.reset()
|
||||
}
|
||||
it("can't remove a missing app") {
|
||||
mockLibrary.apps = []
|
||||
|
||||
let result = uninstall.run(options)
|
||||
expect(result).to(beFailure { error in
|
||||
expect(error) == .notInstalled
|
||||
})
|
||||
}
|
||||
it("removes an app") {
|
||||
mockLibrary.apps.append(app)
|
||||
mockLibrary.installedApps.append(app)
|
||||
|
||||
let result = uninstall.run(options)
|
||||
expect(result).to(beSuccess())
|
||||
}
|
||||
it("fails if there is a problem with the trash command") {
|
||||
mockLibrary.apps = []
|
||||
var brokenUninstall = app // make mutable copy
|
||||
brokenUninstall.bundlePath = "/dev/null"
|
||||
mockLibrary.apps.append(brokenUninstall)
|
||||
mockLibrary.installedApps.append(brokenUninstall)
|
||||
|
||||
let result = uninstall.run(options)
|
||||
expect(result).to(beFailure { error in
|
||||
|
|
25
MasKitTests/Commands/UpgradeCommandSpec.swift
Normal file
25
MasKitTests/Commands/UpgradeCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// UpgradeCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class UpgradeCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("upgrade command") {
|
||||
it("updates stuff") {
|
||||
let cmd = UpgradeCommand()
|
||||
let result = cmd.run(UpgradeCommand.Options(apps: [""]))
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
MasKitTests/Commands/VersionCommandSpec.swift
Normal file
25
MasKitTests/Commands/VersionCommandSpec.swift
Normal file
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// VersionCommandSpec.swift
|
||||
// MasKitTests
|
||||
//
|
||||
// Created by Ben Chatelain on 2018-12-28.
|
||||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import MasKit
|
||||
import Result
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
class VersionCommandSpec: QuickSpec {
|
||||
override func spec() {
|
||||
describe("version command") {
|
||||
it("displays the current version") {
|
||||
let cmd = VersionCommand()
|
||||
let result = cmd.run(VersionCommand.Options())
|
||||
print(result)
|
||||
// expect(result).to(beSuccess())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,8 +15,8 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.5</string>
|
||||
<string>1.5.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>10500000</string>
|
||||
<string>10501000</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -9,14 +9,18 @@
|
|||
@testable import MasKit
|
||||
|
||||
class MockAppLibrary: AppLibrary {
|
||||
var apps = [SoftwareProduct]()
|
||||
var installedApps = [SoftwareProduct]()
|
||||
|
||||
func installedApp(appId: UInt64) -> SoftwareProduct? {
|
||||
return apps.first { $0.itemIdentifier == NSNumber(value: appId) }
|
||||
/// Finds an app using a bundle identifier.
|
||||
///
|
||||
/// - Parameter bundleId: Bundle identifier of app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
public func installedApp(forBundleId bundleId: String) -> SoftwareProduct? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func uninstallApp(app: SoftwareProduct) throws {
|
||||
if !apps.contains(where: { (product) -> Bool in
|
||||
if !installedApps.contains(where: { (product) -> Bool in
|
||||
return app.itemIdentifier == product.itemIdentifier
|
||||
}) { throw MASError.notInstalled }
|
||||
|
||||
|
@ -28,3 +32,11 @@ class MockAppLibrary: AppLibrary {
|
|||
// Success is the default, watch out for false positives!
|
||||
}
|
||||
}
|
||||
|
||||
/// Members not part of the AppLibrary protocol that are only for test state managment.
|
||||
extension MockAppLibrary {
|
||||
/// Clears out the list of installed apps.
|
||||
func reset() {
|
||||
installedApps = []
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,5 +11,6 @@
|
|||
struct MockSoftwareProduct: SoftwareProduct {
|
||||
var appName: String
|
||||
var bundlePath: String
|
||||
var bundleVersion: String
|
||||
var itemIdentifier: NSNumber
|
||||
}
|
||||
|
|
|
@ -31,6 +31,17 @@
|
|||
B594B13021D5855D00F3AC59 /* MasAppLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B12F21D5855D00F3AC59 /* MasAppLibrary.swift */; };
|
||||
B594B13221D5876200F3AC59 /* ResultPredicates.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B13121D5876200F3AC59 /* ResultPredicates.swift */; };
|
||||
B594B13421D5897100F3AC59 /* MockSoftwareProduct.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B13321D5897100F3AC59 /* MockSoftwareProduct.swift */; };
|
||||
B594B13621D6D68600F3AC59 /* VersionCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B13521D6D68600F3AC59 /* VersionCommandSpec.swift */; };
|
||||
B594B13821D6D6C100F3AC59 /* UpgradeCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B13721D6D6C100F3AC59 /* UpgradeCommandSpec.swift */; };
|
||||
B594B13A21D6D70400F3AC59 /* SignOutCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B13921D6D70400F3AC59 /* SignOutCommandSpec.swift */; };
|
||||
B594B13C21D6D72E00F3AC59 /* SignInCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B13B21D6D72E00F3AC59 /* SignInCommandSpec.swift */; };
|
||||
B594B13E21D6D78900F3AC59 /* SearchCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B13D21D6D78900F3AC59 /* SearchCommandSpec.swift */; };
|
||||
B594B14021D6D8BF00F3AC59 /* ResetCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B13F21D6D8BF00F3AC59 /* ResetCommandSpec.swift */; };
|
||||
B594B14221D6D8EC00F3AC59 /* OutdatedCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B14121D6D8EC00F3AC59 /* OutdatedCommandSpec.swift */; };
|
||||
B594B14421D6D91800F3AC59 /* LuckyCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B14321D6D91800F3AC59 /* LuckyCommandSpec.swift */; };
|
||||
B594B14621D6D95700F3AC59 /* InstallCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B14521D6D95700F3AC59 /* InstallCommandSpec.swift */; };
|
||||
B594B14821D6D98400F3AC59 /* InfoCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B14721D6D98400F3AC59 /* InfoCommandSpec.swift */; };
|
||||
B594B14A21D6D9AE00F3AC59 /* AccountCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B594B14921D6D9AE00F3AC59 /* AccountCommandSpec.swift */; };
|
||||
ED031A7C1B5127C00097692E /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED031A7B1B5127C00097692E /* main.swift */; };
|
||||
F83213892173D3E1008BA8A0 /* CKAccountStore.h in Headers */ = {isa = PBXBuildFile; fileRef = F8FB719B20F2EC4500F56FDC /* CKAccountStore.h */; };
|
||||
F832138A2173D3E1008BA8A0 /* CKDownloadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = F8FB719C20F2EC4500F56FDC /* CKDownloadQueue.h */; };
|
||||
|
@ -64,7 +75,6 @@
|
|||
F83213AA2173F5D0008BA8A0 /* Result.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 90CB4069213F4DDD0044E445 /* Result.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
F8FB715B20F2B41400F56FDC /* MasKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8FB715220F2B41400F56FDC /* MasKit.framework */; };
|
||||
F8FB716220F2B41400F56FDC /* MasKit.h in Headers */ = {isa = PBXBuildFile; fileRef = F8FB715420F2B41400F56FDC /* MasKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
F8FB716920F2B4DD00F56FDC /* CKSoftwareMap+AppLookup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4913269A1F48921D0010EB86 /* CKSoftwareMap+AppLookup.swift */; };
|
||||
F8FB716A20F2B4DD00F56FDC /* Downloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F238A1B87569C00AE40CD /* Downloader.swift */; };
|
||||
F8FB716B20F2B4DD00F56FDC /* ISStoreAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F238F1B87A56F00AE40CD /* ISStoreAccount.swift */; };
|
||||
F8FB716C20F2B4DD00F56FDC /* PurchaseDownloadObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F23881B87543D00AE40CD /* PurchaseDownloadObserver.swift */; };
|
||||
|
@ -153,7 +163,6 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
4913269A1F48921D0010EB86 /* CKSoftwareMap+AppLookup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CKSoftwareMap+AppLookup.swift"; sourceTree = "<group>"; };
|
||||
693A98981CBFFA760004D3B4 /* Search.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Search.swift; sourceTree = "<group>"; };
|
||||
693A989A1CBFFAAA0004D3B4 /* NSURLSession+Synchronous.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSURLSession+Synchronous.swift"; sourceTree = "<group>"; };
|
||||
8078FAA71EC4F2FB004B5B3F /* Lucky.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Lucky.swift; sourceTree = "<group>"; };
|
||||
|
@ -176,6 +185,17 @@
|
|||
B594B12F21D5855D00F3AC59 /* MasAppLibrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasAppLibrary.swift; sourceTree = "<group>"; };
|
||||
B594B13121D5876200F3AC59 /* ResultPredicates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultPredicates.swift; sourceTree = "<group>"; };
|
||||
B594B13321D5897100F3AC59 /* MockSoftwareProduct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSoftwareProduct.swift; sourceTree = "<group>"; };
|
||||
B594B13521D6D68600F3AC59 /* VersionCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionCommandSpec.swift; sourceTree = "<group>"; };
|
||||
B594B13721D6D6C100F3AC59 /* UpgradeCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpgradeCommandSpec.swift; sourceTree = "<group>"; };
|
||||
B594B13921D6D70400F3AC59 /* SignOutCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignOutCommandSpec.swift; sourceTree = "<group>"; };
|
||||
B594B13B21D6D72E00F3AC59 /* SignInCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignInCommandSpec.swift; sourceTree = "<group>"; };
|
||||
B594B13D21D6D78900F3AC59 /* SearchCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchCommandSpec.swift; sourceTree = "<group>"; };
|
||||
B594B13F21D6D8BF00F3AC59 /* ResetCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResetCommandSpec.swift; sourceTree = "<group>"; };
|
||||
B594B14121D6D8EC00F3AC59 /* OutdatedCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutdatedCommandSpec.swift; sourceTree = "<group>"; };
|
||||
B594B14321D6D91800F3AC59 /* LuckyCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LuckyCommandSpec.swift; sourceTree = "<group>"; };
|
||||
B594B14521D6D95700F3AC59 /* InstallCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstallCommandSpec.swift; sourceTree = "<group>"; };
|
||||
B594B14721D6D98400F3AC59 /* InfoCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InfoCommandSpec.swift; sourceTree = "<group>"; };
|
||||
B594B14921D6D9AE00F3AC59 /* AccountCommandSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountCommandSpec.swift; sourceTree = "<group>"; };
|
||||
ED031A781B5127C00097692E /* mas */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mas; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
ED031A7B1B5127C00097692E /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||
ED0F237E1B87522400AE40CD /* Install.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Install.swift; sourceTree = "<group>"; };
|
||||
|
@ -282,9 +302,20 @@
|
|||
B594B12321D57FF300F3AC59 /* Commands */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B594B14921D6D9AE00F3AC59 /* AccountCommandSpec.swift */,
|
||||
B594B14721D6D98400F3AC59 /* InfoCommandSpec.swift */,
|
||||
B594B14521D6D95700F3AC59 /* InstallCommandSpec.swift */,
|
||||
B594B12121D5416100F3AC59 /* ListCommandSpec.swift */,
|
||||
B594B14321D6D91800F3AC59 /* LuckyCommandSpec.swift */,
|
||||
B594B14121D6D8EC00F3AC59 /* OutdatedCommandSpec.swift */,
|
||||
B594B13F21D6D8BF00F3AC59 /* ResetCommandSpec.swift */,
|
||||
B594B13D21D6D78900F3AC59 /* SearchCommandSpec.swift */,
|
||||
B555292C219A1FE700ACB4CA /* SearchSpec.swift */,
|
||||
B594B13B21D6D72E00F3AC59 /* SignInCommandSpec.swift */,
|
||||
B594B13921D6D70400F3AC59 /* SignOutCommandSpec.swift */,
|
||||
B594B12421D580BB00F3AC59 /* UninstallCommandSpec.swift */,
|
||||
B594B13721D6D6C100F3AC59 /* UpgradeCommandSpec.swift */,
|
||||
B594B13521D6D68600F3AC59 /* VersionCommandSpec.swift */,
|
||||
);
|
||||
path = Commands;
|
||||
sourceTree = "<group>";
|
||||
|
@ -354,7 +385,6 @@
|
|||
ED0F238E1B87A54700AE40CD /* AppStore */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4913269A1F48921D0010EB86 /* CKSoftwareMap+AppLookup.swift */,
|
||||
B594B12A21D5837200F3AC59 /* CKSoftwareProduct+SoftwareProduct.swift */,
|
||||
ED0F238A1B87569C00AE40CD /* Downloader.swift */,
|
||||
ED0F238F1B87A56F00AE40CD /* ISStoreAccount.swift */,
|
||||
|
@ -668,14 +698,25 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B594B12221D5416100F3AC59 /* ListCommandSpec.swift in Sources */,
|
||||
B555292B219A1CB200ACB4CA /* MASErrorTestCase.swift in Sources */,
|
||||
B594B12E21D5850700F3AC59 /* MockAppLibrary.swift in Sources */,
|
||||
B594B13421D5897100F3AC59 /* MockSoftwareProduct.swift in Sources */,
|
||||
B5793E2B219BE0CD00135B39 /* MockURLSession.swift in Sources */,
|
||||
B594B13221D5876200F3AC59 /* ResultPredicates.swift in Sources */,
|
||||
B555292D219A1FE700ACB4CA /* SearchSpec.swift in Sources */,
|
||||
B555292B219A1CB200ACB4CA /* MASErrorTestCase.swift in Sources */,
|
||||
B594B13421D5897100F3AC59 /* MockSoftwareProduct.swift in Sources */,
|
||||
B594B14421D6D91800F3AC59 /* LuckyCommandSpec.swift in Sources */,
|
||||
B594B12221D5416100F3AC59 /* ListCommandSpec.swift in Sources */,
|
||||
B594B13C21D6D72E00F3AC59 /* SignInCommandSpec.swift in Sources */,
|
||||
B594B13A21D6D70400F3AC59 /* SignOutCommandSpec.swift in Sources */,
|
||||
B594B12521D580BB00F3AC59 /* UninstallCommandSpec.swift in Sources */,
|
||||
B594B13E21D6D78900F3AC59 /* SearchCommandSpec.swift in Sources */,
|
||||
B594B13821D6D6C100F3AC59 /* UpgradeCommandSpec.swift in Sources */,
|
||||
B594B14821D6D98400F3AC59 /* InfoCommandSpec.swift in Sources */,
|
||||
B555292D219A1FE700ACB4CA /* SearchSpec.swift in Sources */,
|
||||
B594B14621D6D95700F3AC59 /* InstallCommandSpec.swift in Sources */,
|
||||
B594B14021D6D8BF00F3AC59 /* ResetCommandSpec.swift in Sources */,
|
||||
B594B12E21D5850700F3AC59 /* MockAppLibrary.swift in Sources */,
|
||||
B594B14221D6D8EC00F3AC59 /* OutdatedCommandSpec.swift in Sources */,
|
||||
B594B13221D5876200F3AC59 /* ResultPredicates.swift in Sources */,
|
||||
B594B14A21D6D9AE00F3AC59 /* AccountCommandSpec.swift in Sources */,
|
||||
B594B13621D6D68600F3AC59 /* VersionCommandSpec.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -723,7 +764,7 @@
|
|||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CREATE_INFOPLIST_SECTION_IN_BINARY = YES;
|
||||
CURRENT_PROJECT_VERSION = 10500000;
|
||||
CURRENT_PROJECT_VERSION = 10501000;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
|
@ -788,7 +829,7 @@
|
|||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CREATE_INFOPLIST_SECTION_IN_BINARY = YES;
|
||||
CURRENT_PROJECT_VERSION = 10500000;
|
||||
CURRENT_PROJECT_VERSION = 10501000;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
|
@ -875,10 +916,10 @@
|
|||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 10500000;
|
||||
CURRENT_PROJECT_VERSION = 10501000;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 5.0;
|
||||
DYLIB_CURRENT_VERSION = 5.0;
|
||||
DYLIB_CURRENT_VERSION = 5.1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
@ -913,10 +954,10 @@
|
|||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 10500000;
|
||||
CURRENT_PROJECT_VERSION = 10501000;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 5.0;
|
||||
DYLIB_CURRENT_VERSION = 5.0;
|
||||
DYLIB_CURRENT_VERSION = 5.1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
|
10
mas.xcworkspace/contents.xcworkspacedata
generated
Normal file
10
mas.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "container:mas-cli.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
8
mas.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
Normal file
8
mas.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildSystemType</key>
|
||||
<string>Latest</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -11,6 +11,6 @@
|
|||
<key>CFBundleName</key>
|
||||
<string>mas-cli</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.5</string>
|
||||
<string>1.5.1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -23,7 +23,7 @@ main() {
|
|||
# but is set per-project or per-user. By default, this is set to `$(PROJECT_DIR)/build`.
|
||||
|
||||
test() {
|
||||
echo "==> 🏗️ Building"
|
||||
echo "==> ✅ Testing"
|
||||
set -o pipefail && \
|
||||
xcodebuild -project "$PROJECT" \
|
||||
-scheme "$SCHEME" \
|
||||
|
|
Loading…
Reference in a new issue