Skip to content

Commit ede9fca

Browse files
committed
wip: flag parsing and help generation
1 parent 4a02221 commit ede9fca

File tree

11 files changed

+170
-88
lines changed

11 files changed

+170
-88
lines changed

Sources/ArgumentParser/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ add_library(ArgumentParser
3737
Usage/DumpHelpGenerator.swift
3838
Usage/HelpCommand.swift
3939
Usage/HelpGenerator.swift
40+
Usage/HelpOptions.swift
4041
Usage/MessageInfo.swift
4142
Usage/UsageGenerator.swift
4243

Sources/ArgumentParser/Parsable Types/ParsableArguments.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ extension ParsableArguments {
7575
// Parse the command and unwrap the result if necessary.
7676
switch try self.asCommand.parseAsRoot(arguments) {
7777
case let helpCommand as HelpCommand:
78-
throw ParserError.helpRequested(visibility: helpCommand.visibility)
78+
throw ParserError.helpRequested(options: helpCommand.options)
7979
case let result as _WrappedParsableCommand<Self>:
8080
return result.options
8181
case var result as Self:
@@ -142,7 +142,11 @@ extension ParsableArguments {
142142
includeHidden: Bool = false,
143143
columns: Int? = nil
144144
) -> String {
145-
HelpGenerator(self, visibility: includeHidden ? .hidden : .default)
145+
HelpGenerator(
146+
self,
147+
options: .init(
148+
visibility: includeHidden ? .hidden : .default,
149+
detailed: false))
146150
.rendered(screenWidth: columns)
147151
}
148152

Sources/ArgumentParser/Parsable Types/ParsableCommand.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ extension ParsableCommand {
109109
) -> String {
110110
HelpGenerator(
111111
commandStack: CommandParser(self).commandStack(for: subcommand),
112-
visibility: includeHidden ? .hidden : .default)
112+
options: .init(
113+
visibility: includeHidden ? .hidden : .default,
114+
detailed: false))
113115
.rendered(screenWidth: columns)
114116
}
115117

Sources/ArgumentParser/Parsing/CommandParser.swift

+11-10
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct CommandError: Error {
1515
}
1616

1717
struct HelpRequested: Error {
18-
var visibility: ArgumentVisibility
18+
var options: HelpOptions
1919
}
2020

2121
struct CommandParser {
@@ -85,15 +85,16 @@ extension CommandParser {
8585
requireSoloArgument: Bool = false
8686
) throws {
8787
guard !requireSoloArgument || split.count == 1 else { return }
88-
89-
// Look for help flags
90-
guard !split.contains(anyOf: self.commandStack.getHelpNames(visibility: .default)) else {
91-
throw HelpRequested(visibility: .default)
92-
}
9388

94-
// Look for help-hidden flags
95-
guard !split.contains(anyOf: self.commandStack.getHelpNames(visibility: .hidden)) else {
96-
throw HelpRequested(visibility: .hidden)
89+
// Search for various help flags [.default, .hidden] x [standard, detailed]
90+
for visibility in [ArgumentVisibility.default, .hidden] {
91+
for detailed in [false, true] {
92+
let options = HelpOptions(visibility: visibility, detailed: detailed)
93+
let helpNames = self.commandStack.getHelpNames(options: options)
94+
if split.contains(anyOf: helpNames) {
95+
throw HelpRequested(options: options)
96+
}
97+
}
9798
}
9899

99100
// Look for dump-help flag
@@ -254,7 +255,7 @@ extension CommandParser {
254255
} catch let helpRequest as HelpRequested {
255256
return .success(HelpCommand(
256257
commandStack: commandStack,
257-
visibility: helpRequest.visibility))
258+
options: helpRequest.options))
258259
} catch {
259260
return .failure(CommandError(commandStack: commandStack, parserError: .invalidState))
260261
}

Sources/ArgumentParser/Parsing/ParserError.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
/// Gets thrown while parsing and will be handled by the error output generation.
1313
enum ParserError: Error {
14-
case helpRequested(visibility: ArgumentVisibility)
14+
case helpRequested(options: HelpOptions)
1515
case versionRequested
1616
case dumpHelpRequested
1717

Sources/ArgumentParser/Usage/HelpCommand.swift

+26-23
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
//===----------------------------------------------------------------------===//
1111

1212
struct HelpCommand: ParsableCommand {
13+
enum CodingKeys: CodingKey {
14+
case subcommands
15+
case help
16+
}
17+
1318
static var configuration = CommandConfiguration(
1419
commandName: "help",
1520
abstract: "Show subcommand help information.",
@@ -23,16 +28,32 @@ struct HelpCommand: ParsableCommand {
2328
var help = false
2429

2530
private(set) var commandStack: [ParsableCommand.Type] = []
26-
private(set) var visibility: ArgumentVisibility = .default
31+
private(set) var options = HelpOptions.plain
2732

28-
init() {}
33+
init() { }
34+
35+
init(from decoder: Decoder) throws {
36+
let container = try decoder.container(keyedBy: CodingKeys.self)
37+
self.subcommands = try container.decode([String].self, forKey: .subcommands)
38+
self.help = try container.decode(Bool.self, forKey: .help)
39+
}
2940

41+
init(
42+
commandStack: [ParsableCommand.Type],
43+
options: HelpOptions
44+
) {
45+
self.commandStack = commandStack
46+
self.options = options
47+
self.subcommands = commandStack.map { $0._commandName }
48+
self.help = false
49+
}
50+
3051
mutating func run() throws {
3152
throw CommandError(
3253
commandStack: commandStack,
33-
parserError: .helpRequested(visibility: visibility))
54+
parserError: .helpRequested(options: options))
3455
}
35-
56+
3657
mutating func buildCommandStack(with parser: CommandParser) throws {
3758
commandStack = parser.commandStack(for: subcommands)
3859
}
@@ -41,25 +62,7 @@ struct HelpCommand: ParsableCommand {
4162
func generateHelp(screenWidth: Int) -> String {
4263
HelpGenerator(
4364
commandStack: commandStack,
44-
visibility: visibility)
65+
options: options)
4566
.rendered(screenWidth: screenWidth)
4667
}
47-
48-
enum CodingKeys: CodingKey {
49-
case subcommands
50-
case help
51-
}
52-
53-
init(from decoder: Decoder) throws {
54-
let container = try decoder.container(keyedBy: CodingKeys.self)
55-
self.subcommands = try container.decode([String].self, forKey: .subcommands)
56-
self.help = try container.decode(Bool.self, forKey: .help)
57-
}
58-
59-
init(commandStack: [ParsableCommand.Type], visibility: ArgumentVisibility) {
60-
self.commandStack = commandStack
61-
self.visibility = visibility
62-
self.subcommands = commandStack.map { $0._commandName }
63-
self.help = false
64-
}
6568
}

0 commit comments

Comments
 (0)