@@ -30,13 +30,25 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha
3030
3131 do {
3232#if !SWT_NO_EXIT_TESTS
33- // If an exit test was specified, run it. `exitTest` returns `Never`.
34- if let exitTest = ExitTest . findInEnvironmentForEntryPoint ( ) {
35- await exitTest ( )
36- }
33+ // If an exit test was specified, run it. `exitTest` returns `Never`.
34+ if let exitTest = ExitTest . findInEnvironmentForEntryPoint ( ) {
35+ await exitTest ( )
36+ }
3737#endif
3838
3939 let args = try args ?? parseCommandLineArguments ( from: CommandLine . arguments)
40+
41+ #if !SWT_NO_RUNTIME_LIBRARY_DISCOVERY
42+ // If the user requested a different testing library, run it instead of
43+ // Swift Testing. (If they requested Swift Testing, we're already here so
44+ // there's no real need to recurse).
45+ if args. experimentalListLibraries != true ,
46+ let library = args. testingLibrary. flatMap ( Library . init ( withHint: ) ) ,
47+ library. canonicalHint != " swift-testing " {
48+ return await library. callEntryPoint ( passing: args)
49+ }
50+ #endif
51+
4052 // Configure the test runner.
4153 var configuration = try configurationForEntryPoint ( from: args)
4254
@@ -91,9 +103,10 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha
91103
92104 // The set of matching tests (or, in the case of `swift test list`, the set
93105 // of all tests.)
94- let tests : [ Test ]
106+ var tests = [ Test] ( )
107+ var libraries = [ Library] ( )
95108
96- if args. listTests ?? false {
109+ if args. listTests == true {
97110 tests = await Array ( Test . all)
98111
99112 if args. verbosity > . min {
@@ -112,6 +125,29 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha
112125 for test in tests {
113126 Event . post ( . testDiscovered, for: ( test, nil ) , configuration: configuration)
114127 }
128+ } else if args. experimentalListLibraries == true {
129+ #if !SWT_NO_RUNTIME_LIBRARY_DISCOVERY
130+ libraries = Array ( Library . all)
131+ #else
132+ libraries = [ Library . swiftTesting]
133+ #endif
134+
135+ if args. verbosity > . min {
136+ for library in libraries {
137+ // Print the test ID to stdout (classical CLI behavior.)
138+ let libraryDescription = " \( library. name) (swift test --experimental-testing-library \( library. canonicalHint) ) "
139+ #if SWT_TARGET_OS_APPLE && !SWT_NO_FILE_IO
140+ try ? FileHandle . stdout. write ( " \( libraryDescription) \n " )
141+ #else
142+ print ( libraryDescription)
143+ #endif
144+ }
145+ }
146+
147+ // Post an event for every discovered library (as with tests above).
148+ for library in libraries {
149+ Event . post ( . libraryDiscovered( library) , for: ( nil , nil ) , configuration: configuration)
150+ }
115151 } else {
116152 // Run the tests.
117153 let runner = await Runner ( configuration: configuration)
@@ -122,7 +158,7 @@ func entryPoint(passing args: __CommandLineArguments_v0?, eventHandler: Event.Ha
122158 // If there were no matching tests, exit with a dedicated exit code so that
123159 // the caller (assumed to be Swift Package Manager) can implement special
124160 // handling.
125- if tests. isEmpty {
161+ if tests. isEmpty && libraries . isEmpty {
126162 exitCode. withLock { exitCode in
127163 if exitCode == EXIT_SUCCESS {
128164 exitCode = EXIT_NO_TESTS_FOUND
@@ -207,6 +243,9 @@ public struct __CommandLineArguments_v0: Sendable {
207243 /// The value of the `--list-tests` argument.
208244 public var listTests : Bool ?
209245
246+ /// The value of the `--experimental-list-libraries` argument.
247+ public var experimentalListLibraries : Bool ?
248+
210249 /// The value of the `--parallel` or `--no-parallel` argument.
211250 public var parallel : Bool ?
212251
@@ -331,13 +370,17 @@ public struct __CommandLineArguments_v0: Sendable {
331370
332371 /// The value of the `--attachments-path` argument.
333372 public var attachmentsPath : String ?
373+
374+ /// The value of the `--testing-library` argument.
375+ public var testingLibrary : String ?
334376}
335377
336378extension __CommandLineArguments_v0 : Codable {
337379 // Explicitly list the coding keys so that storage properties like _verbosity
338380 // do not end up with leading underscores when encoded.
339381 enum CodingKeys : String , CodingKey {
340382 case listTests
383+ case experimentalListLibraries
341384 case parallel
342385 case experimentalMaximumParallelizationWidth
343386 case symbolicateBacktraces
@@ -353,6 +396,7 @@ extension __CommandLineArguments_v0: Codable {
353396 case repetitions
354397 case repeatUntil
355398 case attachmentsPath
399+ case testingLibrary
356400 }
357401}
358402
@@ -466,6 +510,11 @@ func parseCommandLineArguments(from args: [String]) throws -> __CommandLineArgum
466510 }
467511#endif
468512
513+ // Testing library
514+ if let testingLibrary = Environment . variable ( named: " SWT_EXPERIMENTAL_LIBRARY " ) ?? args. argumentValue ( forLabel: " --testing-library " ) {
515+ result. testingLibrary = testingLibrary
516+ }
517+
469518 // XML output
470519 if let xunitOutputPath = args. argumentValue ( forLabel: " --xunit-output " ) {
471520 result. xunitOutput = xunitOutputPath
@@ -484,6 +533,9 @@ func parseCommandLineArguments(from args: [String]) throws -> __CommandLineArgum
484533 // makes invocation from e.g. Wasmtime a bit more intuitive/idiomatic.
485534 result. listTests = true
486535 }
536+ if Environment . flag ( named: " SWT_EXPERIMENTAL_LIST_LIBRARIES " ) == true || args. contains ( " --experimental-list-libraries " ) {
537+ result. experimentalListLibraries = true
538+ }
487539
488540 // Parallelization (on by default)
489541 if args. contains ( " --no-parallel " ) {
0 commit comments