I've found ArgumentParser extremely useful as I am working on a CLI iOS app that takes commands as input. I'm using this module to parse commands that users write into the app. I've described, as an example, the SSH command that would have the following format.
struct SSHCommand: ParsableCommand {
@Option(name: [.customLong("port"), .customShort("P")],
default: "22",
help: "Specifies the port to connect to on the remote host.")
var port: String
@Argument(help: "user@host")
var host: String
var username: String {
get {
if host.contains("@") {
return host.components(separatedBy: "@")[0]
} else {
guard let hostName = SSHCommons.getHosts(by: host.components(separatedBy: ":")[0]) else {
return ""
}
return hostName.user!
}
}
}
var remoteHost: String {
get {
if host.contains("@") {
return host.components(separatedBy: "@")[1].components(separatedBy: ":")[0]
} else {
guard let hostName = SSHCommons.getHosts(by: host.components(separatedBy: ":")[0]) else {
return ""
}
return hostName.hostName!
}
}
}
func run() throws {
}
func validate() throws {
if host == nil || host.count == 0 {
throw ValidationError("Missing '<host>'")
}
}
}
This won't be run from the console but on an app validating the command input,
do {
sshCommand = try SSHCommand.parse(("ssh host -p 22".components(separatedBy: " "))
} catch {
print(message: error.localizedDescription)
}
It all runs okay but I'd like to prompt the user a descriptive error in the case of running a command such as ssh
stating that it's missing a host to connect to.
I am having trouble propagating the validation errors such as ValidationError("Missing '<host>'")
to be shown in the app. As far as I know that error would propagate through the screen an be shown if the app was a CLI application but in this case I'm at a loss. When the error is thrown in the catch
block its type is not of ValidationError
but ArgumentParser.CommandError
which is not made publicly available in the Package.
Is there a guide on how to show the user this kind of informative errors when using ArgumentParser
in an app instead of in a CLI app?