Skip to content

Commit 6f30db0

Browse files
authored
Don't trigger help for unconditional remaining commands (#417)
1 parent c959b3a commit 6f30db0

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

Sources/ArgumentParser/Parsing/CommandParser.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,19 @@ extension CommandParser {
7373
return subcommandNode
7474
}
7575

76-
/// Throws a `HelpRequested` error if the user has specified either of the
77-
/// built in help flags.
78-
func checkForBuiltInFlags(_ split: SplitArguments) throws {
76+
/// Throws a `HelpRequested` error if the user has specified any of the
77+
/// built-in flags.
78+
///
79+
/// - Parameters:
80+
/// - split: The remaining arguments to examine.
81+
/// - requireSoloArgument: `true` if the built-in flag must be the only
82+
/// one remaining for this to catch it.
83+
func checkForBuiltInFlags(
84+
_ split: SplitArguments,
85+
requireSoloArgument: Bool = false
86+
) throws {
87+
guard !requireSoloArgument || split.count == 1 else { return }
88+
7989
// Look for help flags
8090
guard !split.contains(anyOf: self.commandStack.getHelpNames(visibility: .default)) else {
8191
throw HelpRequested(visibility: .default)
@@ -187,7 +197,7 @@ extension CommandParser {
187197
}
188198

189199
// Look for the help flag before falling back to a default command.
190-
try checkForBuiltInFlags(split)
200+
try checkForBuiltInFlags(split, requireSoloArgument: true)
191201

192202
// No command was found, so fall back to the default subcommand.
193203
if let defaultSubcommand = currentNode.element.configuration.defaultSubcommand {

Sources/ArgumentParser/Parsing/SplitArguments.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ struct SplitArguments {
180180
var elements: ArraySlice<Element> {
181181
_elements[firstUnused...]
182182
}
183+
184+
var count: Int {
185+
elements.count
186+
}
183187
}
184188

185189
extension SplitArguments.Element: CustomDebugStringConvertible {

Tests/ArgumentParserEndToEndTests/DefaultSubcommandEndToEndTests.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ extension DefaultSubcommandEndToEndTests {
123123
XCTAssertEqual(plugin.pluginArguments, ["--verbose"])
124124
XCTAssertEqual(plugin.options.verbose, true)
125125
}
126+
AssertParseCommand(MyCommand.self, Plugin.self, ["my-plugin", "--help"]) { plugin in
127+
XCTAssertEqual(plugin.pluginName, "my-plugin")
128+
XCTAssertEqual(plugin.pluginArguments, ["--help"])
129+
XCTAssertEqual(plugin.options.verbose, false)
130+
}
126131
}
127132

128133
func testRemainingDefaultExplicit() throws {
@@ -141,6 +146,11 @@ extension DefaultSubcommandEndToEndTests {
141146
XCTAssertEqual(plugin.pluginArguments, ["--verbose"])
142147
XCTAssertEqual(plugin.options.verbose, true)
143148
}
149+
AssertParseCommand(MyCommand.self, Plugin.self, ["--verbose", "plugin", "my-plugin", "--help"]) { plugin in
150+
XCTAssertEqual(plugin.pluginName, "my-plugin")
151+
XCTAssertEqual(plugin.pluginArguments, ["--help"])
152+
XCTAssertEqual(plugin.options.verbose, true)
153+
}
144154
}
145155

146156
func testRemainingNonDefault() throws {
@@ -159,6 +169,11 @@ extension DefaultSubcommandEndToEndTests {
159169
XCTAssertEqual(nondef.pluginArguments, ["--verbose"])
160170
XCTAssertEqual(nondef.options.verbose, true)
161171
}
172+
AssertParseCommand(MyCommand.self, NonDefault.self, ["--verbose", "non-default", "my-plugin", "--help"]) { nondef in
173+
XCTAssertEqual(nondef.pluginName, "my-plugin")
174+
XCTAssertEqual(nondef.pluginArguments, ["--help"])
175+
XCTAssertEqual(nondef.options.verbose, true)
176+
}
162177
}
163178

164179
func testRemainingDefaultOther() throws {

0 commit comments

Comments
 (0)