turbo_tests2 3.1.14 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4031f877288b31974b622b8dffb0acffb1361ee96347d695ea69dd9c47a5950
4
- data.tar.gz: 8bc186019f3b056c15dc2f68cf42b2062a68f4dc9d1fa34c397446933ac37999
3
+ metadata.gz: b472277b993feef40505fbd17ec4b7602310b703c965a1a632aa3c21489812c7
4
+ data.tar.gz: f792e2de4afb78108715d74c488aeb8123ac81c67364a27a1859a194190a100a
5
5
  SHA512:
6
- metadata.gz: 9a28f75223e3bd926d6cc5ebf4e94bd0de1efa10b82eab792e595cedc73aa1a6bb398e2093058f170c4c7a2d5a76d4b7dc1e8edcc0d01971e4d03d7406d97170
7
- data.tar.gz: 4eed7b464c8e3d26419a2822bdeed6c60084c5e25968352af3a053d728f25004b18383b4fed4ab13994f3dfcb28a02e23542560c51c1a1c73fbb3a03ffa90755
6
+ metadata.gz: 70d7b9f1cc88b356531dfb38281b58f96a0c3f6f6e4c4cfcfff57fafb03fda83a5380d880259f4ae34e040c3292d98c2d0593b779a8157ccd2df34c23e2bfc39
7
+ data.tar.gz: 6a128634eacabc86bab67908576250ec996b52718417073ef1efad6f5765c9855f4d8c71f1d36282551cd0104721b5fe88ce645c2aae3953a282da462f62bb31
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,100 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [3.2.1] - 2026-07-25
34
+
35
+ - TAG: [v3.2.1][3.2.1t]
36
+ - COVERAGE: 96.88% -- 869/897 lines in 10 files
37
+ - BRANCH COVERAGE: 84.44% -- 217/257 branches in 10 files
38
+ - 34.69% documented
39
+
40
+ ### Changed
41
+
42
+ - The `turbo_tests2` executable now supports `-v` / `--version` and prints a
43
+ standard startup header on normal runs.
44
+
45
+ - kettle-jem-template-20260716-001 - Shim gemspec manifests now include
46
+ `LICENSE.md` instead of nonexistent `LICENSE.txt`.
47
+ - kettle-jem-template-20260716-002 - Generated gemspec manifests now ship fewer
48
+ repository-only files by default to reduce downstream distro packaging churn.
49
+ - kettle-jem-template-20260720-001 - Generated READMEs can now render
50
+ template-managed corporate sponsor logos from project or family config.
51
+ - kettle-jem-template-20260720-002 - Generated development Gemfiles now use the
52
+ released `tree_sitter_language_pack` gem 1.13.3 or newer by default.
53
+ - kettle-jem-template-20260720-003 - Generated StructuredMerge Git diff driver
54
+ config now uses the installed `smorg-rb` Ruby driver name.
55
+ - kettle-jem-template-20260720-004 - Generated multi-engine workflow files now
56
+ omit JRuby and TruffleRuby jobs when project config declares MRI-only engines.
57
+ - kettle-jem-template-20260720-005 - Generated README Support & Community rows
58
+ now include a RubyForum help badge.
59
+ - kettle-jem-template-20260725-001 - Generated JRuby and TruffleRuby workflow
60
+ files now run when pull request head branches start with `feature/release`,
61
+ so release CI monitoring does not report intentionally skipped engine
62
+ workflows as failures.
63
+
64
+ ### Fixed
65
+
66
+ - Worker commands now drop project `.rspec` presentation formatter and output
67
+ options after preserving the behavioral options needed by each shard,
68
+ preventing direct-RSpec formatter output from being replayed alongside the
69
+ turbo summary.
70
+ - Runtime-based runs now silence the preliminary sizing probe, so
71
+ `Using recorded test runtime` is printed once by the actual grouping pass.
72
+
73
+ ## [3.2.0] - 2026-07-18
74
+
75
+ - TAG: [v3.2.0][3.2.0t]
76
+ - COVERAGE: 96.88% -- 869/897 lines in 10 files
77
+ - BRANCH COVERAGE: 84.44% -- 217/257 branches in 10 files
78
+ - 34.69% documented
79
+
80
+ ### Added
81
+
82
+ - `--count` is now accepted as an alias for `-n`, matching the
83
+ `parallel_tests` process-count option while keeping the existing
84
+ `-w` / `--workers` aliases.
85
+ - Documented the supported `parallel_tests` option subset and clarified that
86
+ unsupported flags are not blindly passed through after `--`.
87
+ - Added `--worker-output MODE` and `TURBO_TESTS2_WORKER_OUTPUT` support for
88
+ selecting raw worker stdout/stderr handling: `warnings`, `stream`, `buffered`,
89
+ or `quiet`.
90
+ - `--group-by runtime|filesize|found` is now parsed explicitly and mapped to
91
+ `parallel_tests` grouping modes, including when supplied after the
92
+ compatibility `--` separator.
93
+ - `--allowed-missing PERCENT` and `--unknown-runtime SECONDS` are now parsed
94
+ explicitly and mapped to `parallel_tests` runtime grouping tuning options,
95
+ including when supplied after the compatibility `--` separator.
96
+
97
+ ### Changed
98
+
99
+ - Pull request engine workflows now keep JRuby and TruffleRuby coverage
100
+ available via branch opt-in prefixes: `jruby/*` runs JRuby workflows,
101
+ `truffleruby/*` runs TruffleRuby workflows, and `engines/*` runs all engine
102
+ workflows. Other pull request branches continue to run MRI checks without the
103
+ alternate engine jobs.
104
+ - The delayed documentation formatter spec now lives under fixtures so the
105
+ normal suite does not pay its fixed load-time delay.
106
+
107
+ ### Fixed
108
+
109
+ - Successful non-verbose runs now surface warning and deprecation lines emitted
110
+ as raw worker stdout/stderr without dumping all buffered worker output.
111
+ - `heads.yml` and `dep-heads.yml` now gate JRuby and TruffleRuby PR coverage
112
+ at the job level, so non-matching PR branches skip those engine jobs before a
113
+ runner is provisioned.
114
+ - Direct `turbo_tests2` runs now refresh the default
115
+ `tmp/turbo_rspec_runtime.log` timing log, and `--runtime-log` writes the
116
+ requested timing log even when the run groups by filesize.
117
+ - `--only-group GROUP_INDEX[,GROUP_INDEX]` is now parsed explicitly and runs
118
+ only the selected 1-based `parallel_tests` group index(es), using filesize
119
+ grouping by default for selected-group reruns.
120
+ - `--pattern PATTERN` is now parsed explicitly and mapped to `parallel_tests`
121
+ file discovery instead of being treated as a spec file when supplied after
122
+ `--`.
123
+ - `--exclude-pattern PATTERN` is now parsed explicitly and mapped to
124
+ `parallel_tests` file discovery instead of being treated as a spec file when
125
+ supplied after `--`.
126
+
33
127
  ## [3.1.14] - 2026-07-17
