@@ -73,6 +73,12 @@ struct BuildCommandOptions: ParsableArguments {
73
73
@Flag ( help: " Build both source and test targets " )
74
74
var buildTests : Bool = false
75
75
76
+ /// Whether to enable code coverage.
77
+ @Flag ( name: . customLong( " code-coverage " ) ,
78
+ inversion: . prefixedEnableDisable,
79
+ help: " Enable code coverage " )
80
+ var enableCodeCoverage : Bool = false
81
+
76
82
/// If the binary output path should be printed.
77
83
@Flag ( name: . customLong( " show-bin-path " ) , help: " Print the binary output path " )
78
84
var shouldPrintBinPath : Bool = false
@@ -148,9 +154,20 @@ package struct SwiftBuildCommand: AsyncSwiftCommand {
148
154
guard let subset = options. buildSubset ( observabilityScope: swiftCommandState. observabilityScope) else {
149
155
throw ExitCode . failure
150
156
}
157
+
158
+ var productsBuildParameters = try swiftCommandState. productsBuildParameters
159
+ var toolsBuildParameters = try swiftCommandState. toolsBuildParameters
160
+
161
+ // Clean out the code coverage directory that may contain stale
162
+ // profraw files from a previous run of the code coverage tool.
163
+ if self . options. enableCodeCoverage {
164
+ try swiftCommandState. fileSystem. removeFileTree ( swiftCommandState. productsBuildParameters. codeCovPath)
165
+ productsBuildParameters. testingParameters. enableCodeCoverage = true
166
+ toolsBuildParameters. testingParameters. enableCodeCoverage = true
167
+ }
168
+
151
169
if case . allIncludingTests = subset {
152
- var buildParameters = try swiftCommandState. productsBuildParameters
153
- for library in try options. testLibraryOptions. enabledTestingLibraries ( swiftCommandState: swiftCommandState) {
170
+ func updateTestingParameters( of buildParameters: inout BuildParameters , library: BuildParameters . Testing . Library ) {
154
171
buildParameters. testingParameters = . init(
155
172
configuration: buildParameters. configuration,
156
173
targetTriple: buildParameters. triple,
@@ -161,18 +178,28 @@ package struct SwiftBuildCommand: AsyncSwiftCommand {
161
178
testEntryPointPath: globalOptions. build. testEntryPointPath,
162
179
library: library
163
180
)
164
- try build ( swiftCommandState, subset: subset, buildParameters: buildParameters)
181
+ }
182
+ for library in try options. testLibraryOptions. enabledTestingLibraries ( swiftCommandState: swiftCommandState) {
183
+ updateTestingParameters ( of: & productsBuildParameters, library: library)
184
+ updateTestingParameters ( of: & toolsBuildParameters, library: library)
185
+ try build ( swiftCommandState, subset: subset, productsBuildParameters: productsBuildParameters, toolsBuildParameters: toolsBuildParameters)
165
186
}
166
187
} else {
167
- try build ( swiftCommandState, subset: subset)
188
+ try build ( swiftCommandState, subset: subset, productsBuildParameters : productsBuildParameters , toolsBuildParameters : toolsBuildParameters )
168
189
}
169
190
}
170
191
171
- private func build( _ swiftCommandState: SwiftCommandState , subset: BuildSubset , buildParameters: BuildParameters ? = nil ) throws {
192
+ private func build(
193
+ _ swiftCommandState: SwiftCommandState ,
194
+ subset: BuildSubset ,
195
+ productsBuildParameters: BuildParameters ,
196
+ toolsBuildParameters: BuildParameters
197
+ ) throws {
172
198
let buildSystem = try swiftCommandState. createBuildSystem (
173
199
explicitProduct: options. product,
174
200
shouldLinkStaticSwiftStdlib: options. shouldLinkStaticSwiftStdlib,
175
- productsBuildParameters: buildParameters,
201
+ productsBuildParameters: productsBuildParameters,
202
+ toolsBuildParameters: toolsBuildParameters,
176
203
// command result output goes on stdout
177
204
// ie "swift build" should output to stdout
178
205
outputStream: TSCBasic . stdoutStream
0 commit comments