Skip to content

Commit 3b38de6

Browse files
committed
feat: add arguments
1 parent 5221a1b commit 3b38de6

File tree

15 files changed

+489
-163
lines changed

15 files changed

+489
-163
lines changed

Examples/main.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@ import Commands
99

1010
fileprivate extension Commands.Result {
1111
func log() {
12-
if let dashc = request.dashc {
13-
print(">>> \(request.executableURL) \(dashc) \(request.command)")
14-
} else {
15-
print(">>> \(request.executableURL) \(request.command)")
16-
}
12+
print("---------------")
13+
print(">>> \(request.absoluteCommand)")
1714
print("\(self.reponse.output)")
15+
print("---------------")
1816
}
1917
}
2018

@@ -28,8 +26,10 @@ Commands.Ruby.run("require 'base64'; puts Base64.encode64('qiuzhifei')").log()
2826
Commands.Python.run("import base64; print(base64.b64encode('qiuzhifei').decode('ascii'))").log()
2927

3028
// Custom
31-
let nodeResult = Commands.Bash.run("which node")
32-
if nodeResult.isSuccess {
33-
let node = Commands.Custom(nodeResult.output, dashc: "-e")
34-
node.run("console.log('qiuzhifei')").log()
35-
}
29+
let node = Commands.Alias("node", dashc: "-e")
30+
node.run("console.log('qiuzhifei')").log()
31+
32+
// Task
33+
Commands.Task.run("bash -c pwd").log()
34+
Commands.Task.run("python main.py").log()
35+
Commands.Task.run("ruby -v").log()

Package.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@ import PackageDescription
66
let package = Package(
77
name: "swift-commands",
88
products: [
9-
.library(name: "Commands", targets: ["Commands"]),
9+
.library(name: "Commands",
10+
targets: ["Commands"]),
1011
],
1112
dependencies: [],
1213
targets: [
13-
.target(name: "Commands", dependencies: []),
14-
.target(name: "Examples", dependencies: ["Commands"], path: "Examples/"),
15-
.testTarget(name: "CommandsTests", dependencies: ["Commands"])
14+
.target(name: "Commands",
15+
dependencies: []),
16+
.target(name: "Examples",
17+
dependencies: ["Commands"],
18+
path: "Examples/"),
19+
.testTarget(name: "CommandsTests",
20+
dependencies: ["Commands"],
21+
resources: [.process("Resources")])
1622
]
1723
)

README.md

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,6 @@ Executes command in a subprocess.
2020
Commands.Bash.system("ls")
2121
```
2222

23-
Returns the `Commands.Result` of running cmd in a subprocess.
24-
```
25-
let lsResult = Commands.Bash.run("ls")
26-
switch lsResult {
27-
case .Success(let output):
28-
debugPrint("success output: \(output)")
29-
case .Failure(let code, let output):
30-
debugPrint("failure code: \(code), output: \(output)")
31-
}
32-
```
3323
### Python
3424
Executes command in a subprocess.
3525
```swift
@@ -41,13 +31,54 @@ Executes command in a subprocess.
4131
Commands.Ruby.system("require 'base64'; puts Base64.encode64('qiuzhifei')")
4232
```
4333

44-
### Custom
45-
Executes command in a subprocess.
34+
### Alias
35+
Create a shortcut name for a command.
4636
```swift
4737
let node = Commands.Custom("/usr/local/bin/node", dashc: "-e")
4838
node.system("console.log('qiuzhifei')")
4939
```
5040

41+
### Custom
42+
Executes command in a subprocess.
43+
```swift
44+
Commands.Task.system("python main.py")
45+
```
46+
```swift
47+
Commands.Task.system("ruby -v")
48+
```
49+
50+
### Making Commands
51+
```swift
52+
Commands.Task.system("python main.py")
53+
```
54+
Or
55+
```swift
56+
let request: Commands.Request = "node -v"
57+
Commands.Task.system(request)
58+
```
59+
Change environment variables
60+
```swift
61+
var request: Commands.Request = "node -v"
62+
request.environment?.add(PATH: "/usr/local/bin")
63+
request.environment?["http_proxy"] = "http://127.0.0.1:7890"
64+
request.environment?["https_proxy"] = "http://127.0.0.1:7890"
65+
request.environment?["all_proxy"] = "socks5://127.0.0.1:7890"
66+
67+
Commands.Task.system(request)
68+
```
69+
70+
### Result Handler
71+
Returns the `Commands.Result` of running cmd in a subprocess.
72+
```
73+
let lsResult = Commands.Bash.run("ls")
74+
switch lsResult {
75+
case .Success(let request, let response):
76+
debugPrint("command: \(request.absoluteCommand), success output: \(response.output)")
77+
case .Failure(let request, let response):
78+
debugPrint("command: \(request.absoluteCommand), failure output: \(response.errorOutput)")
79+
}
80+
```
81+
5182
## Adding Commands as a Dependency
5283
To use the `Commands` library in a SwiftPM project,
5384
add the following line to the dependencies in your `Package.swift` file:

Scripts/deploy.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
# 1. Bump the version in https://github.com/QiuZhiFei/swift-commands/blob/dev/Commands.podspec#L3.
4+
# 2. Bump the git tag and push tag to github, create a release in https://github.com/QiuZhiFei/swift-commands/tags.
5+
# 3. Publish a cocoapods podspec, Run `pod trunk push Commands.podspec --allow-warnings --verbose`.

Sources/Commands/Commands.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,3 @@
66
//
77

88
public enum Commands { }
9-
10-
public extension Commands {
11-
static let Bash = BashENV()
12-
13-
static let Ruby = RubyENV()
14-
15-
static let Python = PythonENV()
16-
17-
static func Custom(_ executableURL: String, dashc: String? = nil) -> CustomENV {
18-
return CustomENV(executableURL, dashc: dashc)
19-
}
20-
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//
2+
// CommandsAlias.swift
3+
//
4+
//
5+
// Created by zhifei qiu on 2021/8/24.
6+
//
7+
8+
import Foundation
9+
10+
extension Commands {
11+
public struct Alias {
12+
public let executableURL: String
13+
public let dashc: Commands.Arguments?
14+
15+
public init(_ executableURL: String, dashc: Commands.Arguments? = nil) {
16+
self.executableURL = executableURL
17+
self.dashc = dashc
18+
}
19+
}
20+
}
21+
22+
public extension Commands.Alias {
23+
@discardableResult
24+
func run(_ arguments: Commands.Arguments? = nil,
25+
environment: Commands.ENV? = Commands.ENV()) -> Commands.Result {
26+
let request = prepare(arguments, environment: environment)
27+
return Commands.Task.run(request)
28+
}
29+
30+
func system(_ arguments: Commands.Arguments? = nil,
31+
environment: Commands.ENV? = Commands.ENV()) {
32+
let request = prepare(arguments, environment: environment)
33+
Commands.Task.system(request)
34+
}
35+
36+
func system(_ arguments: Commands.Arguments? = nil,
37+
environment: Commands.ENV? = Commands.ENV(),
38+
output: ((String) -> Void)?,
39+
errorOutput: ((String) -> Void)?) {
40+
let request = prepare(arguments, environment: environment)
41+
Commands.Task.system(request, output: output, errorOutput: errorOutput)
42+
}
43+
}
44+
45+
private extension Commands.Alias {
46+
func prepare(_ arguments: Commands.Arguments?,
47+
environment: Commands.ENV?) -> Commands.Request {
48+
return Commands.Request(environment,
49+
executableURL: executableURL,
50+
dashc: dashc,
51+
arguments: arguments)
52+
}
53+
}
54+
55+
public extension Commands {
56+
static let Bash = Commands.Alias("bash", dashc: "-c")
57+
static let Ruby = Commands.Alias("ruby", dashc: "-e")
58+
static let Python = Commands.Alias("python", dashc: "-c")
59+
static let Node = Commands.Alias("node", dashc: "-e")
60+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//
2+
// CommandsArguments.swift
3+
//
4+
//
5+
// Created by zhifei qiu on 2021/8/6.
6+
//
7+
8+
public extension Commands {
9+
enum Arguments {
10+
case value(String)
11+
case elements([String])
12+
13+
init(_ value: String) {
14+
self = Arguments.value(value)
15+
}
16+
17+
init(_ elements: [String]) {
18+
self = Arguments.elements(elements)
19+
}
20+
}
21+
}
22+
23+
extension Commands.Arguments {
24+
var raw: [String] {
25+
switch self {
26+
case .value(let value):
27+
return [value]
28+
case .elements(let elements):
29+
return elements
30+
}
31+
}
32+
}
33+
34+
extension Commands.Arguments: Swift.ExpressibleByStringLiteral {
35+
public init(stringLiteral value: StringLiteralType) {
36+
self.init(value)
37+
}
38+
39+
public init(extendedGraphemeClusterLiteral value: String) {
40+
self.init(value)
41+
}
42+
43+
public init(unicodeScalarLiteral value: String) {
44+
self.init(value)
45+
}
46+
}
47+
48+
extension Commands.Arguments: Swift.ExpressibleByStringInterpolation {
49+
public init(stringInterpolation: DefaultStringInterpolation) {
50+
self.init(stringInterpolation.description)
51+
}
52+
}
53+
54+
extension Commands.Arguments: Swift.ExpressibleByArrayLiteral {
55+
public init(arrayLiteral elements: String...) {
56+
self.init(elements)
57+
}
58+
}
59+
60+
extension Commands.Arguments: Equatable {
61+
public static func == (lhs: Self, rhs: Self) -> Bool {
62+
return lhs.raw == rhs.raw
63+
}
64+
}

Sources/Commands/CommandsENV.swift

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,47 @@
22
// CommandsENV.swift
33
//
44
//
5-
// Created by zhifei qiu on 2021/8/2.
5+
// Created by zhifei qiu on 2021/8/25.
66
//
77

88
import Foundation
99

10-
public protocol CommandsENV {
11-
var executableURL: String { get }
12-
var dashc: String? { get }
13-
14-
func run(_ command: String, environment: [String: String]?) -> Commands.Result
15-
func system(_ command: String, environment: [String: String]?)
16-
func system(_ command: String, environment: [String: String]?, output: ((String) -> Void)?, errorOutput: ((String) -> Void)?)
10+
extension Commands {
11+
public struct ENV {
12+
public private(set) var data: [String: String] = [:]
13+
14+
public init(_ data: [String: String]? = ProcessInfo.processInfo.environment) {
15+
self.data = data ?? [:]
16+
}
17+
}
1718
}
1819

19-
public extension CommandsENV {
20-
@discardableResult
21-
func run(_ command: String, environment: [String: String]? = nil) -> Commands.Result {
22-
let request = prepare(command, environment: environment)
23-
return Commands.Task.run(request)
20+
public extension Commands.ENV {
21+
mutating func add(PATH: String) {
22+
data["PATH"] = data["PATH"] == nil ? PATH : "\(PATH):\(data["PATH"]!)"
2423
}
25-
26-
func system(_ command: String, environment: [String: String]? = nil) {
27-
let request = prepare(command, environment: environment)
28-
Commands.Task.system(request)
24+
}
25+
26+
public extension Commands.ENV {
27+
subscript(_ key: String) -> String? {
28+
set(newValue) {
29+
data[key] = newValue
30+
}
31+
get {
32+
return data[key]
33+
}
2934
}
30-
31-
func system(_ command: String, environment: [String: String]? = nil, output: ((String) -> Void)?, errorOutput: ((String) -> Void)?) {
32-
let request = prepare(command, environment: environment)
33-
Commands.Task.system(request, output: output, errorOutput: errorOutput)
35+
}
36+
37+
extension Commands.ENV: Swift.ExpressibleByDictionaryLiteral {
38+
public init(dictionaryLiteral elements: (String, String)...) {
39+
let dictionary = elements.reduce(into: [String: String](), { $0[$1.0] = $1.1})
40+
self.init(dictionary)
3441
}
3542
}
3643

37-
private extension CommandsENV {
38-
func prepare(_ command: String, environment: [String: String]? = nil) -> Commands.Request {
39-
return Commands.Request(executableURL, dashc: dashc, command: command, environment: environment)
44+
extension Commands.ENV: Equatable {
45+
public static func == (lhs: Self, rhs: Self) -> Bool {
46+
lhs.data == rhs.data
4047
}
4148
}

0 commit comments

Comments
 (0)