Skip to content

Commit 458b6ba

Browse files
authored
Merge pull request #1394 from MrNickBarker/master
[SR-6347] Added "SEE ALSO" to --help for Swift commands
2 parents 7d531f2 + 592672c commit 458b6ba

File tree

10 files changed

+74
-7
lines changed

10 files changed

+74
-7
lines changed

Sources/Commands/SwiftBuildTool.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public class SwiftBuildTool: SwiftTool<BuildToolOptions> {
3737
toolName: "build",
3838
usage: "[options]",
3939
overview: "Build sources into binary products",
40-
args: args
40+
args: args,
41+
seeAlso: type(of: self).otherToolNames()
4142
)
4243
}
4344

@@ -178,3 +179,9 @@ fileprivate extension BuildSubset {
178179
}
179180
}
180181
}
182+
183+
extension SwiftBuildTool: ToolName {
184+
static var toolName: String {
185+
return "swift build"
186+
}
187+
}

Sources/Commands/SwiftPackageTool.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public class SwiftPackageTool: SwiftTool<PackageToolOptions> {
3737
toolName: "package",
3838
usage: "[options] subcommand",
3939
overview: "Perform operations on Swift packages",
40-
args: args
40+
args: args,
41+
seeAlso: type(of: self).otherToolNames()
4142
)
4243
}
4344
override func runImpl() throws {
@@ -470,3 +471,9 @@ extension PackageToolOptions.CompletionToolMode: StringEnumArgument {
470471
])
471472
}
472473
}
474+
475+
extension SwiftPackageTool: ToolName {
476+
static var toolName: String {
477+
return "swift package"
478+
}
479+
}

Sources/Commands/SwiftRunTool.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ public class SwiftRunTool: SwiftTool<RunToolOptions> {
8989
toolName: "run",
9090
usage: "[options] [executable [arguments ...]]",
9191
overview: "Build and run an executable product",
92-
args: args
92+
args: args,
93+
seeAlso: type(of: self).otherToolNames()
9394
)
9495
}
9596

@@ -187,3 +188,8 @@ public class SwiftRunTool: SwiftTool<RunToolOptions> {
187188
}
188189
}
189190

191+
extension SwiftRunTool: ToolName {
192+
static var toolName: String {
193+
return "swift run"
194+
}
195+
}

Sources/Commands/SwiftTestTool.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ public class SwiftTestTool: SwiftTool<TestToolOptions> {
115115
toolName: "test",
116116
usage: "[options]",
117117
overview: "Build and run tests",
118-
args: args
118+
args: args,
119+
seeAlso: type(of: self).otherToolNames()
119120
)
120121
}
121122

@@ -620,3 +621,9 @@ fileprivate extension Sequence where Iterator.Element == TestSuite {
620621
}
621622
}
622623
}
624+
625+
extension SwiftTestTool: ToolName {
626+
static var toolName: String {
627+
return "swift test"
628+
}
629+
}

Sources/Commands/SwiftTool.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,17 @@ private class ToolWorkspaceDelegate: WorkspaceDelegate {
104104
}
105105
}
106106

