rspec-tracer 1.2.3 → 2.0.0.pre.2

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.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +384 -67
  3. data/README.md +454 -429
  4. data/bin/rspec-tracer +15 -0
  5. data/lib/rspec_tracer/cache/Rakefile +43 -0
  6. data/lib/rspec_tracer/cli/cache_clear.rb +111 -0
  7. data/lib/rspec_tracer/cli/cache_info.rb +104 -0
  8. data/lib/rspec_tracer/cli/doctor.rb +284 -0
  9. data/lib/rspec_tracer/cli/explain.rb +158 -0
  10. data/lib/rspec_tracer/cli/report_open.rb +82 -0
  11. data/lib/rspec_tracer/cli.rb +116 -0
  12. data/lib/rspec_tracer/configuration.rb +1196 -3
  13. data/lib/rspec_tracer/engine.rb +1168 -0
  14. data/lib/rspec_tracer/example.rb +141 -11
  15. data/lib/rspec_tracer/filter.rb +35 -0
  16. data/lib/rspec_tracer/line_stub.rb +61 -0
  17. data/lib/rspec_tracer/load_config.rb +2 -2
  18. data/lib/rspec_tracer/logger.rb +15 -0
  19. data/lib/rspec_tracer/rails/README.md +78 -0
  20. data/lib/rspec_tracer/rails/i18n_tracking.rb +137 -0
  21. data/lib/rspec_tracer/rails/notifications.rb +263 -0
  22. data/lib/rspec_tracer/rails/preset.rb +94 -0
  23. data/lib/rspec_tracer/rails/railtie.rb +22 -0
  24. data/lib/rspec_tracer/rails.rb +15 -0
  25. data/lib/rspec_tracer/remote_cache/README.md +140 -0
  26. data/lib/rspec_tracer/remote_cache/Rakefile +35 -11
  27. data/lib/rspec_tracer/remote_cache/archive.rb +137 -0
  28. data/lib/rspec_tracer/remote_cache/backend.rb +73 -0
  29. data/lib/rspec_tracer/remote_cache/git_ancestry.rb +241 -0
  30. data/lib/rspec_tracer/remote_cache/local_fs_backend.rb +439 -0
  31. data/lib/rspec_tracer/remote_cache/redis_backend.rb +554 -0
  32. data/lib/rspec_tracer/remote_cache/s3_backend.rb +712 -0
  33. data/lib/rspec_tracer/remote_cache/user_tasks.rb +436 -0
  34. data/lib/rspec_tracer/remote_cache/validator.rb +40 -62
  35. data/lib/rspec_tracer/remote_cache.rb +22 -0
  36. data/lib/rspec_tracer/reporters/README.md +103 -0
  37. data/lib/rspec_tracer/reporters/base.rb +87 -0
  38. data/lib/rspec_tracer/reporters/coverage_json_reporter.rb +338 -0
  39. data/lib/rspec_tracer/reporters/html/.gitignore +19 -0
  40. data/lib/rspec_tracer/reporters/html/.prettierignore +4 -0
  41. data/lib/rspec_tracer/reporters/html/.prettierrc.json +9 -0
  42. data/lib/rspec_tracer/reporters/html/README.md +80 -0
  43. data/lib/rspec_tracer/reporters/html/dist/assets/index.css +2 -0
  44. data/lib/rspec_tracer/reporters/html/dist/assets/index.js +1 -0
  45. data/lib/rspec_tracer/reporters/html/dist/index.html +24 -0
  46. data/lib/rspec_tracer/reporters/html/eslint.config.js +62 -0
  47. data/lib/rspec_tracer/reporters/html/package-lock.json +4941 -0
  48. data/lib/rspec_tracer/reporters/html/package.json +29 -0
  49. data/lib/rspec_tracer/reporters/html/src/app.jsx +130 -0
  50. data/lib/rspec_tracer/reporters/html/src/components/AllExamples.jsx +86 -0
  51. data/lib/rspec_tracer/reporters/html/src/components/DuplicateExamples.jsx +68 -0
  52. data/lib/rspec_tracer/reporters/html/src/components/ExamplesDependency.jsx +78 -0
  53. data/lib/rspec_tracer/reporters/html/src/components/FilesDependency.jsx +72 -0
  54. data/lib/rspec_tracer/reporters/html/src/components/FlakyExamples.jsx +42 -0
  55. data/lib/rspec_tracer/reporters/html/src/components/ReportTable.jsx +131 -0
  56. data/lib/rspec_tracer/reporters/html/src/components/SearchBar.jsx +19 -0
  57. data/lib/rspec_tracer/reporters/html/src/index.html +23 -0
  58. data/lib/rspec_tracer/reporters/html/src/main.jsx +37 -0
  59. data/lib/rspec_tracer/reporters/html/src/styles.css +434 -0
  60. data/lib/rspec_tracer/reporters/html/vite.config.js +42 -0
  61. data/lib/rspec_tracer/reporters/html_reporter.rb +266 -0
  62. data/lib/rspec_tracer/reporters/json_reporter.rb +88 -0
  63. data/lib/rspec_tracer/reporters/payload_builder.rb +235 -0
  64. data/lib/rspec_tracer/reporters/registry.rb +120 -0
  65. data/lib/rspec_tracer/reporters/terminal_reporter.rb +264 -0
  66. data/lib/rspec_tracer/rspec/README.md +73 -0
  67. data/lib/rspec_tracer/rspec/installation.rb +97 -0
  68. data/lib/rspec_tracer/rspec/metadata.rb +96 -0
  69. data/lib/rspec_tracer/rspec/parallel_tests.rb +459 -0
  70. data/lib/rspec_tracer/rspec/reporter_hook.rb +84 -0
  71. data/lib/rspec_tracer/rspec/runner_hook.rb +239 -0
  72. data/lib/rspec_tracer/source_file.rb +24 -7
  73. data/lib/rspec_tracer/storage/README.md +35 -0
  74. data/lib/rspec_tracer/storage/backend.rb +130 -0
  75. data/lib/rspec_tracer/storage/json_backend.rb +884 -0
  76. data/lib/rspec_tracer/storage/lazy_snapshot.rb +65 -0
  77. data/lib/rspec_tracer/storage/schema.rb +50 -0
  78. data/lib/rspec_tracer/storage/serializer/json.rb +41 -0
  79. data/lib/rspec_tracer/storage/serializer/msgpack.rb +167 -0
  80. data/lib/rspec_tracer/storage/snapshot.rb +141 -0
  81. data/lib/rspec_tracer/storage/sqlite_backend.rb +693 -0
  82. data/lib/rspec_tracer/time_formatter.rb +37 -18
  83. data/lib/rspec_tracer/tracker/README.md +36 -0
  84. data/lib/rspec_tracer/tracker/coverage_adapter.rb +174 -0
  85. data/lib/rspec_tracer/tracker/declared_globs.rb +100 -0
  86. data/lib/rspec_tracer/tracker/dependency_graph.rb +134 -0
  87. data/lib/rspec_tracer/tracker/env_matcher.rb +127 -0
  88. data/lib/rspec_tracer/tracker/env_snapshot.rb +77 -0
  89. data/lib/rspec_tracer/tracker/example_registry.rb +153 -0
  90. data/lib/rspec_tracer/tracker/file_digest.rb +61 -0
  91. data/lib/rspec_tracer/tracker/filter.rb +127 -0
  92. data/lib/rspec_tracer/tracker/input.rb +99 -0
  93. data/lib/rspec_tracer/tracker/io_hooks/file.rb +55 -0
  94. data/lib/rspec_tracer/tracker/io_hooks/io.rb +24 -0
  95. data/lib/rspec_tracer/tracker/io_hooks/json.rb +23 -0
  96. data/lib/rspec_tracer/tracker/io_hooks/kernel.rb +26 -0
  97. data/lib/rspec_tracer/tracker/io_hooks/yaml.rb +38 -0
  98. data/lib/rspec_tracer/tracker/io_hooks.rb +195 -0
  99. data/lib/rspec_tracer/tracker/loaded_files_tracker.rb +295 -0
  100. data/lib/rspec_tracer/tracker/new_file_detector.rb +62 -0
  101. data/lib/rspec_tracer/tracker/whole_suite_invalidators.rb +96 -0
  102. data/lib/rspec_tracer/version.rb +4 -1
  103. data/lib/rspec_tracer.rb +231 -491
  104. metadata +94 -43
  105. data/lib/rspec_tracer/cache.rb +0 -207
  106. data/lib/rspec_tracer/coverage_merger.rb +0 -42
  107. data/lib/rspec_tracer/coverage_reporter.rb +0 -187
  108. data/lib/rspec_tracer/coverage_writer.rb +0 -58
  109. data/lib/rspec_tracer/html_reporter/Rakefile +0 -18
  110. data/lib/rspec_tracer/html_reporter/assets/javascripts/application.js +0 -56
  111. data/lib/rspec_tracer/html_reporter/assets/javascripts/libraries/jquery.js +0 -10881
  112. data/lib/rspec_tracer/html_reporter/assets/javascripts/plugins/datatables.js +0 -15381
  113. data/lib/rspec_tracer/html_reporter/assets/stylesheets/application.css +0 -196
  114. data/lib/rspec_tracer/html_reporter/assets/stylesheets/plugins/datatables.css +0 -459
  115. data/lib/rspec_tracer/html_reporter/assets/stylesheets/plugins/jquery-ui.css +0 -436
  116. data/lib/rspec_tracer/html_reporter/assets/stylesheets/print.css +0 -92
  117. data/lib/rspec_tracer/html_reporter/assets/stylesheets/reset.css +0 -265
  118. data/lib/rspec_tracer/html_reporter/public/application.css +0 -5
  119. data/lib/rspec_tracer/html_reporter/public/application.js +0 -6
  120. data/lib/rspec_tracer/html_reporter/public/datatables/images/sort_asc.png +0 -0
  121. data/lib/rspec_tracer/html_reporter/public/datatables/images/sort_asc_disabled.png +0 -0
  122. data/lib/rspec_tracer/html_reporter/public/datatables/images/sort_both.png +0 -0
  123. data/lib/rspec_tracer/html_reporter/public/datatables/images/sort_desc.png +0 -0
  124. data/lib/rspec_tracer/html_reporter/public/datatables/images/sort_desc_disabled.png +0 -0
  125. data/lib/rspec_tracer/html_reporter/public/favicon.png +0 -0
  126. data/lib/rspec_tracer/html_reporter/public/loading.gif +0 -0
  127. data/lib/rspec_tracer/html_reporter/reporter.rb +0 -242
  128. data/lib/rspec_tracer/html_reporter/views/duplicate_examples.erb +0 -34
  129. data/lib/rspec_tracer/html_reporter/views/examples.erb +0 -58
  130. data/lib/rspec_tracer/html_reporter/views/examples_dependency.erb +0 -36
  131. data/lib/rspec_tracer/html_reporter/views/files_dependency.erb +0 -36
  132. data/lib/rspec_tracer/html_reporter/views/flaky_examples.erb +0 -38
  133. data/lib/rspec_tracer/html_reporter/views/layout.erb +0 -38
  134. data/lib/rspec_tracer/remote_cache/aws.rb +0 -176
  135. data/lib/rspec_tracer/remote_cache/cache.rb +0 -75
  136. data/lib/rspec_tracer/remote_cache/repo.rb +0 -210
  137. data/lib/rspec_tracer/report_generator.rb +0 -158
  138. data/lib/rspec_tracer/report_merger.rb +0 -68
  139. data/lib/rspec_tracer/report_writer.rb +0 -141
  140. data/lib/rspec_tracer/reporter.rb +0 -204
  141. data/lib/rspec_tracer/rspec_reporter.rb +0 -41
  142. data/lib/rspec_tracer/rspec_runner.rb +0 -56
  143. data/lib/rspec_tracer/ruby_coverage.rb +0 -9
  144. data/lib/rspec_tracer/runner.rb +0 -278
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c0ed3fbdb4a082d56a4d83a528dff26bd174abeb28cf1669dc5dd79de521cee
4
- data.tar.gz: ebc2fbdfde4c6ac82072b5464f5dc0441d73efd24b4410ed96d3892ea765f1a9
3
+ metadata.gz: 552b92475298cfa692f8748b7b7097b12a82a2e8b1003848d1194fe560c0b385
4
+ data.tar.gz: 34a9d94756083aaf46220460c4d10002d30992703c1aad0e417640ad5b2d79ae
5
5
  SHA512:
