A simple, modern Swift class for running shell commands
? Coquille
A simple Swift wrapper around Process
supporting Swift Concurrency and streamed output from stdout
and stderr
.
Requirements
macOS 10.15+
Installation
Add Coquille to your project using Xcode (File > Add Packages…) or by adding it to your project’s Package.swift
file:
dependencies: [
.package(url: "https://github.com/alexrozanski/Coquille.git", from: "0.1.0")
]
Usage
Coquille exposes its own Process
class which you can interact with to execute commands. Process.run()
is an async
function so you can just await
the exit code:
import Coquille
let process = Process(commandString: "pwd"))
_ = try await process.run() // Prints `pwd` to `stdout`
// Use `command:` for more easily working with variable command-line arguments
let deps = ["numpy", "torch"]
let process = Process(command: .init("python3", arguments: ["-m", "pip", "install"] + deps)))
_ = try await process.run()
I/O
By default Process
pipes output from the spawned process to stdout
and stderr
. This can be configured with printStdout
and printStderr
:
import Coquille
let process = Process(commandString: "brew install wget", printStderr: false))
_ = try await process.run() // Pipes standard output to `stdout` but will not pipe error output to `stderr`
You can also pass an OutputHandler
for both stdout and stderr which will stream contents from both:
import Coquille
let process = Process(
commandString: "swift build",
stdout: { stdout in
...
},
stderr: { stderr in
...
})
_ = try await process.run() // Streams standard and error output to the handlers provided to `stdout:` and `stderr:`
Exit Codes
// `isSuccess` can be used to test the exit code for success
let hasRuby = (try await Process(commandString: "which ruby").run()).isSuccess
// Use `errorCode` to get a nonzero exit code
if let errorCode = (try await Process(commandString: "swift build").run()).errorCode {
switch errorCode {
case 127:
// Command not found
default:
...
}
}
Acknowledgements
Thanks to Ben Chatelain for their blog post on intercepting stdout, used to implement some of the tests in the test suite.