@@ -136,10 +136,38 @@ public class TestToolOptions: ToolOptions {
136
136
/// Generate LinuxMain entries and exit.
137
137
var shouldGenerateLinuxMain = false
138
138
139
- var testCaseSpecifier : TestCaseSpecifier = . none
139
+ var testCaseSpecifier : TestCaseSpecifier {
140
+ testCaseSpecifierOverride ( ) ?? _testCaseSpecifier
141
+ }
142
+
143
+ var _testCaseSpecifier : TestCaseSpecifier = . none
140
144
141
145
/// Path where the xUnit xml file should be generated.
142
146
var xUnitOutput : AbsolutePath ?
147
+
148
+ /// Returns the test case specifier if overridden in the env.
149
+ private func testCaseSpecifierOverride( ) -> TestCaseSpecifier ? {
150
+ guard let override = ProcessEnv . vars [ " _SWIFTPM_SKIP_TESTS_LIST " ] else {
151
+ return nil
152
+ }
153
+
154
+ do {
155
+ let skipTests : [ String . SubSequence ]
156
+ // Read from the file if it exists.
157
+ if let path = try ? AbsolutePath ( validating: override) , localFileSystem. exists ( path) {
158
+ let contents = try localFileSystem. readFileContents ( path) . cString
159
+ skipTests = contents. split ( separator: " \n " , omittingEmptySubsequences: true )
160
+ } else {
161
+ // Otherwise, read the env variable.
162
+ skipTests = override. split ( separator: " : " , omittingEmptySubsequences: true )
163
+ }
164
+
165
+ return . skip( skipTests. map ( String . init) )
166
+ } catch {
167
+ // FIXME: We should surface errors from here.
168
+ }
169
+ return nil
170
+ }
143
171
}
144
172
145
173
/// Tests filtering specifier
@@ -152,6 +180,7 @@ public enum TestCaseSpecifier {
152
180
case none
153
181
case specific( String )
154
182
case regex( String )
183
+ case skip( [ String ] )
155
184
}
156
185
157
186
public enum TestMode {
@@ -234,7 +263,7 @@ public class SwiftTestTool: SwiftTool<TestToolOptions> {
234
263
)
235
264
ranSuccessfully = runner. test ( )
236
265
237
- case . regex, . specific:
266
+ case . regex, . specific, . skip :
238
267
// If old specifier `-s` option was used, emit deprecation notice.
239
268
if case . specific = options. testCaseSpecifier {
240
269
diagnostics. emit ( data: SpecifierDeprecatedDiagnostic ( ) )
@@ -419,7 +448,7 @@ public class SwiftTestTool: SwiftTool<TestToolOptions> {
419
448
420
449
binder. bind (
421
450
option: parser. add ( option: " --specifier " , shortName: " -s " , kind: String . self) ,
422
- to: { $0. testCaseSpecifier = . specific( $1) } )
451
+ to: { $0. _testCaseSpecifier = . specific( $1) } )
423
452
424
453
binder. bind (
425
454
option: parser. add ( option: " --xunit-output " , kind: PathArgument . self) ,
@@ -429,7 +458,7 @@ public class SwiftTestTool: SwiftTool<TestToolOptions> {
429
458
option: parser. add ( option: " --filter " , kind: String . self,
430
459
usage: " Run test cases matching regular expression, Format: <test-target>.<test-case> or " +
431
460
" <test-target>.<test-case>/<test> " ) ,
432
- to: { $0. testCaseSpecifier = . regex( $1) } )
461
+ to: { $0. _testCaseSpecifier = . regex( $1) } )
433
462
434
463
binder. bind (
435
464
option: parser. add ( option: " --enable-code-coverage " , kind: Bool . self,
@@ -925,6 +954,14 @@ fileprivate extension Sequence where Iterator.Element == TestSuite {
925
954
} )
926
955
case . specific( let name) :
927
956
return allTests. filter { $0. specifier == name }
957
+ case . skip( let skippedTests) :
958
+ var result = allTests
959
+ for skippedTest in skippedTests {
960
+ result = result. filter {
961
+ $0. specifier. range ( of: skippedTest, options: . regularExpression) == nil
962
+ }
963
+ }
964
+ return result
928
965
}
929
966
}
930
967
}
0 commit comments