Skip to content

Commit

Permalink
Hide optional flags when a command has too many options (#416)
Browse files Browse the repository at this point in the history
The usage string feature that only shows positional args and required
options/flags was incorrectly allowing through flags with type
`Bool?`.
  • Loading branch information
natecook1000 authored Mar 8, 2022
1 parent b3a9c24 commit c959b3a
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
18 changes: 16 additions & 2 deletions Sources/ArgumentParser/Parsable Properties/Flag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,14 @@ extension Flag where Value == Optional<Bool> {
help: ArgumentHelp? = nil
) {
self.init(_parsedValue: .init { key in
.flag(key: key, name: name, default: nil, inversion: inversion, exclusivity: exclusivity, help: help)
.flag(
key: key,
name: name,
default: nil,
required: false,
inversion: inversion,
exclusivity: exclusivity,
help: help)
})
}
}
Expand Down Expand Up @@ -257,7 +264,14 @@ extension Flag where Value == Bool {
help: ArgumentHelp?
) {
self.init(_parsedValue: .init { key in
.flag(key: key, name: name, default: initial, inversion: inversion, exclusivity: exclusivity, help: help)
.flag(
key: key,
name: name,
default: initial,
required: initial == nil,
inversion: inversion,
exclusivity: exclusivity,
help: help)
})
}

Expand Down
13 changes: 10 additions & 3 deletions Sources/ArgumentParser/Parsing/ArgumentSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,16 @@ extension ArgumentSet {
}

/// Creates an argument set for a pair of inverted Boolean flags.
static func flag(key: InputKey, name: NameSpecification, default initialValue: Bool?, inversion: FlagInversion, exclusivity: FlagExclusivity, help: ArgumentHelp?) -> ArgumentSet {
// The flag is required if initialValue is `nil`, otherwise it's optional
let helpOptions: ArgumentDefinition.Help.Options = initialValue != nil ? .isOptional : []
static func flag(
key: InputKey,
name: NameSpecification,
default initialValue: Bool?,
required: Bool,
inversion: FlagInversion,
exclusivity: FlagExclusivity,
help: ArgumentHelp?) -> ArgumentSet
{
let helpOptions: ArgumentDefinition.Help.Options = required ? [] : .isOptional

let enableHelp = ArgumentDefinition.Help(options: helpOptions, help: help, defaultValue: initialValue.map(String.init), key: key, isComposite: true)
let disableHelp = ArgumentDefinition.Help(options: [.isOptional], help: help, key: key)
Expand Down
10 changes: 10 additions & 0 deletions Tests/ArgumentParserUnitTests/UsageGenerationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ extension UsageGenerationTests {
}

struct M: ParsableArguments {
enum Color: String, EnumerableFlag {
case green, blue, yellow
}

@Flag var a: Bool = false
@Flag var b: Bool = false
@Flag var c: Bool = false
Expand All @@ -187,6 +191,12 @@ extension UsageGenerationTests {
@Flag var j: Bool = false
@Flag var k: Bool = false
@Flag var l: Bool = false

@Flag(inversion: .prefixedEnableDisable)
var optionalBool: Bool?

@Flag var optionalColor: Color?

@Option var option: Bool
@Argument var input: String
@Argument var output: String?
Expand Down

0 comments on commit c959b3a

Please sign in to comment.