Skip to content

Commit ab563a2

Browse files
committed
Add an optional abstract to command groups
1 parent b013355 commit ab563a2

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

Sources/ArgumentParser/Parsable Types/CommandGroup.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,21 @@ public struct CommandGroup: Sendable {
1414
/// The name of the command group that will be displayed in help.
1515
public let name: String
1616

17+
/// A short description of the commands in this group, which will be
18+
/// displayed in help.
19+
public let abstract: String?
20+
1721
/// The list of subcommands that are part of this group.
1822
public let subcommands: [ParsableCommand.Type]
1923

2024
/// Create a command group.
2125
public init(
2226
name: String,
27+
abstract: String? = nil,
2328
@CommandsBuilder subcommands: () -> [ParsableCommand.Type]
2429
) {
2530
self.name = name
31+
self.abstract = abstract
2632
self.subcommands = subcommands()
2733
}
2834
}

Sources/ArgumentParser/Usage/HelpGenerator.swift

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ internal struct HelpGenerator {
5252
case subcommands
5353
case options
5454
case title(String)
55-
case groupedSubcommands(String)
55+
case groupedSubcommands(String, String?)
5656

5757
var description: String {
5858
switch self {
@@ -64,10 +64,19 @@ internal struct HelpGenerator {
6464
return "Options"
6565
case .title(let name):
6666
return name
67-
case .groupedSubcommands(let name):
67+
case .groupedSubcommands(let name, _):
6868
return "\(name) Subcommands"
6969
}
7070
}
71+
72+
var abstract: String? {
73+
switch self {
74+
case .positionalArguments, .subcommands, .options, .title:
75+
return nil
76+
case .groupedSubcommands(_, let abstract):
77+
return abstract
78+
}
79+
}
7180
}
7281

7382
var header: Header
@@ -79,8 +88,14 @@ internal struct HelpGenerator {
7988
guard !elements.isEmpty else { return "" }
8089

8190
let renderedElements = elements.map { $0.rendered(screenWidth: screenWidth) }.joined()
82-
return "\(String(describing: header).uppercased()):\n"
83-
+ renderedElements
91+
92+
var renderedHeader = String(describing: header).uppercased() + ":"
93+
if let abstract = header.abstract {
94+
renderedHeader += " "
95+
renderedHeader += abstract.wrapped(to: screenWidth)
96+
}
97+
98+
return renderedHeader + "\n" + renderedElements
8499
}
85100
}
86101

@@ -217,7 +232,8 @@ internal struct HelpGenerator {
217232

218233
// Create section for a grouping of subcommands.
219234
func subcommandSection(
220-
header: Section.Header,
235+
header: Section.Header,
236+
abstract: String? = nil,
221237
subcommands: [ParsableCommand.Type]
222238
) -> Section {
223239
let subcommandElements: [Section.Element] =
@@ -235,7 +251,10 @@ internal struct HelpGenerator {
235251
abstract: command.configuration.abstract)
236252
}
237253

238-
return Section(header: header, elements: subcommandElements)
254+
return Section(
255+
header: header,
256+
elements: subcommandElements
257+
)
239258
}
240259

241260
// Sections for all of the grouped subcommands.
@@ -247,7 +266,7 @@ internal struct HelpGenerator {
247266

248267
case .group(let group):
249268
return subcommandSection(
250-
header: .groupedSubcommands(group.name),
269+
header: .groupedSubcommands(group.name, group.abstract),
251270
subcommands: group.subcommands
252271
)
253272
}

Tests/ArgumentParserUnitTests/HelpGenerationTests.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,10 @@ extension HelpGenerationTests {
519519
static let configuration = CommandConfiguration(
520520
commandName: "subgroupings"
521521
) {
522-
CommandGroup(name: "Broken") {
522+
CommandGroup(
523+
name: "Broken",
524+
abstract: "These commands are currently non-functional due to XYZ."
525+
) {
523526
Foo.self
524527
Bar.self
525528
}
@@ -533,7 +536,7 @@ extension HelpGenerationTests {
533536
}
534537

535538
func testHelpSubcommandGroups() throws {
536-
AssertHelp(.default, for: WithSubgroups.self, equals: """
539+
AssertHelp(.default, for: WithSubgroups.self, columns: 50, equals: """
537540
USAGE: subgroupings <subcommand>
538541
539542
OPTIONS:
@@ -542,7 +545,8 @@ extension HelpGenerationTests {
542545
SUBCOMMANDS:
543546
m
544547
545-
BROKEN SUBCOMMANDS:
548+
BROKEN SUBCOMMANDS: These commands are currently non-functional due
549+
to XYZ.
546550
foo Perform some foo
547551
bar Perform bar operations
548552

0 commit comments

Comments
 (0)