@@ -34,13 +34,25 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha
3434
3535 do {
3636#if !SWT_NO_EXIT_TESTS
37- // If an exit test was specified, run it. `exitTest` returns `Never`.
38- if let exitTest = ExitTest . findInEnvironmentForEntryPoint ( ) {
39- await exitTest ( )
40- }
37+ // If an exit test was specified, run it. `exitTest` returns `Never`.
38+ if let exitTest = ExitTest . findInEnvironmentForEntryPoint ( ) {
39+ await exitTest ( )
40+ }
4141#endif
4242
4343 let args = try args ?? parseCommandLineArguments ( from: CommandLine . arguments)
44+
45+ #if !SWT_NO_RUNTIME_LIBRARY_DISCOVERY
46+ // If the user requested a different testing library, run it instead of
47+ // Swift Testing. (If they requested Swift Testing, we're already here so
48+ // there's no real need to recurse).
49+ if args. experimentalListLibraries != true ,
50+ let library = args. testingLibrary. flatMap ( Library . init ( withHint: ) ) ,
51+ library. canonicalHint != " swift-testing " {
52+ return await library. callEntryPoint ( passing: args)
53+ }
54+ #endif
55+
4456 // Configure the test runner.
4557 var configuration = try configurationForEntryPoint ( from: args)
4658
@@ -95,9 +107,10 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha
95107
96108 // The set of matching tests (or, in the case of `swift test list`, the set
97109 // of all tests.)
98- let tests : [ Test ]
110+ var tests = [ Test] ( )
111+ var libraries = [ Library] ( )
99112
100- if args. listTests ?? false {
113+ if args. listTests == true {
101114 tests = await Array ( Test . all)
102115
103116 if args. verbosity > . min {
@@ -116,6 +129,29 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha
116129 for test in tests {
117130 Event . post ( . testDiscovered, for: ( test, nil ) , configuration: configuration)
118131 }
132+ } else if args. experimentalListLibraries == true {
133+ #if !SWT_NO_RUNTIME_LIBRARY_DISCOVERY
134+ libraries = Array ( Library . all)
135+ #else
136+ libraries = [ Library . swiftTesting]
137+ #endif
138+
139+ if args. verbosity > . min {
140+ for library in libraries {
141+ // Print the test ID to stdout (classical CLI behavior.)
142+ let libraryDescription = " \( library. name) (swift test --experimental-testing-library \( library. canonicalHint) ) "
143+ #if SWT_TARGET_OS_APPLE && !SWT_NO_FILE_IO
144+ try ? FileHandle . stdout. write ( " \( libraryDescription) \n " )
145+ #else
146+ print ( libraryDescription)
147+ #endif
148+ }
149+ }
150+
151+ // Post an event for every discovered library (as with tests above).
152+ for library in libraries {
153+ Event . post ( . libraryDiscovered( library) , for: ( nil , nil ) , configuration: configuration)
154+ }
119155 } else {
120156 // Run the tests.
121157 let runner = await Runner ( configuration: configuration)
@@ -126,7 +162,7 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha
126162 // If there were no matching tests, exit with a dedicated exit code so that
127163 // the caller (assumed to be Swift Package Manager) can implement special
128164 // handling.
129- if tests. isEmpty {
165+ if tests. isEmpty && libraries . isEmpty {
130166 exitCode. withLock { exitCode in
131167 if exitCode == EXIT_SUCCESS {
132168 exitCode = EXIT_NO_TESTS_FOUND
@@ -211,6 +247,9 @@ public struct __CommandLineArguments_v0: Sendable {
211247 /// The value of the `--list-tests` argument.
212248 public var listTests : Bool ?
213249
250+ /// The value of the `--experimental-list-libraries` argument.
251+ public var experimentalListLibraries : Bool ?
252+
214253 /// The value of the `--parallel` or `--no-parallel` argument.
215254 public var parallel : Bool ?
216255
@@ -335,13 +374,17 @@ public struct __CommandLineArguments_v0: Sendable {
335374
336375 /// The value of the `--attachments-path` argument.
337376 public var attachmentsPath : String ?
377+
378+ /// The value of the `--testing-library` argument.
379+ public var testingLibrary : String ?
338380}
339381
340382extension __CommandLineArguments_v0 : Codable {
341383 // Explicitly list the coding keys so that storage properties like _verbosity
342384 // do not end up with leading underscores when encoded.
343385 enum CodingKeys : String , CodingKey {
344386 case listTests
387+ case experimentalListLibraries
345388 case parallel
346389 case experimentalMaximumParallelizationWidth
347390 case symbolicateBacktraces
@@ -357,6 +400,7 @@ extension __CommandLineArguments_v0: Codable {
357400 case repetitions
358401 case repeatUntil
359402 case attachmentsPath
403+ case testingLibrary
360404 }
361405}
362406
@@ -468,6 +512,11 @@ func parseCommandLineArguments(from args: [String]) throws -> __CommandLineArgum
468512 }
469513#endif
470514
515+ // Testing library
516+ if let testingLibrary = Environment . variable ( named: " SWT_EXPERIMENTAL_LIBRARY " ) ?? args. argumentValue ( forLabel: " --testing-library " ) {
517+ result. testingLibrary = testingLibrary
518+ }
519+
471520 // XML output
472521 if let xunitOutputPath = args. argumentValue ( forLabel: " --xunit-output " ) {
473522 result. xunitOutput = xunitOutputPath
@@ -486,6 +535,9 @@ func parseCommandLineArguments(from args: [String]) throws -> __CommandLineArgum
486535 // makes invocation from e.g. Wasmtime a bit more intuitive/idiomatic.
487536 result. listTests = true
488537 }
538+ if Environment . flag ( named: " SWT_EXPERIMENTAL_LIST_LIBRARIES " ) == true || args. contains ( " --experimental-list-libraries " ) {
539+ result. experimentalListLibraries = true
540+ }
489541
490542 // Parallelization (on by default)
491543 if args. contains ( " --no-parallel " ) {
0 commit comments