6
- metadata.gz: 1c28a6a997cf74dbb8d910972d9dd8e0b6e9f36aaacc9670e8a50a6bf7c0d4100f6cf421befcba8349750c3ba179a05b86d2a0cbdf740280d490d4bd42c37512
7
- data.tar.gz: ce834032d235ea1e2775fb127ac040d6f12f560e7cf9babe5fd208a68cb5dd7260a2ac1f2af78b2a782a622902d9b8291adb2ca339837de70b9f12259e05a456
6
+ metadata.gz: 57b510bf3f8da2071a72ee222d598e9ce8042b5745cec84e053ea7b7db87e203e73829f890f105d934901835813cee66290ff0b24a07f278b1821c3b75febdb7
7
+ data.tar.gz: 57adb9424e1bdc3775294de9573726f3b80bea35615d6a41410985724d930faa00c984bf3c9b637297565fa11bf72c938bb92ce8464b7968c9be9fa5b476b2f2
data/CHANGELOG.md CHANGED
@@ -1,81 +1,398 @@
1
- ## [1.2.3] - 2026-05-06
1
+ ## [2.0.0.pre.2] - 2026-05-16
2
+
3
+ Bug-fix + interop release after the field-test pass that followed
4
+ `v2.0.0.pre.1`. 15 issues filed publicly
5
+ ([#182](https://github.com/avmnu-sng/rspec-tracer/issues/182)–[#196](https://github.com/avmnu-sng/rspec-tracer/issues/196))
6
+ plus two follow-on findings
7
+ ([#210](https://github.com/avmnu-sng/rspec-tracer/issues/210) and
8
+ [#218](https://github.com/avmnu-sng/rspec-tracer/issues/218))
9
+ surfaced during fix-verification; all 17 are closed at tag. No CI
10
+ surface drops, no Ruby / Rails / RSpec floor changes.
11
+
12
+ The cumulative cache `schema_version` path is `3 → 5` (two bumps
13
+ across [#209](https://github.com/avmnu-sng/rspec-tracer/pull/209)
14
+ and [#211](https://github.com/avmnu-sng/rspec-tracer/pull/211));
15
+ a pre.1 cache cold-loads cleanly on the pre.2 upgrade in one cold
16
+ run, then warm caches resume. See [`UPGRADING.md`](UPGRADING.md).
17
+
18
+ ### Added
19
+
20
+ - **`coverage_modes` config DSL** for the standalone Coverage
21
+ path (no SimpleCov). Pass any subset of
22
+ `[:lines, :branches, :methods, :oneshot_lines, :eval]`; default
23
+ `[:lines]` keeps byte-compatibility with prior runs. Threaded
24
+ through both `RSpecTracer.setup_coverage` and
25
+ `Engine#ensure_coverage_started`; inert when SimpleCov drives
26
+ Coverage. New COOKBOOK recipe "Coverage modes (rspec-tracer +
27
+ SimpleCov interop)" under recipe 9 documents the per-mode
28
+ interop matrix.
29
+ - **`bin/rspec-tracer cache:clear --force` / `-f`** as a synonym
30
+ for `--yes` / `-y`. Matches the common Unix-CLI convention.
31
+ - **COOKBOOK recipe for the `:msgpack` serializer** documenting
32
+ the `storage_backend :json, serializer: :msgpack` option for
33
+ ~3.5× smaller caches than `:json` on dependency-heavy suites.
34
+ Notes that `.msgpack.gz` payloads are raw `Zlib::Deflate`
35
+ streams (not gzip format) — the suffix is cosmetic and may
36
+ change in a future major release.
37
+
38
+ ### Changed
39
+
40
+ - **Cache `schema_version` bump 3 → 5** (cumulative). The
41
+ `example_id` digest now drops the load-order-dependent
42
+ generated-class-name suffix and the line-number fields, and
43
+ substitutes a positional discriminator for unnamed
44
+ `it { }` / `specify { }` / `example { }` examples that
45
+ previously picked up RSpec's `"example at <path>:<line>"`
46
+ description fallback. First run on pre.2 is cold; subsequent
47
+ runs return to warm. See [`UPGRADING.md`](UPGRADING.md)
48
+ "Schema-version cold runs."
49
+ - **Duplicate-example-identity detection now prune-and-continue.**
50
+ When the runner detects two examples with the same identity,
51
+ it drops the colliders from the run and lets the rest of the
52
+ suite proceed, instead of aborting the entire run to zero
53
+ examples. `fail_on_duplicates` becomes purely an exit-code
54
+ lever — the non-colliding remainder always runs. The error log
55
+ names the colliding examples (file:line + description) with a
56
+ remediation hint. See [`UPGRADING.md`](UPGRADING.md)
57
+ "Duplicate example identities."
2
58
 
3
59
  ### Fixed
4
60
 
5
- - **Parallel-tests purge race when a sibling worker is still mid-flush**
6
- the elected worker trusted only `parallel_tests`'s pid-file barrier
7
- (`ParallelTests.wait_for_other_processes_to_finish`), which under
8
- specific scheduling/I/O timing on GHA Linux x86_64 can return while a
9
- sibling's `parallel_tests_N/` dir hasn't fully flushed. The elected
10
- then merged + purged, racing the in-progress sibling. Symptoms:
11
- intermittent leftover `parallel_tests_N/` dir post-purge AND/OR
12
- silently dropped peer caches in the merge.
13
-
14
- Backport of upstream PR
15
- [#168](https://github.com/avmnu-sng/rspec-tracer/pull/168). Adds a
16
- filesystem barrier layered on top of the pid-file wait. Each worker
17
- writes a `.rspec_tracer_boot` marker at `RSpecTracer.start` time and
18
- a `.rspec_tracer_done` marker as the first step of its at_exit tasks;
19
- the elected worker waits for every booted peer's `.done` to
20
- materialize before proceeding to merge + purge. Two independent
21
- signals (pid file + filesystem) must agree before the elected worker
22
- declares the peer set stable. Bounded at 5 s with a graceful warn for
23
- crashed peers — their dirs are purged regardless of completion state,
24
- and the merge accepts whatever's on disk.
25
-
26
- ## [1.2.2] - 2026-05-04
61
+ - **Restored flaky-test detection across runs.** A top-line
62
+ README feature present in 1.x since v1.0.0; silently dropped
63
+ in the 2.0 rewrite — the registry `:flaky` status, the
64
+ `:flaky_example` filter reason, the `flaky_examples` snapshot
65
+ field, and the HTML reporter's Flaky tab were all retained,
66
+ but no production code path transitioned an example into
67
+ `:flaky`. `on_example_passed` now promotes a
68
+ previously-failed-or-flaky example into `:flaky`;
69
+ `on_example_failed` keeps a previously-flaky example sticky.
70
+ Closes [#194](https://github.com/avmnu-sng/rspec-tracer/issues/194).
71
+ - **`run_reason` field in `report.json` (and the terminal
72
+ `by reason:` line) now persists the correct reason on warm
73
+ runs for every reason path** `Failed previously`,
74
+ `Pending previously`, `Interrupted previously`, `Files changed`,
75
+ `Environment changed`. Previously displayed as `No cache` on
76
+ every warm-run case because `Engine#register_example`
77
+ short-circuited on the entry already seeded from the previous
78
+ snapshot. Single-character fix closing all five reason paths.
79
+ Closes [#186](https://github.com/avmnu-sng/rspec-tracer/issues/186).
80
+ - **Parallel-`tests` `cache_hit_reason` counts no longer inflated
81
+ by worker count.** Each worker independently computed an
82
+ identical `filtered_examples` hash against the global
83
+ previous-run snapshot; the pre-fix sum-merge inflated
84
+ always-re-run buckets N-fold. The merge now keys on
85
+ `example_id` (first-write-wins), then re-tallies. Closes
86
+ [#193](https://github.com/avmnu-sng/rspec-tracer/issues/193).
87
+ - **`example_id` stable across runs when multiple files share a
88
+ `describe` name** (the load-order-dependent
89
+ `RSpec::ExampleGroups::Name_N` disambiguator suffix is no
90
+ longer in the digest) **and stable across line-shift edits for
91
+ unnamed one-liner examples** (`it { is_expected.to eq(7) }`,
92
+ `specify { ... }`, `example { ... }`). Long-standing bugs since
93
+ v1.0.0; pervasive in shoulda-matchers model specs which are
94
+ almost entirely one-liner matcher syntax. Closes
95
+ [#196](https://github.com/avmnu-sng/rspec-tracer/issues/196)
96
+ + [#210](https://github.com/avmnu-sng/rspec-tracer/issues/210).
97
+ - **NPE in `RSpec.world.example_count` for suites with
98
+ intermediate describe groups after rspec-tracer drops a
99
+ duplicate-identity example.** Companion fix to the
100
+ duplicate-detection prune-and-continue redesign above — the
101
+ kept-map needed a default block so descendants of an
102
+ intermediate describe (a describe containing only nested
103
+ describes, no direct `it`s) resolve to an empty array on the
104
+ `filtered_examples` lookup instead of `nil`. Closes
105
+ [#218](https://github.com/avmnu-sng/rspec-tracer/issues/218).
106
+ - **`storage_backend :json, serializer: :msgpack` no longer
107
+ crashes on `Time` values** (and `Symbol` values now round-trip
108
+ losslessly across the cache). Registered
109
+ `MessagePack::Factory` type extensions for `Time` (12-byte
110
+ `tv_sec + tv_nsec`, UTC-canonicalized on decode) and `Symbol`
111
+ (UTF-8 body). Users who followed rspec-tracer's own 50 MiB
112
+ cache warning's `:msgpack` recommendation no longer brick
113
+ their cache silently on the first run that writes a `Time`.
114
+ Closes [#182](https://github.com/avmnu-sng/rspec-tracer/issues/182).
115
+ - **`bin/rspec-tracer cache:info` and `explain` now compose with
116
+ `storage_backend :sqlite`.** Previously hardcoded the
117
+ JsonBackend on-disk layout and reported `no last_run.json yet`
118
+ on every sqlite run, even after a successful rspec. Both CLI
119
+ sub-commands now dispatch through a shared
120
+ `Storage::Backend.build` factory; sqlite metadata-table reads
121
+ surface alongside JSON manifest reads behind the same
122
+ protocol. Closes
123
+ [#183](https://github.com/avmnu-sng/rspec-tracer/issues/183).
124
+ - **`bin/rspec-tracer doctor` no longer false-reports `SimpleCov:
125
+ not loaded` / `Rails: not loaded`** when those gems ARE in the
126
+ Gemfile (doctor runs in its own process; app code doesn't load
127
+ there). Three states are now reported: loaded-in-this-process
128
+ (`OK`), installed-but-not-loaded
129
+ (`INFO ... installed (<version>; not loaded in doctor's process)`),
130
+ and not-installed (`INFO ... not installed`). Closes
131
+ [#184](https://github.com/avmnu-sng/rspec-tracer/issues/184).
132
+ - **`bin/rspec-tracer` invocation guidance flipped to
133
+ `bundle exec rspec-tracer`** across README, COOKBOOK, and
134
+ UPGRADING. The bare `bin/rspec-tracer` form required users to
135
+ run `bundle binstubs rspec-tracer` first; `bundle exec
136
+ rspec-tracer` works out of the box. Closes
137
+ [#185](https://github.com/avmnu-sng/rspec-tracer/issues/185).
138
+ - **`reports_s3_path` deprecation warning no longer false-flags
139
+ on the probe path** — when no `remote_cache_backend` /
140
+ `remote_cache_uri` is configured AND the user runs
141
+ `rake rspec_tracer:remote_cache:download` / `:upload` /
142
+ `:prune_all`. A new non-warning predicate gates the probe; the
143
+ deprecation now fires only on legitimate use of the legacy
144
+ DSL. Closes
145
+ [#187](https://github.com/avmnu-sng/rspec-tracer/issues/187).
146
+ - **`remote_cache` success now emits visible INFO lines** for
147
+ `download!` (`restored cache from <ref>` — with a
148
+ `(cross-branch fallback)` qualifier when a PR-tier download
149
+ falls through to a commit-ancestry ref successfully),
150
+ `upload!` (`uploaded cache to <ref>`), and `prune_all!`
151
+ (`prune_all removed N refs`). One fix covers all three
152
+ backends (s3 / redis / file) + the cron-driven `prune_all`
153
+ admin task. Closes
154
+ [#188](https://github.com/avmnu-sng/rspec-tracer/issues/188).
155
+ - **`track_ar_schema_notifications` now installs correctly under
156
+ the canonical README setup order** (`RSpecTracer.start` BEFORE
157
+ `require_relative '../config/environment'`). Previously,
158
+ `defined?(::Rails::VERSION)` was false at engine.setup time
159
+ and the entire Rails-observer install path short-circuited —
160
+ the `sql.active_record` subscriber never attached AND the
161
+ documented `use_transactional_fixtures`-widening warn never
162
+ fired. Now late-binds via a `before(:suite)` hook that
163
+ re-checks Rails-loaded state after `rails_helper.rb` has
164
+ required the environment. Closes
165
+ [#192](https://github.com/avmnu-sng/rspec-tracer/issues/192).
166
+ - **`RSpecTracer.start` no longer crashes** when the user
167
+ pre-starts `::Coverage` (e.g. to opt into branch coverage for
168
+ SimpleCov-free runs). The `setup_coverage` entry point now
169
+ matches `Engine#ensure_coverage_started`'s `Coverage.running?`
170
+ guard + `RuntimeError` rescue. Closes
171
+ [#195](https://github.com/avmnu-sng/rspec-tracer/issues/195).
172
+ - **`InvalidUsageError` raised on conflicting
173
+ `remote_cache_backend` / `remote_cache_uri` configuration now
174
+ names both DSLs and explains they are alternatives.** The
175
+ previous `<dsl> already configured` message was confusing when
176
+ the user only typed `remote_cache_uri` (which dispatches
177
+ internally to `remote_cache_backend`).
178
+ - **README per-example-precision section now covers Rails
179
+ engines.** An engine's own `lib/` is `require`d at gem-load
180
+ time via the Gemfile.lock cascade and lands in the boot set
181
+ **regardless of `eager_load`**. COOKBOOK gains a
182
+ `transitive_load_tracking false` opt-out recipe with the
183
+ trade-off documented. Closes
184
+ [#189](https://github.com/avmnu-sng/rspec-tracer/issues/189).
185
+ - **Engine + dummy-app two-rspec-summary explainer** added to
186
+ COOKBOOK — clarifies which of the two terminal summary totals
187
+ is authoritative when an engine fixture invokes RSpec against
188
+ its dummy app. Closes
189
+ [#190](https://github.com/avmnu-sng/rspec-tracer/issues/190).
190
+
191
+ ## [2.0.0.pre.1] - 2026-05-06
192
+
193
+ The first pre-release of the 2.0 line. Architecture rewrite around
194
+ the input-taxonomy mental model documented in
195
+ [`ARCHITECTURE.md`](ARCHITECTURE.md): every test is a pure function
196
+ of its inputs; tracking is input identification; cache invalidation
197
+ is input-digest mismatch.
198
+
199
+ The 1.x cache is not readable by 2.0 — first run on the new version
200
+ is cold, then warm caches resume. Existing CI integration (`rake
201
+ rspec_tracer:remote_cache:download` / `:upload`, the env vars,
202
+ the `rspec_tracer_cache/` / `rspec_tracer_coverage/` /
203
+ `rspec_tracer_report/` directory contracts) is preserved bit-for-bit.
204
+
205
+ ### Added
206
+
207
+ - **Pluggable storage backends.** `storage_backend :json` (default,
208
+ preserves 1.x JSON layout) or `storage_backend :sqlite` (single-
209
+ file SQLite database; MRI only — JRuby falls back to `:json` with
210
+ a one-time warn). The 10-file per-run JSON layout (`last_run.json`
211
+ + `<run_id>/{all_examples,duplicate_examples,interrupted_examples,
212
+ flaky_examples,failed_examples,pending_examples,skipped_examples,
213
+ all_files,dependency,examples_coverage}.json`) is unchanged.
214
+ - **Pluggable remote-cache backends.** `remote_cache_backend :s3`
215
+ (preserves the 1.x S3 layout including `awslocal` / LocalStack
216
+ support), `:local_fs` (filesystem-backed; no S3 needed), or
217
+ `:redis` (with optional per-key TTL + `<prefix>:pr_branches`
218
+ sidecar SADD on PR-tier uploads for ops dashboards).
219
+ - **Per-example `tracks:` DSL.** Annotate any describe / context /
220
+ example with `tracks: { files: 'app/policies/**/*.rb', env:
221
+ 'ROLE_CONFIG' }` to declare extra inputs the tracker can't auto-
222
+ observe — config files baked at boot, env-var branches, and
223
+ similar. `:files` accepts a string glob or array; `:env` accepts a
224
+ literal name, array, or single-wildcard pattern (`'RAILS_*'`,
225
+ `'*_TOKEN'`, `'*'`). Cascade unions parent + child without
226
+ clobbering.
227
+ - **`track_env(*names)` config-level DSL** for env vars every test
228
+ depends on (`AUTH_TOKEN`, `DATABASE_URL`, `RAILS_ENV`). Same
229
+ wildcard syntax as the per-example `tracks: { env: ... }`.
230
+ Persists as `env_snapshot.json` (concrete keys only, no pattern
231
+ leakage).
232
+ - **`track_files(*globs)` config-level DSL** for files every test
233
+ depends on (`Gemfile.lock`, schema, locale catalogs).
234
+ - **Rails preset** via `track_rails_defaults` — auto-attaches the
235
+ common Rails-side declared globs (views, locales, fixtures,
236
+ factories, helpers, config). `track_rails_defaults except:
237
+ [:views, :schema]` opts specific globs out so framework-event
238
+ subscribers (`render_template.action_view` for views; the opt-in
239
+ `sql.active_record` observer enabled by
240
+ `track_ar_schema_notifications` for `db/schema.rb`) attribute
241
+ them per-example instead.
242
+ - **Auto-detection of Rails** at start time; the engine attaches
243
+ `ActionView` template + `ActiveRecord` schema (when opted in)
244
+ notification observers automatically when `::Rails::VERSION` is
245
+ defined.
246
+ - **`bin/rspec-tracer` CLI** with five sub-commands:
247
+ `doctor` (config + environment diagnosis, schema-version + remote-
248
+ cache reachability + AR-schema-narrow checks), `cache:info`
249
+ (size, last run, invalidation stats), `cache:clear` (rm cache
250
+ dirs), `report:open` (open the HTML report in the default
251
+ browser), `explain <example_id>` (show why a given example is
252
+ scheduled to run or skip). The CLI is opt-in for local-dev
253
+ convenience; the `rake rspec_tracer:remote_cache:*` tasks remain
254
+ first-class for CI integration.
255
+ - **Boot-time warns** for two common user-trust traps:
256
+ - SimpleCov loaded but not started before `RSpecTracer.start`
257
+ (load-order is part of the documented contract; the warn
258
+ surfaces it instead of silently bolting onto a Coverage already
259
+ in flight).
260
+ - `track_ar_schema_notifications` enabled with
261
+ `use_transactional_fixtures` defaulting to true (per-example
262
+ BEGIN/COMMIT fires `sql.active_record` and attributes
263
+ `db/schema.rb` to every AR-touching example; the warn points
264
+ at the README "Narrow AR-schema attribution" guidance).
265
+ - **`.rspec-tracer` DSL typo `did you mean?` suggestions** at config
266
+ load — typos like `track_filez` raise `InvalidUsageError` with a
267
+ pointer at `track_files`.
268
+ - **Rails 8.0 CI-gated support** (Ruby 3.2+ required; Rails 8.0
269
+ dropped Ruby 3.1 support upstream). `jruby-9.4 × Rails 8.0` is
270
+ unsupported (no `activerecord-jdbcsqlite3-adapter ~> 80.0`
271
+ upstream).
272
+ - **Schema-version field** in `last_run.json` for explicit
273
+ cross-version cache validation. Cache-shape changes bump the
274
+ field; mismatched caches refuse-to-load with an info-level "cold
275
+ run" log line.
276
+ - **`docs/CI_RECIPES.md`** translating the
277
+ [`.github/workflows/example-tracer-cache.yml`](.github/workflows/example-tracer-cache.yml)
278
+ GitHub Actions cache pattern to CircleCI / GitLab CI / Buildkite
279
+ / Heroku CI. The 4-component cache key (`runner.os` +
280
+ `.ruby-version` + `lib/rspec_tracer/version.rb` + Gemfile-hash)
281
+ translates 1:1 across providers; only the YAML envelope is
282
+ GHA-specific.
283
+ - **Coexistence smokes** for `rspec-retry`, `rspec-rerun`, and
284
+ `knapsack`. All three compose with rspec-tracer's `Module#prepend`
285
+ chain on `RSpec::Core::Runner` / `Reporter` without override.
286
+ - **`bin/rspec-tracer doctor` reachability checks** for the
287
+ configured remote-cache backend (S3 / Local-FS / Redis) — surfaces
288
+ misconfigured credentials / missing buckets / unreachable Redis
289
+ hosts at first invocation instead of mid-CI-run.
290
+ - **HTML reporter** (committed build output, no `assets:precompile`
291
+ step on user installs) and **JSON reporter** (machine-readable,
292
+ for CI dashboards) alongside the existing terminal output. The
293
+ terminal line now includes a `by reason:` breakdown
294
+ (`12 Files changed · 3 Whole-suite invalidator changed · ...`)
295
+ and a cache size + delta suffix (`14.4 MiB; +6.7 KiB vs prev
296
+ run`).
297
+
298
+ ### Changed
299
+
300
+ - **Ruby ≥ 3.1** is the floor (1.x supported Ruby 2.5+). 3.2, 3.3,
301
+ 3.4, 4.0 + JRuby 9.4 are CI-gated. Rails 7.0 / 7.1 / 7.2 / 8.0 +
302
+ RSpec 3.12 / 3.13 are CI-gated.
303
+ - **SimpleCov branch coverage now works alongside rspec-tracer.**
304
+ The 1.x caveat ("SimpleCov would not report branch coverage
305
+ results even when enabled") is **no longer applicable** — the
306
+ coverage-stack rewrite decoupled rspec-tracer's line-only
307
+ emission from SimpleCov's branch-tracking. Users who turned
308
+ `enable_coverage :branch` off when adopting rspec-tracer 1.x can
309
+ re-enable in 2.0.
310
+ - **Cache schema bump.** First run on 2.0 is cold; subsequent runs
311
+ return to warm.
312
+ - **Coverage adapter** consolidated: a single
313
+ `Reporters::CoverageJsonReporter` owns `coverage.json` emission
314
+ (replacing the 1.x `CoverageReporter` + `CoverageWriter` pair).
315
+ Output shape preserved.
316
+ - **Parallel-tests reporter behavior:** terminal / JSON / HTML
317
+ reports now emit ONCE at the merged top-level location after
318
+ `merge_snapshot!` runs, instead of per-worker (where
319
+ `purge_worker_dirs!` then removed them and left users with no
320
+ usable output). Per-worker emission was a pre-2.0 behavior bug.
27
321
 
28
322
  ### Fixed
29
323
 
324
+ - **ERB template tracking via `render_template.action_view`** (closes
325
+ the issue behind upstream
326
+ [#66](https://github.com/avmnu-sng/rspec-tracer/issues/66)). The
327
+ Rails subscriber attributes rendered ERB partials to the example
328
+ that triggered the render.
329
+ - **Phantom `metadata[:file_path]` graceful skip** (closes the issue
330
+ behind upstream
331
+ [#72](https://github.com/avmnu-sng/rspec-tracer/issues/72)). Specs
332
+ whose `metadata[:file_path]` doesn't resolve to a readable file
333
+ (gem-generated examples, deleted-between-runs files) now log
334
+ debug + skip dependency registration instead of raising.
30
335
  - **Default filter list now excludes rspec-tracer's own output
31
- directories** (`rspec_tracer_cache/`, `rspec_tracer_coverage/`,
32
- `rspec_tracer_report/`, and the `rspec_tracer.lock` file). Prior
33
- versions did not exclude these paths, so any spec that read a tracer
34
- cache file (typical for outer integration specs that assert on cache
35
- state after a fixture subprocess run) had those paths attributed as
36
- dependencies. The user-visible symptom was reverse-dependency reports
37
- showing tracer-self paths as deps of unrelated specs, plus
38
- spurious files-changed re-runs whenever the tracer rewrote its own
39
- cache. Both `add_filter` and `add_coverage_filter` defaults updated.
40
-
41
- - **Carry-forward filter contract** — newly added filters now apply
42
- uniformly to both fresh attribution AND prior-snapshot carry-forward.
43
- Previously, `Cache#load_all_files_cache` and `load_dependency_cache`
44
- read previous-run state without re-applying the current filter list.
45
- A user adding a new filter mid-development saw the filter take
46
- effect only for fresh attributions on cold runs; previously-cached
47
- paths matching the new filter persisted in `all_files` and
48
- `dependency` until the next cold run. Filter additions now take
336
+ directories** `rspec_tracer_cache/`, `rspec_tracer_coverage/`,
337
+ `rspec_tracer_report/`, `rspec_tracer.lock`. Previously, tests
338
+ that read the tracer's own cache files (e.g. integration specs
339
+ asserting on cache state after a fixture subprocess run) got
340
+ those paths attributed as deps. The tracer's output is
341
+ regenerated every run by design and should never invalidate a
342
+ test. Both `add_filter` (dep graph) and `add_coverage_filter`
343
+ (coverage report) lists were updated.
344
+ - **`add_filter` / `add_coverage_filter` now apply uniformly to
345
+ both fresh attributions AND prior-snapshot carry-forward.**
346
+ Previously, `Engine#seed_all_files_from_previous` and
347
+ `Engine#seed_graph_from_previous` seeded paths from the previous
348
+ run's snapshot WITHOUT re-applying the current filter list — so
349
+ a filter added between runs would NOT exclude already-cached
350
+ paths until a cold run wiped them. Filter additions now take
49
351
  effect on the very next warm run.
50
352
 
51
- ## [1.2.1] - 2026-05-01
353
+ ### Deprecated
52
354
 
53
- ### Fixed
355
+ The 1.x configuration surface keeps working; each deprecated entry
356
+ fires one `logger.warn` at first use pointing at the replacement.
357
+ The deprecated values still resolve semantically. All four are slated
358
+ for removal in 3.0.
359
+
360
+ - **`reports_s3_path(uri)`** → use **`remote_cache_uri(uri)`**.
361
+ - **`use_local_aws(bool)`** → use **`remote_cache_backend :s3,
362
+ local: true`**.
363
+ - **`RSPEC_TRACER_REPORTS_S3_PATH`** → use
364
+ **`RSPEC_TRACER_REMOTE_CACHE_URI`**.
365
+ - **`RSPEC_TRACER_USE_LOCAL_AWS`** → fold into
366
+ `remote_cache_backend` params.
367
+
368
+ ### Removed
54
369
 
55
- - **Parallel-tests merge silently dropped peer caches and left worker
56
- directories behind** when the spawned-worker count exceeded
57
- `ENV['PARALLEL_TEST_GROUPS']`. The merge + purge call-sites in
58
- `lib/rspec_tracer.rb` (`merge_parallel_tests_reports`,
59
- `merge_parallel_tests_coverage_reports`,
60
- `purge_parallel_tests_reports`) iterated `1..ENV['PARALLEL_TEST_GROUPS']`
61
- to construct per-worker directory names. But parallel_tests sets
62
- `PARALLEL_TEST_GROUPS = num_processes.to_s` for each child, where
63
- `num_processes` is the user-requested process count
64
- (`Parallel.processor_count` by default) — not the actual worker
65
- count. When `num_processes < spawned_worker_count` (e.g. when the
66
- spec-count partition produces more non-empty groups than
67
- `num_processes`, or shared-runner CPU detection drifts mid-run),
68
- peer caches with `TEST_ENV_NUMBER` above the env bound were silently
69
- dropped from the merge (warm-run skip decisions get made against
70
- an under-sampled merged manifest) and left behind by the purge
71
- (visible as straggler `parallel_tests_<N>/` directories under
72
- `rspec_tracer_cache/`). The same gem behaviour was documented on
73
- v1.1.1's `last_process?` fix
74
- ([PR #101](https://github.com/avmnu-sng/rspec-tracer/pull/101)) but
75
- the iteration call-sites kept the buggy bound. Each method now globs
76
- the actual `parallel_tests_*` subdirectories under its base path,
77
- making the merge + purge robust to whatever count parallel_tests
78
- spawned. No cache format change.
370
+ - **Cucumber feature-file integration suite.** Contributor-facing
371
+ only; users see no change. Replaced by RSpec subprocess
372
+ integration specs under `spec/integration/`. The `bundle exec
373
+ rake` legacy entry point is removed; `task` (Taskfile) is the
374
+ canonical dev loop.
375
+ - **Ruby ≤ 3.0 and Rails ≤ 6.x support** (already dropped in 1.1.0;
376
+ re-stated here for clarity at the major boundary).
377
+ - **Windows support** (no CI gate; never actively maintained).
378
+
379
+ ### Deferred to 2.1
380
+
381
+ - **Per-example dependency attribution under Rails
382
+ `config.eager_load = true`.** When `eager_load = true` (Rails
383
+ default for CI tests to mirror prod), all `app/` files load at
384
+ boot and land in the boot-set; the whole-suite invalidator fires
385
+ on any `app/` edit, re-running every example. This is SAFE (never
386
+ misses a dep) but coarser than per-example attribution. The 2.1
387
+ enhancement will install a class-attribution mechanism (working
388
+ name: `track_class_attribution`) using `TracePoint(:class)` at
389
+ boot + `TracePoint(:call)` per example to trim the invalidator
390
+ scope to only examples that touched the changed file's class /
391
+ method surface. Opt-in by default; designed from scratch on the
392
+ user-shape problem (not a resurrection of any 1.x DSL name).
393
+ Today's escape hatches: set `config.eager_load = false` in test
394
+ env for full per-example precision, or use `tracks: { files:
395
+ '...' }` for per-example narrowing on specific groups.
79
396
 
80
397
  ## [1.2.0] - 2026-04-24
81
398