Skip to content

Commit 68b94a4

Browse files
authored
List valid options in error messages for enum array argument (#445)
When an array of argument values fails to parse, no custom error message is provided, and a list of valid candidate values is available, include the list as part of the error message. Addresses #401.
1 parent 060d523 commit 68b94a4

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

Sources/ArgumentParser/Parsable Properties/Argument.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,12 @@ extension Argument {
338338
helpDefaultValue = nil
339339
}
340340

341-
let help = ArgumentDefinition.Help(options: [.isOptional, .isRepeating], help: help, key: key)
341+
let help = ArgumentDefinition.Help(
342+
allValues: Element.allValueStrings,
343+
options: [.isOptional, .isRepeating],
344+
help: help,
345+
key: key
346+
)
342347
var arg = ArgumentDefinition(
343348
kind: .positional,
344349
help: help,

Tests/ArgumentParserUnitTests/ErrorMessageTests.swift

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,28 +64,39 @@ extension ErrorMessageTests {
6464
}
6565
}
6666

67-
fileprivate struct Foo: ParsableArguments {
68-
enum Format: String, Equatable, Decodable, ExpressibleByArgument, CaseIterable {
69-
case text
70-
case json
71-
case csv
72-
}
67+
fileprivate enum Format: String, Equatable, Decodable, ExpressibleByArgument, CaseIterable {
68+
case text
69+
case json
70+
case csv
71+
}
7372

74-
enum Name: String, Equatable, Decodable, ExpressibleByArgument, CaseIterable {
75-
case bruce
76-
case clint
77-
case hulk
78-
case natasha
79-
case steve
80-
case thor
81-
case tony
82-
}
73+
fileprivate enum Name: String, Equatable, Decodable, ExpressibleByArgument, CaseIterable {
74+
case bruce
75+
case clint
76+
case hulk
77+
case natasha
78+
case steve
79+
case thor
80+
case tony
81+
}
82+
83+
fileprivate struct Foo: ParsableArguments {
8384
@Option(name: [.short, .long])
8485
var format: Format
8586
@Option(name: [.short, .long])
8687
var name: Name?
8788
}
8889

90+
fileprivate struct EnumWithFewCasesArrayArgument: ParsableArguments {
91+
@Argument
92+
var formats: [Format]
93+
}
94+
95+
fileprivate struct EnumWithManyCasesArrayArgument: ParsableArguments {
96+
@Argument
97+
var names: [Name]
98+
}
99+
89100
extension ErrorMessageTests {
90101
func testWrongEnumValue() {
91102
AssertErrorMessage(Foo.self, ["--format", "png"], "The value 'png' is invalid for '--format <format>'. Please provide one of 'text', 'json' or 'csv'.")
@@ -112,6 +123,18 @@ extension ErrorMessageTests {
112123
- thor
113124
- tony
114125
""")
126+
AssertErrorMessage(EnumWithFewCasesArrayArgument.self, ["png"], "The value 'png' is invalid for '<formats>'. Please provide one of 'text', 'json' or 'csv'.")
127+
AssertErrorMessage(EnumWithManyCasesArrayArgument.self, ["loki"],
128+
"""
129+
The value 'loki' is invalid for '<names>'. Please provide one of the following:
130+
- bruce
131+
- clint
132+
- hulk
133+
- natasha
134+
- steve
135+
- thor
136+
- tony
137+
""")
115138
}
116139
}
117140

0 commit comments

Comments
 (0)