XSTooling
XSTooling copied to clipboard
Xcode + Swift toolset
🛠 XSTooling 🧰
Xcode and Swift toolset
Supported tools:
- shell
- xcrun
- simstl
Getting Started
To use the XSTooling library in a SwiftPM project, add the following line to the dependencies in your Package.swift file:
.package(url: "https://github.com/Alexander-Ignition/XSTooling", from: "0.0.2"),
Include "XSTooling" as a dependency for your executable target:
.target(name: "<target>", dependencies: [
"XSTooling",
]),
Finally, add import XSTooling to your source code.
import XSTooling
let sh = Shell.default
try await sh("swift build").run()
Shell
Shell command can be run or read.
Read the shell command output.
let version = try await sh("xcodebuild -version").read().string
Run shell command with redirection to stdout and stderr.
try await sh("ls -al").run()
Redirection can be configured, for example, to write to a log file.
let url = URL(fileURLWithPath: "logs.txt", isDirectory: false)
FileManager.default.createFile(atPath: url.path, contents: nil)
let file = try FileHandle(forWritingTo: url)
try await sh("swift build").run(.output(file).error(file))
Shell has predefined instances.
Shell.default
Shell.sh
Shell.bash
Shell.zsh
Conceptually, a Shell is a wrapper over a ProcessCommand.
sh.commandcontains common parameters for all commands.sh("ls")each call to this method returned a copy of theProcessCommandwith additional arguments
let sh = Shell.default
sh.command // ProcessCommand
sh.command.environment // [String: String]?
sh.command.currentDirectoryURL // URL?
sh("ls") // ProcessCommand
ProcessCommand
The main component is ProcessCommand. Which can configure and run a subprocess. The read and run methods are called on the ProcessCommand.
let command = ProcessCommand(
path: "/usr/bin/xcodebuild",
arguments: ["-version"]
)
try await command.run()
The location of the executable file is not always known. To do this, there is a find method that searches for an executable file by name.
try await ProcessCommand
.find("xcodebuild")!
.appending(argument: "-version")
.run()
simctl
By analogy with Shell, you can make other wrappers over the ProcessCommand
Simctl (Simulator control tool) is an example of a complex such wrapper
Using simctl, you can search for iPhone 12, turn it on and launch the application.
let xcrun = XCRun()
let simulator = xcrun.simctl
let list = try await simulator.list(.devices, "iPhone 12", available: true).json.decode()
let devices = list.devices.flatMap { $0.value }
for info in devices where info.state == "Booted" {
try await simulator.device(info.udid).shutdown.run()
}
let udid = devices.first!.udid
try await simulator.device(udid).boot.run()
try await simulator.device(udid).app("com.example.app").launch.run()
License
MIT