34
128
 
35
129
  - TAG: [v3.1.14][3.1.14t]
@@ -302,7 +396,11 @@ Please file a bug if you notice a violation of semantic versioning.
302
396
 
303
397
  - Initial release
304
398
 
305
- [Unreleased]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.1.14...HEAD
399
+ [Unreleased]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.2.1...HEAD
400
+ [3.2.1]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.2.0...v3.2.1
401
+ [3.2.1t]: https://github.com/galtzo-floss/turbo_tests2/releases/tag/v3.2.1
402
+ [3.2.0]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.1.14...v3.2.0
403
+ [3.2.0t]: https://github.com/galtzo-floss/turbo_tests2/releases/tag/v3.2.0
306
404
  [3.1.14]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.1.13...v3.1.14
307
405
  [3.1.14t]: https://github.com/galtzo-floss/turbo_tests2/releases/tag/v3.1.14
308
406
  [3.1.13]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.1.12...v3.1.13
data/LICENSE.md CHANGED
@@ -3,7 +3,7 @@
3
3
  This project is made available under the following license.
4
4
  Choose the option that best fits your use case:
5
5
 
6
- - [MIT](MIT.md)
6
+ - [MIT](https://github.com/galtzo-floss/turbo_tests2/blob/main/MIT.md)
7
7
 
8
8
  ## Copyright Notice
9
9
 
data/README.md CHANGED
@@ -71,8 +71,8 @@ Finished in 2 minute 25.15 seconds (files took 0 seconds to load)
71
71
  | Works with MRI Ruby 4 | [![Ruby current Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf]|
72
72
  | Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎ruby-3.0-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎ruby-3.1-wf] [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎ruby-3.2-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎ruby-3.3-wf] [![Ruby 3.4 Compat][💎ruby-3.4i]][🚎ruby-3.4-wf]|
73
73
  | Works with MRI Ruby 2 | [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎ruby-2.4-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎ruby-2.5-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎ruby-2.6-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎ruby-2.7-wf]|
74
- | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
75
- | Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on CodeBerg.org][📜src-cb-img]][📜src-cb] [![Source on Github.com][📜src-gh-img]][📜src-gh] [![The best SHA: dQw4w9WgXcQ!][🧮kloc-img]][🧮kloc] |
74
+ | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Get help from RubyForum][✉️ruby-forum-img]][✉️ruby-forum] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
75
+ | Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on CodeBerg.org][📜src-cb-img]][📜src-cb] [![Source on GitHub.com][📜src-gh-img]][📜src-gh] [![The best SHA: dQw4w9WgXcQ!][🧮kloc-img]][🧮kloc] |
76
76
  | Documentation | [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![YARD on Galtzo.com][📜docs-head-rd-img]][🚎yard-head] [![Maintainer Blog][🚂maint-blog-img]][🚂maint-blog] [![GitLab Wiki][📜gl-wiki-img]][📜gl-wiki] [![GitHub Wiki][📜gh-wiki-img]][📜gh-wiki] |
