{"id":31065730,"url":"https://github.com/nikolainobadi/nnshellkit","last_synced_at":"2026-04-17T20:31:40.318Z","repository":{"id":310281876,"uuid":"1039320863","full_name":"nikolainobadi/NnShellKit","owner":"nikolainobadi","description":"Lightweight package for easy command-line interaction","archived":false,"fork":false,"pushed_at":"2025-12-06T01:53:27.000Z","size":85,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-09T17:14:05.210Z","etag":null,"topics":["command-line","shell","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nikolainobadi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-08-17T00:41:41.000Z","updated_at":"2025-12-06T01:52:25.000Z","dependencies_parsed_at":"2025-08-17T02:29:32.683Z","dependency_job_id":"f40c6030-7057-4e42-92ff-8ebf68a83af8","html_url":"https://github.com/nikolainobadi/NnShellKit","commit_stats":null,"previous_names":["nikolainobadi/nnshellkit"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/nikolainobadi/NnShellKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolainobadi%2FNnShellKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolainobadi%2FNnShellKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolainobadi%2FNnShellKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolainobadi%2FNnShellKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nikolainobadi","download_url":"https://codeload.github.com/nikolainobadi/NnShellKit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nikolainobadi%2FNnShellKit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31944963,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-17T17:29:20.459Z","status":"ssl_error","status_checked_at":"2026-04-17T17:28:47.801Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command-line","shell","swift"],"created_at":"2025-09-15T16:55:53.962Z","updated_at":"2026-04-17T20:31:40.302Z","avatar_url":"https://github.com/nikolainobadi.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NnShellKit\n\n![Build Status](https://github.com/nikolainobadi/NnShellKit/actions/workflows/ci.yml/badge.svg)\n![Swift Version](https://badgen.net/badge/swift/5.5%2B/purple)\n![Platform](https://img.shields.io/badge/platform-macOS-lightgrey)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\nNnShellKit 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.\n\nThis package is built to be simple, reliable, and easy to test.\n\n## Table of Contents\n- [Overview](#overview)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Core Concepts](#core-concepts)\n- [API Summary](#api-summary)\n- [Using NnShell](#using-nnshell)\n  - [Bash Commands](#bash-commands)\n  - [Direct Program Execution](#direct-program-execution)\n  - [Streaming Output](#streaming-output)\n  - [Timeouts](#timeouts)\n- [Using MockShell](#using-mockshell)\n  - [Basic Usage](#basic-usage)\n  - [Result Strategies](#result-strategies)\n  - [MockCommand](#mockcommand)\n  - [Subclassing MockShell](#subclassing-mockshell)\n- [Xcode Integration](#xcode-integration)\n- [Error Handling](#error-handling)\n- [Architecture](#architecture)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Overview\n\nNnShellKit 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.\n\n## Installation\n\nAdd the package\n```swift\n.package(url: \"https://github.com/nikolainobadi/NnShellKit.git\", from: \"2.2.0\")\n```\n\nAdd NnShellKit as a target dependency\n```swift\n.product(name: \"NnShellKit\", package: \"NnShellKit\")\n```\n\nAdd NnShellTesting as a test target dependency (optional)\n```swift\n.product(name: \"NnShellTesting\", package: \"NnShellKit\")\n```\n\n## Quick Start\n\n```swift\nimport NnShellKit\n\nlet shell = NnShell()\n\nlet status = try shell.bash(\"git status\")\nlet files = try shell.run(\"/bin/ls\", args: [\"-la\"])\n\ntry shell.runAndPrint(\"/usr/bin/swift\", args: [\"build\"])\n```\n\n## Core Concepts\n\n- `bash` uses `/bin/bash -c` for pipes, redirects, env variables.\n- `run` executes programs directly with no shell overhead.\n- Streaming methods print directly to stdout and stderr.\n- Timeout is available on captured output commands.\n\n## API Summary\n\n| Method                     | Captures output | Streams output | Timeout support |\n|---------------------------|-----------------|----------------|-----------------|\n| bash                      | Yes             | No             | Yes             |\n| run                       | Yes             | No             | Yes             |\n| runAndPrint               | No              | Yes            | No              |\n| runAndPrint(bash)         | No              | Yes            | No              |\n\n## Using NnShell\n\n### Bash Commands\n\n```swift\nlet result = try shell.bash(\"git status | grep modified\")\ntry shell.bash(\"echo $HOME \u003e /tmp/home.txt\")\ntry shell.bash(\"ls *.swift | wc -l\")\n```\n\n### Direct Program Execution\n\n```swift\nlet output = try shell.run(\"/bin/echo\", args: [\"Hello\"])\ntry shell.run(\"/usr/bin/git\", args: [\"status\", \"--porcelain\"])\n```\n\n### Streaming Output\n\n```swift\ntry shell.runAndPrint(\"/usr/bin/swift\", args: [\"build\"])\ntry shell.runAndPrint(bash: \"git clone https://github.com/user/repo.git\")\n```\n\n### Timeouts\n\n```swift\nlet shell = NnShell(timeout: 20)\ntry shell.bash(\"sleep 30\")\n```\n\nTimeout behavior includes terminate, kill signal fallback, and partial output capture in the error.\n\n## Using MockShell\n\nImport:\n\n```swift\nimport NnShellKit\nimport NnShellTesting\n```\n\n### Basic Usage\n\n```swift\nlet mock = MockShell(results: [\"one\", \"two\"])\n\nlet first = try mock.bash(\"cmd\")\nlet second = try mock.run(\"/bin/ls\", args: [])\n```\n\n### Result Strategies\n\nFIFO results or command mapping:\n\n```swift\nlet mock = MockShell(results: [\"a\", \"b\"])\n```\n\n```swift\nlet mock = MockShell(commands: [\n    MockCommand(command: \"git status\", output: \"clean\"),\n    MockCommand(command: \"git push\", error: ShellError.failed(program: \"git\", code: 1, output: \"fail\"))\n])\n```\n\n### MockCommand\n\n```swift\nlet mock = MockShell(commands: [\n    MockCommand(command: \"/usr/bin/git status\", output: \"OK\"),\n    MockCommand(command: \"/usr/bin/git push origin main\", output: \"Done\")\n])\n```\n\n### Subclassing MockShell\n\nMockShell is `open` and can be subclassed to add custom properties and methods:\n\n```swift\nclass CustomMockShell: MockShell {\n    var customCallCount = 0\n\n    func trackCustomBehavior() {\n        customCallCount += 1\n    }\n}\n```\n\n## Xcode Integration\n\n```swift\ntry shell.run(\"/usr/bin/xcodebuild\", args: [\n    \"-project\", \"MyApp.xcodeproj\",\n    \"-scheme\", \"MyApp\",\n    \"build\"\n])\n```\n\n## Error Handling\n\n```swift\ndo {\n    try shell.bash(\"git status\")\n} catch let error as ShellError {\n    switch error {\n    case .failed(let program, let code, let output):\n        print(program)\n        print(code)\n        print(output)\n    }\n}\n```\n\n## Architecture\n\n- Shell protocol defines the interface.\n- NnShell is the production implementation.\n- MockShell and MockCommand support testing.\n- ShellError includes exit details.\n\n## Contributing\n\nAny feedback or ideas to enhance NnShellKit would be well received. Please feel free to open an issue.\n\n## License\n\nNnShellKit is available under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikolainobadi%2Fnnshellkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnikolainobadi%2Fnnshellkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikolainobadi%2Fnnshellkit/lists"}