@@ -192,9 +192,46 @@ func parseCommandLineArguments(from args: [String]) throws -> __CommandLineArgum
192
192
// Do not consider the executable path AKA argv[0].
193
193
let args = args. dropFirst ( )
194
194
195
+ func isLastArgument( at index: [ String ] . Index) -> Bool {
196
+ args. index ( after: index) >= args. endIndex
197
+ }
198
+
199
+ #if !SWT_NO_FILE_IO
200
+ #if canImport(Foundation)
201
+ // Configuration for the test run passed in as a JSON file (experimental)
202
+ //
203
+ // This argument should always be the first one we parse.
204
+ //
205
+ // NOTE: While the output event stream is opened later, it is necessary to
206
+ // open the configuration file early (here) in order to correctly construct
207
+ // the resulting __CommandLineArguments_v0 instance.
208
+ if let configurationIndex = args. firstIndex ( of: " --experimental-configuration-path " ) , !isLastArgument( at: configurationIndex) {
209
+ let path = args [ args. index ( after: configurationIndex) ]
210
+ let file = try FileHandle ( forReadingAtPath: path)
211
+ let configurationJSON = try file. readToEnd ( )
212
+ result = try configurationJSON. withUnsafeBufferPointer { configurationJSON in
213
+ try JSON . decode ( __CommandLineArguments_v0. self, from: . init( configurationJSON) )
214
+ }
215
+
216
+ // NOTE: We don't return early or block other arguments here: a caller is
217
+ // allowed to pass a configuration AND --verbose and they'll both be
218
+ // respected (it should be the least "surprising" outcome of passing both.)
219
+ }
220
+
221
+ // Event stream output (experimental)
222
+ if let eventOutputIndex = args. firstIndex ( of: " --experimental-event-stream-output " ) , !isLastArgument( at: eventOutputIndex) {
223
+ result. experimentalEventStreamOutput = args [ args. index ( after: eventOutputIndex) ]
224
+ }
225
+ #endif
226
+
227
+ // XML output
228
+ if let xunitOutputIndex = args. firstIndex ( of: " --xunit-output " ) , !isLastArgument( at: xunitOutputIndex) {
229
+ result. xunitOutput = args [ args. index ( after: xunitOutputIndex) ]
230
+ }
231
+ #endif
232
+
195
233
if args. contains ( " --list-tests " ) {
196
234
result. listTests = true
197
- return result // do not bother parsing the other arguments
198
235
}
199
236
200
237
// Parallelization (on by default)
@@ -206,20 +243,6 @@ func parseCommandLineArguments(from args: [String]) throws -> __CommandLineArgum
206
243
result. verbose = true
207
244
}
208
245
209
- #if !SWT_NO_FILE_IO
210
- // XML output
211
- if let xunitOutputIndex = args. firstIndex ( of: " --xunit-output " ) , xunitOutputIndex < args. endIndex {
212
- result. xunitOutput = args [ args. index ( after: xunitOutputIndex) ]
213
- }
214
-
215
- #if canImport(Foundation)
216
- // Event stream output (experimental)
217
- if let eventOutputIndex = args. firstIndex ( of: " --experimental-event-stream-output " ) , eventOutputIndex < args. endIndex {
218
- result. experimentalEventStreamOutput = args [ args. index ( after: eventOutputIndex) ]
219
- }
220
- #endif
221
- #endif
222
-
223
246
// Filtering
224
247
func filterValues( forArgumentsWithLabel label: String ) -> [ String ] {
225
248
args. indices. lazy
@@ -230,10 +253,10 @@ func parseCommandLineArguments(from args: [String]) throws -> __CommandLineArgum
230
253
result. skip = filterValues ( forArgumentsWithLabel: " --skip " )
231
254
232
255
// Set up the iteration policy for the test run.
233
- if let repetitionsIndex = args. firstIndex ( of: " --repetitions " ) , repetitionsIndex < args . endIndex {
256
+ if let repetitionsIndex = args. firstIndex ( of: " --repetitions " ) , !isLastArgument ( at : repetitionsIndex ) {
234
257
result. repetitions = Int ( args [ args. index ( after: repetitionsIndex) ] )
235
258
}
236
- if let repeatUntilIndex = args. firstIndex ( of: " --repeat-until " ) , repeatUntilIndex < args . endIndex {
259
+ if let repeatUntilIndex = args. firstIndex ( of: " --repeat-until " ) , !isLastArgument ( at : repeatUntilIndex ) {
237
260
result. repeatUntil = args [ args. index ( after: repeatUntilIndex) ]
238
261
}
239
262
0 commit comments