Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/GeorgeLyon/Shwift
Shell scripting in Swift
https://github.com/GeorgeLyon/Shwift
Last synced: 3 months ago
JSON representation
Shell scripting in Swift
- Host: GitHub
- URL: https://github.com/GeorgeLyon/Shwift
- Owner: GeorgeLyon
- Created: 2021-05-05T21:48:25.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-04-01T01:47:34.000Z (7 months ago)
- Last Synced: 2024-07-05T13:46:18.018Z (4 months ago)
- Language: Swift
- Size: 172 KB
- Stars: 70
- Watchers: 3
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Shwift
## Overview
Shwift is a package which provides tools for shell scripting in Swift.
For example, you can write the following Swift code to achieve `echo Foo Bar | sed s/Bar/Baz/`:
```swift
try await echo("Foo", "Bar") | sed("s/Bar/Baz/")
```While a bit more verbose, this is natively integrated into Swift and utilizes Swift's concurrency APIs. As a result, interacting with command-line tools becomes very natural, and you can do things like `echo("Foo", "Bar") | map { $0.replacingOccurences(of: "Bar", with: "Baz") }`. We've worked very hard to make the performance of `Shwift` analogous with the command line. So if you execute the line `try await cat("/dev/urandom") | xxd() | head("-n2")`, You won't read any more from `/dev/urandom` than if you executed the analogous command in the terminal.
The `Script` module provides API that is as similar as possible to the terminal, but expressed in Swift. It leverages `swift-argument-parser` and is optimized for writing shell-script-like programs. Here is an example of a simple program you can write (a more detailed example can be found in the [`ScriptExample` target](https://github.com/GeorgeLyon/Shwift/blob/552b32eacbf02a20ae51cae316e47ec4223a2005/Sources/ScriptExample/Main.swift#L29)):
```swift
import Script@main struct Main: Script {
func run() async throws {
/**
Declare the executables first so that we fail fast if one is missing.We could also instead use the `execute("executable", ...)` form to resolve executables at invocation time.
*/
let echo = try await executable(named: "echo")try await echo("Foo", "Bar") | map { $0.replacingOccurrences(of: "Bar", with: "Baz") }
}
}
````Script` is implemented using the `Shwift` module, which implements the core functionality needed to call command-line tools and process their output. This module can be used directly if you want to interact with command-line tools in a more complex program. For example, you could implement a server which may call a command-line tool in response to an HTTP request.
`Shwift` is more explicit about exactly what is being executed. You have a `Shwift.Context` which you can use to manage the lifetime of resources used by `Shwift` (for example, closing the `Shwift.Context` once it is no longer necessary). It also provides `Builtin`, which is a namespace for core functionality that is used to implement higher level Swift functions for interacting with command line tools in `Script`, like `map` and `reduce`.
`Shwift` is build on top of `swift-nio` and as a result aims to be completely non-blocking, and thus suitable for use Swift programs which make extensive use of Swift's concurrency features, such as servers.