77
77
  | Compliance | [![License: MIT][📄license-img]][📄license] [![Apache license compatibility: Category A][📄license-compat-img]][📄license-compat] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
78
78
  | Style | [![Enforced Code Style Linter][💎rlts-img]][💎rlts] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] [![Gitmoji Commits][📌gitmoji-img]][📌gitmoji] [![Compatibility appraised by: appraisal2][💎appraisal2-img]][💎appraisal2] |
@@ -196,14 +196,23 @@ Usage: turbo_tests2 [options]
196
196
  turbo_tests2 spec/bar spec/baz/xxx_spec.rb
197
197
 
198
198
  Options:
199
- -n, -w, --workers [PROCESSES] How many processes to use, default: available CPUs
199
+ -n, --count [PROCESSES] How many processes to use, default: available CPUs
200
+ -w, --workers [PROCESSES] Alias for -n, --count
200
201
  -r, --require PATH Require a file.
201
202
  -f, --format FORMATTER Choose a formatter. Available formatters: progress (p), documentation (d). Default: progress
202
203
  -t, --tag TAG Run examples with the specified tag.
203
204
  -o, --out FILE Write output to a file instead of $stdout
204
205
  --runtime-log FILE Location of previously recorded test runtimes
205
206
  --example-status-log FILE Use RSpec example status persistence timings for grouping
207
+ --pattern PATTERN Run spec files matching this regex pattern
208
+ --exclude-pattern PATTERN Exclude spec files matching this regex pattern
209
+ --only-group GROUP_INDEX[,GROUP_INDEX]
210
+ Run only the selected 1-based parallel_tests group index(es)
211
+ --group-by MODE Group files by runtime, filesize, or found order
212
+ --allowed-missing PERCENT Allowed percentage of missing runtimes for runtime grouping
213
+ --unknown-runtime SECONDS Runtime in seconds to assign files missing runtime history
206
214
  -v, --verbose More output
215
+ --worker-output MODE Raw worker output mode: warnings, stream, buffered, or quiet; env: TURBO_TESTS2_WORKER_OUTPUT
207
216
  --fail-fast=[N]
208
217
  --seed SEED Seed for RSpec
209
218
  --order ORDER RSpec example order: random (default) or defined
@@ -217,12 +226,104 @@ By default, `turbo_tests2` generates one random RSpec seed, prints it, and passe
217
226
  that same seed to every worker process. Use `--seed SEED` to replay a run, or
