mirror of
https://github.com/mas-cli/mas
synced 2025-02-19 14:08:30 +00:00
🙈 hide unnecessary publics and @objc types
This commit is contained in:
parent
6b8e91b136
commit
a27cc68d2c
22 changed files with 97 additions and 66 deletions
MasKit
Commands
Controllers
ExternalCommands
Models
Network
MasKitTests
mas
|
@ -19,8 +19,15 @@ public struct HomeCommand: CommandProtocol {
|
|||
private let storeSearch: StoreSearch
|
||||
private var openCommand: ExternalCommand
|
||||
|
||||
public init() {
|
||||
self.init(
|
||||
storeSearch: MasStoreSearch(),
|
||||
openCommand: OpenSystemCommand()
|
||||
)
|
||||
}
|
||||
|
||||
/// Designated initializer.
|
||||
public init(
|
||||
init(
|
||||
storeSearch: StoreSearch = MasStoreSearch(),
|
||||
openCommand: ExternalCommand = OpenSystemCommand()
|
||||
) {
|
||||
|
|
|
@ -17,8 +17,12 @@ public struct InfoCommand: CommandProtocol {
|
|||
|
||||
private let storeSearch: StoreSearch
|
||||
|
||||
public init() {
|
||||
self.init(storeSearch: MasStoreSearch())
|
||||
}
|
||||
|
||||
/// Designated initializer.
|
||||
public init(storeSearch: StoreSearch = MasStoreSearch()) {
|
||||
init(storeSearch: StoreSearch = MasStoreSearch()) {
|
||||
self.storeSearch = storeSearch
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,13 @@ public struct LuckyCommand: CommandProtocol {
|
|||
private let appLibrary: AppLibrary
|
||||
private let storeSearch: StoreSearch
|
||||
|
||||
/// Public initializer.
|
||||
public init() {
|
||||
self.init(storeSearch: MasStoreSearch())
|
||||
}
|
||||
|
||||
/// Designated initializer.
|
||||
/// - Parameter storeSearch: Search manager.
|
||||
public init(storeSearch: StoreSearch = MasStoreSearch()) {
|
||||
init(storeSearch: StoreSearch = MasStoreSearch()) {
|
||||
self.init(appLibrary: MasAppLibrary(), storeSearch: storeSearch)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,15 @@ public struct OpenCommand: CommandProtocol {
|
|||
private let storeSearch: StoreSearch
|
||||
private var systemOpen: ExternalCommand
|
||||
|
||||
public init() {
|
||||
self.init(
|
||||
storeSearch: MasStoreSearch(),
|
||||
openCommand: OpenSystemCommand()
|
||||
)
|
||||
}
|
||||
|
||||
/// Designated initializer.
|
||||
public init(
|
||||
init(
|
||||
storeSearch: StoreSearch = MasStoreSearch(),
|
||||
openCommand: ExternalCommand = OpenSystemCommand()
|
||||
) {
|
||||
|
|
|
@ -17,10 +17,14 @@ public struct SearchCommand: CommandProtocol {
|
|||
|
||||
private let storeSearch: StoreSearch
|
||||
|
||||
public init() {
|
||||
self.init(storeSearch: MasStoreSearch())
|
||||
}
|
||||
|
||||
/// Designated initializer.
|
||||
///
|
||||
/// - Parameter storeSearch: Search manager.
|
||||
public init(storeSearch: StoreSearch = MasStoreSearch()) {
|
||||
init(storeSearch: StoreSearch = MasStoreSearch()) {
|
||||
self.storeSearch = storeSearch
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,15 @@ public struct VendorCommand: CommandProtocol {
|
|||
private let storeSearch: StoreSearch
|
||||
private var openCommand: ExternalCommand
|
||||
|
||||
public init() {
|
||||
self.init(
|
||||
storeSearch: MasStoreSearch(),
|
||||
openCommand: OpenSystemCommand()
|
||||
)
|
||||
}
|
||||
|
||||
/// Designated initializer.
|
||||
public init(
|
||||
init(
|
||||
storeSearch: StoreSearch = MasStoreSearch(),
|
||||
openCommand: ExternalCommand = OpenSystemCommand()
|
||||
) {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import Foundation
|
||||
|
||||
/// Utility for managing installed apps.
|
||||
public protocol AppLibrary {
|
||||
protocol AppLibrary {
|
||||
/// Entire set of installed apps.
|
||||
var installedApps: [SoftwareProduct] { get }
|
||||
|
||||
|
@ -44,7 +44,7 @@ extension AppLibrary {
|
|||
///
|
||||
/// - Parameter id: MAS ID for app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
public func installedApp(forId identifier: UInt64) -> SoftwareProduct? {
|
||||
func installedApp(forId identifier: UInt64) -> SoftwareProduct? {
|
||||
let appId = NSNumber(value: identifier)
|
||||
return installedApps.first { $0.itemIdentifier == appId }
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ extension AppLibrary {
|
|||
///
|
||||
/// - Parameter appName: Full title of an app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
public func installedApp(named appName: String) -> SoftwareProduct? {
|
||||
func installedApp(named appName: String) -> SoftwareProduct? {
|
||||
installedApps.first { $0.appName == appName }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
import CommerceKit
|
||||
|
||||
/// Utility for managing installed apps.
|
||||
public class MasAppLibrary: AppLibrary {
|
||||
class MasAppLibrary: AppLibrary {
|
||||
/// CommerceKit's singleton manager of installed software.
|
||||
private let softwareMap: SoftwareMap
|
||||
|
||||
/// Array of installed software products.
|
||||
public lazy var installedApps: [SoftwareProduct] = {
|
||||
lazy var installedApps: [SoftwareProduct] = {
|
||||
softwareMap.allSoftwareProducts()
|
||||
}()
|
||||
|
||||
|
@ -28,7 +28,7 @@ public class MasAppLibrary: AppLibrary {
|
|||
///
|
||||
/// - Parameter bundleId: Bundle identifier of app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
public func installedApp(forBundleId bundleId: String) -> SoftwareProduct? {
|
||||
func installedApp(forBundleId bundleId: String) -> SoftwareProduct? {
|
||||
softwareMap.product(for: bundleId)
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ public class MasAppLibrary: AppLibrary {
|
|||
///
|
||||
/// - Parameter app: App to be removed.
|
||||
/// - Throws: Error if there is a problem.
|
||||
public func uninstallApp(app: SoftwareProduct) throws {
|
||||
func uninstallApp(app: SoftwareProduct) throws {
|
||||
if !userIsRoot() {
|
||||
printWarning("Apps installed from the Mac App Store require root permission to remove.")
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import Foundation
|
|||
import Version
|
||||
|
||||
/// Manages searching the MAS catalog through the iTunes Search and Lookup APIs.
|
||||
public class MasStoreSearch: StoreSearch {
|
||||
class MasStoreSearch: StoreSearch {
|
||||
private let networkManager: NetworkManager
|
||||
private static let versionExpression: NSRegularExpression? = {
|
||||
do {
|
||||
|
@ -21,7 +21,7 @@ public class MasStoreSearch: StoreSearch {
|
|||
}()
|
||||
|
||||
/// Designated initializer.
|
||||
public init(networkManager: NetworkManager = NetworkManager()) {
|
||||
init(networkManager: NetworkManager = NetworkManager()) {
|
||||
self.networkManager = networkManager
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class MasStoreSearch: StoreSearch {
|
|||
/// - Parameter appName: MAS ID of app
|
||||
/// - Parameter completion: A closure that receives the search results or an Error if there is a
|
||||
/// problem with the network request. Results array will be empty if there were no matches.
|
||||
public func search(for appName: String, _ completion: @escaping ([SearchResult]?, Error?) -> Void) {
|
||||
func search(for appName: String, _ completion: @escaping ([SearchResult]?, Error?) -> Void) {
|
||||
guard let url = searchURL(for: appName)
|
||||
else {
|
||||
completion(nil, MASError.urlEncoding)
|
||||
|
@ -52,7 +52,7 @@ public class MasStoreSearch: StoreSearch {
|
|||
/// - Parameter appId: MAS ID of app
|
||||
/// - Parameter completion: A closure that receives the search result record of app, or nil if no apps match the ID,
|
||||
/// or an Error if there is a problem with the network request.
|
||||
public func lookup(app appId: Int, _ completion: @escaping (SearchResult?, Error?) -> Void) {
|
||||
func lookup(app appId: Int, _ completion: @escaping (SearchResult?, Error?) -> Void) {
|
||||
guard let url = lookupURL(forApp: appId)
|
||||
else {
|
||||
completion(nil, MASError.urlEncoding)
|
||||
|
@ -69,7 +69,7 @@ public class MasStoreSearch: StoreSearch {
|
|||
}
|
||||
}
|
||||
|
||||
public func loadSearchResults(_ url: URL, _ completion: @escaping ([SearchResult]?, Error?) -> Void) {
|
||||
private func loadSearchResults(_ url: URL, _ completion: @escaping ([SearchResult]?, Error?) -> Void) {
|
||||
networkManager.loadData(from: url) { data, error in
|
||||
guard let data = data else {
|
||||
if let error = error {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import Foundation
|
||||
|
||||
/// Protocol for searching the MAS catalog.
|
||||
public protocol StoreSearch {
|
||||
protocol StoreSearch {
|
||||
func lookup(app appId: Int, _ completion: @escaping (SearchResult?, Error?) -> Void)
|
||||
func search(for appName: String, _ completion: @escaping ([SearchResult]?, Error?) -> Void)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ extension StoreSearch {
|
|||
/// - Parameter appId: MAS ID of app
|
||||
/// - Returns: Search result record of app or nil if no apps match the ID.
|
||||
/// - Throws: Error if there is a problem with the network request.
|
||||
public func lookup(app appId: Int) throws -> SearchResult? {
|
||||
func lookup(app appId: Int) throws -> SearchResult? {
|
||||
var result: SearchResult?
|
||||
var error: Error?
|
||||
|
||||
|
@ -47,7 +47,7 @@ extension StoreSearch {
|
|||
/// - Parameter appName: MAS ID of app
|
||||
/// - Returns: Search results. Empty if there were no matches.
|
||||
/// - Throws: Error if there is a problem with the network request.
|
||||
public func search(for appName: String) throws -> [SearchResult] {
|
||||
func search(for appName: String) throws -> [SearchResult] {
|
||||
var results: [SearchResult]?
|
||||
var error: Error?
|
||||
|
||||
|
@ -72,7 +72,7 @@ extension StoreSearch {
|
|||
///
|
||||
/// - Parameter appName: MAS app identifier.
|
||||
/// - Returns: URL for the search service or nil if appName can't be encoded.
|
||||
public func searchURL(for appName: String) -> URL? {
|
||||
func searchURL(for appName: String) -> URL? {
|
||||
guard let urlString = searchURLString(forApp: appName) else { return nil }
|
||||
return URL(string: urlString)
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ extension StoreSearch {
|
|||
///
|
||||
/// - Parameter appId: MAS app identifier.
|
||||
/// - Returns: URL for the lookup service or nil if appId can't be encoded.
|
||||
public func lookupURL(forApp appId: Int) -> URL? {
|
||||
func lookupURL(forApp appId: Int) -> URL? {
|
||||
guard let urlString = lookupURLString(forApp: appId) else { return nil }
|
||||
return URL(string: urlString)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import Foundation
|
||||
|
||||
/// CLI command
|
||||
public protocol ExternalCommand {
|
||||
protocol ExternalCommand {
|
||||
var binaryPath: String { get set }
|
||||
|
||||
var process: Process { get }
|
||||
|
@ -29,30 +29,30 @@ public protocol ExternalCommand {
|
|||
|
||||
/// Common implementation
|
||||
extension ExternalCommand {
|
||||
public var stdout: String {
|
||||
var stdout: String {
|
||||
let data = stdoutPipe.fileHandleForReading.readDataToEndOfFile()
|
||||
return String(data: data, encoding: .utf8) ?? ""
|
||||
}
|
||||
|
||||
public var stderr: String {
|
||||
var stderr: String {
|
||||
let data = stderrPipe.fileHandleForReading.readDataToEndOfFile()
|
||||
return String(data: data, encoding: .utf8) ?? ""
|
||||
}
|
||||
|
||||
public var exitCode: Int32 {
|
||||
var exitCode: Int32 {
|
||||
process.terminationStatus
|
||||
}
|
||||
|
||||
public var succeeded: Bool {
|
||||
var succeeded: Bool {
|
||||
process.terminationReason == .exit && exitCode == 0
|
||||
}
|
||||
|
||||
public var failed: Bool {
|
||||
var failed: Bool {
|
||||
!succeeded
|
||||
}
|
||||
|
||||
/// Runs the command.
|
||||
public func run(arguments: String...) throws {
|
||||
func run(arguments: String...) throws {
|
||||
process.standardOutput = stdoutPipe
|
||||
process.standardError = stderrPipe
|
||||
process.arguments = arguments
|
||||
|
|
|
@ -10,17 +10,15 @@ import Foundation
|
|||
|
||||
/// Wrapper for the external open system command.
|
||||
/// https://ss64.com/osx/open.html
|
||||
public struct OpenSystemCommand: ExternalCommand {
|
||||
public var binaryPath: String
|
||||
struct OpenSystemCommand: ExternalCommand {
|
||||
var binaryPath: String
|
||||
|
||||
public let process = Process()
|
||||
let process = Process()
|
||||
|
||||
public let stdoutPipe = Pipe()
|
||||
public let stderrPipe = Pipe()
|
||||
let stdoutPipe = Pipe()
|
||||
let stderrPipe = Pipe()
|
||||
|
||||
public init(
|
||||
binaryPath: String = "/usr/bin/open"
|
||||
) {
|
||||
init(binaryPath: String = "/usr/bin/open") {
|
||||
self.binaryPath = binaryPath
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,20 +6,20 @@
|
|||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
public struct SearchResult: Decodable {
|
||||
public var bundleId: String
|
||||
public var currentVersionReleaseDate: String
|
||||
public var fileSizeBytes: String?
|
||||
public var formattedPrice: String?
|
||||
public var minimumOsVersion: String
|
||||
public var price: Double?
|
||||
public var sellerName: String
|
||||
public var sellerUrl: String?
|
||||
public var trackId: Int
|
||||
public var trackCensoredName: String
|
||||
public var trackName: String
|
||||
public var trackViewUrl: String
|
||||
public var version: String
|
||||
struct SearchResult: Decodable {
|
||||
var bundleId: String
|
||||
var currentVersionReleaseDate: String
|
||||
var fileSizeBytes: String?
|
||||
var formattedPrice: String?
|
||||
var minimumOsVersion: String
|
||||
var price: Double?
|
||||
var sellerName: String
|
||||
var sellerUrl: String?
|
||||
var trackId: Int
|
||||
var trackCensoredName: String
|
||||
var trackName: String
|
||||
var trackViewUrl: String
|
||||
var version: String
|
||||
|
||||
init(
|
||||
bundleId: String = "",
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// Copyright © 2018 mas-cli. All rights reserved.
|
||||
//
|
||||
|
||||
public struct SearchResultList: Decodable {
|
||||
struct SearchResultList: Decodable {
|
||||
var resultCount: Int
|
||||
var results: [SearchResult]
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import Foundation
|
|||
import Version
|
||||
|
||||
/// Protocol describing the members of CKSoftwareProduct used throughout MasKit.
|
||||
public protocol SoftwareProduct {
|
||||
protocol SoftwareProduct {
|
||||
var appName: String { get }
|
||||
var bundleIdentifier: String { get set }
|
||||
var bundlePath: String { get set }
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
import Foundation
|
||||
|
||||
/// Network abstraction
|
||||
public class NetworkManager {
|
||||
class NetworkManager {
|
||||
private let session: NetworkSession
|
||||
|
||||
/// Designated initializer
|
||||
///
|
||||
/// - Parameter session: A networking session.
|
||||
public init(session: NetworkSession = URLSession(configuration: .ephemeral)) {
|
||||
init(session: NetworkSession = URLSession(configuration: .ephemeral)) {
|
||||
self.session = session
|
||||
|
||||
// Older releases allowed URLSession to write a cache. We clean it up here.
|
||||
|
|
|
@ -8,6 +8,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
@objc public protocol NetworkSession {
|
||||
@objc func loadData(from url: URL, completionHandler: @escaping (Data?, Error?) -> Void)
|
||||
protocol NetworkSession {
|
||||
func loadData(from url: URL, completionHandler: @escaping (Data?, Error?) -> Void)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import Foundation
|
||||
|
||||
extension URLSession: NetworkSession {
|
||||
@objc open func loadData(from url: URL, completionHandler: @escaping (Data?, Error?) -> Void) {
|
||||
open func loadData(from url: URL, completionHandler: @escaping (Data?, Error?) -> Void) {
|
||||
let task = dataTask(with: url) { data, _, error in
|
||||
completionHandler(data, error)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ class AppLibraryMock: AppLibrary {
|
|||
///
|
||||
/// - Parameter bundleId: Bundle identifier of app.
|
||||
/// - Returns: Software Product of app if found; nil otherwise.
|
||||
public func installedApp(forBundleId _: String) -> SoftwareProduct? {
|
||||
func installedApp(forBundleId _: String) -> SoftwareProduct? {
|
||||
nil
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import MasKit
|
||||
@testable import MasKit
|
||||
|
||||
/// Mock NetworkSession for testing.
|
||||
class NetworkSessionMock: NetworkSession {
|
||||
|
@ -38,7 +38,7 @@ class NetworkSessionMock: NetworkSession {
|
|||
/// - Parameters:
|
||||
/// - url: unused
|
||||
/// - completionHandler: Closure which is delivered either data or an error.
|
||||
@objc func loadData(from _: URL, completionHandler: @escaping (Data?, Error?) -> Void) {
|
||||
func loadData(from _: URL, completionHandler: @escaping (Data?, Error?) -> Void) {
|
||||
completionHandler(data, error)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class NetworkSessionMockFromFile: NetworkSessionMock {
|
|||
/// - Parameters:
|
||||
/// - url: unused
|
||||
/// - completionHandler: Closure which is delivered either data or an error.
|
||||
@objc override func loadData(from _: URL, completionHandler: @escaping (Data?, Error?) -> Void) {
|
||||
override func loadData(from _: URL, completionHandler: @escaping (Data?, Error?) -> Void) {
|
||||
guard let fileURL = Bundle.url(for: responseFile)
|
||||
else { fatalError("Unable to load file \(responseFile)") }
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ import Commandant
|
|||
import Foundation
|
||||
import MasKit
|
||||
|
||||
public struct StderrOutputStream: TextOutputStream {
|
||||
public mutating func write(_ string: String) {
|
||||
struct StderrOutputStream: TextOutputStream {
|
||||
mutating func write(_ string: String) {
|
||||
fputs(string, stderr)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue