Skip to content

Commit ef4d83f

Browse files
committed
Better input handling in cli
1 parent 931d153 commit ef4d83f

File tree

1 file changed

+57
-36
lines changed

1 file changed

+57
-36
lines changed

Sources/CLI/CLI.swift

+57-36
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,14 @@ struct Check: ParsableCommand {
2424
"""
2525
)
2626

27-
@Argument(help: "Input file. Standard input is used if omitted")
28-
var file: FileURL?
29-
30-
func validate() throws {
31-
_ = try self.file?.url.checkResourceIsReachable()
32-
}
27+
@Option(
28+
name: [.customShort("i"), .long],
29+
help: "Input. Standard input is used with -. If omitted, try to use .env in cwd"
30+
)
31+
var input: Input?
3332

3433
func run() throws {
35-
let string = try readInput(self.file)
36-
do {
37-
_ = try DotEnvironment.parse(string: string)
38-
} catch let error as ParseErrorWithLocation {
39-
FileHandle.standardError.write(Data(error.formatError(source: string).utf8))
40-
FileHandle.standardError.write(Data("\n".utf8))
41-
throw ExitCode.failure
42-
}
34+
_ = try loadInput(self.input)
4335
}
4436
}
4537

@@ -58,30 +50,37 @@ struct JSON: ParsableCommand {
5850
"""
5951
)
6052

61-
@Argument(help: "Input file. Standard input is used if omitted")
62-
var file: FileURL?
53+
@Option(
54+
name: [.customShort("i"), .long],
55+
help: "Input. Standard input is used with -. If omitted, try to use .env in cwd"
56+
)
57+
var input: Input?
6358

6459
@Flag(help: "Pretty print JSON")
6560
var pretty: Bool = false
6661

67-
func validate() throws {
68-
_ = try self.file?.url.checkResourceIsReachable()
62+
func run() throws {
63+
let values = try loadInput(self.input)
64+
let json = try JSONSerialization.data(
65+
withJSONObject: values,
66+
options: self.pretty ? [.prettyPrinted, .sortedKeys] : []
67+
)
68+
FileHandle.standardOutput.write(json)
69+
FileHandle.standardOutput.write(Data("\n".utf8))
6970
}
71+
}
7072

71-
func run() throws {
72-
let string = try readInput(self.file)
73-
do {
74-
let values = try DotEnvironment.parse(string: string)
75-
let json = try JSONSerialization.data(
76-
withJSONObject: values,
77-
options: self.pretty ? [.prettyPrinted, .sortedKeys] : []
78-
)
79-
FileHandle.standardOutput.write(json)
80-
FileHandle.standardOutput.write(Data("\n".utf8))
81-
} catch let error as ParseErrorWithLocation {
82-
FileHandle.standardError.write(Data(error.formatError(source: string).utf8))
83-
FileHandle.standardError.write(Data("\n".utf8))
84-
throw ExitCode.failure
73+
enum Input: ExpressibleByArgument {
74+
case stdin
75+
case fileURL(FileURL)
76+
77+
init?(argument: String) {
78+
if argument == "-" {
79+
self = .stdin
80+
} else if let fileURL = FileURL(argument: argument) {
81+
self = .fileURL(fileURL)
82+
} else {
83+
return nil
8584
}
8685
}
8786
}
@@ -99,12 +98,34 @@ struct FileURL: ExpressibleByArgument {
9998
}
10099
}
101100

102-
private func readInput(_ file: FileURL?) throws -> String {
103-
let data: Data
104-
if let file {
105-
data = try Data(contentsOf: file.url)
101+
private func loadInput(_ input: Input?) throws -> [String: String] {
102+
if let input = input {
103+
let string = try readInput(input)
104+
do {
105+
return try DotEnvironment.parse(string: string)
106+
} catch let error as ParseErrorWithLocation {
107+
FileHandle.standardError.write(Data(error.formatError(source: string).utf8))
108+
FileHandle.standardError.write(Data("\n".utf8))
109+
throw ExitCode.failure
110+
}
106111
} else {
112+
do {
113+
return try DotEnvironment.loadValues()
114+
} catch let error as LoadError {
115+
FileHandle.standardError.write(Data(error.description.utf8))
116+
FileHandle.standardError.write(Data("\n".utf8))
117+
throw ExitCode.failure
118+
}
119+
}
120+
}
121+
122+
private func readInput(_ input: Input) throws -> String {
123+
let data: Data
124+
switch input {
125+
case .stdin:
107126
data = FileHandle.standardInput.readDataToEndOfFile()
127+
case let .fileURL(fileURL):
128+
data = try Data(contentsOf: fileURL.url)
108129
}
109130
guard let string = String(data: data, encoding: .utf8) else {
110131
throw ValidationError("Input could not be decoded as UTF-8")

0 commit comments

Comments
 (0)