https://github.com/nikolainobadi/nnshellkit
Lightweight package for easy command-line interaction
https://github.com/nikolainobadi/nnshellkit
command-line shell swift
Last synced: 2 months ago
JSON representation
Lightweight package for easy command-line interaction
- Host: GitHub
- URL: https://github.com/nikolainobadi/nnshellkit
- Owner: nikolainobadi
- License: mit
- Created: 2025-08-17T00:41:41.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-12-06T01:53:27.000Z (7 months ago)
- Last Synced: 2025-12-09T17:14:05.210Z (7 months ago)
- Topics: command-line, shell, swift
- Language: Swift
- Homepage:
- Size: 83 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# NnShellKit



[](https://opensource.org/licenses/MIT)
NnShellKit is a lightweight Swift package for executing shell commands in Swift. It provides a simple API, real time streaming, timeout control, and a dedicated testing module for predictable unit tests.
This package is built to be simple, reliable, and easy to test.
## Table of Contents
- [Overview](#overview)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Core Concepts](#core-concepts)
- [API Summary](#api-summary)
- [Using NnShell](#using-nnshell)
- [Bash Commands](#bash-commands)
- [Direct Program Execution](#direct-program-execution)
- [Streaming Output](#streaming-output)
- [Timeouts](#timeouts)
- [Using MockShell](#using-mockshell)
- [Basic Usage](#basic-usage)
- [Result Strategies](#result-strategies)
- [MockCommand](#mockcommand)
- [Subclassing MockShell](#subclassing-mockshell)
- [Xcode Integration](#xcode-integration)
- [Error Handling](#error-handling)
- [Architecture](#architecture)
- [Contributing](#contributing)
- [License](#license)
## Overview
NnShellKit provides a simple interface for bash commands and direct program execution, real time streaming, combined stdout and stderr capture, configurable timeouts, predictable testing utilities, and protocol oriented design.
## Installation
Add the package
```swift
.package(url: "https://github.com/nikolainobadi/NnShellKit.git", from: "2.2.0")
```
Add NnShellKit as a target dependency
```swift
.product(name: "NnShellKit", package: "NnShellKit")
```
Add NnShellTesting as a test target dependency (optional)
```swift
.product(name: "NnShellTesting", package: "NnShellKit")
```
## Quick Start
```swift
import NnShellKit
let shell = NnShell()
let status = try shell.bash("git status")
let files = try shell.run("/bin/ls", args: ["-la"])
try shell.runAndPrint("/usr/bin/swift", args: ["build"])
```
## Core Concepts
- `bash` uses `/bin/bash -c` for pipes, redirects, env variables.
- `run` executes programs directly with no shell overhead.
- Streaming methods print directly to stdout and stderr.
- Timeout is available on captured output commands.
## API Summary
| Method | Captures output | Streams output | Timeout support |
|---------------------------|-----------------|----------------|-----------------|
| bash | Yes | No | Yes |
| run | Yes | No | Yes |
| runAndPrint | No | Yes | No |
| runAndPrint(bash) | No | Yes | No |
## Using NnShell
### Bash Commands
```swift
let result = try shell.bash("git status | grep modified")
try shell.bash("echo $HOME > /tmp/home.txt")
try shell.bash("ls *.swift | wc -l")
```
### Direct Program Execution
```swift
let output = try shell.run("/bin/echo", args: ["Hello"])
try shell.run("/usr/bin/git", args: ["status", "--porcelain"])
```
### Streaming Output
```swift
try shell.runAndPrint("/usr/bin/swift", args: ["build"])
try shell.runAndPrint(bash: "git clone https://github.com/user/repo.git")
```
### Timeouts
```swift
let shell = NnShell(timeout: 20)
try shell.bash("sleep 30")
```
Timeout behavior includes terminate, kill signal fallback, and partial output capture in the error.
## Using MockShell
Import:
```swift
import NnShellKit
import NnShellTesting
```
### Basic Usage
```swift
let mock = MockShell(results: ["one", "two"])
let first = try mock.bash("cmd")
let second = try mock.run("/bin/ls", args: [])
```
### Result Strategies
FIFO results or command mapping:
```swift
let mock = MockShell(results: ["a", "b"])
```
```swift
let mock = MockShell(commands: [
MockCommand(command: "git status", output: "clean"),
MockCommand(command: "git push", error: ShellError.failed(program: "git", code: 1, output: "fail"))
])
```
### MockCommand
```swift
let mock = MockShell(commands: [
MockCommand(command: "/usr/bin/git status", output: "OK"),
MockCommand(command: "/usr/bin/git push origin main", output: "Done")
])
```
### Subclassing MockShell
MockShell is `open` and can be subclassed to add custom properties and methods:
```swift
class CustomMockShell: MockShell {
var customCallCount = 0
func trackCustomBehavior() {
customCallCount += 1
}
}
```
## Xcode Integration
```swift
try shell.run("/usr/bin/xcodebuild", args: [
"-project", "MyApp.xcodeproj",
"-scheme", "MyApp",
"build"
])
```
## Error Handling
```swift
do {
try shell.bash("git status")
} catch let error as ShellError {
switch error {
case .failed(let program, let code, let output):
print(program)
print(code)
print(output)
}
}
```
## Architecture
- Shell protocol defines the interface.
- NnShell is the production implementation.
- MockShell and MockCommand support testing.
- ShellError includes exit details.
## Contributing
Any feedback or ideas to enhance NnShellKit would be well received. Please feel free to open an issue.
## License
NnShellKit is available under the MIT license.