107+
protocol ToolName {
108+
static var toolName: String { get }
109+
}
110+
111+
extension ToolName {
112+
static func otherToolNames() -> String {
113+
let allTools: [ToolName.Type] = [SwiftBuildTool.self, SwiftRunTool.self, SwiftPackageTool.self, SwiftTestTool.self]
114+
return allTools.filter({ $0 != self }).map({ $0.toolName }).joined(separator: ", ")
115+
}
116+
}
117+
107118
public class SwiftTool<Options: ToolOptions> {
108119
/// The original working directory.
109120
let originalWorkingDirectory: AbsolutePath
@@ -149,15 +160,16 @@ public class SwiftTool<Options: ToolOptions> {
149160
/// Create an instance of this tool.
150161
///
151162
/// - parameter args: The command line arguments to be passed to this tool.
152-
public init(toolName: String, usage: String, overview: String, args: [String]) {
163+
public init(toolName: String, usage: String, overview: String, args: [String], seeAlso: String? = nil) {
153164
// Capture the original working directory ASAP.
154165
originalWorkingDirectory = currentWorkingDirectory
155166

156167
// Create the parser.
157168
parser = ArgumentParser(
158169
commandName: "swift \(toolName)",
159170
usage: usage,
160-
overview: overview)
171+
overview: overview,
172+
seeAlso: seeAlso)
161173

162174
// Create the binder.
163175
let binder = ArgumentBinder<Options>()

Sources/Utility/ArgumentParser.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,9 @@ public final class ArgumentParser {
597597

598598
/// Overview text of this parser.
599599
let overview: String
600+
601+
/// See more text of this parser.
602+
let seeAlso: String?
600603

601604
/// If this parser is a subparser.
602605
private let isSubparser: Bool
@@ -613,11 +616,13 @@ public final class ArgumentParser {
613616
/// Otherwise, first command line argument will be used.
614617
/// - usage: The "usage" line of the generated usage text.
615618
/// - overview: The "overview" line of the generated usage text.
616-
public init(commandName: String? = nil, usage: String, overview: String) {
619+
/// - seeAlso: The "see also" line of generated usage text.
620+
public init(commandName: String? = nil, usage: String, overview: String, seeAlso: String? = nil) {
617621
self.isSubparser = false
618622
self.commandName = commandName
619623
self.usage = usage
620624
self.overview = overview
625+
self.seeAlso = seeAlso
621626
}
622627

623628
/// Create a subparser with its help text.
@@ -626,6 +631,7 @@ public final class ArgumentParser {
626631
self.commandName = nil
627632
self.usage = ""
628633
self.overview = overview
634+
self.seeAlso = nil
629635
}
630636

631637
/// Adds an option to the parser.
@@ -901,6 +907,12 @@ public final class ArgumentParser {
901907
print(formatted: argument.name, usage: usage, on: stream)
902908
}
903909
}
910+
911+
if let seeAlso = seeAlso {
912+
stream <<< "\n\n"
913+
stream <<< "SEE ALSO: \(seeAlso)"
914+
}
915+
904916
stream <<< "\n"
905917
stream.flush()
906918
}

Tests/CommandsTests/BuildToolTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ final class BuildToolTests: XCTestCase {
2323
XCTAssert(try execute(["-help"]).contains("USAGE: swift build"))
2424
}
2525

26+
func testSeeAlso() throws {
27+
XCTAssert(try execute(["--help"]).contains("SEE ALSO: swift run, swift package, swift test"))
28+
}
29+
2630
func testVersion() throws {
2731
XCTAssert(try execute(["--version"]).contains("Swift Package Manager"))
2832
}

Tests/CommandsTests/PackageToolTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ final class PackageToolTests: XCTestCase {
2929
XCTAssert(try execute(["--help"]).contains("USAGE: swift package"))
3030
}
3131

32+
func testSeeAlso() throws {
33+
XCTAssert(try execute(["--help"]).contains("SEE ALSO: swift build, swift run, swift test"))
34+
}
35+
3236
func testVersion() throws {
3337
XCTAssert(try execute(["--version"]).contains("Swift Package Manager"))
3438
}

Tests/CommandsTests/RunToolTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ final class RunToolTests: XCTestCase {
2424
XCTAssert(try execute(["--help"]).contains("USAGE: swift run [options] [executable [arguments ...]]"))
2525
}
2626

27+
func testSeeAlso() throws {
28+
XCTAssert(try execute(["--help"]).contains("SEE ALSO: swift build, swift package, swift test"))
29+
}
30+
2731
func testVersion() throws {
2832
XCTAssert(try execute(["--version"]).contains("Swift Package Manager"))
2933
}

Tests/CommandsTests/TestToolTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ final class TestToolTests: XCTestCase {
2222
XCTAssert(try execute(["--help"]).contains("USAGE: swift test"))
2323
}
2424

25+
func testSeeAlso() throws {
26+
XCTAssert(try execute(["--help"]).contains("SEE ALSO: swift build, swift run, swift package"))
27+
}
28+
2529
func testVersion() throws {
2630
XCTAssert(try execute(["--version"]).contains("Swift Package Manager"))
2731
}

0 commit comments

Comments
 (0)