From da3a0f5361150112de1d789d05f68db3bc766465 Mon Sep 17 00:00:00 2001 From: Kare Morstol Date: Thu, 6 Aug 2015 02:56:22 +0200 Subject: [PATCH] Add $(bash:) . Refactor command.swift. Had to add leading spaces (shudder) to the documentation comment to get Xcode to render it properly. Hopefully this is just a temporary fix. --- SwiftShell/Command.swift | 52 ++++++++++++++++++++++------- SwiftShellTests/Command_Tests.swift | 12 +++++++ SwiftShellTests/Context_Tests.swift | 2 +- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/SwiftShell/Command.swift b/SwiftShell/Command.swift index 982e9d6..906cf36 100644 --- a/SwiftShell/Command.swift +++ b/SwiftShell/Command.swift @@ -16,24 +16,28 @@ import Foundation extension ShellContextType { - func runLater (shellcommand: String, args: [String]) -> NSTask { + func setupTask (executable: String, args: [String]) -> NSTask { let task = NSTask() task.arguments = args - task.launchPath = shellcommand - task.environment = main.env + task.launchPath = executable + + task.environment = self.env + task.currentDirectoryPath = self.currentdirectory + + task.standardInput = self.stdin + task.standardOutput = self.stdout + task.standardError = self.stderror return task } - func runLater (bash bashcommand: String) -> NSTask { - return runLater("/bin/bash", args: ["-c", bashcommand]) + func setupTask (bash bashcommand: String) -> NSTask { + return setupTask("/bin/bash", args: ["-c", bashcommand]) } + - /** Shortcut for in-line command, returns output as String. */ - public func $ (shellcommand: String, args: String ...) -> String { - let task = runLater(shellcommand, args: args) - - // avoids implicit reading of the main script's standardInput + private func outputFrom$ (task: NSTask) -> String { + // avoids implicit reading from standardInput task.standardInput = NSPipe () let output = NSPipe () @@ -41,8 +45,32 @@ extension ShellContextType { task.standardError = output task.launch() task.waitUntilExit() + var outputstring = output.fileHandleForReading.read(encoding: self.encoding) - return output.fileHandleForReading.read(encoding: self.encoding) + // if output is single-line, trim it. + if outputstring.hasSuffix("\n") && outputstring.characters.indexOf("\n") == outputstring.endIndex.predecessor() { + outputstring = outputstring.stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet()) + } + + return outputstring + } + + /** + Shortcut for shell command, returns output and errors as a String. + + - parameter args: the arguments, one string for each. + - returns: standard output and standard error in one string, trimmed of whitespace and newline if it is single-line. + */ + public func $ (executable: String, _ args: String ...) -> String { + return outputFrom$(setupTask(executable, args: args)) + } + + /** + Shortcut for bash shell command, returns output and errors as a String. + + - returns: standard output and standard error in one string, trimmed of whitespace and newline if it is single-line. + */ + public func $ (bash bashcommand: String) -> String { + return outputFrom$(setupTask(bash: bashcommand)) } - } diff --git a/SwiftShellTests/Command_Tests.swift b/SwiftShellTests/Command_Tests.swift index 4b11083..0858a54 100644 --- a/SwiftShellTests/Command_Tests.swift +++ b/SwiftShellTests/Command_Tests.swift @@ -11,4 +11,16 @@ import XCTest class Command_Tests: XCTestCase { + func test$BashCommand () { + XCTAssertEqual( main.$(bash:"echo one"), "one" ) + } + + func testSingleline$Command () { + XCTAssertEqual( main.$("/bin/echo", "one", "two"), "one two" ) + } + + func testMultiline$Command () { + XCTAssertEqual( main.$("/bin/echo", "one\ntwo"), "one\ntwo\n" ) + } + } diff --git a/SwiftShellTests/Context_Tests.swift b/SwiftShellTests/Context_Tests.swift index 6583263..576dbb0 100644 --- a/SwiftShellTests/Context_Tests.swift +++ b/SwiftShellTests/Context_Tests.swift @@ -19,6 +19,6 @@ class Context_Tests: XCTestCase { main.currentdirectory = "/tmp" XCTAssertEqual( main.currentdirectory, "/private/tmp" ) - XCTAssertEqual( main.$("/bin/pwd"), "/tmp\n" ) + XCTAssertEqual( main.$("/bin/pwd"), "/tmp" ) } }