Break functionality out into separate files

This commit is contained in:
Andrew Naylor 2015-08-21 21:02:36 +08:00
parent 454d54517b
commit 76660f9635
9 changed files with 221 additions and 142 deletions

View file

@ -8,6 +8,13 @@
/* Begin PBXBuildFile section */
ED031A7C1B5127C00097692E /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED031A7B1B5127C00097692E /* main.swift */; };
ED0F237F1B87522400AE40CD /* Install.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F237E1B87522400AE40CD /* Install.swift */; };
ED0F23831B87533A00AE40CD /* ListInstalled.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F23821B87533A00AE40CD /* ListInstalled.swift */; };
ED0F23851B87536A00AE40CD /* ListUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F23841B87536A00AE40CD /* ListUpdates.swift */; };
ED0F23871B87537200AE40CD /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F23861B87537200AE40CD /* Account.swift */; };
ED0F23891B87543D00AE40CD /* DownloadQueueObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F23881B87543D00AE40CD /* DownloadQueueObserver.swift */; };
ED0F238B1B87569C00AE40CD /* Downloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F238A1B87569C00AE40CD /* Downloader.swift */; };
ED0F238D1B8756E600AE40CD /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F238C1B8756E600AE40CD /* Error.swift */; };
ED128ECA1B6C2A0B00C4050A /* ArgumentParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED128EC11B6C2A0B00C4050A /* ArgumentParser.swift */; };
ED128ECB1B6C2A0B00C4050A /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED128EC21B6C2A0B00C4050A /* Command.swift */; };
ED128ECC1B6C2A0B00C4050A /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED128EC41B6C2A0B00C4050A /* Errors.swift */; };
@ -37,6 +44,13 @@
/* Begin PBXFileReference section */
ED031A781B5127C00097692E /* mas-cli */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "mas-cli"; 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>"; };
ED0F23821B87533A00AE40CD /* ListInstalled.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListInstalled.swift; sourceTree = "<group>"; };
ED0F23841B87536A00AE40CD /* ListUpdates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListUpdates.swift; sourceTree = "<group>"; };
ED0F23861B87537200AE40CD /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
ED0F23881B87543D00AE40CD /* DownloadQueueObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloadQueueObserver.swift; sourceTree = "<group>"; };
ED0F238A1B87569C00AE40CD /* Downloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Downloader.swift; sourceTree = "<group>"; };
ED0F238C1B8756E600AE40CD /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Error.swift; sourceTree = "<group>"; };
ED128EC11B6C2A0B00C4050A /* ArgumentParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArgumentParser.swift; sourceTree = "<group>"; };
ED128EC21B6C2A0B00C4050A /* Command.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Command.swift; sourceTree = "<group>"; };
ED128EC31B6C2A0B00C4050A /* Commandant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Commandant.h; sourceTree = "<group>"; };
@ -275,12 +289,28 @@
ED031A7A1B5127C00097692E /* mas-cli */ = {
isa = PBXGroup;
children = (
ED0F23801B87524700AE40CD /* Commands */,
ED0F238A1B87569C00AE40CD /* Downloader.swift */,
ED0F23881B87543D00AE40CD /* DownloadQueueObserver.swift */,
ED0F238C1B8756E600AE40CD /* Error.swift */,
ED031A7B1B5127C00097692E /* main.swift */,
EDEAA12C1B51CF8000F2FC3F /* mas-cli-Bridging-Header.h */,
);
path = "mas-cli";
sourceTree = "<group>";
};
ED0F23801B87524700AE40CD /* Commands */ = {
isa = PBXGroup;
children = (
ED0F23861B87537200AE40CD /* Account.swift */,
ED0F237E1B87522400AE40CD /* Install.swift */,
ED0F23821B87533A00AE40CD /* ListInstalled.swift */,
ED0F23841B87536A00AE40CD /* ListUpdates.swift */,
);
name = Commands;
path = "mas-cli/Commands";
sourceTree = SOURCE_ROOT;
};
ED128EC91B6C2A0B00C4050A /* Commandant */ = {
isa = PBXGroup;
children = (
@ -590,7 +620,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
ED0F23871B87537200AE40CD /* Account.swift in Sources */,
ED0F238B1B87569C00AE40CD /* Downloader.swift in Sources */,
ED0F23891B87543D00AE40CD /* DownloadQueueObserver.swift in Sources */,
ED0F238D1B8756E600AE40CD /* Error.swift in Sources */,
ED128ECC1B6C2A0B00C4050A /* Errors.swift in Sources */,
ED0F237F1B87522400AE40CD /* Install.swift in Sources */,
ED0F23831B87533A00AE40CD /* ListInstalled.swift in Sources */,
ED0F23851B87536A00AE40CD /* ListUpdates.swift in Sources */,
ED031A7C1B5127C00097692E /* main.swift in Sources */,
ED128EDE1B6C2B4400C4050A /* MutableBox.swift in Sources */,
ED128ECA1B6C2A0B00C4050A /* ArgumentParser.swift in Sources */,

View file

@ -0,0 +1,22 @@
//
// Account.swift
// mas-cli
//
// Created by Andrew Naylor on 21/08/2015.
// Copyright (c) 2015 Andrew Naylor. All rights reserved.
//
struct AccountCommand: CommandType {
let verb = "account"
let function = "Prints the primary account Apple ID"
func run(mode: CommandMode) -> Result<(), CommandantError<MASError>> {
switch mode {
case .Arguments:
print(primaryAccount().identifier)
default:
break
}
return .success(())
}
}

View file

@ -0,0 +1,36 @@
//
// Install.swift
// mas-cli
//
// Created by Andrew Naylor on 21/08/2015.
// Copyright (c) 2015 Andrew Naylor. All rights reserved.
//
struct InstallCommand: CommandType {
let verb = "install"
let function = "Install from the Mac App Store"
func run(mode: CommandMode) -> Result<(), CommandantError<MASError>> {
return InstallOptions.evaluate(mode).map { options in
download(options.appId) { (purchase, completed, error, response) in
print(purchase)
print(completed)
print(error)
print(response)
}
}
}
}
struct InstallOptions: OptionsType {
let appId: UInt64
static func create(appId: Int) -> InstallOptions {
return InstallOptions(appId: UInt64(appId))
}
static func evaluate(m: CommandMode) -> Result<InstallOptions, CommandantError<MASError>> {
return create
<*> m <| Option(key: nil, defaultValue: nil, usage: "the app ID to install")
}
}

View file

@ -0,0 +1,28 @@
//
// ListInstalled.swift
// mas-cli
//
// Created by Andrew Naylor on 21/08/2015.
// Copyright (c) 2015 Andrew Naylor. All rights reserved.
//
struct ListInstalledCommand: CommandType {
let verb = "list-installed"
let function = "Lists apps from the Mac App Store which are currently installed"
func run(mode: CommandMode) -> Result<(), CommandantError<MASError>> {
switch mode {
case .Arguments:
let softwareMap = CKSoftwareMap.sharedSoftwareMap()
let products = softwareMap.allProducts() as! [CKSoftwareProduct]
products.map({ product -> Bool in
println("\(product.itemIdentifier) \(product.appName)")
return true
})
default:
break
}
return .success(())
}
}

View file

@ -0,0 +1,23 @@
//
// ListUpdates.swift
// mas-cli
//
// Created by Andrew Naylor on 21/08/2015.
// Copyright (c) 2015 Andrew Naylor. All rights reserved.
//
struct ListUpdatesCommand: CommandType {
let verb = "list-updates"
let function = "Lists pending updates from the Mac App Store"
func run(mode: CommandMode) -> Result<(), CommandantError<MASError>> {
switch mode {
case .Arguments:
let updateController = CKUpdateController.sharedUpdateController()
print(updateController.availableUpdates())
default:
break
}
return .success(())
}
}

View file

@ -0,0 +1,27 @@
//
// DownloadQueueObserver.swift
// mas-cli
//
// Created by Andrew Naylor on 21/08/2015.
// Copyright (c) 2015 Andrew Naylor. All rights reserved.
//
@objc class DownloadQueueObserver: CKDownloadQueueObserver {
func downloadQueue(queue: CKDownloadQueue, statusChangedForDownload download: SSDownload!) {
if let activePhase = download.status.activePhase {
let percentage = String(Int(floor(download.status.percentComplete * 100))) + "%"
// let phase = String(activePhase.phaseType)
print("\(csi)2K\(csi)0G" + percentage)
}
}
func downloadQueue(queue: CKDownloadQueue, changedWithAddition download: SSDownload!) {
print("Downloading: " + download.metadata.title)
}
func downloadQueue(queue: CKDownloadQueue, changedWithRemoval download: SSDownload!) {
print("")
print("Finished: " + download.metadata.title)
exit(EXIT_SUCCESS)
}
}

30
mas-cli/Downloader.swift Normal file
View file

@ -0,0 +1,30 @@
//
// Downloader.swift
// mas-cli
//
// Created by Andrew Naylor on 21/08/2015.
// Copyright (c) 2015 Andrew Naylor. All rights reserved.
//
typealias DownloadCompletion = (purchase: SSPurchase!, completed: Bool, error: NSError?, response: SSPurchaseResponse!) -> ()
func download(adamId: UInt64, completion:DownloadCompletion) {
let buyParameters = "productType=C&price=0&salableAdamId=\(String(adamId))&pricingParameters=STDRDL"
let purchase = SSPurchase()
purchase.buyParameters = buyParameters
purchase.itemIdentifier = adamId
purchase.accountIdentifier = primaryAccount().dsID
purchase.appleID = primaryAccount().identifier
let downloadMetadata = SSDownloadMetadata()
downloadMetadata.kind = "software"
downloadMetadata.itemIdentifier = adamId
purchase.downloadMetadata = downloadMetadata
let purchaseController = CKPurchaseController.sharedPurchaseController()
purchaseController.performPurchase(purchase, withOptions: 0, completionHandler: completion)
while true {
NSRunLoop.mainRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate(timeIntervalSinceNow: 10))
}
}

17
mas-cli/Error.swift Normal file
View file

@ -0,0 +1,17 @@
//
// Error.swift
// mas-cli
//
// Created by Andrew Naylor on 21/08/2015.
// Copyright (c) 2015 Andrew Naylor. All rights reserved.
//
public enum MASError: Equatable {
public var description: String {
return ""
}
}
public func == (lhs: MASError, rhs: MASError) -> Bool {
return false
}

View file

@ -15,149 +15,8 @@ func primaryAccount() -> ISStoreAccount {
return accountController.primaryAccount
}
@objc class Observer: CKDownloadQueueObserver {
func downloadQueue(queue: CKDownloadQueue, statusChangedForDownload download: SSDownload!) {
if let activePhase = download.status.activePhase {
let percentage = String(Int(floor(download.status.percentComplete * 100))) + "%"
// let phase = String(activePhase.phaseType)
print("\u{001B}[2K\r" + percentage + " " + download.metadata.title)
}
}
func downloadQueue(queue: CKDownloadQueue, changedWithAddition download: SSDownload!) {
print("Downloading: " + download.metadata.title)
}
func downloadQueue(queue: CKDownloadQueue, changedWithRemoval download: SSDownload!) {
print("")
print("Finished: " + download.metadata.title)
exit(EXIT_SUCCESS)
}
}
var downloadQueue = CKDownloadQueue.sharedDownloadQueue()
downloadQueue.addObserver(Observer())
var softwareMap = CKSoftwareMap.sharedSoftwareMap()
//print(softwareMap.allProducts())
//print(softwareMap.productForBundleIdentifier("com.apple.iBooksAuthor"))
//print(softwareMap.adaptableBundleIdentifiers())
func download(adamId: UInt64, completion:(purchase: SSPurchase!, completed: Bool, error: NSError?, response: SSPurchaseResponse!) -> ()) {
let buyParameters = "productType=C&price=0&salableAdamId=" + String(adamId) + "&pricingParameters=STDRDL"
let purchase = SSPurchase()
purchase.buyParameters = buyParameters
purchase.itemIdentifier = adamId
purchase.accountIdentifier = primaryAccount().dsID
purchase.appleID = primaryAccount().identifier
let downloadMetadata = SSDownloadMetadata()
downloadMetadata.kind = "software"
downloadMetadata.itemIdentifier = adamId
purchase.downloadMetadata = downloadMetadata
let purchaseController = CKPurchaseController.sharedPurchaseController()
purchaseController.performPurchase(purchase, withOptions: 0, completionHandler: completion)
while true {
NSRunLoop.mainRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate(timeIntervalSinceNow: 10))
}
}
let paintCode: UInt64 = 808809998
let xcode: UInt64 = 497799835
let aperture: UInt64 = 408981426
struct AccountCommand: CommandType {
let verb = "account"
let function = "Prints the primary account Apple ID"
func run(mode: CommandMode) -> Result<(), CommandantError<MASError>> {
switch mode {
case .Arguments:
print(primaryAccount().identifier)
default:
break
}
return .success(())
}
}
struct InstallCommand: CommandType {
let verb = "install"
let function = "Install from the Mac App Store"
func run(mode: CommandMode) -> Result<(), CommandantError<MASError>> {
return InstallOptions.evaluate(mode).map { options in
download(options.appId) { (purchase, completed, error, response) in
print(purchase)
print(completed)
print(error)
print(response)
}
}
}
}
struct InstallOptions: OptionsType {
let appId: UInt64
static func create(appId: Int) -> InstallOptions {
return InstallOptions(appId: UInt64(appId))
}
static func evaluate(m: CommandMode) -> Result<InstallOptions, CommandantError<MASError>> {
return create
<*> m <| Option(key: nil, defaultValue: nil, usage: "the app ID to install")
}
}
struct ListUpdatesCommand: CommandType {
let verb = "list-updates"
let function = "Lists pending updates from the Mac App Store"
func run(mode: CommandMode) -> Result<(), CommandantError<MASError>> {
switch mode {
case .Arguments:
let updateController = CKUpdateController.sharedUpdateController()
print(updateController.availableUpdates())
default:
break
}
return .success(())
}
}
struct ListInstalledCommand: CommandType {
let verb = "list-installed"
let function = "Lists apps from the Mac App Store which are currently installed"
func run(mode: CommandMode) -> Result<(), CommandantError<MASError>> {
switch mode {
case .Arguments:
let softwareMap = CKSoftwareMap.sharedSoftwareMap()
let products = softwareMap.allProducts()
products.map({ product -> Bool in
print(String(product.itemIdentifier) + " " + product.appName)
return true
})
default:
break
}
return .success(())
}
}
public enum MASError: Equatable {
public var description: String {
return ""
}
}
public func == (lhs: MASError, rhs: MASError) -> Bool {
return false
}
downloadQueue.addObserver(DownloadQueueObserver())
let registry = CommandRegistry<MASError>()
let helpCommand = HelpCommand(registry: registry)