218
227
  `--order defined` / `--no-random` when you want ordered examples without a seed.
219
228
 
220
- To pass any options supported by parallel_tests, use `--`:
229
+ `turbo_tests2` supports selected `parallel_tests` options explicitly. It does
230
+ not invoke the `parallel_tests` CLI directly, and it does not blindly pass
231
+ unknown `parallel_tests` flags through after `--`. Options after `--` are parsed
232
+ only when listed as supported below.
233
+
234
+ To select or exclude files matching a regex:
235
+
236
+ ```bash
237
+ bundle exec turbo_tests2 -n 4 --pattern spec/system
238
+ bundle exec turbo_tests2 -n 4 --exclude-pattern spec/system
239
+ ```
240
+
241
+ The compatibility separator also accepts supported options:
221
242
 
222
243
  ```bash
223
- bundle exec turbo_tests2 -n 4 -- --only-group 1 --pattern spec/system
244
+ bundle exec turbo_tests2 -n 4 -- --pattern spec/system
245
+ bundle exec turbo_tests2 -n 4 -- --exclude-pattern spec/system
224
246
  ```
225
247
 
248
+ To rerun one or more selected 1-based groups from a prior parallel split:
249
+
250
+ ```bash
251
+ bundle exec turbo_tests2 -n 4 --only-group 2
252
+ bundle exec turbo_tests2 -n 4 -- --only-group 1,3
253
+ ```
254
+
255
+ To choose a supported `parallel_tests` grouping mode explicitly:
256
+
257
+ ```bash
258
+ bundle exec turbo_tests2 -n 4 --group-by runtime
259
+ bundle exec turbo_tests2 -n 4 --group-by filesize
260
+ bundle exec turbo_tests2 -n 4 --group-by found
261
+ bundle exec turbo_tests2 -n 4 -- --group-by runtime
262
+ ```
263
+
264
+ `runtime` grouping uses the configured runtime log, which `turbo_tests2`
265
+ continues to record by default. `filesize` and `found` do not use runtime
266
+ history for the initial split, but worker runtime recording still runs so
267
+ future runtime-based runs can use the updated log.
268
+
269
+ Runtime grouping also supports the explicit `parallel_tests` tuning flags
270
+ `--allowed-missing PERCENT` and `--unknown-runtime SECONDS`:
271
+
272
+ ```bash
273
+ bundle exec turbo_tests2 -n 4 --group-by runtime --allowed-missing 25
274
+ bundle exec turbo_tests2 -n 4 --group-by runtime --unknown-runtime 0.5
275
+ bundle exec turbo_tests2 -n 4 -- --allowed-missing 25 --unknown-runtime 0.5
276
+ ```
277
+
278
+ Selected group runs default to filesize grouping unless `--group-by` is
279
+ provided.
280
+
281
+ ### Supported `parallel_tests` Options
282
+
283
+ | `parallel_tests` option | Status | `turbo_tests2` equivalent | Notes |
284
+ |-------------------------|--------|---------------------------|-------|
285
+ | `-n`, `--count PROCESSES` | Supported natively | `-n`, `--count`; `-w`, `--workers` aliases | Parsed as a `turbo_tests2` option before any `--` separator. |
286
+ | `-p`, `--pattern PATTERN` | Supported | `--pattern PATTERN` | May be supplied before or after `--`; mapped to `parallel_tests` file discovery. |
287
+ | `--exclude-pattern PATTERN` | Supported | `--exclude-pattern PATTERN` | May be supplied before or after `--`; mapped to `parallel_tests` file discovery. |
288
+ | `--only-group GROUP_INDEX[,GROUP_INDEX]` | Supported | `--only-group GROUP_INDEX[,GROUP_INDEX]` | May be supplied before or after `--`; uses 1-based `parallel_tests` group indexes. |
289
+ | `--group-by runtime` | Supported | `--group-by runtime` | May be supplied before or after `--`; uses runtime-log grouping. |
290
+ | `--group-by filesize` | Supported | `--group-by filesize` | May be supplied before or after `--`; groups by file size. |
291
+ | `--group-by found` | Supported | `--group-by found` | May be supplied before or after `--`; keeps discovered file order. |
292
+ | `--allowed-missing PERCENT` | Supported | `--allowed-missing PERCENT` | May be supplied before or after `--`; validates `0..100`. |
293
+ | `--unknown-runtime SECONDS` | Supported | `--unknown-runtime SECONDS` | May be supplied before or after `--`; validates finite non-negative seconds. |
294
+ | `--runtime-log PATH` | Supported natively | `--runtime-log FILE` | Parsed as a `turbo_tests2` option before any `--` separator. |
295
+ | `--nice` | Supported natively | `--nice` | Parsed as a `turbo_tests2` option before any `--` separator. |
296
+ | `--fail-fast` | Supported natively | `--fail-fast[=N]` | Uses `turbo_tests2` fail-fast handling and RSpec worker arguments. |
297
+ | `--verbose` | Supported natively | `-v`, `--verbose` | Enables `turbo_tests2` verbose output. |
298
+ | `--test-options`, `-o` | Not supported as pass-through | Use `turbo_tests2` RSpec-facing flags | `turbo_tests2` exposes selected RSpec options directly, such as `--seed`, `--order`, `--no-random`, `--tag`, `--format`, and `--out`. |
299
+ | `--group-by default`, `steps`, `scenarios` | Not supported | None | `turbo_tests2` targets RSpec file grouping, not every `parallel_tests` framework mode. |
300
+ | `--single`, `--isolate`, `--isolate-n` | Not supported | None | No first-class mapping yet. |
301
+ | `--specify-groups` | Not supported | None | No first-class mapping yet. |
302
+ | `-m`, `--multiply-processes` | Not supported | None | Use an explicit `-n`/`--count` value. |
303
+ | `-e`, `--exec`, `--exec-args`, `--non-parallel` | Not supported | None | `turbo_tests2` runs RSpec workers, not arbitrary command groups. |
304
+ | `--suffix`, `--type`, `--ignore-tags` | Not supported | None | `turbo_tests2` currently targets RSpec. |
305
+ | `--serialize-stdout`, `--prefix-output-with-test-env-number`, `--combine-stderr`, `--quiet`, `--verbose-command`, `--verbose-process-command`, `--verbose-rerun-command` | Not supported | None | `turbo_tests2` owns worker output collection and formatter reporting. |
306
+ | `--no-symlinks`, `--allow-duplicates`, `--first-is-1`, `--highest-exit-status`, `--failure-exit-code`, `--test-file-limit` | Not supported | None | These need explicit design and tests before they can be accepted. |
307
+
308
+ ### Worker Output Modes
309
+
310
+ Raw worker stdout/stderr is separate from the parent process formatter output.
311
+ The progress dot parade is reconstructed from JSON formatter events and already
312
+ streams from the parent process as workers report examples. Use
313
+ `--worker-output MODE`, or `TURBO_TESTS2_WORKER_OUTPUT=MODE`, to choose how raw
314
+ worker stdout/stderr is handled. A CLI flag takes precedence over the
315
+ environment variable.
316
+
317
+ | Mode | Behavior |
318
+ |------|----------|
319
+ | `warnings` | Default. Buffer raw worker output, print warning/deprecation lines after successful runs, and print full buffered raw output on failures. |
320
+ | `stream` | Stream raw worker stdout/stderr immediately without enabling verbose command logging. Buffered output is not replayed at the end. |
321
+ | `buffered` | Buffer raw worker output and print all buffered output after the run completes. |
322
+ | `quiet` | Suppress raw worker output on successful runs. Failed runs still print buffered raw output. |
323
+
324
+ Known coverage formatter chatter remains collapsed into the concise coverage
325
+ summary.
326
+
226
327
  `turbo_tests2` supports custom formatter such as Fuubar, but you might need to require it:
