rigortype 0.1.17 → 0.1.19
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/README.md +159 -222
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +24 -1
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +25 -0
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +29 -0
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +54 -0
- data/lib/rigor/analysis/check_rules/rule_walk.rb +213 -0
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +24 -1
- data/lib/rigor/analysis/check_rules.rb +275 -44
- data/lib/rigor/analysis/diagnostic.rb +8 -0
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +581 -0
- data/lib/rigor/analysis/runner/pool_coordinator.rb +569 -0
- data/lib/rigor/analysis/runner/project_pre_passes.rb +321 -0
- data/lib/rigor/analysis/runner/run_snapshots.rb +46 -0
- data/lib/rigor/analysis/runner.rb +207 -1200
- data/lib/rigor/analysis/worker_session.rb +60 -11
- data/lib/rigor/bleeding_edge.rb +123 -0
- data/lib/rigor/cache/descriptor.rb +86 -8
- data/lib/rigor/cache/incremental_snapshot.rb +10 -4
- data/lib/rigor/cache/rbs_cache_producer.rb +5 -1
- data/lib/rigor/cache/rbs_descriptor.rb +2 -1
- data/lib/rigor/cache/store.rb +46 -13
- data/lib/rigor/cli/annotate_command.rb +100 -15
- data/lib/rigor/cli/check_command.rb +708 -0
- data/lib/rigor/cli/ci_detector.rb +94 -0
- data/lib/rigor/cli/diagnostic_formats.rb +345 -0
- data/lib/rigor/cli/plugins_command.rb +2 -4
- data/lib/rigor/cli/plugins_renderer.rb +0 -2
- data/lib/rigor/cli/prism_colorizer.rb +10 -3
- data/lib/rigor/cli/show_bleedingedge_command.rb +114 -0
- data/lib/rigor/cli/trace_command.rb +143 -0
- data/lib/rigor/cli/trace_renderer.rb +310 -0
- data/lib/rigor/cli/triage_command.rb +6 -3
- data/lib/rigor/cli/triage_renderer.rb +15 -1
- data/lib/rigor/cli.rb +21 -612
- data/lib/rigor/configuration/severity_profile.rb +13 -1
- data/lib/rigor/configuration.rb +66 -7
- data/lib/rigor/environment/rbs_loader.rb +78 -68
- data/lib/rigor/environment.rb +1 -1
- data/lib/rigor/inference/acceptance.rb +10 -0
- data/lib/rigor/inference/body_fixpoint.rb +89 -0
- data/lib/rigor/inference/budget_trace.rb +29 -2
- data/lib/rigor/inference/expression_typer.rb +1080 -105
- data/lib/rigor/inference/flow_tracer.rb +180 -0
- data/lib/rigor/inference/macro_block_self_type.rb +11 -12
- data/lib/rigor/inference/method_dispatcher/array_to_h_folding.rb +60 -0
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +54 -14
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +33 -1
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +281 -0
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +71 -0
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +148 -10
- data/lib/rigor/inference/method_dispatcher.rb +187 -55
- data/lib/rigor/inference/method_parameter_binder.rb +56 -2
- data/lib/rigor/inference/multi_target_binder.rb +46 -3
- data/lib/rigor/inference/mutation_widening.rb +142 -0
- data/lib/rigor/inference/narrowing.rb +330 -37
- data/lib/rigor/inference/scope_indexer.rb +770 -39
- data/lib/rigor/inference/statement_evaluator.rb +998 -68
- data/lib/rigor/inference/synthetic_method_scanner.rb +1 -1
- data/lib/rigor/plugin/additional_initializer.rb +61 -38
- data/lib/rigor/plugin/base.rb +517 -120
- data/lib/rigor/plugin/macro/block_as_method.rb +22 -21
- data/lib/rigor/plugin/macro/nested_class_template.rb +9 -7
- data/lib/rigor/plugin/macro.rb +2 -3
- data/lib/rigor/plugin/manifest.rb +4 -24
- data/lib/rigor/plugin/node_rule_walk.rb +192 -0
- data/lib/rigor/plugin/registry.rb +264 -35
- data/lib/rigor/plugin.rb +1 -0
- data/lib/rigor/rbs_extended/conformance_checker.rb +86 -1
- data/lib/rigor/scope/discovery_index.rb +60 -0
- data/lib/rigor/scope.rb +199 -204
- data/lib/rigor/sig_gen/generator.rb +8 -0
- data/lib/rigor/sig_gen/observation_collector.rb +6 -6
- data/lib/rigor/source/literals.rb +14 -0
- data/lib/rigor/triage/catalogue.rb +4 -19
- data/lib/rigor/triage.rb +69 -1
- data/lib/rigor/type/combinator.rb +34 -0
- data/lib/rigor/version.rb +1 -1
- data/lib/rigor.rb +0 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +13 -29
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +13 -32
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +1 -2
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +27 -90
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +13 -30
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +2 -4
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +90 -51
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +3 -3
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +25 -29
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +1 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +1 -2
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +11 -40
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +2 -2
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +1 -1
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +10 -21
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +21 -34
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +11 -18
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +0 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +12 -2
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +1 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +37 -31
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers.rb +3 -23
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +8 -21
- data/plugins/rigor-sinatra/lib/rigor/plugin/sinatra.rb +1 -1
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +8 -29
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +17 -1
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sigil_detector.rb +2 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +108 -36
- data/sig/rigor/analysis/fact_store.rbs +3 -0
- data/sig/rigor/environment.rbs +0 -2
- data/sig/rigor/inference/builtins/method_catalog.rbs +1 -1
- data/sig/rigor/inference.rbs +5 -0
- data/sig/rigor/plugin/base.rbs +6 -4
- data/sig/rigor/plugin/manifest.rbs +1 -2
- data/sig/rigor/scope.rbs +50 -29
- data/sig/rigor/source.rbs +1 -0
- data/sig/rigor/type.rbs +1 -0
- data/sig/rigor.rbs +1 -1
- data/skills/rigor-baseline-reduce/references/01-classify.md +27 -0
- data/skills/rigor-ci-setup/SKILL.md +319 -0
- data/skills/rigor-plugin-author/SKILL.md +6 -4
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +22 -17
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +18 -1
- metadata +21 -3
- data/lib/rigor/cache/rbs_instance_definitions.rb +0 -66
- data/lib/rigor/plugin/macro/external_file.rb +0 -143
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rigor-ci-setup
|
|
3
|
+
description: |
|
|
4
|
+
Wire Rigor type-checking into a project's CI pipeline: run it in its own isolated Ruby-4.0 job and surface diagnostics inline on the pull / merge request via a CI-native output format (SARIF, GitHub Actions annotations, GitLab Code Quality, Checkstyle, JUnit) or through reviewdog. Triggers: "add Rigor to CI", "run rigor in GitHub Actions / GitLab CI", "show Rigor errors on the PR", "set up reviewdog for rigor". NOT for first-time project configuration (use rigor-project-init to create `.rigor.yml` first) or reducing a baseline (use rigor-baseline-reduce).
|
|
5
|
+
license: MPL-2.0
|
|
6
|
+
metadata:
|
|
7
|
+
version: 0.1.0
|
|
8
|
+
homepage: https://github.com/rigortype/rigor
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Rigor CI Setup
|
|
12
|
+
|
|
13
|
+
Wire Rigor into a project's CI so type diagnostics appear **inline on the
|
|
14
|
+
pull / merge request**, not just in the job log. This skill is for **users
|
|
15
|
+
running Rigor on their own project** with the published `rigor` executable —
|
|
16
|
+
Rigor is a tool, not a library, so it is **not** added to the project's
|
|
17
|
+
`Gemfile` (see [ADR-27](https://github.com/rigortype/rigor/blob/main/docs/adr/27-tool-distribution-model.md)).
|
|
18
|
+
|
|
19
|
+
If the project has no `.rigor.yml` yet, run the **rigor-project-init** skill
|
|
20
|
+
first — this skill assumes `rigor check` already runs locally.
|
|
21
|
+
|
|
22
|
+
## The one hard rule: Rigor gets its own job
|
|
23
|
+
|
|
24
|
+
Rigor runs on **Ruby 4.0**. `ruby/setup-ruby` sets the *job's* active Ruby,
|
|
25
|
+
so a job that provisions the project's test Ruby (often 3.x, or a matrix)
|
|
26
|
+
**cannot** also provision Rigor's 4.0 — the second `setup-ruby` clobbers the
|
|
27
|
+
first. Always give Rigor a **separate job** (better: a separate workflow
|
|
28
|
+
file, for its own triggers, concurrency, and status badge). Every template
|
|
29
|
+
below does this.
|
|
30
|
+
|
|
31
|
+
## Phase 0 — Detect the project's CI platform
|
|
32
|
+
|
|
33
|
+
**Inspect the repository first; do not ask what you can detect.** Look for
|
|
34
|
+
these markers from the project root and let them drive the platform choice:
|
|
35
|
+
|
|
36
|
+
| Marker (check existence) | Platform → template |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| `.github/workflows/` directory exists | **GitHub Actions** (Phase 2 GitHub templates) |
|
|
39
|
+
| `.gitlab-ci.yml` exists | **GitLab CI** (Phase 2 GitLab template) |
|
|
40
|
+
| `.circleci/config.yml` exists | **CircleCI** (generic recipe, `junit`) |
|
|
41
|
+
| `Jenkinsfile` exists | **Jenkins** (generic recipe, `junit` / `checkstyle`) |
|
|
42
|
+
| `bitbucket-pipelines.yml` / `azure-pipelines.yml` / `.drone.yml` | that platform (generic recipe) |
|
|
43
|
+
| none of the above | no CI yet — **ask** the user which platform they use |
|
|
44
|
+
|
|
45
|
+
Concretely (the agent has file tools — use them):
|
|
46
|
+
|
|
47
|
+
- List `.github/workflows/*.yml` and `.gitlab-ci.yml`. **If
|
|
48
|
+
`.github/workflows/rigor.yml` already exists, read it** — this is an
|
|
49
|
+
*update*, not a fresh add: preserve the user's triggers / pinning and only
|
|
50
|
+
change the format / steps that are wrong or missing. The same applies to
|
|
51
|
+
an existing `rigor` job inside `.gitlab-ci.yml`.
|
|
52
|
+
- Check for an existing pin: `.github/rigor/Gemfile` (+ lockfile) means the
|
|
53
|
+
project already pins Rigor — keep it (Phase 4).
|
|
54
|
+
- Check for `.rigor-baseline.yml` — if present, the project is in baseline
|
|
55
|
+
adoption mode, which changes the gate advice (Phase 5).
|
|
56
|
+
- Grep existing CI files for `reviewdog` — if already used, prefer the
|
|
57
|
+
reviewdog path (Phase 3) for consistency.
|
|
58
|
+
|
|
59
|
+
**Routing:** exactly one platform marker → use it, state what you found, and
|
|
60
|
+
proceed. Multiple (e.g. both `.github/workflows/` and `.gitlab-ci.yml`) →
|
|
61
|
+
tell the user both were found and ask which to wire (or do both). None → ask.
|
|
62
|
+
|
|
63
|
+
## Phase 1 — Pick the surface (what the reviewer should see)
|
|
64
|
+
|
|
65
|
+
With the platform from Phase 0, pick the matching `--format` (confirm with
|
|
66
|
+
the user only when the platform offers more than one good surface). All
|
|
67
|
+
formats are pure renderings of the same diagnostics; the exit code is
|
|
68
|
+
unchanged (`0` clean, `1` on errors), so the job still gates.
|
|
69
|
+
|
|
70
|
+
| Platform / goal | `--format` | How it surfaces |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| **GitHub — the default** | `github` | `::error file=…::` workflow commands → inline PR-diff annotations. No upload, no permissions, works on **every** repo. |
|
|
73
|
+
| GitHub — Security tab + persistent/deduped alerts | `sarif` | SARIF 2.1.0 via `upload-sarif`. **Requires code scanning** (see note) + `security-events: write`. |
|
|
74
|
+
| GitHub/GitLab/Gerrit/Bitbucket/Gitea — PR/MR **review comments** | `checkstyle` (or `sarif`) piped to **reviewdog** | reviewdog posts comments. See Phase 3. |
|
|
75
|
+
| GitLab — MR Code Quality widget | `gitlab` | Code Quality JSON published as a `codequality` report artifact. |
|
|
76
|
+
| Any test-report CI (CircleCI, Jenkins, …) | `junit` | JUnit XML; every diagnostic is a `testcase` failure. |
|
|
77
|
+
|
|
78
|
+
**The GitHub default is `github` (annotations).** It is the one path that
|
|
79
|
+
works on every repository with zero setup — no upload step, no extra
|
|
80
|
+
permissions, no paid features — so lead with it unless the user asks for
|
|
81
|
+
more. (It is also what PHPStan recommends for GitHub Actions.)
|
|
82
|
+
|
|
83
|
+
In fact, on GitHub Actions and TeamCity Rigor **auto-detects the CI and
|
|
84
|
+
emits the native annotations even without `--format`** (it augments the
|
|
85
|
+
default text output; ADR-51 WD7). So the simplest GitHub setup is the
|
|
86
|
+
minimal workflow — plain `rigor check`, no `--format` — and you still get
|
|
87
|
+
inline annotations. Pass `--format github` only when you want *just* the
|
|
88
|
+
annotation stream (e.g. piping elsewhere); use `--no-ci-detect` to turn the
|
|
89
|
+
augmentation off. Upgrade beyond annotations only when there is a concrete
|
|
90
|
+
reason:
|
|
91
|
+
|
|
92
|
+
- **`sarif`** *only when code scanning is available* — i.e. a **public**
|
|
93
|
+
repo (free) or a **private** repo with **GitHub Advanced Security /
|
|
94
|
+
Code Security** enabled. Without it, `upload-sarif` fails with
|
|
95
|
+
*"GitHub Advanced Security must be enabled for this repository"*. When
|
|
96
|
+
available it adds the Security tab, deduped + persistent alerts, and PR
|
|
97
|
+
alerts. If you cannot tell whether the repo is public or has GHAS, **do
|
|
98
|
+
not default to SARIF** — use `github`, and offer SARIF as an option to a
|
|
99
|
+
public-repo / GHAS user.
|
|
100
|
+
- **reviewdog** when the team wants threaded **review comments** filtered to
|
|
101
|
+
the changed lines (works on private repos; needs a token, Phase 3).
|
|
102
|
+
|
|
103
|
+
GitHub annotation caveat: the run UI shows only a limited number of
|
|
104
|
+
annotations per type, so on a first adoption of a large codebase prefer the
|
|
105
|
+
baseline gate (Phase 5) or SARIF/reviewdog, which page through everything.
|
|
106
|
+
|
|
107
|
+
Other platforms: **Code Quality** (`gitlab`) on GitLab; `junit` on the
|
|
108
|
+
test-report CIs.
|
|
109
|
+
|
|
110
|
+
## Phase 2 — Drop in the workflow
|
|
111
|
+
|
|
112
|
+
Pick **one** template, copy it into the project, and adjust nothing but the
|
|
113
|
+
trigger if asked. Pin the version later (Phase 4).
|
|
114
|
+
|
|
115
|
+
### GitHub — inline annotations (no setup) — the default
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
# .github/workflows/rigor.yml
|
|
119
|
+
name: rigor
|
|
120
|
+
on: [push, pull_request]
|
|
121
|
+
jobs:
|
|
122
|
+
rigor:
|
|
123
|
+
runs-on: ubuntu-latest
|
|
124
|
+
steps:
|
|
125
|
+
- uses: actions/checkout@v4
|
|
126
|
+
- uses: ruby/setup-ruby@v1
|
|
127
|
+
with:
|
|
128
|
+
ruby-version: "4.0"
|
|
129
|
+
- run: gem install rigortype
|
|
130
|
+
- run: rigor check --format github
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### GitHub — SARIF → code scanning
|
|
134
|
+
|
|
135
|
+
Use this **only if code scanning is available** for the repo — a public repo
|
|
136
|
+
(free), or a private repo with GitHub Advanced Security / Code Security.
|
|
137
|
+
Otherwise `upload-sarif` fails; use the annotations template above.
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
# .github/workflows/rigor.yml
|
|
141
|
+
name: rigor
|
|
142
|
+
on: [push, pull_request]
|
|
143
|
+
permissions:
|
|
144
|
+
contents: read
|
|
145
|
+
security-events: write # required by upload-sarif
|
|
146
|
+
jobs:
|
|
147
|
+
rigor:
|
|
148
|
+
runs-on: ubuntu-latest
|
|
149
|
+
steps:
|
|
150
|
+
- uses: actions/checkout@v4
|
|
151
|
+
- uses: ruby/setup-ruby@v1
|
|
152
|
+
with:
|
|
153
|
+
ruby-version: "4.0"
|
|
154
|
+
- run: gem install rigortype
|
|
155
|
+
- run: rigor check --format sarif > rigor.sarif
|
|
156
|
+
continue-on-error: true # so a non-zero exit still uploads
|
|
157
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
158
|
+
if: always()
|
|
159
|
+
with:
|
|
160
|
+
sarif_file: rigor.sarif
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### GitLab — Code Quality widget
|
|
164
|
+
|
|
165
|
+
```yaml
|
|
166
|
+
# .gitlab-ci.yml
|
|
167
|
+
rigor:
|
|
168
|
+
image: ruby:4.0
|
|
169
|
+
script:
|
|
170
|
+
- gem install rigortype
|
|
171
|
+
- rigor check --format gitlab > gl-code-quality-report.json
|
|
172
|
+
artifacts:
|
|
173
|
+
reports:
|
|
174
|
+
codequality: gl-code-quality-report.json
|
|
175
|
+
when: always
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`--format gitlab` emits exactly the
|
|
179
|
+
[Code Quality report format](https://docs.gitlab.com/ci/testing/code_quality/)
|
|
180
|
+
GitLab requires: each finding carries `description`, `check_name`,
|
|
181
|
+
`fingerprint` (a stable SHA-256, so a finding keeps its identity across
|
|
182
|
+
runs), `severity` (`major`/`minor`/`info`), and `location.path` +
|
|
183
|
+
`location.lines.begin`. Paths are repo-relative with no `./` prefix and the
|
|
184
|
+
JSON has no BOM, both of which GitLab demands. For the MR widget to show a
|
|
185
|
+
*diff* of new vs resolved findings, the report must exist on **both** the
|
|
186
|
+
target (default) branch and the MR branch — the job above runs on each
|
|
187
|
+
pipeline, which satisfies that automatically once it has run once on the
|
|
188
|
+
default branch. (Note: a long-standing GitLab display bug can hide
|
|
189
|
+
`check_name`; Rigor already folds the rule id into `description` as
|
|
190
|
+
`… [rule]`, so the identifier shows regardless.)
|
|
191
|
+
|
|
192
|
+
### Other runners (generic)
|
|
193
|
+
|
|
194
|
+
Provision Ruby 4.0, `gem install rigortype`, then
|
|
195
|
+
`rigor check --format junit > junit.xml` (or `checkstyle`, `json`) and
|
|
196
|
+
publish the file with whatever artifact mechanism the platform offers.
|
|
197
|
+
|
|
198
|
+
## Phase 3 — reviewdog (inline review comments)
|
|
199
|
+
|
|
200
|
+
[reviewdog](https://github.com/reviewdog/reviewdog) turns Rigor's output
|
|
201
|
+
into PR/MR review comments. It reads Rigor's `checkstyle` (preferred — light,
|
|
202
|
+
no code scanning) or `sarif`, so the format is the same everywhere — **but
|
|
203
|
+
the `-reporter` is platform-specific, so it must match the platform you
|
|
204
|
+
detected in Phase 0.** Pick the reporter first, then the token/env it needs:
|
|
205
|
+
|
|
206
|
+
| Phase 0 platform | `-reporter` | Token / env | Other needs |
|
|
207
|
+
| --- | --- | --- | --- |
|
|
208
|
+
| GitHub | `github-pr-review` (threaded comments) · `github-pr-check` (Check run) · `github-pr-annotations` | `REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}` | `permissions: pull-requests: write` |
|
|
209
|
+
| GitLab | `gitlab-mr-discussion` (threaded) · `gitlab-mr-commit` | `REVIEWDOG_GITLAB_API_TOKEN` (a project/personal token) + `CI_API_V4_URL` | runs on MR pipelines |
|
|
210
|
+
| Gerrit / Bitbucket / Gitea | `gerrit-change-review` · `bitbucket-code-report` · `gitea-pr-review` | the platform's token var (see reviewdog README) | — |
|
|
211
|
+
|
|
212
|
+
There is **no cross-platform reviewdog reporter** — `github-*` posts only to
|
|
213
|
+
GitHub, `gitlab-*` only to GitLab. So a reviewdog setup is always tied to one
|
|
214
|
+
platform; if a project targets two (e.g. a GitHub mirror of a GitLab repo),
|
|
215
|
+
wire one reviewdog job per platform, or use the platform-native format
|
|
216
|
+
(`sarif` / `gitlab`) on each.
|
|
217
|
+
|
|
218
|
+
Install reviewdog with
|
|
219
|
+
[`reviewdog/action-setup`](https://github.com/reviewdog/action-setup) (GitHub)
|
|
220
|
+
or `go install` / the binary (GitLab and others).
|
|
221
|
+
|
|
222
|
+
**GitHub** (`.github/workflows/rigor.yml`):
|
|
223
|
+
|
|
224
|
+
```yaml
|
|
225
|
+
name: rigor
|
|
226
|
+
on: [pull_request]
|
|
227
|
+
permissions:
|
|
228
|
+
contents: read
|
|
229
|
+
pull-requests: write # required for github-pr-review
|
|
230
|
+
jobs:
|
|
231
|
+
rigor:
|
|
232
|
+
runs-on: ubuntu-latest
|
|
233
|
+
steps:
|
|
234
|
+
- uses: actions/checkout@v4
|
|
235
|
+
- uses: ruby/setup-ruby@v1
|
|
236
|
+
with:
|
|
237
|
+
ruby-version: "4.0"
|
|
238
|
+
- run: gem install rigortype
|
|
239
|
+
- uses: reviewdog/action-setup@v1
|
|
240
|
+
with:
|
|
241
|
+
reviewdog_version: latest
|
|
242
|
+
- run: rigor check --format checkstyle | reviewdog -f=checkstyle -reporter=github-pr-review -fail-level=error
|
|
243
|
+
env:
|
|
244
|
+
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**GitLab** (`.gitlab-ci.yml`) — install the reviewdog binary, then pipe:
|
|
248
|
+
|
|
249
|
+
```yaml
|
|
250
|
+
rigor:
|
|
251
|
+
image: ruby:4.0
|
|
252
|
+
rules:
|
|
253
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
254
|
+
variables:
|
|
255
|
+
REVIEWDOG_GITLAB_API_TOKEN: $RIGOR_REVIEWDOG_TOKEN # a CI/CD variable you set
|
|
256
|
+
script:
|
|
257
|
+
- gem install rigortype
|
|
258
|
+
- wget -O - -q https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s -- -b /usr/local/bin
|
|
259
|
+
- rigor check --format checkstyle | reviewdog -f=checkstyle -reporter=gitlab-mr-discussion -fail-level=error
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Knobs (both platforms):
|
|
263
|
+
|
|
264
|
+
- **`-fail-level`** — `error` fails the step only on Rigor errors (matches
|
|
265
|
+
Rigor's exit code); `any` fails on warnings too; `none` is comment-only.
|
|
266
|
+
Default `error`.
|
|
267
|
+
- **`-filter-mode`** — reviewdog's default `added` comments only on lines
|
|
268
|
+
the PR/MR changed; `nofilter` comments on everything. Keep `added` to adopt
|
|
269
|
+
on an existing codebase (the reviewdog analogue of Rigor's baseline).
|
|
270
|
+
- **`checkstyle` vs `sarif`** — both work (`-f=checkstyle` / `-f=sarif`);
|
|
271
|
+
prefer `checkstyle` (lighter, no code scanning). Use `sarif` only if the
|
|
272
|
+
job *also* uploads to the GitHub Security tab and wants a single format.
|
|
273
|
+
|
|
274
|
+
## Phase 4 — Pin Rigor's version (reproducible CI)
|
|
275
|
+
|
|
276
|
+
The templates install the latest `rigortype` at run time. To pin it:
|
|
277
|
+
|
|
278
|
+
- **CI-only `Gemfile` (recommended, Dependabot-updatable).** Commit
|
|
279
|
+
`.github/rigor/Gemfile` (`source "https://rubygems.org"` +
|
|
280
|
+
`gem "rigortype", "~> 0.1"`) and its lockfile, set
|
|
281
|
+
`env: BUNDLE_GEMFILE: .github/rigor/Gemfile` on the Rigor job, use
|
|
282
|
+
`ruby/setup-ruby` with `bundler-cache: true`, and run `bundle exec rigor
|
|
283
|
+
check …`. Add a Dependabot `bundler` entry scoped to `/.github/rigor`.
|
|
284
|
+
This file is read only by the Rigor job — it never enters the project's
|
|
285
|
+
resolution.
|
|
286
|
+
- **Pinned `gem install`.** `gem install rigortype -v "X.Y.Z"`. Simple, but
|
|
287
|
+
Dependabot can't see it (manual updates).
|
|
288
|
+
|
|
289
|
+
## Phase 5 — Gate behaviour (optional, with the user)
|
|
290
|
+
|
|
291
|
+
- **Baseline adoption.** If the project uses `.rigor-baseline.yml`
|
|
292
|
+
(rigor-project-init / rigor-baseline-reduce), the same `rigor check`
|
|
293
|
+
honours it — CI fails only on *new* diagnostics. Add `--baseline-strict`
|
|
294
|
+
to also fail when the baseline has drifted loose (a CI gate that forces
|
|
295
|
+
regeneration). With reviewdog, `-filter-mode=added` plays the analogous
|
|
296
|
+
role for review comments.
|
|
297
|
+
- **Determinism.** Add `--no-cache` in CI if you want each run independent
|
|
298
|
+
of any persisted `.rigor/cache`.
|
|
299
|
+
|
|
300
|
+
## Verify
|
|
301
|
+
|
|
302
|
+
1. The Rigor job runs on `ruby-version: "4.0"` in its own job (not merged
|
|
303
|
+
into a test matrix job).
|
|
304
|
+
2. On a PR that introduces a type error, the finding appears inline (an
|
|
305
|
+
annotation / review comment / widget entry, per the chosen surface) and
|
|
306
|
+
the job fails (exit 1).
|
|
307
|
+
3. On a clean PR the job passes (exit 0).
|
|
308
|
+
|
|
309
|
+
## References
|
|
310
|
+
|
|
311
|
+
- Manual: `rigor`'s CI chapter — `docs/manual/11-ci.md` in the repo, or
|
|
312
|
+
<https://github.com/rigortype/rigor/blob/main/docs/manual/11-ci.md>. The
|
|
313
|
+
copy-paste template files live at `docs/manual/ci-templates/`.
|
|
314
|
+
- [ADR-51](https://github.com/rigortype/rigor/blob/main/docs/adr/51-ci-diagnostic-output-formats.md)
|
|
315
|
+
— the output-format surface (the severity / identifier contract).
|
|
316
|
+
- [ADR-27](https://github.com/rigortype/rigor/blob/main/docs/adr/27-tool-distribution-model.md)
|
|
317
|
+
— why Rigor installs standalone and runs in its own job.
|
|
318
|
+
- [reviewdog](https://github.com/reviewdog/reviewdog) /
|
|
319
|
+
[action-setup](https://github.com/reviewdog/action-setup).
|
|
@@ -98,9 +98,11 @@ AST walk per file — hands every matching node to the block along with a
|
|
|
98
98
|
`Rigor::Analysis::Diagnostic` (built via the `diagnostic` helper).
|
|
99
99
|
Optionally the plugin also declares `dynamic_return(receivers:)` /
|
|
100
100
|
`type_specifier(methods:)` to *supply* a return type or narrowing facts
|
|
101
|
-
for call sites the core analyzer types as `Dynamic`.
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
for call sites the core analyzer types as `Dynamic`. `#diagnostics_for_file`
|
|
102
|
+
is the file-rule surface for whole-file diagnostics a per-node walk can't
|
|
103
|
+
express. (`flow_contribution_for` was removed pre-1.0 in ADR-52 WD3 —
|
|
104
|
+
defining it now raises `ArgumentError`; use `dynamic_return` /
|
|
105
|
+
`type_specifier`. See Phase 2.)
|
|
104
106
|
|
|
105
107
|
## Phase outline
|
|
106
108
|
|
|
@@ -115,5 +117,5 @@ deprecated escape valves — see Phase 2.)
|
|
|
115
117
|
| Module | Read | Covers |
|
|
116
118
|
| --- | --- | --- |
|
|
117
119
|
| 1 | [`references/01-plan-and-scaffold.md`](references/01-plan-and-scaffold.md) | **Phase 1.** The gem vs project-private packaging split, directory trees for both, gemspec template, project-private path-gem / `RUBYLIB` activation, the `Rigor::Plugin::Base` skeleton, `.rigor.yml` `plugins:` wiring. |
|
|
118
|
-
| 2 | [`references/02-walker-and-types.md`](references/02-walker-and-types.md) | **Phase 2.** The `node_rule` engine-owned AST walk over Prism nodes, the `Base#diagnostic` helper, asking the analyzer for inferred types via `scope.type_of`, two-pass / lexical context (`node_file_context` / `NodeContext`), the optional `dynamic_return` / `type_specifier` return-type hooks (
|
|
120
|
+
| 2 | [`references/02-walker-and-types.md`](references/02-walker-and-types.md) | **Phase 2.** The `node_rule` engine-owned AST walk over Prism nodes, the `Base#diagnostic` helper, asking the analyzer for inferred types via `scope.type_of`, two-pass / lexical context (`node_file_context` / `NodeContext`), the optional `dynamic_return` / `type_specifier` return-type hooks (`flow_contribution_for` was removed pre-1.0 in ADR-52 WD3), calling the target library's pure methods directly rather than reimplementing them (ADR-39: `Plugin::Inflector` over the real `ActiveSupport::Inflector`; `Base.suggest` for did-you-mean), and shipping `sig/*.rbs` so the DSL's types are visible. |
|
|
119
121
|
| 3 | [`references/03-test-and-ship.md`](references/03-test-and-ship.md) | **Phase 3.** Testing a plugin from outside the monorepo — fixture projects driven through `rigor check --format json`, plus pure unit tests of dispatch tables — with RSpec or Minitest. Version pinning against the pre-1.0 contract. README. Publishing to RubyGems or keeping the plugin private. |
|
|
@@ -37,12 +37,15 @@ rows the rule positions with `diagnostic` (the bundled plugins follow
|
|
|
37
37
|
this `Analyzer.violations_for` split, which also makes the logic
|
|
38
38
|
unit-testable without running the whole engine).
|
|
39
39
|
|
|
40
|
-
>
|
|
41
|
-
>
|
|
42
|
-
>
|
|
43
|
-
>
|
|
44
|
-
>
|
|
45
|
-
>
|
|
40
|
+
> `diagnostics_for_file(path:, scope:, root:)` is the **file-rule**
|
|
41
|
+
> surface — use it for a genuinely file-scoped result (a single
|
|
42
|
+
> load-error row, a cross-file aggregation, or a check that needs the
|
|
43
|
+
> whole parsed file at once). It is not deprecated; it is the right tool
|
|
44
|
+
> when a check isn't per-node. Per-node checks use `node_rule` (you don't
|
|
45
|
+
> hand-roll a `def walk` / `compact_child_nodes.each` recursion — the
|
|
46
|
+
> engine owns the walk). Map a violation array to diagnostics with
|
|
47
|
+
> `diagnostics_for(violations, path:, node:)` rather than a hand-rolled
|
|
48
|
+
> `.map { diagnostic(...) }`.
|
|
46
49
|
|
|
47
50
|
### Recognising call sites
|
|
48
51
|
|
|
@@ -59,7 +62,9 @@ re-deriving the `unescaped.to_sym` shape.
|
|
|
59
62
|
validate references): declare `node_file_context { |root, scope| … }`.
|
|
60
63
|
It runs once per file before the walk and its return value is threaded
|
|
61
64
|
to every rule as `file_context`. (A *cross-file* collect belongs in
|
|
62
|
-
`#prepare` + `services.fact_store
|
|
65
|
+
`#prepare` + `services.fact_store.publish`; the consuming plugin reads
|
|
66
|
+
it with `read_fact(plugin_id:, name:)` — the nil-inclusive memo means
|
|
67
|
+
you never hand-roll an `@x_resolved` flag. See
|
|
63
68
|
[`01-plan-and-scaffold.md`](01-plan-and-scaffold.md).)
|
|
64
69
|
- **Where the node sits**: `context` (a `Rigor::Plugin::NodeContext`)
|
|
65
70
|
carries the lexical ancestor chain — `context.enclosing_def`,
|
|
@@ -213,16 +218,16 @@ plugin is confident; a wrong contribution propagates downstream.
|
|
|
213
218
|
`rigor plugins --capabilities` catalogue enumerates — run it to see
|
|
214
219
|
exactly what each loaded plugin contributes.
|
|
215
220
|
|
|
216
|
-
> **The
|
|
217
|
-
>
|
|
218
|
-
> `
|
|
219
|
-
>
|
|
220
|
-
>
|
|
221
|
-
>
|
|
222
|
-
>
|
|
223
|
-
> (ActiveStorage's `Attached::One`
|
|
224
|
-
>
|
|
225
|
-
>
|
|
221
|
+
> **The removed fat hook.** The original `flow_contribution_for(call_node:,
|
|
222
|
+
> scope:)` was **deleted pre-1.0 in ADR-52 WD3** — defining it now raises
|
|
223
|
+
> `ArgumentError` at load time. The two shapes it used to cover are
|
|
224
|
+
> expressed by `dynamic_return`'s callable gates: a **method-gated return
|
|
225
|
+
> type** (an RSpec `let(:x) { … }` binding, a Sorbet `sig`-driven return —
|
|
226
|
+
> keyed on the method, not a fixed receiver class) uses
|
|
227
|
+
> `dynamic_return methods: -> { [...] }` or `file_methods: ->(path) { [...] }`;
|
|
228
|
+
> a **dynamic per-project receiver set** (ActiveStorage's `Attached::One`
|
|
229
|
+
> on discovered model classes) uses `dynamic_return receivers: -> { [...] }`,
|
|
230
|
+
> the callable resolved once after `#prepare`. These return-type surfaces
|
|
226
231
|
> are the most contract-sensitive part of the API — implement one only
|
|
227
232
|
> if the plugin genuinely needs to sharpen call-site types; a
|
|
228
233
|
> diagnostics-only plugin skips them entirely.
|
|
@@ -23,6 +23,8 @@ The JSON shape:
|
|
|
23
23
|
{
|
|
24
24
|
"summary": { "total": 489, "error": 480, "warning": 9, "info": 0 },
|
|
25
25
|
"distribution": [ { "rule": "call.undefined-method", "count": 437 } ],
|
|
26
|
+
"selectors": [ { "receiver": "String", "method": "squish", "count": 31,
|
|
27
|
+
"files": 12, "rules": { "call.undefined-method": 31 } } ],
|
|
26
28
|
"hotspots": [ { "file": "app/models/status.rb", "count": 42,
|
|
27
29
|
"by_rule": { "call.undefined-method": 40 } } ],
|
|
28
30
|
"hints": [
|
|
@@ -32,11 +34,26 @@ The JSON shape:
|
|
|
32
34
|
}
|
|
33
35
|
```
|
|
34
36
|
|
|
35
|
-
Use the
|
|
37
|
+
Use the sections like this:
|
|
36
38
|
|
|
37
39
|
- **`summary` / `distribution`** — the scale, and which rules
|
|
38
40
|
dominate. Decides nothing on its own; feeds the mode sanity-check
|
|
39
41
|
(>100 errors → acknowledge mode is the right default).
|
|
42
|
+
- **`selectors`** — the by-(class, method) axis. Each row is a
|
|
43
|
+
dispatch target (`String#squish`) with its `count`, the `files` it
|
|
44
|
+
spans, and the `rules` that fired. Read it with `jq` to find the
|
|
45
|
+
*shape* of the problem before touching code — these are structured
|
|
46
|
+
fields, never parse the `message`:
|
|
47
|
+
```sh
|
|
48
|
+
# the 10 methods responsible for the most diagnostics
|
|
49
|
+
rigor triage --format json | jq -r '.selectors[:10][] | "\(.count)\t\(.receiver)#\(.method)"'
|
|
50
|
+
# methods missing on the same receiver across many files = one config
|
|
51
|
+
# gap (an unloaded core-ext / unseen monkey-patch), not many bugs
|
|
52
|
+
rigor triage --format json | jq '.selectors[] | select(.files >= 5)'
|
|
53
|
+
```
|
|
54
|
+
A high `count` + high `files` selector is almost always a *systemic
|
|
55
|
+
cause* (a plugin / `pre_eval:` fix clears it in bulk); a low `count`
|
|
56
|
+
selector is a candidate genuine bug.
|
|
40
57
|
- **`hotspots`** — files carrying the most diagnostics. A single hot
|
|
41
58
|
file is often one structural cause, not many bugs.
|
|
42
59
|
- **`hints`** — the heuristic catalogue. Each hint names a *likely
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rigortype
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.19
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rigor contributors
|
|
@@ -289,6 +289,8 @@ files:
|
|
|
289
289
|
- lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb
|
|
290
290
|
- lib/rigor/analysis/check_rules/dead_assignment_collector.rb
|
|
291
291
|
- lib/rigor/analysis/check_rules/ivar_write_collector.rb
|
|
292
|
+
- lib/rigor/analysis/check_rules/main_pass_collector.rb
|
|
293
|
+
- lib/rigor/analysis/check_rules/rule_walk.rb
|
|
292
294
|
- lib/rigor/analysis/check_rules/self_closedness_scanner.rb
|
|
293
295
|
- lib/rigor/analysis/check_rules/unreachable_clause_collector.rb
|
|
294
296
|
- lib/rigor/analysis/dependency_recorder.rb
|
|
@@ -309,10 +311,15 @@ files:
|
|
|
309
311
|
- lib/rigor/analysis/rule_catalog.rb
|
|
310
312
|
- lib/rigor/analysis/run_stats.rb
|
|
311
313
|
- lib/rigor/analysis/runner.rb
|
|
314
|
+
- lib/rigor/analysis/runner/diagnostic_aggregator.rb
|
|
315
|
+
- lib/rigor/analysis/runner/pool_coordinator.rb
|
|
316
|
+
- lib/rigor/analysis/runner/project_pre_passes.rb
|
|
317
|
+
- lib/rigor/analysis/runner/run_snapshots.rb
|
|
312
318
|
- lib/rigor/analysis/self_call_resolution_recorder.rb
|
|
313
319
|
- lib/rigor/analysis/worker_session.rb
|
|
314
320
|
- lib/rigor/ast.rb
|
|
315
321
|
- lib/rigor/ast/type_node.rb
|
|
322
|
+
- lib/rigor/bleeding_edge.rb
|
|
316
323
|
- lib/rigor/builtins/hkt_builtins.rb
|
|
317
324
|
- lib/rigor/builtins/imported_refinements.rb
|
|
318
325
|
- lib/rigor/builtins/regex_refinement.rb
|
|
@@ -326,16 +333,18 @@ files:
|
|
|
326
333
|
- lib/rigor/cache/rbs_descriptor.rb
|
|
327
334
|
- lib/rigor/cache/rbs_environment.rb
|
|
328
335
|
- lib/rigor/cache/rbs_environment_marshal_patch.rb
|
|
329
|
-
- lib/rigor/cache/rbs_instance_definitions.rb
|
|
330
336
|
- lib/rigor/cache/rbs_known_class_names.rb
|
|
331
337
|
- lib/rigor/cache/store.rb
|
|
332
338
|
- lib/rigor/cli.rb
|
|
333
339
|
- lib/rigor/cli/annotate_command.rb
|
|
334
340
|
- lib/rigor/cli/baseline_command.rb
|
|
341
|
+
- lib/rigor/cli/check_command.rb
|
|
342
|
+
- lib/rigor/cli/ci_detector.rb
|
|
335
343
|
- lib/rigor/cli/command.rb
|
|
336
344
|
- lib/rigor/cli/coverage_command.rb
|
|
337
345
|
- lib/rigor/cli/coverage_renderer.rb
|
|
338
346
|
- lib/rigor/cli/coverage_report.rb
|
|
347
|
+
- lib/rigor/cli/diagnostic_formats.rb
|
|
339
348
|
- lib/rigor/cli/diff_command.rb
|
|
340
349
|
- lib/rigor/cli/explain_command.rb
|
|
341
350
|
- lib/rigor/cli/lsp_command.rb
|
|
@@ -346,8 +355,11 @@ files:
|
|
|
346
355
|
- lib/rigor/cli/plugins_renderer.rb
|
|
347
356
|
- lib/rigor/cli/prism_colorizer.rb
|
|
348
357
|
- lib/rigor/cli/renderable.rb
|
|
358
|
+
- lib/rigor/cli/show_bleedingedge_command.rb
|
|
349
359
|
- lib/rigor/cli/sig_gen_command.rb
|
|
350
360
|
- lib/rigor/cli/skill_command.rb
|
|
361
|
+
- lib/rigor/cli/trace_command.rb
|
|
362
|
+
- lib/rigor/cli/trace_renderer.rb
|
|
351
363
|
- lib/rigor/cli/triage_command.rb
|
|
352
364
|
- lib/rigor/cli/triage_renderer.rb
|
|
353
365
|
- lib/rigor/cli/type_of_command.rb
|
|
@@ -377,6 +389,7 @@ files:
|
|
|
377
389
|
- lib/rigor/flow_contribution/merger.rb
|
|
378
390
|
- lib/rigor/inference/acceptance.rb
|
|
379
391
|
- lib/rigor/inference/block_parameter_binder.rb
|
|
392
|
+
- lib/rigor/inference/body_fixpoint.rb
|
|
380
393
|
- lib/rigor/inference/budget_trace.rb
|
|
381
394
|
- lib/rigor/inference/builtins/array_catalog.rb
|
|
382
395
|
- lib/rigor/inference/builtins/comparable_catalog.rb
|
|
@@ -404,6 +417,7 @@ files:
|
|
|
404
417
|
- lib/rigor/inference/expression_typer.rb
|
|
405
418
|
- lib/rigor/inference/fallback.rb
|
|
406
419
|
- lib/rigor/inference/fallback_tracer.rb
|
|
420
|
+
- lib/rigor/inference/flow_tracer.rb
|
|
407
421
|
- lib/rigor/inference/hkt_body.rb
|
|
408
422
|
- lib/rigor/inference/hkt_body_parser.rb
|
|
409
423
|
- lib/rigor/inference/hkt_reducer.rb
|
|
@@ -411,6 +425,7 @@ files:
|
|
|
411
425
|
- lib/rigor/inference/indexed_narrowing.rb
|
|
412
426
|
- lib/rigor/inference/macro_block_self_type.rb
|
|
413
427
|
- lib/rigor/inference/method_dispatcher.rb
|
|
428
|
+
- lib/rigor/inference/method_dispatcher/array_to_h_folding.rb
|
|
414
429
|
- lib/rigor/inference/method_dispatcher/block_folding.rb
|
|
415
430
|
- lib/rigor/inference/method_dispatcher/call_context.rb
|
|
416
431
|
- lib/rigor/inference/method_dispatcher/cgi_folding.rb
|
|
@@ -425,6 +440,7 @@ files:
|
|
|
425
440
|
- lib/rigor/inference/method_dispatcher/overload_selector.rb
|
|
426
441
|
- lib/rigor/inference/method_dispatcher/rbs_dispatch.rb
|
|
427
442
|
- lib/rigor/inference/method_dispatcher/receiver_affinity.rb
|
|
443
|
+
- lib/rigor/inference/method_dispatcher/reduce_folding.rb
|
|
428
444
|
- lib/rigor/inference/method_dispatcher/regexp_folding.rb
|
|
429
445
|
- lib/rigor/inference/method_dispatcher/set_folding.rb
|
|
430
446
|
- lib/rigor/inference/method_dispatcher/shape_dispatch.rb
|
|
@@ -479,12 +495,12 @@ files:
|
|
|
479
495
|
- lib/rigor/plugin/loader.rb
|
|
480
496
|
- lib/rigor/plugin/macro.rb
|
|
481
497
|
- lib/rigor/plugin/macro/block_as_method.rb
|
|
482
|
-
- lib/rigor/plugin/macro/external_file.rb
|
|
483
498
|
- lib/rigor/plugin/macro/heredoc_template.rb
|
|
484
499
|
- lib/rigor/plugin/macro/nested_class_template.rb
|
|
485
500
|
- lib/rigor/plugin/macro/trait_registry.rb
|
|
486
501
|
- lib/rigor/plugin/manifest.rb
|
|
487
502
|
- lib/rigor/plugin/node_context.rb
|
|
503
|
+
- lib/rigor/plugin/node_rule_walk.rb
|
|
488
504
|
- lib/rigor/plugin/protocol_contract.rb
|
|
489
505
|
- lib/rigor/plugin/registry.rb
|
|
490
506
|
- lib/rigor/plugin/services.rb
|
|
@@ -497,6 +513,7 @@ files:
|
|
|
497
513
|
- lib/rigor/rbs_extended/reporter.rb
|
|
498
514
|
- lib/rigor/reflection.rb
|
|
499
515
|
- lib/rigor/scope.rb
|
|
516
|
+
- lib/rigor/scope/discovery_index.rb
|
|
500
517
|
- lib/rigor/sig_gen.rb
|
|
501
518
|
- lib/rigor/sig_gen/classification.rb
|
|
502
519
|
- lib/rigor/sig_gen/generator.rb
|
|
@@ -715,6 +732,7 @@ files:
|
|
|
715
732
|
- skills/rigor-baseline-reduce/SKILL.md
|
|
716
733
|
- skills/rigor-baseline-reduce/references/01-classify.md
|
|
717
734
|
- skills/rigor-baseline-reduce/references/02-fix-or-suppress.md
|
|
735
|
+
- skills/rigor-ci-setup/SKILL.md
|
|
718
736
|
- skills/rigor-plugin-author/SKILL.md
|
|
719
737
|
- skills/rigor-plugin-author/references/01-plan-and-scaffold.md
|
|
720
738
|
- skills/rigor-plugin-author/references/02-walker-and-types.md
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "rbs_descriptor"
|
|
4
|
-
require_relative "rbs_cache_producer"
|
|
5
|
-
require_relative "rbs_environment_marshal_patch"
|
|
6
|
-
|
|
7
|
-
module Rigor
|
|
8
|
-
module Cache
|
|
9
|
-
# Cache producer that materialises the full
|
|
10
|
-
# `Hash<String, RBS::Definition>` for instance-side class
|
|
11
|
-
# definitions in the RBS environment, in a single cache
|
|
12
|
-
# entry. Mirrors the {RbsConstantTable} layout.
|
|
13
|
-
#
|
|
14
|
-
# ADR-7 § "Slice 6-D" carry-over and dogfooding feedback:
|
|
15
|
-
# the earlier per-class cache layout (one entry per class,
|
|
16
|
-
# ~1300 files) made warm runs *slower* than `--no-cache`
|
|
17
|
-
# because each `instance_definition` call paid disk-open +
|
|
18
|
-
# `Marshal.load` overhead and the in-memory
|
|
19
|
-
# `RBS::DefinitionBuilder.build_instance` was actually fast
|
|
20
|
-
# given a cached `RBS::Environment`. The single-blob layout
|
|
21
|
-
# collapses that to one `Marshal.load` per process; warm runs
|
|
22
|
-
# now match `--no-cache` timing while preserving the
|
|
23
|
-
# cross-process invalidation story.
|
|
24
|
-
#
|
|
25
|
-
# Marshal-cleanness of `RBS::Definition` is enabled by the
|
|
26
|
-
# v0.0.9 C2 `RBS::Location` patch.
|
|
27
|
-
class RbsInstanceDefinitions < RbsCacheProducer
|
|
28
|
-
PRODUCER_ID = "rbs.instance_definitions"
|
|
29
|
-
|
|
30
|
-
# @param loader [Rigor::Environment::RbsLoader]
|
|
31
|
-
# @param store [Rigor::Cache::Store]
|
|
32
|
-
# @return [Hash{String => RBS::Definition}]
|
|
33
|
-
def self.compute(loader)
|
|
34
|
-
table = {}
|
|
35
|
-
loader.each_known_class_name do |name|
|
|
36
|
-
definition = loader.uncached_instance_definition(name)
|
|
37
|
-
table[name] = definition if definition
|
|
38
|
-
end
|
|
39
|
-
table
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
private_class_method :compute
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Singleton-side equivalent of {RbsInstanceDefinitions}.
|
|
46
|
-
# Caches the full `Hash<String, RBS::Definition>` for the
|
|
47
|
-
# singleton class of every RBS-known class.
|
|
48
|
-
class RbsSingletonDefinitions < RbsCacheProducer
|
|
49
|
-
PRODUCER_ID = "rbs.singleton_definitions"
|
|
50
|
-
|
|
51
|
-
# @param loader [Rigor::Environment::RbsLoader]
|
|
52
|
-
# @param store [Rigor::Cache::Store]
|
|
53
|
-
# @return [Hash{String => RBS::Definition}]
|
|
54
|
-
def self.compute(loader)
|
|
55
|
-
table = {}
|
|
56
|
-
loader.each_known_class_name do |name|
|
|
57
|
-
definition = loader.uncached_singleton_definition(name)
|
|
58
|
-
table[name] = definition if definition
|
|
59
|
-
end
|
|
60
|
-
table
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
private_class_method :compute
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|