♻️ Refactor AppLibrary to use TrashCommand

This commit is contained in:
Ben Chatelain 2019-01-02 23:16:45 -08:00
parent 3630df5750
commit ae8d8f5f46
3 changed files with 23 additions and 53 deletions

View file

@ -13,8 +13,8 @@ public protocol ExternalCommand {
var process: Process { get }
var stdout: String? { get }
var stderr: String? { get }
var stdout: String { get }
var stderr: String { get }
var stdoutPipe: Pipe { get }
var stderrPipe: Pipe { get }
@ -23,19 +23,19 @@ public protocol ExternalCommand {
var failed: Bool { get }
/// Runs the command.
mutating func run() throws
func run() throws
}
/// Common implementation
extension ExternalCommand {
public var stdout: String? { get {
public var stdout: String { get {
let data = stdoutPipe.fileHandleForReading.readDataToEndOfFile()
return String(data: data, encoding: .utf8)
return String(data: data, encoding: .utf8) ?? ""
}}
public var stderr: String? { get {
public var stderr: String { get {
let data = stderrPipe.fileHandleForReading.readDataToEndOfFile()
return String(data: data, encoding: .utf8)
return String(data: data, encoding: .utf8) ?? ""
}}
public var exitCode: Int? { get {
@ -51,7 +51,7 @@ extension ExternalCommand {
}}
/// Runs the command.
public mutating func run() throws {
public func run() throws {
process.standardOutput = stdoutPipe
process.standardError = stderrPipe
process.arguments = arguments

View file

@ -6,7 +6,9 @@
// Copyright © 2019 mas-cli. All rights reserved.
//
/// CLI command
/// Wrapper for the external trash command. Relies on the "trash" command
/// from Homebrew. Trash requires el_capitan or higher for core bottles:
/// https://github.com/Homebrew/homebrew-core/blob/master/Formula/trash.rb
public struct TrashCommand: ExternalCommand {
public var binaryPath: String
public var arguments: [String]

View file

@ -22,8 +22,9 @@ public class MasAppLibrary: AppLibrary {
return products
}()
private let trashCommand: ExternalCommand
private var trashCommand: ExternalCommand
/// Designated initializer
public init(trashCommand: ExternalCommand = TrashCommand()) {
self.trashCommand = trashCommand
}
@ -41,50 +42,17 @@ public class MasAppLibrary: AppLibrary {
/// - Parameter app: App to be removed.
/// - Throws: Error if there is a problem.
public func uninstallApp(app: SoftwareProduct) throws {
let status = trash(path: app.bundlePath)
if !status {
trashCommand.arguments = [app.bundlePath]
do {
try trashCommand.run()
} catch {
printError("Unable to launch trash command")
throw MASError.uninstallFailed
}
if trashCommand.failed {
let reason = trashCommand.process.terminationReason
printError("Uninstall failed: (\(reason)) \(trashCommand.stderr)")
throw MASError.uninstallFailed
}
}
/// Runs the trash command in another process. Relies on the "trash" command
/// from Homebrew. Trash requires el_capitan or higher for core bottles:
/// https://github.com/Homebrew/homebrew-core/blob/master/Formula/trash.rb
///
/// - Parameter path: Absolute path to the application bundle to uninstall.
/// - Returns: true on success; fail on error
func trash(path: String) -> Bool {
let binaryPath = "/usr/local/bin/trash"
let process = Process()
let stdout = Pipe()
let stderr = Pipe()
process.standardOutput = stdout
process.standardError = stderr
process.arguments = [path]
if #available(OSX 10.13, *) {
process.executableURL = URL(fileURLWithPath: binaryPath)
do {
try process.run()
} catch {
printError("Unable to launch trash command")
return false
}
} else {
process.launchPath = binaryPath
process.launch()
}
process.waitUntilExit()
if process.terminationStatus == 0 {
return true
} else {
let reason = process.terminationReason
let output = stderr.fileHandleForReading.readDataToEndOfFile()
printError("Uninstall failed: \(reason)\n\(String(data: output, encoding: .utf8)!)")
return false
}
}
}