Skip to content

Commit e14c634

Browse files
committed
Remove safeCommand: initialiser, cleanup
1 parent caa7d14 commit e14c634

File tree

4 files changed

+54
-47
lines changed

4 files changed

+54
-47
lines changed

Sources/Argument.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ public enum Argument {
3535
extension String {
3636
var quoted: Argument { .init(quoted: self) }
3737
var verbatim: Argument { .init(verbatim: self) }
38-
func safe() throws -> SafeString { try .init(self) }
3938
}
4039

4140

Sources/SafeString.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,11 @@ public struct SafeString {
1919
extension SafeString: CustomStringConvertible {
2020
public var description: String { value }
2121
}
22+
23+
24+
extension String {
25+
var safe: SafeString {
26+
get throws { try .init(self) }
27+
}
28+
var unchecked: SafeString { .init(unchecked: self) }
29+
}

Sources/ShellOut.swift

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,7 @@ public struct ShellOutCommand {
9696
self.init(command: try SafeString(command), arguments: arguments)
9797
}
9898

99-
public init(safeCommand: String, arguments: [Argument] = []) {
100-
self.init(command: SafeString(unchecked: safeCommand), arguments: arguments)
101-
}
102-
103-
public init(command: SafeString, arguments: [Argument]) {
99+
public init(command: SafeString, arguments: [Argument] = []) {
104100
self.command = command
105101
self.arguments = arguments
106102
}
@@ -131,7 +127,7 @@ public struct ShellOutCommand {
131127
public extension ShellOutCommand {
132128
/// Initialize a git repository
133129
static func gitInit() -> ShellOutCommand {
134-
.init(safeCommand: "git", arguments: ["init".verbatim])
130+
.init(command: "git".unchecked, arguments: ["init".verbatim])
135131
}
136132

137133
/// Clone a git repository at a given URL
@@ -211,7 +207,7 @@ public extension ShellOutCommand {
211207

212208
/// Checkout a given git branch
213209
static func gitCheckout(branch: String, quiet: Bool = true) -> ShellOutCommand {
214-
var command = ShellOutCommand(safeCommand: "git",
210+
var command = ShellOutCommand(command: "git".unchecked,
215211
arguments: ["checkout".verbatim, branch.quoted])
216212

217213
if quiet {
@@ -223,8 +219,9 @@ public extension ShellOutCommand {
223219

224220
private static func git(allowingPrompt: Bool) -> Self {
225221
allowingPrompt
226-
? .init(safeCommand: "git")
227-
: .init(safeCommand: "env", arguments: ["GIT_TERMINAL_PROMPT=0", "git"].verbatim)
222+
? .init(command: "git".unchecked)
223+
: .init(command: "env".unchecked,
224+
arguments: ["GIT_TERMINAL_PROMPT=0", "git"].verbatim)
228225

229226
}
230227
}
@@ -233,62 +230,64 @@ public extension ShellOutCommand {
233230
public extension ShellOutCommand {
234231
/// Create a folder with a given name
235232
static func createFolder(named name: String) -> ShellOutCommand {
236-
.init(safeCommand: "mkdir", arguments: [name.quoted])
233+
.init(command: "mkdir".unchecked, arguments: [name.quoted])
237234
}
238235

239236
/// Create a file with a given name and contents (will overwrite any existing file with the same name)
240237
static func createFile(named name: String, contents: String) -> ShellOutCommand {
241-
.init(safeCommand: "echo", arguments: [contents.quoted])
238+
.init(command: "echo".unchecked, arguments: [contents.quoted])
242239
.appending(argument: ">".verbatim)
243240
.appending(argument: name.quoted)
244241
}
245242

246243
/// Move a file from one path to another
247244
static func moveFile(from originPath: String, to targetPath: String) -> ShellOutCommand {
248-
.init(safeCommand: "mv", arguments: [originPath, targetPath].quoted)
245+
.init(command: "mv".unchecked, arguments: [originPath, targetPath].quoted)
249246
}
250247

251248
/// Copy a file from one path to another
252249
static func copyFile(from originPath: String, to targetPath: String) -> ShellOutCommand {
253-
.init(safeCommand: "cp", arguments: [originPath, targetPath].quoted)
250+
.init(command: "cp".unchecked, arguments: [originPath, targetPath].quoted)
254251
}
255252

256253
/// Remove a file
257254
static func removeFile(from path: String, arguments: [String] = ["-f"]) -> ShellOutCommand {
258-
.init(safeCommand: "rm", arguments: arguments.quoted + [path.quoted])
255+
.init(command: "rm".unchecked, arguments: arguments.quoted + [path.quoted])
259256
}
260257

261258
/// Open a file using its designated application
262259
static func openFile(at path: String) -> ShellOutCommand {
263-
.init(safeCommand: "open", arguments: [path.quoted])
260+
.init(command: "open".unchecked, arguments: [path.quoted])
264261
}
265262

266263
/// Read a file as a string
267264
static func readFile(at path: String) -> ShellOutCommand {
268-
.init(safeCommand: "cat", arguments: [path.quoted])
265+
.init(command: "cat".unchecked, arguments: [path.quoted])
269266
}
270267

271268
/// Create a symlink at a given path, to a given target
272269
static func createSymlink(to targetPath: String, at linkPath: String) -> ShellOutCommand {
273-
.init(safeCommand: "ln", arguments: ["-s", targetPath, linkPath].quoted)
270+
.init(command: "ln".unchecked, arguments: ["-s", targetPath, linkPath].quoted)
274271
}
275272

276273
/// Expand a symlink at a given path, returning its target path
277274
static func expandSymlink(at path: String) -> ShellOutCommand {
278-
.init(safeCommand: "readlink", arguments: [path.quoted])
275+
.init(command: "readlink".unchecked, arguments: [path.quoted])
279276
}
280277
}
281278

282279
/// Marathon commands
283280
public extension ShellOutCommand {
284281
/// Run a Marathon Swift script
285282
static func runMarathonScript(at path: String, arguments: [String] = []) -> ShellOutCommand {
286-
.init(safeCommand: "marathon", arguments: ["run", path].quoted + arguments.quoted)
283+
.init(command: "marathon".unchecked,
284+
arguments: ["run", path].quoted + arguments.quoted)
287285
}
288286

289287
/// Update all Swift packages managed by Marathon
290288
static func updateMarathonPackages() -> ShellOutCommand {
291-
.init(safeCommand: "marathon", arguments: ["update".verbatim])
289+
.init(command: "marathon".unchecked,
290+
arguments: ["update".verbatim])
292291
}
293292
}
294293

@@ -308,29 +307,30 @@ public extension ShellOutCommand {
308307

309308
/// Create a Swift package with a given type (see SwiftPackageType for options)
310309
static func createSwiftPackage(withType type: SwiftPackageType = .library) -> ShellOutCommand {
311-
.init(safeCommand: "swift",
310+
.init(command: "swift".unchecked,
312311
arguments: ["package init --type \(type)".verbatim])
313312
}
314313

315314
/// Update all Swift package dependencies
316315
static func updateSwiftPackages() -> ShellOutCommand {
317-
.init(safeCommand: "swift", arguments: ["package", "update"].verbatim)
316+
.init(command: "swift".unchecked, arguments: ["package", "update"].verbatim)
318317
}
319318

320319
/// Generate an Xcode project for a Swift package
321320
static func generateSwiftPackageXcodeProject() -> ShellOutCommand {
322-
.init(safeCommand: "swift", arguments: ["package", "generate-xcodeproj"].verbatim)
321+
.init(command: "swift".unchecked,
322+
arguments: ["package", "generate-xcodeproj"].verbatim)
323323
}
324324

325325
/// Build a Swift package using a given configuration (see SwiftBuildConfiguration for options)
326326
static func buildSwiftPackage(withConfiguration configuration: SwiftBuildConfiguration = .debug) -> ShellOutCommand {
327-
.init(safeCommand: "swift",
327+
.init(command: "swift".unchecked,
328328
arguments: ["build -c \(configuration)".verbatim])
329329
}
330330

331331
/// Test a Swift package using a given configuration (see SwiftBuildConfiguration for options)
332332
static func testSwiftPackage(withConfiguration configuration: SwiftBuildConfiguration = .debug) -> ShellOutCommand {
333-
.init(safeCommand: "swift",
333+
.init(command: "swift".unchecked,
334334
arguments: ["test -c \(configuration)".verbatim])
335335
}
336336
}
@@ -339,20 +339,20 @@ public extension ShellOutCommand {
339339
public extension ShellOutCommand {
340340
/// Run Fastlane using a given lane
341341
static func runFastlane(usingLane lane: String) -> ShellOutCommand {
342-
.init(safeCommand: "fastlane", arguments: [lane.quoted])
342+
.init(command: "fastlane".unchecked, arguments: [lane.quoted])
343343
}
344344
}
345345

346346
/// CocoaPods commands
347347
public extension ShellOutCommand {
348348
/// Update all CocoaPods dependencies
349349
static func updateCocoaPods() -> ShellOutCommand {
350-
.init(safeCommand: "pod", arguments: ["update".verbatim])
350+
.init(command: "pod".unchecked, arguments: ["update".verbatim])
351351
}
352352

353353
/// Install all CocoaPods dependencies
354354
static func installCocoaPods() -> ShellOutCommand {
355-
.init(safeCommand: "pod", arguments: ["install".verbatim])
355+
.init(command: "pod".unchecked, arguments: ["install".verbatim])
356356
}
357357
}
358358

Tests/ShellOutTests/ShellOutTests.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,23 @@ class ShellOutTests: XCTestCase {
3232
}
3333

3434
func testWithoutArguments() throws {
35-
let uptime = try shellOut(to: "uptime".safe())
35+
let uptime = try shellOut(to: "uptime".safe)
3636
XCTAssertTrue(uptime.contains("load average"))
3737
}
3838

3939
func testWithArguments() throws {
40-
let echo = try shellOut(to: "echo".safe(), arguments: ["Hello world".quoted])
40+
let echo = try shellOut(to: "echo".safe, arguments: ["Hello world".quoted])
4141
XCTAssertEqual(echo, "Hello world")
4242
}
4343

4444
func testSingleCommandAtPath() throws {
4545
try shellOut(
46-
to: "echo".safe(),
46+
to: "echo".safe,
4747
arguments: [#"Hello" > \#(NSTemporaryDirectory())ShellOutTests-SingleCommand.txt"#.quoted]
4848
)
4949

5050
let textFileContent = try shellOut(
51-
to: "cat".safe(),
51+
to: "cat".safe,
5252
arguments: ["ShellOutTests-SingleCommand.txt".quoted],
5353
at: NSTemporaryDirectory()
5454
)
@@ -57,26 +57,26 @@ class ShellOutTests: XCTestCase {
5757
}
5858

5959
func testSingleCommandAtPathContainingSpace() throws {
60-
try shellOut(to: "mkdir".safe(),
60+
try shellOut(to: "mkdir".safe,
6161
arguments: ["-p".verbatim, "ShellOut Test Folder".quoted],
6262
at: NSTemporaryDirectory())
63-
try shellOut(to: "echo".safe(), arguments: ["Hello", ">", "File"].verbatim,
63+
try shellOut(to: "echo".safe, arguments: ["Hello", ">", "File"].verbatim,
6464
at: NSTemporaryDirectory() + "ShellOut Test Folder")
6565

6666
let output = try shellOut(
67-
to: "cat".safe(),
67+
to: "cat".safe,
6868
arguments: ["\(NSTemporaryDirectory())ShellOut Test Folder/File".quoted])
6969
XCTAssertEqual(output, "Hello")
7070
}
7171

7272
func testSingleCommandAtPathContainingTilde() throws {
73-
let homeContents = try shellOut(to: "ls".safe(), at: "~")
73+
let homeContents = try shellOut(to: "ls".safe, at: "~")
7474
XCTAssertFalse(homeContents.isEmpty)
7575
}
7676

7777
func testThrowingError() {
7878
do {
79-
try shellOut(to: "cd".safe(), arguments: ["notADirectory".verbatim])
79+
try shellOut(to: "cd".safe, arguments: ["notADirectory".verbatim])
8080
XCTFail("Expected expression to throw")
8181
} catch let error as ShellOutError {
8282
XCTAssertTrue(error.message.contains("notADirectory"))
@@ -110,7 +110,7 @@ class ShellOutTests: XCTestCase {
110110

111111
func testCapturingOutputWithHandle() throws {
112112
let pipe = Pipe()
113-
let output = try shellOut(to: "echo".safe(),
113+
let output = try shellOut(to: "echo".safe,
114114
arguments: ["Hello".verbatim],
115115
outputHandle: pipe.fileHandleForWriting)
116116
let capturedData = pipe.fileHandleForReading.readDataToEndOfFile()
@@ -122,7 +122,7 @@ class ShellOutTests: XCTestCase {
122122
let pipe = Pipe()
123123

124124
do {
125-
try shellOut(to: "cd".safe(),
125+
try shellOut(to: "cd".safe,
126126
arguments: ["notADirectory".verbatim],
127127
errorHandle: pipe.fileHandleForWriting)
128128
XCTFail("Expected expression to throw")
@@ -149,10 +149,10 @@ class ShellOutTests: XCTestCase {
149149
func testGitCommands() throws {
150150
// Setup & clear state
151151
let tempFolderPath = NSTemporaryDirectory()
152-
try shellOut(to: "rm".safe(),
152+
try shellOut(to: "rm".safe,
153153
arguments: ["-rf", "GitTestOrigin"].verbatim,
154154
at: tempFolderPath)
155-
try shellOut(to: "rm".safe(),
155+
try shellOut(to: "rm".safe,
156156
arguments: ["-rf", "GitTestClone"].verbatim,
157157
at: tempFolderPath)
158158

@@ -183,7 +183,7 @@ class ShellOutTests: XCTestCase {
183183
func testSwiftPackageManagerCommands() throws {
184184
// Setup & clear state
185185
let tempFolderPath = NSTemporaryDirectory()
186-
try shellOut(to: "rm".safe(),
186+
try shellOut(to: "rm".safe,
187187
arguments: ["-rf", "SwiftPackageManagerTest"].verbatim,
188188
at: tempFolderPath)
189189
try shellOut(to: .createFolder(named: "SwiftPackageManagerTest"), at: tempFolderPath)
@@ -196,22 +196,22 @@ class ShellOutTests: XCTestCase {
196196
// Build the package and verify that there's a .build folder
197197
try shellOut(to: .buildSwiftPackage(), at: packagePath)
198198
XCTAssertTrue(
199-
try shellOut(to: "ls".safe(), arguments: ["-a".verbatim], at: packagePath) .contains(".build")
199+
try shellOut(to: "ls".safe, arguments: ["-a".verbatim], at: packagePath) .contains(".build")
200200
)
201201

202202
// Generate an Xcode project
203203
try shellOut(to: .generateSwiftPackageXcodeProject(), at: packagePath)
204204
XCTAssertTrue(
205-
try shellOut(to: "ls".safe(), arguments: ["-a".verbatim], at: packagePath)
205+
try shellOut(to: "ls".safe, arguments: ["-a".verbatim], at: packagePath)
206206
.contains("SwiftPackageManagerTest.xcodeproj")
207207
)
208208
}
209209

210210
func testArgumentQuoting() throws {
211-
XCTAssertEqual(try shellOut(to: "echo".safe(),
211+
XCTAssertEqual(try shellOut(to: "echo".safe,
212212
arguments: ["foo ; echo bar".quoted]),
213213
"foo ; echo bar")
214-
XCTAssertEqual(try shellOut(to: "echo".safe(),
214+
XCTAssertEqual(try shellOut(to: "echo".safe,
215215
arguments: ["foo ; echo bar".verbatim]),
216216
"foo\nbar")
217217
}

0 commit comments

Comments
 (0)