227
328
 
228
329
  ```bash
@@ -433,7 +534,7 @@ See [CHANGELOG.md][📌changelog] for a list of releases.
433
534
  ## 📄 License
434
535
 
435
536
  The gem is available as open source under the terms of
436
- the [MIT](MIT.md) [![License: MIT][📄license-img]][📄license-ref].
537
+ the [MIT](https://github.com/galtzo-floss/turbo_tests2/blob/main/MIT.md) [![License: MIT][📄license-img]][📄license-ref].
437
538
 
438
539
  ### © Copyright
439
540
 
@@ -511,6 +612,8 @@ Thanks for RTFM. ☺️
511
612
  [✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord
512
613
  [✉️ruby-friends-img]: https://img.shields.io/badge/daily.dev-%F0%9F%92%8E_Ruby_Friends-0A0A0A?style=for-the-badge&logo=dailydotdev&logoColor=white
513
614
  [✉️ruby-friends]: https://app.daily.dev/squads/rubyfriends
615
+ [✉️ruby-forum-img]: https://img.shields.io/badge/RubyForum-Help-CC342D?style=for-the-badge&logo=ruby&logoColor=white
616
+ [✉️ruby-forum]: https://www.rubyforum.org/c/help/8
514
617
 
515
618
  [✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
516
619
  [⛳️gem-namespace]: https://github.com/galtzo-floss/turbo_tests2
@@ -556,7 +659,7 @@ Thanks for RTFM. ☺️
556
659
  [📜src-gl]: https://gitlab.com/galtzo-floss/turbo_tests2
557
660
  [📜src-cb-img]: https://img.shields.io/badge/CodeBerg-4893CC?style=for-the-badge&logo=CodeBerg&logoColor=blue
558
661
  [📜src-cb]: https://codeberg.org/galtzo-floss/turbo_tests2
559
- [📜src-gh-img]: https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=Github&logoColor=green
662
+ [📜src-gh-img]: https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=GitHub&logoColor=green
560
663
  [📜src-gh]: https://github.com/galtzo-floss/turbo_tests2
561
664
  [📜docs-cr-rd-img]: https://img.shields.io/badge/RubyDoc-Current_Release-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
562
665
  [📜docs-head-rd-img]: https://img.shields.io/badge/YARD_on_Galtzo.com-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
@@ -666,12 +769,12 @@ Thanks for RTFM. ☺️
666
769
  [📌gitmoji]: https://gitmoji.dev
667
770
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
668
771
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
669
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.779-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
772
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.897-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
670
773
  [🔐security]: https://github.com/galtzo-floss/turbo_tests2/blob/main/SECURITY.md
671
774
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
672
775
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
673
776
  [📄license]: LICENSE.md
674
- [📄license-ref]: MIT.md
777
+ [📄license-ref]: https://github.com/galtzo-floss/turbo_tests2/blob/main/MIT.md
675
778
  [📄license-img]: https://img.shields.io/badge/License-MIT-259D6C.svg
676
779
  [📄license-compat]: https://www.apache.org/legal/resolved.html#category-a
677
780
  [📄license-compat-img]: https://img.shields.io/badge/Apache_Compatible:_Category_A-%E2%9C%93-259D6C.svg?style=flat&logo=Apache
data/exe/turbo_tests2 CHANGED
@@ -1,7 +1,16 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
+ script_basename = File.basename(__FILE__)
5
+ require "turbo_tests/version"
6
+ if ARGV.any? { |arg| arg == "-v" || arg == "--version" }
7
+ puts TurboTests::Version::VERSION
8
+ exit(0)
9
+ end
10
+
4
11
  # Alias for `turbo_tests` — turbo_tests2 is a drop-in replacement for turbo_tests.
5
12
  require "turbo_tests2"
6
13
 
14
+ puts "== #{script_basename} v#{TurboTests::Version::VERSION} =="
15
+
7
16
  TurboTests::CLI.new(ARGV).run
@@ -25,6 +25,9 @@ module TurboTests
25
25
  print_failed_group = false
26
26
  create = false
27
27
  nice = false
28
+ worker_output = nil
29
+ parallel_options = {}
30
+ cli_args, parallel_args = split_parallel_args(@argv)
28
31
 
29
32
  OptionParser.new do |opts|
30
33
  opts.banner = <<~BANNER
@@ -42,7 +45,16 @@ module TurboTests
42
45
  Options:
43
46
  BANNER
44
47
 
45
- opts.on("-n [PROCESSES]", "-w [PROCESSES]", "--workers [PROCESSES]", Integer, "How many processes to use, default: available CPUs") do |n|
48
+ opts.on(
49
+ "-n [PROCESSES]",
50
+ "--count [PROCESSES]",
51
+ Integer,
52
+ "How many processes to use, default: available CPUs"
53
+ ) do |n|
54
+ count = n
55
+ end
56
+
57
+ opts.on("-w [PROCESSES]", "--workers [PROCESSES]", Integer, "Alias for -n, --count") do |n|
46
58
  count = n
47
59
  end
48
60
 
@@ -83,10 +95,41 @@ module TurboTests
83
95
  example_status_log = filename
84
96
  end
85
97
 
98
+ opts.on("--pattern PATTERN", "Run spec files matching this regex pattern") do |pattern|
99
+ parallel_options[:pattern] = compile_pattern(pattern)
100
+ end
101
+
102
+ opts.on("--exclude-pattern PATTERN", "Exclude spec files matching this regex pattern") do |pattern|
103
+ parallel_options[:exclude_pattern] = compile_pattern(pattern)
104
+ end
105
+
106
+ opts.on("--only-group GROUP_INDEX[,GROUP_INDEX]", "Run only the selected 1-based parallel_tests group index(es)") do |groups|
107
+ parallel_options[:only_group] = parse_only_groups(groups)
108
+ end
109
+
110
+ opts.on("--group-by MODE", "Group files by runtime, filesize, or found order") do |mode|
111
+ parallel_options[:group_by] = parse_group_by(mode)
112
+ end
113
+
114
+ opts.on("--allowed-missing PERCENT", Integer, "Allowed percentage of missing runtimes for runtime grouping") do |percent|
115
+ parallel_options[:allowed_missing_percent] = parse_allowed_missing(percent)
116
+ end
117
+
118
+ opts.on("--unknown-runtime SECONDS", Float, "Runtime in seconds to assign files missing runtime history") do |seconds|
119
+ parallel_options[:unknown_runtime] = parse_unknown_runtime(seconds)
120
+ end
121
+
86
122
  opts.on("-v", "--verbose", "More output") do
87
123
  verbose = true
88
124
  end
89
125
 
126
+ opts.on(
127
+ "--worker-output MODE",
128
+ "Raw worker output mode: warnings, stream, buffered, or quiet; env: TURBO_TESTS2_WORKER_OUTPUT"
129
+ ) do |mode|
130
+ worker_output = mode
131
+ end
132
+
90
133
  opts.on("--fail-fast=[N]") do |n|
91
134
  n = begin
92
135
  Integer(n)
@@ -119,7 +162,9 @@ module TurboTests
119
162
  opts.on("--nice", "execute test commands with low priority") do
120
163
  nice = true
121
164
  end
122
- end.parse!(@argv)
165
+ end.parse!(cli_args)
166
+
167
+ parse_parallel_args(parallel_args, parallel_options) unless parallel_args.empty?
123
168
 
124
169
  if create
125
170
  return TurboTests::Runner.create(count)
@@ -142,8 +187,7 @@ module TurboTests
142
187
 
143
188
  invoke_rake_hook("setup")
144
189
 
145
- files = @argv.empty? ? nil : @argv
146
- parallel_options = {}
190
+ files = cli_args.empty? ? nil : cli_args
147
191
 
148
192
  exitstatus = TurboTests::Runner.run(
149
193
  formatters: formatters,
@@ -158,6 +202,7 @@ module TurboTests
158
202
  order: order,
159
203
  nice: nice,
160
204
  print_failed_group: print_failed_group,
205
+ worker_output: worker_output,
161
206
  parallel_options: parallel_options
162
207
  )
163
208
 
@@ -177,12 +222,104 @@ module TurboTests
177
222
  @argv.first == "fan"
178
223
  end
179
224
 
225
+ def split_parallel_args(args)
226
+ separator_index = args.index("--")
227
+ return [args, []] unless separator_index
228
+
229
+ [
230
+ args[0...separator_index],
231
+ args[(separator_index + 1)..-1]
232
+ ]
233
+ end
234
+
235
+ def parse_parallel_args(args, parallel_options)
236
+ OptionParser.new do |opts|
237
+ opts.on("--pattern PATTERN", "Run spec files matching this regex pattern") do |pattern|
238
+ parallel_options[:pattern] = compile_pattern(pattern)
239
+ end
240
+
241
+ opts.on("--exclude-pattern PATTERN", "Exclude spec files matching this regex pattern") do |pattern|
242
+ parallel_options[:exclude_pattern] = compile_pattern(pattern)
243
+ end
244
+
245
+ opts.on("--only-group GROUP_INDEX[,GROUP_INDEX]", "Run only the selected 1-based parallel_tests group index(es)") do |groups|
246
+ parallel_options[:only_group] = parse_only_groups(groups)
247
+ end
248
+
249
+ opts.on("--group-by MODE", "Group files by runtime, filesize, or found order") do |mode|
250
+ parallel_options[:group_by] = parse_group_by(mode)
251
+ end
252
+
253
+ opts.on("--allowed-missing PERCENT", Integer, "Allowed percentage of missing runtimes for runtime grouping") do |percent|
254
+ parallel_options[:allowed_missing_percent] = parse_allowed_missing(percent)
255
+ end
256
+
257
+ opts.on("--unknown-runtime SECONDS", Float, "Runtime in seconds to assign files missing runtime history") do |seconds|
258
+ parallel_options[:unknown_runtime] = parse_unknown_runtime(seconds)
259
+ end
260
+ end.parse!(args)
261
+
262
+ return if args.empty?
263
+
264
+ raise OptionParser::InvalidArgument, "unsupported parallel_tests argument(s): #{args.join(" ")}"
265
+ end
266
+
267
+ def compile_pattern(pattern)
268
+ /#{pattern}/
269
+ rescue RegexpError => error
270
+ raise OptionParser::InvalidArgument, "invalid regex pattern #{pattern.inspect}: #{error.message}"
271
+ end
272
+
273
+ def parse_only_groups(groups)
274
+ groups.to_s.split(",").map do |group|
275
+ group = group.strip
276
+ raise OptionParser::InvalidArgument, "invalid group index #{group.inspect}" unless group.match?(/\A[1-9]\d*\z/)
277
+
278
+ group.to_i
279
+ end
280
+ end
281
+
282
+ def parse_group_by(mode)
283
+ value = mode.to_s.strip
284
+ supported_modes = %w[runtime filesize found]
285
+ unless supported_modes.include?(value)
286
+ raise OptionParser::InvalidArgument, "invalid group-by mode #{value.inspect}; expected one of: #{supported_modes.join(", ")}"
287
+ end
288
+
289
+ value.to_sym
290
+ end
291
+
292
+ def parse_allowed_missing(percent)
293
+ unless (0..100).cover?(percent)
294
+ raise OptionParser::InvalidArgument, "invalid allowed missing percent #{percent.inspect}; expected 0 through 100"
295
+ end
296
+
297
+ percent
298
+ end
299
+
300
+ def parse_unknown_runtime(seconds)
301
+ unless seconds.finite? && !seconds.negative?
302
+ raise OptionParser::InvalidArgument, "invalid unknown runtime #{seconds.inspect}; expected a finite non-negative number"
303
+ end
304
+
305
+ seconds
306
+ end
307
+
180
308
  def handle_fan_command
181
309
  args = @argv.drop(1)
182
310
  count = nil
183
311
  parser = OptionParser.new do |opts|
184
312
  opts.banner = "Usage: turbo_tests2 fan [options] COMMAND [ARGS]"
185
- opts.on("-n [PROCESSES]", "-w [PROCESSES]", "--workers [PROCESSES]", Integer, "How many processes to use, default: available CPUs") do |n|
313
+ opts.on(
314
+ "-n [PROCESSES]",
315
+ "--count [PROCESSES]",
316
+ Integer,
317
+ "How many processes to use, default: available CPUs"
318
+ ) do |n|
319
+ count = n
320
+ end
321
+
322
+ opts.on("-w [PROCESSES]", "--workers [PROCESSES]", Integer, "Alias for -n, --count") do |n|
186
323
  count = n
187
324
  end
188
325
  end