rigortype 0.2.9 → 0.3.0
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 +2 -2
- data/docs/handbook/03-narrowing.md +2 -1
- data/docs/handbook/04-tuples-and-shapes.md +7 -3
- data/docs/handbook/06-classes.md +18 -9
- data/docs/handbook/08-understanding-errors.md +1 -0
- data/docs/handbook/11-sig-gen.md +11 -1
- data/docs/handbook/appendix-mypy.md +4 -3
- data/docs/install.md +14 -6
- data/docs/manual/01-installation.md +98 -4
- data/docs/manual/02-cli-reference.md +49 -12
- data/docs/manual/03-configuration.md +34 -2
- data/docs/manual/04-diagnostics.md +23 -0
- data/docs/manual/07-plugins.md +4 -4
- data/docs/manual/09-editor-integration.md +4 -4
- data/docs/manual/11-ci.md +51 -0
- data/docs/manual/12-caching.md +65 -0
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +9 -1
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +5 -3
- data/lib/rigor/analysis/check_rules/duplicate_hash_key_collector.rb +128 -0
- data/lib/rigor/analysis/check_rules/inferred_param_guard.rb +60 -0
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +3 -2
- data/lib/rigor/analysis/check_rules/return_in_ensure_collector.rb +117 -0
- data/lib/rigor/analysis/check_rules/rule_ids.rb +125 -0
- data/lib/rigor/analysis/check_rules/rule_walk.rb +2 -1
- data/lib/rigor/analysis/check_rules/self_closedness_scanner.rb +2 -1
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +283 -0
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +10 -1
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +93 -0
- data/lib/rigor/analysis/check_rules.rb +557 -95
- data/lib/rigor/analysis/dependency_recorder.rb +93 -9
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +2 -1
- data/lib/rigor/analysis/incremental_session.rb +456 -51
- data/lib/rigor/analysis/path_expansion.rb +42 -0
- data/lib/rigor/analysis/plugin_fact_fingerprint.rb +188 -0
- data/lib/rigor/analysis/rule_catalog.rb +226 -1
- data/lib/rigor/analysis/run_cache_key.rb +68 -0
- data/lib/rigor/analysis/run_cache_probe.rb +72 -0
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +181 -28
- data/lib/rigor/analysis/runner/pool_coordinator.rb +77 -15
- data/lib/rigor/analysis/runner/project_pre_passes.rb +95 -49
- data/lib/rigor/analysis/runner/run_snapshots.rb +9 -2
- data/lib/rigor/analysis/runner.rb +343 -68
- data/lib/rigor/analysis/severity_stamp.rb +43 -0
- data/lib/rigor/analysis/worker_session.rb +30 -2
- data/lib/rigor/bleeding_edge.rb +37 -8
- data/lib/rigor/builtins/regex_refinement.rb +36 -1
- data/lib/rigor/cache/descriptor.rb +88 -28
- data/lib/rigor/cache/file_digest.rb +158 -0
- data/lib/rigor/cache/incremental_snapshot.rb +41 -5
- data/lib/rigor/cache/rbs_descriptor.rb +56 -10
- data/lib/rigor/cache/store.rb +33 -3
- data/lib/rigor/ci_detector.rb +90 -0
- data/lib/rigor/cli/annotate_command.rb +15 -9
- data/lib/rigor/cli/baseline_command.rb +4 -1
- data/lib/rigor/cli/check_command.rb +212 -27
- data/lib/rigor/cli/coverage_command.rb +6 -1
- data/lib/rigor/cli/docs_command.rb +0 -30
- data/lib/rigor/cli/doctor_command.rb +163 -23
- data/lib/rigor/cli/lsp_command.rb +5 -0
- data/lib/rigor/cli/mcp_command.rb +5 -0
- data/lib/rigor/cli/plugins_command.rb +36 -6
- data/lib/rigor/cli/plugins_renderer.rb +44 -12
- data/lib/rigor/cli/probe_environment.rb +85 -0
- data/lib/rigor/cli/sig_gen_command.rb +36 -9
- data/lib/rigor/cli/skill_command.rb +1 -32
- data/lib/rigor/cli/trace_command.rb +5 -6
- data/lib/rigor/cli/type_of_command.rb +9 -8
- data/lib/rigor/cli/type_scan_command.rb +8 -8
- data/lib/rigor/cli.rb +15 -4
- data/lib/rigor/config_audit.rb +48 -2
- data/lib/rigor/configuration/severity_profile.rb +31 -0
- data/lib/rigor/configuration.rb +156 -8
- data/lib/rigor/environment/default_libraries.rb +35 -0
- data/lib/rigor/environment/rbs_loader.rb +164 -5
- data/lib/rigor/environment.rb +19 -27
- data/lib/rigor/inference/budget_trace.rb +77 -2
- data/lib/rigor/inference/closure_escape_analyzer.rb +14 -1
- data/lib/rigor/inference/def_handle.rb +23 -0
- data/lib/rigor/inference/def_node_resolver.rb +90 -0
- data/lib/rigor/inference/def_return_typer.rb +2 -1
- data/lib/rigor/inference/expression_typer.rb +361 -113
- data/lib/rigor/inference/method_dispatcher/data_folding.rb +30 -5
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +200 -0
- data/lib/rigor/inference/method_dispatcher/literal_string_folding.rb +22 -16
- data/lib/rigor/inference/method_dispatcher/member_shape_projection.rb +33 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +11 -0
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +42 -9
- data/lib/rigor/inference/method_dispatcher/receiver_affinity.rb +5 -0
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +28 -35
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +40 -8
- data/lib/rigor/inference/method_dispatcher.rb +57 -1
- data/lib/rigor/inference/mutation_widening.rb +42 -8
- data/lib/rigor/inference/narrowing.rb +127 -17
- data/lib/rigor/inference/parameter_inference_collector.rb +15 -0
- data/lib/rigor/inference/project_patched_scanner.rb +2 -1
- data/lib/rigor/inference/rbs_type_translator.rb +8 -1
- data/lib/rigor/inference/scope_indexer.rb +451 -36
- data/lib/rigor/inference/statement_evaluator.rb +64 -15
- data/lib/rigor/inference/struct_fold_safety.rb +48 -11
- data/lib/rigor/inference/synthetic_method_scanner.rb +15 -14
- data/lib/rigor/inference/void_origin.rb +25 -0
- data/lib/rigor/inference/void_tail_summary.rb +220 -0
- data/lib/rigor/language_server/completion_provider.rb +2 -1
- data/lib/rigor/language_server/document_symbol_provider.rb +2 -1
- data/lib/rigor/language_server/folding_range_provider.rb +2 -1
- data/lib/rigor/language_server/selection_range_provider.rb +2 -1
- data/lib/rigor/language_server/signature_help_provider.rb +2 -1
- data/lib/rigor/plugin/base.rb +9 -22
- data/lib/rigor/plugin/inflector.rb +12 -3
- data/lib/rigor/plugin/io_boundary.rb +5 -1
- data/lib/rigor/plugin/isolation.rb +81 -11
- data/lib/rigor/plugin/load_error.rb +10 -1
- data/lib/rigor/plugin/loader.rb +96 -14
- data/lib/rigor/plugin/node_rule_walk.rb +5 -3
- data/lib/rigor/plugin/registry.rb +32 -23
- data/lib/rigor/plugin.rb +26 -0
- data/lib/rigor/protection/mutator.rb +3 -2
- data/lib/rigor/reflection.rb +64 -0
- data/lib/rigor/runtime/jit.rb +128 -0
- data/lib/rigor/scope/discovery_index.rb +12 -2
- data/lib/rigor/scope.rb +122 -28
- data/lib/rigor/sig_gen/classification.rb +5 -1
- data/lib/rigor/sig_gen/generator.rb +38 -6
- data/lib/rigor/sig_gen/observation_collector.rb +4 -3
- data/lib/rigor/sig_gen/rbs_validity.rb +44 -0
- data/lib/rigor/sig_gen/renderer.rb +10 -0
- data/lib/rigor/sig_gen/write_result.rb +9 -4
- data/lib/rigor/sig_gen/writer.rb +24 -2
- data/lib/rigor/source/node_children.rb +116 -0
- data/lib/rigor/source/node_locator.rb +3 -1
- data/lib/rigor/source/node_walker.rb +4 -2
- data/lib/rigor/source.rb +1 -0
- data/lib/rigor/type/difference.rb +28 -24
- data/lib/rigor/type/hash_shape.rb +34 -10
- data/lib/rigor/version.rb +1 -1
- data/lib/rigortype.rb +24 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +4 -2
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +6 -4
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb +5 -3
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +4 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +3 -1
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +4 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +4 -2
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb +3 -1
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +4 -2
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +38 -6
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +3 -1
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +3 -1
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +10 -0
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest.rb +11 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +3 -1
- data/plugins/rigor-rails/lib/rigor-rails.rb +11 -12
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/grape_api_discoverer.rb +3 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +3 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +7 -5
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +83 -9
- data/plugins/rigor-rbs-inline/lib/rigor-rbs-inline.rb +9 -5
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/let_scope_index.rb +3 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/scope_walker.rb +3 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +11 -0
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails/http_status_codes.rb +4 -1
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb +4 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +3 -1
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +74 -14
- data/sig/prism_node_children.rbs +9 -0
- data/sig/rigor/inference.rbs +7 -0
- data/sig/rigor/plugin/base.rbs +2 -3
- data/sig/rigor/reflection.rbs +1 -0
- data/sig/rigor/scope.rbs +12 -1
- data/skills/rigor-ci-setup/SKILL.md +10 -0
- data/skills/rigor-editor-setup/SKILL.md +11 -0
- data/skills/rigor-next-steps/SKILL.md +23 -2
- data/skills/rigor-plugin-author/SKILL.md +3 -3
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +2 -2
- data/skills/rigor-plugin-review/SKILL.md +2 -2
- data/skills/rigor-plugin-review/references/01-best-practices-checklist.md +5 -4
- data/skills/rigor-project-init/SKILL.md +29 -3
- data/skills/rigor-project-init/references/01-detect.md +1 -1
- data/skills/rigor-project-init/references/02-configure.md +39 -5
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +20 -0
- data/skills/rigor-project-init/references/05-jit-performance.md +125 -0
- metadata +42 -24
- data/lib/rigor/cli/ci_detector.rb +0 -89
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Reference 05 — JIT and run speed (YJIT / ZJIT)
|
|
2
|
+
|
|
3
|
+
Operational, not part of onboarding proper: how Rigor uses a Ruby JIT to
|
|
4
|
+
speed up analysis, how to tell whether it is active in your install, and the
|
|
5
|
+
trade-off (and break-even point) if you want to override the default. Read
|
|
6
|
+
this when a project is large enough that `rigor check` wall time matters —
|
|
7
|
+
Rails monorepos especially. On a small project you can ignore it entirely:
|
|
8
|
+
Rigor already does the right thing with no configuration.
|
|
9
|
+
|
|
10
|
+
## TL;DR
|
|
11
|
+
|
|
12
|
+
- **You usually do nothing.** Rigor enables YJIT automatically once a run has
|
|
13
|
+
been going long enough to be worth it, and leaves it off for short runs
|
|
14
|
+
where it would only add warm-up cost. This is on by default.
|
|
15
|
+
- **Break-even is ~5 seconds.** A JIT pays for its warm-up only on longer
|
|
16
|
+
runs; below it, JIT-on is *slower*. Rigor's 5-second deadline is set at
|
|
17
|
+
that crossover.
|
|
18
|
+
- **YJIT, not ZJIT.** Ruby 4.0 ships both JITs, but YJIT is faster for Rigor's
|
|
19
|
+
workload — measurably so on every run large enough for a JIT to help. Rigor
|
|
20
|
+
uses YJIT; there is no reason to force ZJIT.
|
|
21
|
+
|
|
22
|
+
## How Rigor uses a JIT
|
|
23
|
+
|
|
24
|
+
`rigor check` and `rigor coverage` arm a background timer at the start of a
|
|
25
|
+
run. If the run is still going after ~5 seconds, YJIT is switched on for the
|
|
26
|
+
remainder; a run that finishes first never pays any JIT cost. So:
|
|
27
|
+
|
|
28
|
+
- A quick check (a small project, or a warm cache hit) runs on the plain
|
|
29
|
+
interpreter — no warm-up penalty.
|
|
30
|
+
- A long cold analysis of a large project gets YJIT for its dominant tail,
|
|
31
|
+
where the speed-up more than repays the warm-up.
|
|
32
|
+
|
|
33
|
+
Diagnostics and their counts are identical whether or not the JIT engages —
|
|
34
|
+
a JIT changes wall time only, never results.
|
|
35
|
+
|
|
36
|
+
The long-running servers `rigor lsp` and `rigor mcp` turn YJIT on at start
|
|
37
|
+
instead, since they always run long.
|
|
38
|
+
|
|
39
|
+
## Is a JIT available in my install?
|
|
40
|
+
|
|
41
|
+
The deferred-YJIT feature only helps if the Ruby your `rigor` runs on was
|
|
42
|
+
built with YJIT support. Rigor is installed standalone (see the manual's
|
|
43
|
+
Installing Rigor chapter: `rigor docs manual/01-installation`), so this is a
|
|
44
|
+
property of *that* Ruby, which may differ from your project's Ruby.
|
|
45
|
+
|
|
46
|
+
Check the Ruby that runs `rigor`:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
ruby --yjit -e 'require "rbconfig"; puts "YJIT: #{RbConfig::CONFIG["YJIT_SUPPORT"]}"; puts "ZJIT: #{RbConfig::CONFIG["ZJIT_SUPPORT"]}"'
|
|
50
|
+
# YJIT: yes → the deferred-YJIT engages automatically on long runs
|
|
51
|
+
# YJIT: no → the feature is a silent no-op; runs use the interpreter
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- Most prebuilt CRuby 3.3+ (mise / rbenv / asdf, the recommended install
|
|
55
|
+
channels) ship with YJIT built in but **not** ZJIT — a prebuilt
|
|
56
|
+
mise Ruby 4.0, for example, reports `YJIT: yes` / `ZJIT: no`, because
|
|
57
|
+
ZJIT needs `rustc` at build time and the prebuilt binary omits it. That
|
|
58
|
+
is exactly the configuration Rigor wants: YJIT is the faster JIT for
|
|
59
|
+
Rigor (see the YJIT-vs-ZJIT section below), so a missing ZJIT costs you
|
|
60
|
+
nothing.
|
|
61
|
+
- The Nix flake package of Rigor bundles a Ruby with **both** JITs; that
|
|
62
|
+
is the only common install where `ZJIT: yes` — and Rigor still uses
|
|
63
|
+
YJIT there.
|
|
64
|
+
- A YJIT-less Ruby is not an error — Rigor just runs interpreted, correctly.
|
|
65
|
+
|
|
66
|
+
## Overriding the default
|
|
67
|
+
|
|
68
|
+
Three environment variables, documented in the CLI reference's
|
|
69
|
+
"Environment variables" section (`rigor docs manual/02-cli-reference`):
|
|
70
|
+
|
|
71
|
+
| Want | Do |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| Force YJIT on for the **whole** run (including the first 5 s) | `RUBYOPT="--yjit" rigor check …` |
|
|
74
|
+
| Turn Rigor's JIT off entirely | `RIGOR_DISABLE_YJIT=1 rigor check …` |
|
|
75
|
+
| Change the deadline (advanced) | `RIGOR_YJIT_DEADLINE=<seconds> rigor check …` |
|
|
76
|
+
|
|
77
|
+
When would you override?
|
|
78
|
+
|
|
79
|
+
- **Force-on** helps only if *every* run you care about is long (a big
|
|
80
|
+
monorepo in CI where even the fast path is > 5 s). On mixed workloads the
|
|
81
|
+
default deadline is better — it protects your quick local re-checks.
|
|
82
|
+
- **Off** is the escape hatch if a JIT ever misbehaves on your platform, or to
|
|
83
|
+
get a clean interpreter baseline when measuring.
|
|
84
|
+
|
|
85
|
+
## Why the ~5-second break-even (the trade-off)
|
|
86
|
+
|
|
87
|
+
A JIT compiles hot code to machine code, which costs time up front and repays
|
|
88
|
+
it over the rest of the run. On a short run the compilation never amortizes,
|
|
89
|
+
so JIT-on loses. Measured cold `rigor check`, by project size:
|
|
90
|
+
|
|
91
|
+
| run size | interpreter | YJIT | effect |
|
|
92
|
+
| --- | --- | --- | --- |
|
|
93
|
+
| ~1.6 s (small lib) | baseline | **+67 %** | JIT-on loses badly |
|
|
94
|
+
| ~4 s (medium lib) | baseline | ~break-even | a wash |
|
|
95
|
+
| ~8 s | baseline | **−13 %** | JIT-on wins |
|
|
96
|
+
| ~19 s (Rails monorepo) | baseline | **−20 %** | wins more |
|
|
97
|
+
| ~17 s (large Rails app) | baseline | **−28 %** | biggest win |
|
|
98
|
+
|
|
99
|
+
The deadline parks the enable point just past the loss zone: runs that finish
|
|
100
|
+
before ~5 s never pay warm-up; longer runs collect the win on their tail.
|
|
101
|
+
|
|
102
|
+
## YJIT vs ZJIT (Ruby 4.0)
|
|
103
|
+
|
|
104
|
+
Ruby 4.0 ships a second JIT, **ZJIT** (a newer method-based JIT;
|
|
105
|
+
[upstream docs](https://docs.ruby-lang.org/en/master/jit/zjit_md.html)). It
|
|
106
|
+
is real and correctness-safe on Rigor (identical diagnostics), but **slower
|
|
107
|
+
than YJIT for Rigor's workload** at Ruby 4.0. Measured cold, on the runs where
|
|
108
|
+
a JIT helps at all:
|
|
109
|
+
|
|
110
|
+
| target | YJIT vs interpreter | ZJIT vs interpreter | ZJIT vs YJIT |
|
|
111
|
+
| --- | --- | --- | --- |
|
|
112
|
+
| ~8 s | −13 % | −4 % | +10 % |
|
|
113
|
+
| ~19 s (monorepo) | −20 % | −13 % | +10 % |
|
|
114
|
+
| ~17 s (large app) | −28 % | −14 % | +21 % |
|
|
115
|
+
|
|
116
|
+
YJIT wins on every workload large enough to warrant a JIT; ZJIT's peak
|
|
117
|
+
speed-up is roughly half. ZJIT only edges YJIT on tiny runs — the zone where
|
|
118
|
+
you want no JIT at all. **Do not force ZJIT** (`RUBYOPT="--zjit"`) for Rigor;
|
|
119
|
+
the automatic YJIT is faster. Full measurement + methodology (a
|
|
120
|
+
contributor-side note, web only):
|
|
121
|
+
<https://github.com/rigortype/rigor/blob/master/docs/notes/20260714-jit-evaluation-yjit-zjit-ruby40.md>.
|
|
122
|
+
|
|
123
|
+
This verdict is Ruby-4.0-specific; ZJIT is younger than YJIT and improving, so
|
|
124
|
+
it may close the gap in a later Ruby. Until then YJIT is the right default —
|
|
125
|
+
which is what Rigor already does.
|
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.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rigor contributors
|
|
@@ -129,26 +129,6 @@ dependencies:
|
|
|
129
129
|
- - "<"
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
131
|
version: '1.0'
|
|
132
|
-
- !ruby/object:Gem::Dependency
|
|
133
|
-
name: parallel_tests
|
|
134
|
-
requirement: !ruby/object:Gem::Requirement
|
|
135
|
-
requirements:
|
|
136
|
-
- - ">="
|
|
137
|
-
- !ruby/object:Gem::Version
|
|
138
|
-
version: '4.0'
|
|
139
|
-
- - "<"
|
|
140
|
-
- !ruby/object:Gem::Version
|
|
141
|
-
version: '6.0'
|
|
142
|
-
type: :development
|
|
143
|
-
prerelease: false
|
|
144
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
145
|
-
requirements:
|
|
146
|
-
- - ">="
|
|
147
|
-
- !ruby/object:Gem::Version
|
|
148
|
-
version: '4.0'
|
|
149
|
-
- - "<"
|
|
150
|
-
- !ruby/object:Gem::Version
|
|
151
|
-
version: '6.0'
|
|
152
132
|
- !ruby/object:Gem::Dependency
|
|
153
133
|
name: rake
|
|
154
134
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -269,8 +249,13 @@ dependencies:
|
|
|
269
249
|
- - "<"
|
|
270
250
|
- !ruby/object:Gem::Version
|
|
271
251
|
version: '4.0'
|
|
272
|
-
description: Rigor is a CLI-first static analyzer for Ruby applications that prioritizes
|
|
273
|
-
type inference, clean application code, and zero runtime dependencies.
|
|
252
|
+
description: 'Rigor is a CLI-first static analyzer for Ruby applications that prioritizes
|
|
253
|
+
type inference, clean application code, and zero runtime dependencies. Rigor is
|
|
254
|
+
a standalone tool, not a library: install it independently rather than adding it
|
|
255
|
+
to your application''s Gemfile. It runs on Ruby 4.0 while your project keeps its
|
|
256
|
+
own Ruby, and it reads your project as data rather than loading it, so a Gemfile
|
|
257
|
+
entry only constrains your application''s Ruby and dependency resolution. Installation
|
|
258
|
+
channels (mise, asdf, gem install, container, Nix): https://github.com/rigortype/rigor/blob/master/docs/install.md'
|
|
274
259
|
email:
|
|
275
260
|
- maintainers@example.invalid
|
|
276
261
|
executables:
|
|
@@ -410,11 +395,17 @@ files:
|
|
|
410
395
|
- lib/rigor/analysis/check_rules.rb
|
|
411
396
|
- lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb
|
|
412
397
|
- lib/rigor/analysis/check_rules/dead_assignment_collector.rb
|
|
398
|
+
- lib/rigor/analysis/check_rules/duplicate_hash_key_collector.rb
|
|
399
|
+
- lib/rigor/analysis/check_rules/inferred_param_guard.rb
|
|
413
400
|
- lib/rigor/analysis/check_rules/ivar_write_collector.rb
|
|
414
401
|
- lib/rigor/analysis/check_rules/main_pass_collector.rb
|
|
402
|
+
- lib/rigor/analysis/check_rules/return_in_ensure_collector.rb
|
|
403
|
+
- lib/rigor/analysis/check_rules/rule_ids.rb
|
|
415
404
|
- lib/rigor/analysis/check_rules/rule_walk.rb
|
|
416
405
|
- lib/rigor/analysis/check_rules/self_closedness_scanner.rb
|
|
406
|
+
- lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb
|
|
417
407
|
- lib/rigor/analysis/check_rules/unreachable_clause_collector.rb
|
|
408
|
+
- lib/rigor/analysis/check_rules/void_value_use_collector.rb
|
|
418
409
|
- lib/rigor/analysis/dependency_recorder.rb
|
|
419
410
|
- lib/rigor/analysis/dependency_source_inference.rb
|
|
420
411
|
- lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb
|
|
@@ -428,9 +419,13 @@ files:
|
|
|
428
419
|
- lib/rigor/analysis/fact_store.rb
|
|
429
420
|
- lib/rigor/analysis/incremental.rb
|
|
430
421
|
- lib/rigor/analysis/incremental_session.rb
|
|
422
|
+
- lib/rigor/analysis/path_expansion.rb
|
|
423
|
+
- lib/rigor/analysis/plugin_fact_fingerprint.rb
|
|
431
424
|
- lib/rigor/analysis/project_scan.rb
|
|
432
425
|
- lib/rigor/analysis/result.rb
|
|
433
426
|
- lib/rigor/analysis/rule_catalog.rb
|
|
427
|
+
- lib/rigor/analysis/run_cache_key.rb
|
|
428
|
+
- lib/rigor/analysis/run_cache_probe.rb
|
|
434
429
|
- lib/rigor/analysis/run_stats.rb
|
|
435
430
|
- lib/rigor/analysis/runner.rb
|
|
436
431
|
- lib/rigor/analysis/runner/diagnostic_aggregator.rb
|
|
@@ -438,6 +433,7 @@ files:
|
|
|
438
433
|
- lib/rigor/analysis/runner/project_pre_passes.rb
|
|
439
434
|
- lib/rigor/analysis/runner/run_snapshots.rb
|
|
440
435
|
- lib/rigor/analysis/self_call_resolution_recorder.rb
|
|
436
|
+
- lib/rigor/analysis/severity_stamp.rb
|
|
441
437
|
- lib/rigor/analysis/worker_session.rb
|
|
442
438
|
- lib/rigor/ast.rb
|
|
443
439
|
- lib/rigor/ast/type_node.rb
|
|
@@ -448,6 +444,7 @@ files:
|
|
|
448
444
|
- lib/rigor/builtins/regex_refinement.rb
|
|
449
445
|
- lib/rigor/builtins/static_return_refinements.rb
|
|
450
446
|
- lib/rigor/cache/descriptor.rb
|
|
447
|
+
- lib/rigor/cache/file_digest.rb
|
|
451
448
|
- lib/rigor/cache/incremental_snapshot.rb
|
|
452
449
|
- lib/rigor/cache/rbs_cache_producer.rb
|
|
453
450
|
- lib/rigor/cache/rbs_class_ancestor_table.rb
|
|
@@ -458,12 +455,12 @@ files:
|
|
|
458
455
|
- lib/rigor/cache/rbs_environment_marshal_patch.rb
|
|
459
456
|
- lib/rigor/cache/rbs_known_class_names.rb
|
|
460
457
|
- lib/rigor/cache/store.rb
|
|
458
|
+
- lib/rigor/ci_detector.rb
|
|
461
459
|
- lib/rigor/cli.rb
|
|
462
460
|
- lib/rigor/cli/annotate_command.rb
|
|
463
461
|
- lib/rigor/cli/baseline_command.rb
|
|
464
462
|
- lib/rigor/cli/check_command.rb
|
|
465
463
|
- lib/rigor/cli/check_runner_factory.rb
|
|
466
|
-
- lib/rigor/cli/ci_detector.rb
|
|
467
464
|
- lib/rigor/cli/command.rb
|
|
468
465
|
- lib/rigor/cli/coverage_command.rb
|
|
469
466
|
- lib/rigor/cli/coverage_mutation.rb
|
|
@@ -486,6 +483,7 @@ files:
|
|
|
486
483
|
- lib/rigor/cli/plugins_command.rb
|
|
487
484
|
- lib/rigor/cli/plugins_renderer.rb
|
|
488
485
|
- lib/rigor/cli/prism_colorizer.rb
|
|
486
|
+
- lib/rigor/cli/probe_environment.rb
|
|
489
487
|
- lib/rigor/cli/protection_fork_scan.rb
|
|
490
488
|
- lib/rigor/cli/protection_renderer.rb
|
|
491
489
|
- lib/rigor/cli/protection_report.rb
|
|
@@ -512,6 +510,7 @@ files:
|
|
|
512
510
|
- lib/rigor/environment/bundle_sig_discovery.rb
|
|
513
511
|
- lib/rigor/environment/class_registry.rb
|
|
514
512
|
- lib/rigor/environment/constant_type_cache_holder.rb
|
|
513
|
+
- lib/rigor/environment/default_libraries.rb
|
|
515
514
|
- lib/rigor/environment/hkt_registry_holder.rb
|
|
516
515
|
- lib/rigor/environment/lockfile_resolver.rb
|
|
517
516
|
- lib/rigor/environment/missing_gem_constant_index.rb
|
|
@@ -553,6 +552,8 @@ files:
|
|
|
553
552
|
- lib/rigor/inference/builtins/time_catalog.rb
|
|
554
553
|
- lib/rigor/inference/closure_escape_analyzer.rb
|
|
555
554
|
- lib/rigor/inference/coverage_scanner.rb
|
|
555
|
+
- lib/rigor/inference/def_handle.rb
|
|
556
|
+
- lib/rigor/inference/def_node_resolver.rb
|
|
556
557
|
- lib/rigor/inference/def_return_typer.rb
|
|
557
558
|
- lib/rigor/inference/dynamic_origin.rb
|
|
558
559
|
- lib/rigor/inference/expression_typer.rb
|
|
@@ -609,6 +610,8 @@ files:
|
|
|
609
610
|
- lib/rigor/inference/synthetic_method.rb
|
|
610
611
|
- lib/rigor/inference/synthetic_method_index.rb
|
|
611
612
|
- lib/rigor/inference/synthetic_method_scanner.rb
|
|
613
|
+
- lib/rigor/inference/void_origin.rb
|
|
614
|
+
- lib/rigor/inference/void_tail_summary.rb
|
|
612
615
|
- lib/rigor/language_server.rb
|
|
613
616
|
- lib/rigor/language_server/buffer_resolution.rb
|
|
614
617
|
- lib/rigor/language_server/buffer_table.rb
|
|
@@ -664,6 +667,7 @@ files:
|
|
|
664
667
|
- lib/rigor/rbs_extended/hkt_directives.rb
|
|
665
668
|
- lib/rigor/rbs_extended/reporter.rb
|
|
666
669
|
- lib/rigor/reflection.rb
|
|
670
|
+
- lib/rigor/runtime/jit.rb
|
|
667
671
|
- lib/rigor/scope.rb
|
|
668
672
|
- lib/rigor/scope/discovery_index.rb
|
|
669
673
|
- lib/rigor/sig_gen.rb
|
|
@@ -674,6 +678,7 @@ files:
|
|
|
674
678
|
- lib/rigor/sig_gen/observation_collector.rb
|
|
675
679
|
- lib/rigor/sig_gen/observed_call.rb
|
|
676
680
|
- lib/rigor/sig_gen/path_mapper.rb
|
|
681
|
+
- lib/rigor/sig_gen/rbs_validity.rb
|
|
677
682
|
- lib/rigor/sig_gen/renderer.rb
|
|
678
683
|
- lib/rigor/sig_gen/type_elaborator.rb
|
|
679
684
|
- lib/rigor/sig_gen/write_result.rb
|
|
@@ -682,6 +687,7 @@ files:
|
|
|
682
687
|
- lib/rigor/source.rb
|
|
683
688
|
- lib/rigor/source/constant_path.rb
|
|
684
689
|
- lib/rigor/source/literals.rb
|
|
690
|
+
- lib/rigor/source/node_children.rb
|
|
685
691
|
- lib/rigor/source/node_locator.rb
|
|
686
692
|
- lib/rigor/source/node_walker.rb
|
|
687
693
|
- lib/rigor/testing.rb
|
|
@@ -725,6 +731,7 @@ files:
|
|
|
725
731
|
- lib/rigor/type_node/union.rb
|
|
726
732
|
- lib/rigor/value_semantics.rb
|
|
727
733
|
- lib/rigor/version.rb
|
|
734
|
+
- lib/rigortype.rb
|
|
728
735
|
- plugins/rigor-actioncable/lib/rigor-actioncable.rb
|
|
729
736
|
- plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb
|
|
730
737
|
- plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb
|
|
@@ -850,6 +857,7 @@ files:
|
|
|
850
857
|
- plugins/rigor-statesman/lib/rigor/plugin/statesman.rb
|
|
851
858
|
- plugins/rigor-typescript-utility-types/lib/rigor-typescript-utility-types.rb
|
|
852
859
|
- plugins/rigor-typescript-utility-types/lib/rigor/plugin/typescript_utility_types.rb
|
|
860
|
+
- sig/prism_node_children.rbs
|
|
853
861
|
- sig/rigor.rbs
|
|
854
862
|
- sig/rigor/analysis/baseline.rbs
|
|
855
863
|
- sig/rigor/analysis/check_rules/always_truthy_condition_collector.rbs
|
|
@@ -911,6 +919,7 @@ files:
|
|
|
911
919
|
- skills/rigor-project-init/references/02-configure.md
|
|
912
920
|
- skills/rigor-project-init/references/03-baseline-and-bugs.md
|
|
913
921
|
- skills/rigor-project-init/references/04-sig-uplift.md
|
|
922
|
+
- skills/rigor-project-init/references/05-jit-performance.md
|
|
914
923
|
- skills/rigor-protection-uplift/SKILL.md
|
|
915
924
|
- skills/rigor-rbs-setup/SKILL.md
|
|
916
925
|
- skills/rigor-upgrade/SKILL.md
|
|
@@ -922,6 +931,15 @@ metadata:
|
|
|
922
931
|
source_code_uri: https://github.com/rigortype/rigor
|
|
923
932
|
documentation_uri: https://github.com/rigortype/rigor/tree/master/docs
|
|
924
933
|
rubygems_mfa_required: 'true'
|
|
934
|
+
post_install_message: |
|
|
935
|
+
Rigor installs as a standalone CLI, not a project dependency. Run `rigor check app lib` from your
|
|
936
|
+
project root — no `bundle exec`.
|
|
937
|
+
|
|
938
|
+
If this came from `bundle add rigortype` or a Gemfile entry, remove it: Rigor runs on its own Ruby
|
|
939
|
+
and analyses your project from the outside, so in a Gemfile it constrains your application's Ruby
|
|
940
|
+
and dependency resolution without giving you anything. Per-project version pinning without that
|
|
941
|
+
cost, plus every other channel, is documented in
|
|
942
|
+
https://github.com/rigortype/rigor/blob/master/docs/install.md
|
|
925
943
|
rdoc_options: []
|
|
926
944
|
require_paths:
|
|
927
945
|
- lib
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Rigor
|
|
4
|
-
class CLI
|
|
5
|
-
# Runtime CI-environment detection (ADR-51 WD7), modelled on `OndraM/ci-detector` (the library PHPStan uses). Reads
|
|
6
|
-
# the well-known environment variables a CI provider sets and returns the matching {Platform}, classifying it into a
|
|
7
|
-
# **tier** that decides how `rigor check` surfaces diagnostics there:
|
|
8
|
-
#
|
|
9
|
-
# :native_stdout — Rigor has a native format that renders purely from
|
|
10
|
-
# stdout, so it is auto-emitted on top of the human
|
|
11
|
-
# output (GitHub Actions → `github`, TeamCity →
|
|
12
|
-
# `teamcity`). These are the first-class platforms.
|
|
13
|
-
# :native_artifact — Rigor has a native format but it needs a CI-wired
|
|
14
|
-
# report artifact, not stdout (GitLab CI → `gitlab`).
|
|
15
|
-
# First-class, but Rigor only *hints* the format.
|
|
16
|
-
# :reviewdog — no native Rigor format; second-class, routed through
|
|
17
|
-
# reviewdog (`checkstyle`/`sarif`) or `junit`. Hint
|
|
18
|
-
# only.
|
|
19
|
-
#
|
|
20
|
-
# Detection is a pure function of the environment hash, so it is fully testable; the CLI passes `ENV`.
|
|
21
|
-
# `RIGOR_CI_DETECT=0` (or `false`/`no`) disables it globally — the seam the spec suite uses for determinism.
|
|
22
|
-
module CiDetector
|
|
23
|
-
Platform = Struct.new(:id, :name, :format, :tier, keyword_init: true) do
|
|
24
|
-
def native_stdout? = tier == :native_stdout
|
|
25
|
-
def native_artifact? = tier == :native_artifact
|
|
26
|
-
def reviewdog? = tier == :reviewdog
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# The detection table, ordered most-specific first so the generic `CI=true` catch-all is last (a provider that
|
|
30
|
-
# also sets `CI` is still recognised by its own variable). `match` is `:truthy` (value in 1/true/yes/on),
|
|
31
|
-
# `:present` (variable set non-empty), or `:equals`.
|
|
32
|
-
PROVIDERS = [
|
|
33
|
-
{ id: "github-actions", name: "GitHub Actions", format: "github", tier: :native_stdout,
|
|
34
|
-
var: "GITHUB_ACTIONS", match: :truthy },
|
|
35
|
-
{ id: "gitlab", name: "GitLab CI", format: "gitlab", tier: :native_artifact,
|
|
36
|
-
var: "GITLAB_CI", match: :truthy },
|
|
37
|
-
{ id: "teamcity", name: "TeamCity", format: "teamcity", tier: :native_stdout,
|
|
38
|
-
var: "TEAMCITY_VERSION", match: :present },
|
|
39
|
-
{ id: "circleci", name: "CircleCI", format: nil, tier: :reviewdog,
|
|
40
|
-
var: "CIRCLECI", match: :truthy },
|
|
41
|
-
{ id: "jenkins", name: "Jenkins", format: nil, tier: :reviewdog,
|
|
42
|
-
var: "JENKINS_URL", match: :present },
|
|
43
|
-
{ id: "travis", name: "Travis CI", format: nil, tier: :reviewdog,
|
|
44
|
-
var: "TRAVIS", match: :truthy },
|
|
45
|
-
{ id: "appveyor", name: "AppVeyor", format: nil, tier: :reviewdog,
|
|
46
|
-
var: "APPVEYOR", match: :truthy },
|
|
47
|
-
{ id: "azure-pipelines", name: "Azure Pipelines", format: nil, tier: :reviewdog,
|
|
48
|
-
var: "TF_BUILD", match: :present },
|
|
49
|
-
{ id: "bitbucket", name: "Bitbucket Pipelines", format: nil, tier: :reviewdog,
|
|
50
|
-
var: "BITBUCKET_BUILD_NUMBER", match: :present },
|
|
51
|
-
{ id: "buildkite", name: "Buildkite", format: nil, tier: :reviewdog,
|
|
52
|
-
var: "BUILDKITE", match: :truthy },
|
|
53
|
-
{ id: "drone", name: "Drone CI", format: nil, tier: :reviewdog,
|
|
54
|
-
var: "DRONE", match: :truthy },
|
|
55
|
-
{ id: "semaphore", name: "Semaphore", format: nil, tier: :reviewdog,
|
|
56
|
-
var: "SEMAPHORE", match: :truthy },
|
|
57
|
-
{ id: "codeship", name: "Codeship", format: nil, tier: :reviewdog,
|
|
58
|
-
var: "CI_NAME", match: :equals, value: "codeship" },
|
|
59
|
-
{ id: "ci", name: "CI", format: nil, tier: :reviewdog,
|
|
60
|
-
var: "CI", match: :truthy }
|
|
61
|
-
].freeze
|
|
62
|
-
|
|
63
|
-
module_function
|
|
64
|
-
|
|
65
|
-
# Returns the detected {Platform}, or nil when no CI is recognised or detection is disabled via `RIGOR_CI_DETECT`.
|
|
66
|
-
def detect(env = ENV)
|
|
67
|
-
return nil if disabled?(env)
|
|
68
|
-
|
|
69
|
-
row = PROVIDERS.find { |provider| matches?(env, provider) }
|
|
70
|
-
return nil if row.nil?
|
|
71
|
-
|
|
72
|
-
Platform.new(id: row[:id], name: row[:name], format: row[:format], tier: row[:tier])
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def disabled?(env)
|
|
76
|
-
%w[0 false no off].include?(env["RIGOR_CI_DETECT"].to_s.strip.downcase)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def matches?(env, provider)
|
|
80
|
-
value = env[provider[:var]].to_s.strip
|
|
81
|
-
case provider[:match]
|
|
82
|
-
when :truthy then %w[1 true yes on].include?(value.downcase)
|
|
83
|
-
when :present then !value.empty?
|
|
84
|
-
when :equals then value.downcase == provider[:value]
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|