Skip to content

Commit d2990e9

Browse files
committed
Begin conversion to ArgumentParser for Commands
Started by converting SwiftOptions, SwiftTool, and SwiftRunTool.
1 parent 50f9480 commit d2990e9

File tree

4 files changed

+188
-321
lines changed

4 files changed

+188
-321
lines changed

Package.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ let package = Package(
5555
targets: ["PackageDescription"]
5656
),
5757
],
58+
dependencies: [
59+
.package(url: "https://github.com/apple/swift-argument-parser.git", .branch("master")),
60+
],
5861
targets: [
5962
// The `PackageDescription` targets define the API which is available to
6063
// the `Package.swift` manifest files. We build the latest API version
@@ -130,7 +133,7 @@ let package = Package(
130133
.target(
131134
/** High-level commands */
132135
name: "Commands",
133-
dependencies: ["SwiftToolsSupport-auto", "Build", "PackageGraph", "SourceControl", "Xcodeproj", "Workspace", "XCBuildSupport"]),
136+
dependencies: ["SwiftToolsSupport-auto", "Build", "PackageGraph", "SourceControl", "Xcodeproj", "Workspace", "XCBuildSupport", "ArgumentParser"]),
134137
.target(
135138
/** The main executable provided by SwiftPM */
136139
name: "swift-package",

Sources/Commands/Options.swift

Lines changed: 126 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,116 +8,199 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11+
import ArgumentParser
1112
import TSCBasic
1213
import TSCUtility
1314
import PackageModel
1415
import SPMBuildCore
1516
import Build
1617

17-
public class ToolOptions {
18+
public struct BuildFlagsGroup: ParsableArguments {
19+
@Option(name: .customLong("Xcc", withSingleDash: true),
20+
help: "Pass flag through to all C compiler invocations")
21+
var cCompilerFlags: [String]
22+
23+
@Option(name: .customLong("Xswiftc", withSingleDash: true),
24+
help: "Pass flag through to all Swift compiler invocations")
25+
var swiftCompilerFlags: [String]
26+
27+
@Option(name: .customLong("Xlinker", withSingleDash: true),
28+
help: "Pass flag through to all linker invocations")
29+
var linkerFlags: [String]
30+
31+
@Option(name: .customLong("Xccxx", withSingleDash: true),
32+
help: "Pass flag through to all C++ compiler invocations")
33+
var cxxCompilerFlags: [String]
34+
35+
@Option(name: .customLong("Xxcbuild", withSingleDash: true),
36+
help: "Pass flag through to the Xcode build system invocations")
37+
var xcbuildFlags: [String]
38+
39+
var buildFlags: BuildFlags {
40+
BuildFlags(
41+
xcc: cCompilerFlags,
42+
xcxx: cxxCompilerFlags,
43+
xswiftc: swiftCompilerFlags,
44+
xlinker: linkerFlags)
45+
}
46+
47+
public init() {}
48+
}
49+
50+
extension BuildConfiguration: ExpressibleByArgument {
51+
public init?(argument: String) {
52+
self.init(rawValue: argument)
53+
}
54+
}
55+
56+
public enum BuildSystemKind: String, ExpressibleByArgument {
57+
case native
58+
case xcode
59+
}
60+
61+
public struct SwiftToolOptions: ParsableArguments {
62+
@OptionGroup()
63+
public var buildFlagsGroup: BuildFlagsGroup
64+
1865
/// Custom arguments to pass to C compiler, swift compiler and the linker.
19-
public var buildFlags = BuildFlags()
66+
public var buildFlags: BuildFlags {
67+
buildFlagsGroup.buildFlags
68+
}
2069

2170
/// Build configuration.
22-
public var configuration: BuildConfiguration = .debug
71+
@Option(name: .shortAndLong, default: .debug, help: "Build with configuration")
72+
public var configuration: BuildConfiguration
2373

2474
/// The custom build directory, if provided.
75+
@Option(help: "Specify build/cache directory",
76+
transform: { try PathArgument(argument: $0).path })
2577
public var buildPath: AbsolutePath?
2678

2779
/// The custom working directory that the tool should operate in (deprecated).
80+
@Option(name: [.long, .customShort("C")],
81+
transform: { try PathArgument(argument: $0).path })
2882
public var chdir: AbsolutePath?
2983

3084
/// The custom working directory that the tool should operate in.
85+
@Option(help: "Change working directory before any other operation",
86+
transform: { try PathArgument(argument: $0).path })
3187
public var packagePath: AbsolutePath?
3288

3389
/// The path to the file containing multiroot package data. This is currently Xcode's workspace file.
90+
@Option(name: .customLong("multiroot-data-file"),
91+
transform: { try PathArgument(argument: $0).path })
3492
public var multirootPackageDataFile: AbsolutePath?
3593

3694
/// Enable prefetching in resolver which will kick off parallel git cloning.
37-
public var shouldEnableResolverPrefetching = true
95+
@Flag(name: .customLong("prefetching"), default: true, inversion: .prefixedEnableDisable)
96+
public var shouldEnableResolverPrefetching: Bool
3897

3998
/// If print version option was passed.
40-
public var shouldPrintVersion: Bool = false
99+
@Flag(name: .customLong("version"))
100+
public var shouldPrintVersion: Bool
41101

102+
// FIXME: We need to allow -vv type options for this.
42103
/// The verbosity of informational output.
43-
public var verbosity: Int = 0
104+
@Flag(name: .shortAndLong, help: "Increase verbosity of informational output")
105+
public var verbose: Bool
106+
107+
public var verbosity: Int { verbose ? 1 : 0 }
44108

45109
/// Disables sandboxing when executing subprocesses.
46-
public var shouldDisableSandbox = false
110+
@Flag(name: .customLong("disable-sandbox"), help: "Disable using the sandbox when executing subprocesses")
111+
public var shouldDisableSandbox: Bool
47112

48113
/// Disables manifest caching.
49-
public var shouldDisableManifestCaching = false
114+
@Flag(name: .customLong("disable-package-manifest-caching"), help: "Disable caching Package.swift manifests")
115+
public var shouldDisableManifestCaching: Bool
50116

51117
/// Path to the compilation destination describing JSON file.
118+
@Option(name: .customLong("destination"), transform: { try PathArgument(argument: $0).path })
52119
public var customCompileDestination: AbsolutePath?
120+
53121
/// The compilation destination’s target triple.
122+
@Option(name: .customLong("triple"), transform: Triple.init)
54123
public var customCompileTriple: Triple?
124+
55125
/// Path to the compilation destination’s SDK.
126+
@Option(name: .customLong("sdk"), transform: { try PathArgument(argument: $0).path })
56127
public var customCompileSDK: AbsolutePath?
128+
57129
/// Path to the compilation destination’s toolchain.
130+
@Option(name: .customLong("toolchain"), transform: { try PathArgument(argument: $0).path })
58131
public var customCompileToolchain: AbsolutePath?
59132

60133
/// If should link the Swift stdlib statically.
61-
public var shouldLinkStaticSwiftStdlib = false
134+
@Flag(name: .customLong("static-swift-stdlib"), default: false, inversion: .prefixedNo, help: "Link Swift stdlib statically")
135+
public var shouldLinkStaticSwiftStdlib: Bool
62136

63137
/// Skip updating dependencies from their remote during a resolution.
64-
public var skipDependencyUpdate = false
138+
@Flag(name: .customLong("skip-update"), help: "Skip updating dependencies from their remote during a resolution")
139+
public var skipDependencyUpdate: Bool
65140

66141
/// Which compile-time sanitizers should be enabled.
67-
public var sanitizers = EnabledSanitizers()
142+
@Option(name: .customLong("sanitize"),
143+
help: "Turn on runtime checks for erroneous behavior",
144+
transform: { try Sanitizer(argument: $0) })
145+
public var sanitizers: [Sanitizer]
68146

147+
public var enabledSanitizers: EnabledSanitizers {
148+
EnabledSanitizers(Set(sanitizers))
149+
}
150+
69151
/// Whether to enable code coverage.
70-
public var shouldEnableCodeCoverage = false
152+
@Flag(name: .customLong("enable-code-coverage"), help: "Test with code coverage enabled")
153+
public var shouldEnableCodeCoverage: Bool
71154

155+
// TODO: Does disable-automatic-resolution alias force-resolved-versions?
156+
72157
/// Use Package.resolved file for resolving dependencies.
73-
public var forceResolvedVersions = false
158+
@Flag(name: [.long, .customLong("disable-automatic-resolution")], help: "Disable automatic resolution if Package.resolved file is out-of-date")
159+
public var forceResolvedVersions: Bool
74160

161+
@Flag(name: .customLong("index-store"), inversion: .prefixedEnableDisable, help: "Enable or disable indexing-while-building feature")
162+
public var indexStoreEnable: Bool?
163+
75164
/// The mode to use for indexing-while-building feature.
76-
public var indexStoreMode: BuildParameters.IndexStoreMode = .auto
77-
165+
public var indexStore: BuildParameters.IndexStoreMode {
166+
guard let enable = indexStoreEnable else { return .auto }
167+
return enable ? .on : .off
168+
}
169+
78170
/// Whether to enable generation of `.swiftinterface`s alongside `.swiftmodule`s.
79-
public var shouldEnableParseableModuleInterfaces = false
171+
@Flag(name: .customLong("enable-parseable-module-interfaces"))
172+
public var shouldEnableParseableModuleInterfaces: Bool
80173

81174
/// Write dependency resolver trace to a file.
82-
public var enableResolverTrace = false
175+
@Flag(name: .customLong("trace-resolver"))
176+
public var enableResolverTrace: Bool
83177

84178
/// The number of jobs for llbuild to start (aka the number of schedulerLanes)
85-
public var jobs: UInt32? = nil
179+
@Option(name: .shortAndLong, help: "The number of jobs to spawn in parallel during the build process")
180+
public var jobs: UInt32?
86181

87182
/// Whether to enable test discovery on platforms without Objective-C runtime.
88-
public var enableTestDiscovery: Bool = false
183+
@Flag(help: "Enable test discovery on platforms without Objective-C runtime")
184+
public var enableTestDiscovery: Bool
89185

90186
/// Whether to enable llbuild manifest caching.
91-
public var enableBuildManifestCaching: Bool = false
187+
@Flag()
188+
public var enableBuildManifestCaching: Bool
92189

93190
/// Emit the Swift module separately from the object files.
94-
public var emitSwiftModuleSeparately: Bool = false
95-
191+
@Flag()
192+
public var emitSwiftModuleSeparately: Bool
193+
96194
/// The build system to use.
195+
@Option()
97196
public var buildSystem: BuildSystemKind = .native
98197

99-
/// Extra arguments to pass when using xcbuild.
100-
public var xcbuildFlags: [String] = []
101-
102-
public required init() {}
103-
}
104-
105-
public enum BuildSystemKind: String, ArgumentKind {
106-
case native
107-
case xcode
108-
109-
public init(argument: String) throws {
110-
if let kind = BuildSystemKind(rawValue: argument) {
111-
self = kind
112-
} else {
113-
throw ArgumentConversionError.typeMismatch(value: argument, expectedType: BuildSystemKind.self)
198+
public mutating func validate() throws {
199+
if shouldPrintVersion {
200+
print(Versioning.currentVersion.completeDisplayString)
201+
throw ExitCode.success
114202
}
115203
}
116204

117-
public static var completion: ShellCompletion {
118-
return .values([
119-
(value: "native", description: "Native build system"),
120-
(value: "xcode", description: "Xcode build system"),
121-
])
122-
}
205+
public init() {}
123206
}

0 commit comments

Comments
 (0)