Skip to content

Commit 882c922

Browse files
committed
Merge branch 'main' into async
2 parents 0463e7e + e7765e1 commit 882c922

23 files changed

+372
-242
lines changed

Sources/ArgumentParser/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_library(ArgumentParser
66

77
"Parsable Properties/Argument.swift"
88
"Parsable Properties/ArgumentHelp.swift"
9+
"Parsable Properties/ArgumentVisibility.swift"
910
"Parsable Properties/CompletionKind.swift"
1011
"Parsable Properties/Errors.swift"
1112
"Parsable Properties/Flag.swift"
@@ -34,7 +35,6 @@ add_library(ArgumentParser
3435

3536
Usage/DumpHelpGenerator.swift
3637
Usage/HelpCommand.swift
37-
Usage/HelpHiddenCommand.swift
3838
Usage/HelpGenerator.swift
3939
Usage/MessageInfo.swift
4040
Usage/UsageGenerator.swift

Sources/ArgumentParser/Completions/BashCompletionsGenerator.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,16 @@ struct BashCompletionsGenerator {
122122

123123
/// Returns the option and flag names that can be top-level completions.
124124
fileprivate static func generateArgumentWords(_ commands: [ParsableCommand.Type]) -> [String] {
125-
commands.argumentsForHelp().flatMap { $0.bashCompletionWords() }
125+
commands
126+
.argumentsForHelp(visibility: .default)
127+
.flatMap { $0.bashCompletionWords() }
126128
}
127129

128130
/// Returns additional top-level completions from positional arguments.
129131
///
130132
/// These consist of completions that are defined as `.list` or `.custom`.
131133
fileprivate static func generateArgumentCompletions(_ commands: [ParsableCommand.Type]) -> [String] {
132-
ArgumentSet(commands.last!)
134+
ArgumentSet(commands.last!, visibility: .default)
133135
.compactMap { arg -> String? in
134136
guard arg.isPositional else { return nil }
135137

@@ -156,7 +158,7 @@ struct BashCompletionsGenerator {
156158

157159
/// Returns the case-matching statements for supplying completions after an option or flag.
158160
fileprivate static func generateOptionHandlers(_ commands: [ParsableCommand.Type]) -> String {
159-
ArgumentSet(commands.last!)
161+
ArgumentSet(commands.last!, visibility: .default)
160162
.compactMap { arg -> String? in
161163
let words = arg.bashCompletionWords()
162164
if words.isEmpty { return nil }
@@ -178,7 +180,7 @@ struct BashCompletionsGenerator {
178180
extension ArgumentDefinition {
179181
/// Returns the different completion names for this argument.
180182
fileprivate func bashCompletionWords() -> [String] {
181-
return help.shouldDisplay
183+
return help.visibility == .default
182184
? names.map { $0.synopsisString }
183185
: []
184186
}

Sources/ArgumentParser/Completions/FishCompletionsGenerator.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct FishCompletionsGenerator {
5656
}
5757

5858
let argumentCompletions = commands
59-
.argumentsForHelp()
59+
.argumentsForHelp(visibility: .default)
6060
.flatMap { $0.argumentSegments(commandChain) }
6161
.map { complete(ancestors: $0, suggestion: $1) }
6262

@@ -100,7 +100,7 @@ extension Name {
100100

101101
extension ArgumentDefinition {
102102
fileprivate func argumentSegments(_ commandChain: [String]) -> [([String], String)] {
103-
guard help.shouldDisplay else { return [] }
103+
guard help.visibility == .default else { return [] }
104104

105105
var results = [([String], String)]()
106106
var formattedFlags = [String]()

Sources/ArgumentParser/Completions/ZshCompletionsGenerator.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ struct ZshCompletionsGenerator {
103103
}
104104

105105
static func generateCompletionArguments(_ commands: [ParsableCommand.Type]) -> [String] {
106-
commands.argumentsForHelp().compactMap { $0.zshCompletionString(commands) }
106+
commands
107+
.argumentsForHelp(visibility: .default)
108+
.compactMap { $0.zshCompletionString(commands) }
107109
}
108110
}
109111

@@ -132,7 +134,7 @@ extension ArgumentDefinition {
132134
}
133135

134136
func zshCompletionString(_ commands: [ParsableCommand.Type]) -> String? {
135-
guard help.shouldDisplay else { return nil }
137+
guard help.visibility == .default else { return nil }
136138

137139
var inputs: String
138140
switch update {

Sources/ArgumentParser/Documentation.docc/Extensions/ParsableArguments.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
### Generating Help Text
2121

22-
- ``helpMessage(columns:)``
22+
- ``helpMessage(includeHidden:columns:)``
2323

2424
### Handling Errors
2525

Sources/ArgumentParser/Documentation.docc/Extensions/ParsableCommand.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
### Generating Help Text
1515

16-
- ``helpMessage(for:columns:)``
16+
- ``helpMessage(for:includeHidden:columns:)``
1717

1818
### Starting the Program
1919

Sources/ArgumentParser/Parsable Properties/ArgumentHelp.swift

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,6 @@
1111

1212
/// Help information for a command-line argument.
1313
public struct ArgumentHelp {
14-
/// Visibility level of an argument's help.
15-
public enum Visibility {
16-
/// Show help for this argument whenever appropriate.
17-
case `default`
18-
19-
/// Only show help for this argument in the extended help screen.
20-
case hidden
21-
22-
/// Never show help for this argument.
23-
case `private`
24-
}
25-
2614
/// A short description of the argument.
2715
public var abstract: String = ""
2816

@@ -38,7 +26,7 @@ public struct ArgumentHelp {
3826

3927
/// A visibility level indicating whether this argument should be shown in
4028
/// the extended help display.
41-
public var visibility: Visibility = .default
29+
public var visibility: ArgumentVisibility = .default
4230

4331
/// A Boolean value indicating whether this argument should be shown in
4432
/// the extended help display.
@@ -71,7 +59,7 @@ public struct ArgumentHelp {
7159
_ abstract: String = "",
7260
discussion: String = "",
7361
valueName: String? = nil,
74-
visibility: Visibility = .default)
62+
visibility: ArgumentVisibility = .default)
7563
{
7664
self.abstract = abstract
7765
self.discussion = discussion
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===----------------------------------------------------------*- swift -*-===//
2+
//
3+
// This source file is part of the Swift Argument Parser open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
/// Visibility level of an argument's help.
13+
public enum ArgumentVisibility {
14+
/// Show help for this argument whenever appropriate.
15+
case `default`
16+
17+
/// Only show help for this argument in the extended help screen.
18+
case hidden
19+
20+
/// Never show help for this argument.
21+
case `private`
22+
}
23+
24+
extension ArgumentVisibility {
25+
/// A raw Integer value that represents each visibility level.
26+
///
27+
/// `_comparableLevel` can be used to test if a Visibility case is more or
28+
/// less visible than another, without committing this behavior to API.
29+
/// A lower `_comparableLevel` indicates that the case is less visible (more
30+
/// secret).
31+
private var _comparableLevel: Int {
32+
switch self {
33+
case .default:
34+
return 2
35+
case .hidden:
36+
return 1
37+
case .private:
38+
return 0
39+
}
40+
}
41+
42+
/// - Returns: true if `self` is at least as visible as the supplied argument.
43+
func isAtLeastAsVisible(as other: Self) -> Bool {
44+
self._comparableLevel >= other._comparableLevel
45+
}
46+
}

Sources/ArgumentParser/Parsable Properties/OptionGroup.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@
3131
@propertyWrapper
3232
public struct OptionGroup<Value: ParsableArguments>: Decodable, ParsedWrapper {
3333
internal var _parsedValue: Parsed<Value>
34-
internal var _hiddenFromHelp: Bool = false
35-
34+
internal var _visibility: ArgumentVisibility
35+
3636
// FIXME: Adding this property works around the crasher described in
3737
// https://github.com/apple/swift-argument-parser/issues/338
3838
internal var _dummy: Bool = false
3939

4040
internal init(_parsedValue: Parsed<Value>) {
4141
self._parsedValue = _parsedValue
42+
self._visibility = .default
4243
}
4344

4445
public init(from decoder: Decoder) throws {
@@ -63,7 +64,7 @@ public struct OptionGroup<Value: ParsableArguments>: Decodable, ParsedWrapper {
6364
/// Creates a property that represents another parsable type.
6465
public init() {
6566
self.init(_parsedValue: .init { _ in
66-
ArgumentSet(Value.self)
67+
ArgumentSet(Value.self, visibility: .private)
6768
})
6869
}
6970

@@ -96,8 +97,14 @@ extension OptionGroup: CustomStringConvertible {
9697

9798
// Experimental use with caution
9899
extension OptionGroup {
99-
public init(_hiddenFromHelp: Bool) {
100-
self.init()
101-
self._hiddenFromHelp = _hiddenFromHelp
102-
}
100+
@available(*, deprecated, message: "Use init(_visibility:) instead.")
101+
public init(_hiddenFromHelp: Bool) {
102+
self.init()
103+
self._visibility = .hidden
104+
}
105+
106+
public init(_visibility: ArgumentVisibility) {
107+
self.init()
108+
self._visibility = _visibility
109+
}
103110
}

Sources/ArgumentParser/Parsable Types/ParsableArguments.swift

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,8 @@ extension ParsableArguments {
9595
) throws -> Self {
9696
// Parse the command and unwrap the result if necessary.
9797
switch try self.asCommand.parseAsRoot(arguments) {
98-
case is HelpCommand:
99-
throw ParserError.helpRequested
100-
case is HelpHiddenCommand:
101-
throw ParserError.helpHiddenRequested
98+
case let helpCommand as HelpCommand:
99+
throw ParserError.helpRequested(visibility: helpCommand.visibility)
102100
case let result as _WrappedParsableCommand<Self>:
103101
return result.options
104102
case var result as Self:
@@ -134,15 +132,39 @@ extension ParsableArguments {
134132
) -> String {
135133
MessageInfo(error: error, type: self).fullText(for: self)
136134
}
137-
135+
138136
/// Returns the text of the help screen for this type.
139137
///
140-
/// - Parameter columns: The column width to use when wrapping long lines in
141-
/// the help screen. If `columns` is `nil`, uses the current terminal width,
142-
/// or a default value of `80` if the terminal width is not available.
138+
/// - Parameters:
139+
/// - columns: The column width to use when wrapping long line in the
140+
/// help screen. If `columns` is `nil`, uses the current terminal
141+
/// width, or a default value of `80` if the terminal width is not
142+
/// available.
143143
/// - Returns: The full help screen for this type.
144-
public static func helpMessage(columns: Int? = nil) -> String {
145-
HelpGenerator(self).rendered(screenWidth: columns)
144+
@_disfavoredOverload
145+
@available(*, deprecated, message: "Use helpMessage(includeHidden:columns:) instead.")
146+
public static func helpMessage(
147+
columns: Int?
148+
) -> String {
149+
helpMessage(includeHidden: false, columns: columns)
150+
}
151+
152+
/// Returns the text of the help screen for this type.
153+
///
154+
/// - Parameters:
155+
/// - includeHidden: Include hidden help information in the generated
156+
/// message.
157+
/// - columns: The column width to use when wrapping long line in the
158+
/// help screen. If `columns` is `nil`, uses the current terminal
159+
/// width, or a default value of `80` if the terminal width is not
160+
/// available.
161+
/// - Returns: The full help screen for this type.
162+
public static func helpMessage(
163+
includeHidden: Bool = false,
164+
columns: Int? = nil
165+
) -> String {
166+
HelpGenerator(self, visibility: includeHidden ? .hidden : .default)
167+
.rendered(screenWidth: columns)
146168
}
147169

148170
/// Returns the JSON representation of this type.
@@ -239,15 +261,15 @@ func nilOrValue(_ value: Any) -> Any? {
239261
protocol ArgumentSetProvider {
240262
func argumentSet(for key: InputKey) -> ArgumentSet
241263

242-
var _hiddenFromHelp: Bool { get }
264+
var _visibility: ArgumentVisibility { get }
243265
}
244266

245267
extension ArgumentSetProvider {
246-
var _hiddenFromHelp: Bool { false }
268+
var _visibility: ArgumentVisibility { .default }
247269
}
248270

249271
extension ArgumentSet {
250-
init(_ type: ParsableArguments.Type, creatingHelp: Bool = false, includeHidden: Bool = false) {
272+
init(_ type: ParsableArguments.Type, visibility: ArgumentVisibility) {
251273

252274
#if DEBUG
253275
do {
@@ -263,9 +285,8 @@ extension ArgumentSet {
263285
guard var codingKey = child.label else { return nil }
264286

265287
if let parsed = child.value as? ArgumentSetProvider {
266-
if creatingHelp && !includeHidden {
267-
guard !parsed._hiddenFromHelp else { return nil }
268-
}
288+
guard parsed._visibility.isAtLeastAsVisible(as: visibility)
289+
else { return nil }
269290

270291
// Property wrappers have underscore-prefixed names
271292
codingKey = String(codingKey.first == "_"

Sources/ArgumentParser/Parsable Types/ParsableCommand.swift

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,39 @@ extension ParsableCommand {
7777
/// help screen. If `columns` is `nil`, uses the current terminal
7878
/// width, or a default value of `80` if the terminal width is not
7979
/// available.
80+
/// - Returns: The full help screen for this type.
81+
@_disfavoredOverload
82+
@available(*, deprecated, message: "Use helpMessage(for:includeHidden:columns:) instead.")
8083
public static func helpMessage(
8184
for subcommand: ParsableCommand.Type,
8285
columns: Int? = nil
8386
) -> String {
84-
let stack = CommandParser(self).commandStack(for: subcommand)
85-
return HelpGenerator(commandStack: stack).rendered(screenWidth: columns)
87+
helpMessage(for: subcommand, includeHidden: false, columns: columns)
88+
}
89+
90+
/// Returns the text of the help screen for the given subcommand of this
91+
/// command.
92+
///
93+
/// - Parameters:
94+
/// - subcommand: The subcommand to generate the help screen for.
95+
/// `subcommand` must be declared in the subcommand tree of this
96+
/// command.
97+
/// - includeHidden: Include hidden help information in the generated
98+
/// message.
99+
/// - columns: The column width to use when wrapping long line in the
100+
/// help screen. If `columns` is `nil`, uses the current terminal
101+
/// width, or a default value of `80` if the terminal width is not
102+
/// available.
103+
/// - Returns: The full help screen for this type.
104+
public static func helpMessage(
105+
for subcommand: ParsableCommand.Type,
106+
includeHidden: Bool = false,
107+
columns: Int? = nil
108+
) -> String {
109+
HelpGenerator(
110+
commandStack: CommandParser(self).commandStack(for: subcommand),
111+
visibility: includeHidden ? .hidden : .default)
112+
.rendered(screenWidth: columns)
86113
}
87114

88115
/// Parses an instance of this type, or one of its subcommands, from
@@ -114,7 +141,7 @@ extension ParsableCommand {
114141
/// `true` if this command contains any array arguments that are declared
115142
/// with `.unconditionalRemaining`.
116143
internal static var includesUnconditionalArguments: Bool {
117-
ArgumentSet(self).contains(where: {
144+
ArgumentSet(self, visibility: .private).contains(where: {
118145
$0.isRepeatingPositional && $0.parsingStrategy == .allRemainingInput
119146
})
120147
}

Sources/ArgumentParser/Parsing/ArgumentDefinition.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct ArgumentDefinition {
4444
var abstract: String = ""
4545
var discussion: String = ""
4646
var valueName: String = ""
47-
var shouldDisplay: Bool = true
47+
var visibility: ArgumentVisibility = .default
4848

4949
var defaultValue: String?
5050
var keys: [InputKey]
@@ -79,7 +79,7 @@ struct ArgumentDefinition {
7979
self.abstract = help?.abstract ?? ""
8080
self.discussion = help?.discussion ?? ""
8181
self.valueName = help?.valueName ?? ""
82-
self.shouldDisplay = (help?.visibility ?? .default) == .default
82+
self.visibility = help?.visibility ?? .default
8383
}
8484
}
8585

0 commit comments

Comments
 (0)