Skip to content

Commit 89bedad

Browse files
committed
WIP: supplemental discussion
- IDEA: additional discussion for commands and arguments which is exported to dump-help and can be consumed by supplemental content generators to contains much more detailed information than you may want to include in a help screen. Maybe a better idea would be to have --help-detailed flag that would include this information in the help output. Suggestions are welcome.
1 parent 9f39744 commit 89bedad

File tree

8 files changed

+179
-53
lines changed

8 files changed

+179
-53
lines changed

Sources/ArgumentParser/Parsable Properties/ArgumentHelp.swift

+38-27
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ public struct ArgumentHelp {
1616

1717
/// An expanded description of the argument, in plain text form.
1818
public var discussion: String = ""
19-
19+
20+
/// Additional description of the argument for supplemental content, in plain
21+
/// text form.
22+
public var supplementalDiscussion: String = ""
23+
2024
/// An alternative name to use for the argument's value when showing usage
2125
/// information.
2226
///
@@ -28,41 +32,17 @@ public struct ArgumentHelp {
2832
/// the extended help display.
2933
public var visibility: ArgumentVisibility = .default
3034

31-
/// A Boolean value indicating whether this argument should be shown in
32-
/// the extended help display.
33-
@available(*, deprecated, message: "Use visibility level instead.")
34-
public var shouldDisplay: Bool {
35-
get {
36-
return visibility.base == .default
37-
}
38-
set {
39-
visibility = newValue ? .default : .hidden
40-
}
41-
}
42-
43-
/// Creates a new help instance.
44-
@available(*, deprecated, message: "Use init(_:discussion:valueName:visibility:) instead.")
45-
public init(
46-
_ abstract: String = "",
47-
discussion: String = "",
48-
valueName: String? = nil,
49-
shouldDisplay: Bool)
50-
{
51-
self.abstract = abstract
52-
self.discussion = discussion
53-
self.valueName = valueName
54-
self.shouldDisplay = shouldDisplay
55-
}
56-
5735
/// Creates a new help instance.
5836
public init(
5937
_ abstract: String = "",
6038
discussion: String = "",
39+
supplementalDiscussion: String = "",
6140
valueName: String? = nil,
6241
visibility: ArgumentVisibility = .default)
6342
{
6443
self.abstract = abstract
6544
self.discussion = discussion
45+
self.supplementalDiscussion = supplementalDiscussion
6646
self.valueName = valueName
6747
self.visibility = visibility
6848
}
@@ -83,3 +63,34 @@ extension ArgumentHelp: ExpressibleByStringInterpolation {
8363
self.abstract = value
8464
}
8565
}
66+
67+
// MARK: - Deprecated API
68+
extension ArgumentHelp {
69+
/// A Boolean value indicating whether this argument should be shown in
70+
/// the extended help display.
71+
@available(*, deprecated, message: "Use visibility level instead.")
72+
public var shouldDisplay: Bool {
73+
get {
74+
return visibility.base == .default
75+
}
76+
set {
77+
visibility = newValue ? .default : .hidden
78+
}
79+
}
80+
81+
/// Creates a new help instance.
82+
@available(*, deprecated, message: "Use init(_:discussion:supplementalDiscussion:valueName:visibility:) instead.")
83+
public init(
84+
_ abstract: String = "",
85+
discussion: String = "",
86+
valueName: String? = nil,
87+
shouldDisplay: Bool)
88+
{
89+
self.init(
90+
abstract,
91+
discussion: discussion,
92+
supplementalDiscussion: "",
93+
valueName: valueName,
94+
visibility: shouldDisplay ? .default : .hidden)
95+
}
96+
}

Sources/ArgumentParser/Parsable Types/CommandConfiguration.swift

+37-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ public struct CommandConfiguration {
3838
/// A longer description of this command, to be shown in the extended help
3939
/// display.
4040
public var discussion: String
41+
42+
/// Additional description of this command to be shown in supplemental content
43+
/// such as manuals.
44+
public var supplementalDiscussion: String
4145

4246
/// Version information for this command.
4347
public var version: String
@@ -67,6 +71,8 @@ public struct CommandConfiguration {
6771
/// automatically generating a usage description. Passing an empty string
6872
/// hides the usage string altogether.
6973
/// - discussion: A longer description of the command.
74+
/// - supplementalDiscussion: Additional description of the command for
75+
/// supplemental content.
7076
/// - version: The version number for this command. When you provide a
7177
/// non-empty string, the argument parser prints it if the user provides
7278
/// a `--version` flag.
@@ -85,6 +91,7 @@ public struct CommandConfiguration {
8591
abstract: String = "",
8692
usage: String? = nil,
8793
discussion: String = "",
94+
supplementalDiscussion: String = "",
8895
version: String = "",
8996
shouldDisplay: Bool = true,
9097
subcommands: [ParsableCommand.Type] = [],
@@ -95,6 +102,7 @@ public struct CommandConfiguration {
95102
self.abstract = abstract
96103
self.usage = usage
97104
self.discussion = discussion
105+
self.supplementalDiscussion = supplementalDiscussion
98106
self.version = version
99107
self.shouldDisplay = shouldDisplay
100108
self.subcommands = subcommands
@@ -110,6 +118,7 @@ public struct CommandConfiguration {
110118
abstract: String = "",
111119
usage: String? = nil,
112120
discussion: String = "",
121+
supplementalDiscussion: String = "",
113122
version: String = "",
114123
shouldDisplay: Bool = true,
115124
subcommands: [ParsableCommand.Type] = [],
@@ -121,6 +130,7 @@ public struct CommandConfiguration {
121130
self.abstract = abstract
122131
self.usage = usage
123132
self.discussion = discussion
133+
self.supplementalDiscussion = ""
124134
self.version = version
125135
self.shouldDisplay = shouldDisplay
126136
self.subcommands = subcommands
@@ -130,7 +140,7 @@ public struct CommandConfiguration {
130140
}
131141

132142
extension CommandConfiguration {
133-
@available(*, deprecated, message: "Use the memberwise initializer with the usage parameter.")
143+
@available(*, deprecated, message: "Use the member-wise initializer with the usage parameter.")
134144
public init(
135145
commandName: String?,
136146
abstract: String,
@@ -146,6 +156,32 @@ extension CommandConfiguration {
146156
abstract: abstract,
147157
usage: "",
148158
discussion: discussion,
159+
supplementalDiscussion: "",
160+
version: version,
161+
shouldDisplay: shouldDisplay,
162+
subcommands: subcommands,
163+
defaultSubcommand: defaultSubcommand,
164+
helpNames: helpNames)
165+
}
166+
167+
@available(*, deprecated, message: "Use the member-wise initializer with the extendedDiscussion parameter.")
168+
public init(
169+
commandName: String?,
170+
abstract: String,
171+
usage: String,
172+
discussion: String,
173+
version: String,
174+
shouldDisplay: Bool,
175+
subcommands: [ParsableCommand.Type],
176+
defaultSubcommand: ParsableCommand.Type?,
177+
helpNames: NameSpecification?
178+
) {
179+
self.init(
180+
commandName: commandName,
181+
abstract: abstract,
182+
usage: usage,
183+
discussion: discussion,
184+
supplementalDiscussion: "",
149185
version: version,
150186
shouldDisplay: shouldDisplay,
151187
subcommands: subcommands,

Sources/ArgumentParser/Parsing/ArgumentDefinition.swift

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct ArgumentDefinition {
4343
// `ArgumentHelp` members
4444
var abstract: String = ""
4545
var discussion: String = ""
46+
var supplementalDiscussion: String = ""
4647
var valueName: String = ""
4748
var visibility: ArgumentVisibility = .default
4849

@@ -78,6 +79,7 @@ struct ArgumentDefinition {
7879
mutating func updateArgumentHelp(help: ArgumentHelp?) {
7980
self.abstract = help?.abstract ?? ""
8081
self.discussion = help?.discussion ?? ""
82+
self.supplementalDiscussion = help?.supplementalDiscussion ?? ""
8183
self.valueName = help?.valueName ?? ""
8284
self.visibility = help?.visibility ?? .default
8385
}

Sources/ArgumentParser/Usage/DumpHelpGenerator.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ fileprivate extension CommandInfoV0 {
114114
commandName: command._commandName,
115115
abstract: command.configuration.abstract,
116116
discussion: command.configuration.discussion,
117+
supplementalDiscussion: command.configuration.supplementalDiscussion,
117118
defaultSubcommand: defaultSubcommand,
118119
subcommands: subcommands,
119120
arguments: arguments)
@@ -134,7 +135,8 @@ fileprivate extension ArgumentInfoV0 {
134135
defaultValue: argument.help.defaultValue,
135136
allValues: argument.help.allValues,
136137
abstract: argument.help.abstract,
137-
discussion: argument.help.discussion)
138+
discussion: argument.help.discussion,
139+
supplementalDiscussion: argument.help.supplementalDiscussion)
138140
}
139141
}
140142

Sources/ArgumentParserToolInfo/ToolInfo.swift

+11-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ public struct CommandInfoV0: Codable, Hashable {
5151
public var abstract: String?
5252
/// Extended description of the command's functionality.
5353
public var discussion: String?
54+
/// Additional description of the command's functionality for supplemental
55+
/// content.
56+
public var supplementalDiscussion: String?
5457

5558
/// Optional name of the subcommand invoked when the command is invoked with
5659
/// no arguments.
@@ -65,6 +68,7 @@ public struct CommandInfoV0: Codable, Hashable {
6568
commandName: String,
6669
abstract: String,
6770
discussion: String,
71+
supplementalDiscussion: String,
6872
defaultSubcommand: String?,
6973
subcommands: [CommandInfoV0],
7074
arguments: [ArgumentInfoV0]
@@ -74,6 +78,7 @@ public struct CommandInfoV0: Codable, Hashable {
7478
self.commandName = commandName
7579
self.abstract = abstract.nonEmpty
7680
self.discussion = discussion.nonEmpty
81+
self.supplementalDiscussion = supplementalDiscussion.nonEmpty
7782

7883
self.defaultSubcommand = defaultSubcommand?.nonEmpty
7984
self.subcommands = subcommands.nonEmpty
@@ -143,6 +148,9 @@ public struct ArgumentInfoV0: Codable, Hashable {
143148
public var abstract: String?
144149
/// Extended description of the argument's functionality.
145150
public var discussion: String?
151+
/// Additional description of the argument's functionality for supplemental
152+
/// content.
153+
public var supplementalDiscussion: String?
146154

147155
public init(
148156
kind: KindV0,
@@ -155,7 +163,8 @@ public struct ArgumentInfoV0: Codable, Hashable {
155163
defaultValue: String?,
156164
allValues: [String]?,
157165
abstract: String?,
158-
discussion: String?
166+
discussion: String?,
167+
supplementalDiscussion: String?
159168
) {
160169
self.kind = kind
161170

@@ -172,5 +181,6 @@ public struct ArgumentInfoV0: Codable, Hashable {
172181

173182
self.abstract = abstract?.nonEmpty
174183
self.discussion = discussion?.nonEmpty
184+
self.supplementalDiscussion = supplementalDiscussion?.nonEmpty
175185
}
176186
}

Tools/generate-manual/DSL/SinglePageDescription.swift renamed to Tools/generate-manual/DSL/Description.swift

+25-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
import ArgumentParser
1313
import ArgumentParserToolInfo
1414

15-
struct SinglePageDescription: MDocComponent {
15+
struct Description: MDocComponent {
16+
var multipage: Bool
1617
var command: CommandInfoV0
1718

1819
var body: MDocComponent {
@@ -27,6 +28,14 @@ struct SinglePageDescription: MDocComponent {
2728
discussion
2829
}
2930

31+
if command.discussion != nil, command.supplementalDiscussion != nil {
32+
MDocMacro.ParagraphBreak()
33+
}
34+
35+
if let supplementalDiscussion = command.supplementalDiscussion {
36+
supplementalDiscussion
37+
}
38+
3039
List {
3140
for argument in command.arguments ?? [] {
3241
MDocMacro.ListItem(title: argument.manualPageDescription)
@@ -42,11 +51,23 @@ struct SinglePageDescription: MDocComponent {
4251
if let discussion = argument.discussion {
4352
discussion
4453
}
54+
55+
if argument.discussion != nil, argument.supplementalDiscussion != nil {
56+
MDocMacro.ParagraphBreak()
57+
}
58+
59+
if let supplementalDiscussion = argument.supplementalDiscussion {
60+
supplementalDiscussion
61+
}
4562
}
4663

47-
for subcommand in command.subcommands ?? [] {
48-
MDocMacro.ListItem(title: MDocMacro.Emphasis(arguments: [subcommand.commandName]))
49-
SinglePageDescription(command: subcommand).core
64+
if !multipage {
65+
for subcommand in command.subcommands ?? [] {
66+
MDocMacro.ListItem(title: MDocMacro.Emphasis(arguments: [subcommand.commandName]))
67+
Description(
68+
multipage: multipage,
69+
command: subcommand).core
70+
}
5071
}
5172
}
5273
}

Tools/generate-manual/DSL/Document.swift

+1-5
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@ struct Document: MDocComponent {
2424
Preamble(date: date, section: section, command: command)
2525
Name(command: command)
2626
Synopsis(command: command)
27-
if multiPage {
28-
MultiPageDescription(command: command)
29-
} else {
30-
SinglePageDescription(command: command)
31-
}
27+
Description(multipage: multiPage, command: command)
3228
Exit(section: section)
3329
if multiPage {
3430
SeeAlso(section: section, command: command)

0 commit comments

Comments
 (0)