conformance-kit 0.4.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +4 -3
- data/lib/conformance_kit/store.rb +15 -4
- data/lib/conformance_kit/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 18bb6e4722bbdc745b4efcbd1f9b3c3106b6193f235f9657d33e94f41c93b38a
|
|
4
|
+
data.tar.gz: 6b023ed04a3167ab8a43f0689691a4416b7ab5fcb2714d71bb1864d62162c3df
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 16280d264476d1b02f60039e2c03dc821fc3f063e861b90a5b3fceae5e0fd53620d51c538cdd290169a5c348ac178b565b03c1867acdf24d37992ee5152ce061
|
|
7
|
+
data.tar.gz: 46cbb7fcfdf0ed59f99aa8f11b837b5aff4ad502062b66f0a964feb6f9e7529059f61c86451b276529c78b18f3f933e3438f8b916385a05350a510bb7f7d2ae8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- `ConformanceKit::Store.fetch` on a non-main Ractor below Ruby 3.4: threads that race on the first fetch now get the first value stored instead of each keeping its own (the race shrinks from the whole initializer to the publish; a thread switch inside the publish itself remains possible, as no Ractor-local lock exists before 3.4) (found by zoolutions/docs-kit#103, whose copy of the Store had the same `||= [yield]`).
|
|
6
|
+
|
|
3
7
|
## 0.4.0
|
|
4
8
|
|
|
5
9
|
- `main_only:` takes `ancestor:` rules (with optional `ivars:`): framework class state on the gem's own subclasses (ActiveRecord, ActionController, Rails::Engine, ActiveSupport::Concern, ...) in one entry per framework instead of one per ivar per class. Constants are never covered; unused rules are listed as stale; an entry with an unknown key, or an ancestor every module has (`Object`, `Module`, ...), is a config error. `Audit::Finding` gains a `rule` member (the covering rule, or nil).
|
data/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Background, the finalize-at-boot pattern and the settled decisions: [zoolutions/
|
|
|
16
16
|
```ruby
|
|
17
17
|
# Gemfile
|
|
18
18
|
group :development, :test do
|
|
19
|
-
gem "conformance-kit", "~> 0.
|
|
19
|
+
gem "conformance-kit", "~> 0.4", require: false
|
|
20
20
|
gem "rubocop-thread_safety", ">= 0.8", require: false # for config/rubocop.yml
|
|
21
21
|
gem "async", require: false # optional: runs the fiber example
|
|
22
22
|
end
|
|
@@ -182,7 +182,7 @@ Turns on the six `rubocop-thread_safety` cops (`ClassAndModuleAttributes`, `Clas
|
|
|
182
182
|
Conformance runs as **one reusable workflow in this repo**, `.github/workflows/conformance.yml`. Any repo can call it, inside zoolutions or not. A repo opts in with
|
|
183
183
|
|
|
184
184
|
1. `.conformance.yml` (above),
|
|
185
|
-
2. the Gemfile lines (`conformance-kit ~> 0.
|
|
185
|
+
2. the Gemfile lines (`conformance-kit ~> 0.4`, `rubocop-thread_safety >= 0.8`),
|
|
186
186
|
3. `inherit_gem: { conformance-kit: config/rubocop.yml }` in `.rubocop.yml`,
|
|
187
187
|
4. a caller, pinned to a release tag:
|
|
188
188
|
|
|
@@ -199,7 +199,7 @@ permissions:
|
|
|
199
199
|
|
|
200
200
|
jobs:
|
|
201
201
|
conformance:
|
|
202
|
-
uses: zoolutions/conformance-kit/.github/workflows/conformance.yml@v0.
|
|
202
|
+
uses: zoolutions/conformance-kit/.github/workflows/conformance.yml@v0.4.0
|
|
203
203
|
```
|
|
204
204
|
|
|
205
205
|
To make it a merge requirement, add `conformance / Conformance settings` and `conformance / Conformance (Ruby 4.0)` to the required status checks in the repo's branch ruleset. Require both: if the settings job fails, the gate is skipped, and a skipped check does not block a merge. The prefix is the caller's job id (`conformance` above) and the Ruby is `ractor.ruby`, so the names change with either. Leave the probes out: they never fail. A repo or org that only allows selected actions must allow `zoolutions/conformance-kit/.github/workflows/conformance.yml@*`.
|
|
@@ -220,6 +220,7 @@ version: 2
|
|
|
220
220
|
multi-ecosystem-groups:
|
|
221
221
|
conformance-kit:
|
|
222
222
|
schedule: { interval: weekly }
|
|
223
|
+
labels: ["dependencies", "devops"] # your repo's own type + area labels
|
|
223
224
|
updates:
|
|
224
225
|
- package-ecosystem: github-actions
|
|
225
226
|
directory: /
|
|
@@ -8,8 +8,11 @@ module ConformanceKit
|
|
|
8
8
|
# a Mutex, created at load (never lazily, so there is no check-then-set race);
|
|
9
9
|
# it is the kit's one allowlisted main-only state (.conformance.yml). A
|
|
10
10
|
# non-main Ractor on 3.2/3.3 cannot read it, so it keeps its own values in
|
|
11
|
-
# Ractor-local storage instead
|
|
12
|
-
# build a value
|
|
11
|
+
# Ractor-local storage instead. No lock can be shared there, so threads of
|
|
12
|
+
# one Ractor may each build a value; they all return the first one
|
|
13
|
+
# published, except in the rare case of a thread switch inside the publish
|
|
14
|
+
# itself (`Ractor.current[slot] ||= built` is a read and a write), which no
|
|
15
|
+
# Ractor-local primitive before 3.4 can close.
|
|
13
16
|
module Store
|
|
14
17
|
# rubocop:disable ThreadSafety/MutableClassInstanceVariable -- main-only fallback, guarded by @fallback_lock
|
|
15
18
|
@fallback_lock = Mutex.new
|
|
@@ -31,9 +34,17 @@ module ConformanceKit
|
|
|
31
34
|
|
|
32
35
|
def main_ractor? = !defined?(::Ractor) || ::Ractor.current == ::Ractor.main
|
|
33
36
|
|
|
34
|
-
# Boxed, so a nil or false value is cached rather than rebuilt on every
|
|
37
|
+
# Boxed, so a nil or false value is cached rather than rebuilt on every
|
|
38
|
+
# fetch. Built before the check-and-publish, never between them: threads
|
|
39
|
+
# that raced on the build return whichever value was stored first (see
|
|
40
|
+
# the module comment for the switch-inside-the-publish limit).
|
|
35
41
|
def ractor_local(key)
|
|
36
|
-
|
|
42
|
+
slot = :"conformance_kit_store/#{key}"
|
|
43
|
+
stored = ::Ractor.current[slot]
|
|
44
|
+
return stored.first if stored
|
|
45
|
+
|
|
46
|
+
built = [yield]
|
|
47
|
+
(::Ractor.current[slot] ||= built).first
|
|
37
48
|
end
|
|
38
49
|
|
|
39
50
|
public
|