Refactor argument parsing a bit so we can reuse filtering between commands

This commit is contained in:
Simon Kågedal Reimer 2019-05-30 15:19:12 +02:00
parent 05daa61692
commit 5cb09956d8
5 changed files with 44 additions and 22 deletions

View File

@ -5,6 +5,8 @@ A description of this package.
## TODO ## TODO
* `install-ca` command * `install-ca` command
* `remove-ca` command
* Filter for os types * Filter for os types
* Find out why the argument parsing errors are not printed correctly * Find out why the argument parsing errors are not printed correctly
* `remove` command * `--dry-run` option
* `remove` command that removes simulators

View File

@ -18,6 +18,18 @@ struct FilteringOptions {
var availability: Availability = .yes var availability: Availability = .yes
} }
extension ArgumentBinder where Options == FilteringOptions {
func bind(to options: inout FilteringOptions, parser: ArgumentParser) {
bind(option: parser.add(
option: "--availability",
kind: FilteringOptions.Availability.self,
usage: "Only list available devices? yes|no|all, defaults to all"
), to: { options, availability in
options.availability = availability
})
}
}
struct CommandLineOptions { struct CommandLineOptions {
enum SubCommand { enum SubCommand {
case noCommand case noCommand
@ -92,7 +104,7 @@ struct CommandLineOptions {
guard guard
let subcommandName = result.subparser(parser), let subcommandName = result.subparser(parser),
var command = allCommands.first(where: { $0.name == subcommandName }) let command = allCommands.first(where: { $0.name == subcommandName })
else { else {
throw Error( throw Error(
underlyingError: NoCommandError(), underlyingError: NoCommandError(),

View File

@ -13,6 +13,6 @@ protocol Command {
var overview: String { get } var overview: String { get }
func addOptions(to parser: ArgumentParser) func addOptions(to parser: ArgumentParser)
mutating func fillParseResult(_ parseResult: ArgumentParser.Result) throws func fillParseResult(_ parseResult: ArgumentParser.Result) throws
func run() throws func run() throws
} }

View File

@ -5,29 +5,41 @@
import Foundation import Foundation
import SPMUtility import SPMUtility
struct InstallCACommand: Command { class InstallCACommand: Command {
private struct Options {
var path: String? = nil
}
let name = "install-ca" let name = "install-ca"
let overview = "Install a Certificate Authority" let overview = "Install a Certificate Authority"
private let binder = ArgumentBinder<InstallCACommand>() private let binder = ArgumentBinder<Options>()
private var path: String? private var options = Options()
private let filteringBinder = ArgumentBinder<FilteringOptions>()
private var filteringOptions = FilteringOptions()
func addOptions(to parser: ArgumentParser) { func addOptions(to parser: ArgumentParser) {
binder.bind(positional: parser.add( binder.bind(positional: parser.add(
positional: "path", positional: "path",
kind: String.self kind: String.self,
), to: { command, path in usage: "Path for the certificate to install"
command.path = path ), to: { options, path in
options.path = path
}) })
filteringBinder.bind(to: &filteringOptions, parser: parser)
} }
mutating func fillParseResult(_ parseResult: ArgumentParser.Result) throws { func fillParseResult(_ parseResult: ArgumentParser.Result) throws {
try binder.fill(parseResult: parseResult, into: &self) try binder.fill(parseResult: parseResult, into: &options)
try filteringBinder.fill(parseResult: parseResult, into: &filteringOptions)
} }
func run() throws { func run() throws {
let url = URL(fileURLWithPath: path!) let url = URL(fileURLWithPath: options.path!)
let certificate = try Certificate.load(from: url) let certificate = try Certificate.load(from: url)
print(certificate) print(certificate)
print(filteringOptions)
} }
} }

View File

@ -5,25 +5,21 @@
import Foundation import Foundation
import SPMUtility import SPMUtility
struct ListDevicesCommand: Command { class ListDevicesCommand: Command {
let name = "list-devices" let name = "list-devices"
let overview = "List available Xcode Simulator devices" let overview = "List available Xcode Simulator devices"
private let binder = ArgumentBinder<ListDevicesCommand>() private let binder = ArgumentBinder<ListDevicesCommand>()
private var filteringOptions = FilteringOptions() private var filteringOptions = FilteringOptions()
private let filteringBinder = ArgumentBinder<FilteringOptions>()
func addOptions(to parser: ArgumentParser) { func addOptions(to parser: ArgumentParser) {
binder.bind(option: parser.add( filteringBinder.bind(to: &filteringOptions, parser: parser)
option: "--availability",
kind: FilteringOptions.Availability.self,
usage: "Only list available devices? yes|no|all, defaults to all"
), to: { command, availability in
command.filteringOptions.availability = availability
})
} }
mutating func fillParseResult(_ parseResult: ArgumentParser.Result) throws { func fillParseResult(_ parseResult: ArgumentParser.Result) throws {
try binder.fill(parseResult: parseResult, into: &self) try filteringBinder.fill(parseResult: parseResult, into: &filteringOptions)
// try binder.fill(parseResult: parseResult, into: &self)
} }
func run() throws { func run() throws {