Skip to content

Commit

Permalink
wip: flag parsing and help generation
Browse files Browse the repository at this point in the history
  • Loading branch information
rauhul committed Nov 21, 2022
1 parent 4a02221 commit ede9fca
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 88 deletions.
1 change: 1 addition & 0 deletions Sources/ArgumentParser/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ add_library(ArgumentParser
Usage/DumpHelpGenerator.swift
Usage/HelpCommand.swift
Usage/HelpGenerator.swift
Usage/HelpOptions.swift
Usage/MessageInfo.swift
Usage/UsageGenerator.swift

Expand Down
8 changes: 6 additions & 2 deletions Sources/ArgumentParser/Parsable Types/ParsableArguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ extension ParsableArguments {
// Parse the command and unwrap the result if necessary.
switch try self.asCommand.parseAsRoot(arguments) {
case let helpCommand as HelpCommand:
throw ParserError.helpRequested(visibility: helpCommand.visibility)
throw ParserError.helpRequested(options: helpCommand.options)
case let result as _WrappedParsableCommand<Self>:
return result.options
case var result as Self:
Expand Down Expand Up @@ -142,7 +142,11 @@ extension ParsableArguments {
includeHidden: Bool = false,
columns: Int? = nil
) -> String {
HelpGenerator(self, visibility: includeHidden ? .hidden : .default)
HelpGenerator(
self,
options: .init(
visibility: includeHidden ? .hidden : .default,
detailed: false))
.rendered(screenWidth: columns)
}

Expand Down
4 changes: 3 additions & 1 deletion Sources/ArgumentParser/Parsable Types/ParsableCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ extension ParsableCommand {
) -> String {
HelpGenerator(
commandStack: CommandParser(self).commandStack(for: subcommand),
visibility: includeHidden ? .hidden : .default)
options: .init(
visibility: includeHidden ? .hidden : .default,
detailed: false))
.rendered(screenWidth: columns)
}

Expand Down
21 changes: 11 additions & 10 deletions Sources/ArgumentParser/Parsing/CommandParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct CommandError: Error {
}

struct HelpRequested: Error {
var visibility: ArgumentVisibility
var options: HelpOptions
}

struct CommandParser {
Expand Down Expand Up @@ -85,15 +85,16 @@ extension CommandParser {
requireSoloArgument: Bool = false
) throws {
guard !requireSoloArgument || split.count == 1 else { return }

// Look for help flags
guard !split.contains(anyOf: self.commandStack.getHelpNames(visibility: .default)) else {
throw HelpRequested(visibility: .default)
}

// Look for help-hidden flags
guard !split.contains(anyOf: self.commandStack.getHelpNames(visibility: .hidden)) else {
throw HelpRequested(visibility: .hidden)
// Search for various help flags [.default, .hidden] x [standard, detailed]
for visibility in [ArgumentVisibility.default, .hidden] {
for detailed in [false, true] {
let options = HelpOptions(visibility: visibility, detailed: detailed)
let helpNames = self.commandStack.getHelpNames(options: options)
if split.contains(anyOf: helpNames) {
throw HelpRequested(options: options)
}
}
}

// Look for dump-help flag
Expand Down Expand Up @@ -254,7 +255,7 @@ extension CommandParser {
} catch let helpRequest as HelpRequested {
return .success(HelpCommand(
commandStack: commandStack,
visibility: helpRequest.visibility))
options: helpRequest.options))
} catch {
return .failure(CommandError(commandStack: commandStack, parserError: .invalidState))
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/ArgumentParser/Parsing/ParserError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

/// Gets thrown while parsing and will be handled by the error output generation.
enum ParserError: Error {
case helpRequested(visibility: ArgumentVisibility)
case helpRequested(options: HelpOptions)
case versionRequested
case dumpHelpRequested

Expand Down
49 changes: 26 additions & 23 deletions Sources/ArgumentParser/Usage/HelpCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
//===----------------------------------------------------------------------===//

struct HelpCommand: ParsableCommand {
enum CodingKeys: CodingKey {
case subcommands
case help
}

static var configuration = CommandConfiguration(
commandName: "help",
abstract: "Show subcommand help information.",
Expand All @@ -23,16 +28,32 @@ struct HelpCommand: ParsableCommand {
var help = false

private(set) var commandStack: [ParsableCommand.Type] = []
private(set) var visibility: ArgumentVisibility = .default
private(set) var options = HelpOptions.plain

init() {}
init() { }

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.subcommands = try container.decode([String].self, forKey: .subcommands)
self.help = try container.decode(Bool.self, forKey: .help)
}

init(
commandStack: [ParsableCommand.Type],
options: HelpOptions
) {
self.commandStack = commandStack
self.options = options
self.subcommands = commandStack.map { $0._commandName }
self.help = false
}

mutating func run() throws {
throw CommandError(
commandStack: commandStack,
parserError: .helpRequested(visibility: visibility))
parserError: .helpRequested(options: options))
}

mutating func buildCommandStack(with parser: CommandParser) throws {
commandStack = parser.commandStack(for: subcommands)
}
Expand All @@ -41,25 +62,7 @@ struct HelpCommand: ParsableCommand {
func generateHelp(screenWidth: Int) -> String {
HelpGenerator(
commandStack: commandStack,
visibility: visibility)
options: options)
.rendered(screenWidth: screenWidth)
}

enum CodingKeys: CodingKey {
case subcommands
case help
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.subcommands = try container.decode([String].self, forKey: .subcommands)
self.help = try container.decode(Bool.self, forKey: .help)
}

init(commandStack: [ParsableCommand.Type], visibility: ArgumentVisibility) {
self.commandStack = commandStack
self.visibility = visibility
self.subcommands = commandStack.map { $0._commandName }
self.help = false
}
}

0 comments on commit ede9fca

Please sign in to comment.