From 900c6ef25860718539c12a2534fe9395e2aa4655 Mon Sep 17 00:00:00 2001 From: John Sundell Date: Sat, 4 Nov 2017 21:41:20 +0100 Subject: [PATCH] =?UTF-8?q?Support=20paths=20relative=20to=20the=20user?= =?UTF-8?q?=E2=80=99s=20home=20directory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes a bug that would cause shelling out at a path containing a tilde to fail. The reason was that ShellOut was wrapping all paths in quotes, in order to escape spaces. With this, spaces are properly escaped instead. --- Sources/ShellOut.swift | 6 +++++- Tests/ShellOutTests/ShellOutTests.swift | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Sources/ShellOut.swift b/Sources/ShellOut.swift index 83c6c80..4e1624a 100644 --- a/Sources/ShellOut.swift +++ b/Sources/ShellOut.swift @@ -31,7 +31,7 @@ import Foundation outputHandle: FileHandle? = nil, errorHandle: FileHandle? = nil) throws -> String { let process = Process() - let command = "cd \"\(path)\" && \(command) \(arguments.joined(separator: " "))" + let command = "cd \(path.escapingSpaces) && \(command) \(arguments.joined(separator: " "))" return try process.launchBash(with: command, outputHandle: outputHandle, errorHandle: errorHandle) } @@ -418,6 +418,10 @@ private extension Data { } private extension String { + var escapingSpaces: String { + return replacingOccurrences(of: " ", with: "\\ ") + } + func appending(argument: String) -> String { return "\(self) \"\(argument)\"" } diff --git a/Tests/ShellOutTests/ShellOutTests.swift b/Tests/ShellOutTests/ShellOutTests.swift index 4841d11..90a8fd3 100644 --- a/Tests/ShellOutTests/ShellOutTests.swift +++ b/Tests/ShellOutTests/ShellOutTests.swift @@ -32,6 +32,19 @@ class ShellOutTests: XCTestCase { XCTAssertEqual(textFileContent, "Hello") } + func testSingleCommandAtPathContainingSpace() throws { + try shellOut(to: "mkdir -p \"ShellOut Test Folder\"", at: NSTemporaryDirectory()) + try shellOut(to: "echo \"Hello\" > File", at: NSTemporaryDirectory() + "ShellOut Test Folder") + + let output = try shellOut(to: "cat \(NSTemporaryDirectory())ShellOut\\ Test\\ Folder/File") + XCTAssertEqual(output, "Hello") + } + + func testSingleCommandAtPathContainingTilde() throws { + let homeContents = try shellOut(to: "ls", at: "~") + XCTAssertFalse(homeContents.isEmpty) + } + func testSeriesOfCommands() throws { let echo = try shellOut(to: ["echo \"Hello\"", "echo \"world\""]) XCTAssertEqual(echo, "Hello\nworld")