rigortype 0.3.3 → 0.3.4
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 +1 -1
- data/data/builtins/ruby_core/array.yml +11 -24
- data/data/builtins/ruby_core/enumerable.yml +4 -8
- data/data/builtins/ruby_core/exception.yml +6 -9
- data/data/builtins/ruby_core/hash.yml +13 -20
- data/data/builtins/ruby_core/io.yml +6 -9
- data/data/builtins/ruby_core/numeric.yml +2 -3
- data/data/builtins/ruby_core/proc.yml +4 -8
- data/data/builtins/ruby_core/re.yml +6 -9
- data/data/builtins/ruby_core/set.yml +2 -3
- data/data/builtins/ruby_core/string.yml +4 -7
- data/data/builtins/ruby_core/struct.yml +0 -6
- data/data/builtins/ruby_core/time.yml +3 -6
- data/data/effects/core.yml +843 -0
- data/data/effects/registry.yml +67 -0
- data/docs/handbook/07-rbs-and-extended.md +106 -5
- data/docs/manual/02-cli-reference.md +311 -1
- data/docs/manual/03-configuration.md +84 -1
- data/docs/manual/04-diagnostics.md +6 -2
- data/docs/manual/16-rbs-extended-annotations.md +77 -0
- data/docs/manual/18-removing-dead-code.md +326 -0
- data/docs/manual/README.md +5 -0
- data/docs/manual/plugins/rigor-actionmailer.md +5 -0
- data/docs/manual/plugins/rigor-activejob.md +47 -0
- data/docs/manual/plugins/rigor-factorybot.md +16 -0
- data/docs/manual/plugins/rigor-pundit.md +26 -0
- data/docs/manual/plugins/rigor-rails-routes.md +41 -2
- data/docs/manual/plugins/rigor-rspec-rails.md +5 -0
- data/docs/manual/plugins/rigor-rspec.md +8 -0
- data/docs/manual/plugins/rigor-sidekiq.md +54 -0
- data/lib/rigor/analysis/check_rules/rule_ids.rb +28 -2
- data/lib/rigor/analysis/incremental_session.rb +140 -6
- data/lib/rigor/analysis/reachability/graph.rb +244 -0
- data/lib/rigor/analysis/reachability/plugin_roots.rb +164 -0
- data/lib/rigor/analysis/reachability/project_files.rb +58 -0
- data/lib/rigor/analysis/reachability/scan.rb +241 -0
- data/lib/rigor/analysis/reachability/signature_scan.rb +134 -0
- data/lib/rigor/analysis/rule_catalog.rb +158 -0
- data/lib/rigor/analysis/run_cache_key.rb +16 -0
- data/lib/rigor/analysis/runner/declaration_position.rb +54 -0
- data/lib/rigor/analysis/runner/effect_annotation_residual_pass.rb +108 -0
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +358 -0
- data/lib/rigor/analysis/runner/envelope_messages.rb +61 -0
- data/lib/rigor/analysis/runner/pool_coordinator.rb +68 -10
- data/lib/rigor/analysis/runner.rb +420 -10
- data/lib/rigor/analysis/worker_session.rb +58 -2
- data/lib/rigor/bleeding_edge.rb +22 -0
- data/lib/rigor/cache/incremental_snapshot.rb +24 -5
- data/lib/rigor/cli/check_command.rb +13 -1
- data/lib/rigor/cli/check_runner_factory.rb +4 -1
- data/lib/rigor/cli/effects_command.rb +131 -0
- data/lib/rigor/cli/effects_diff_renderer.rb +123 -0
- data/lib/rigor/cli/effects_explain_renderer.rb +68 -0
- data/lib/rigor/cli/effects_renderer.rb +54 -0
- data/lib/rigor/cli/effects_report.rb +53 -0
- data/lib/rigor/cli/effects_snapshot_command.rb +256 -0
- data/lib/rigor/cli/unused_command.rb +288 -0
- data/lib/rigor/cli.rb +16 -0
- data/lib/rigor/configuration/severity_profile.rb +23 -0
- data/lib/rigor/configuration.rb +296 -14
- data/lib/rigor/effects/attribution.rb +76 -0
- data/lib/rigor/effects/catalog.rb +275 -0
- data/lib/rigor/effects/collector.rb +182 -0
- data/lib/rigor/effects/config_envelopes.rb +185 -0
- data/lib/rigor/effects/discharge.rb +69 -0
- data/lib/rigor/effects/effect_table.rb +92 -0
- data/lib/rigor/effects/entry_points.rb +93 -0
- data/lib/rigor/effects/envelope.rb +86 -0
- data/lib/rigor/effects/envelope_check.rb +172 -0
- data/lib/rigor/effects/envelope_index.rb +157 -0
- data/lib/rigor/effects/file_collection.rb +160 -0
- data/lib/rigor/effects/framework_units.rb +167 -0
- data/lib/rigor/effects/identity.rb +104 -0
- data/lib/rigor/effects/label.rb +77 -0
- data/lib/rigor/effects/label_intent.rb +73 -0
- data/lib/rigor/effects/label_set.rb +136 -0
- data/lib/rigor/effects/liskov_check.rb +167 -0
- data/lib/rigor/effects/local_ownership.rb +132 -0
- data/lib/rigor/effects/method_key.rb +40 -0
- data/lib/rigor/effects/mutation_classifier.rb +92 -0
- data/lib/rigor/effects/narrowing.rb +202 -0
- data/lib/rigor/effects/origin.rb +66 -0
- data/lib/rigor/effects/path_finder.rb +89 -0
- data/lib/rigor/effects/plugin_facts.rb +335 -0
- data/lib/rigor/effects/propagator.rb +275 -0
- data/lib/rigor/effects/registry.rb +193 -0
- data/lib/rigor/effects/scanner.rb +290 -0
- data/lib/rigor/effects/signature_sources.rb +74 -0
- data/lib/rigor/effects/snapshot.rb +380 -0
- data/lib/rigor/effects/snapshot_diff.rb +265 -0
- data/lib/rigor/effects/summary.rb +154 -0
- data/lib/rigor/effects/taint_cause.rb +38 -0
- data/lib/rigor/effects/unit_scan.rb +572 -0
- data/lib/rigor/effects/unknown_label_check.rb +86 -0
- data/lib/rigor/effects/unknown_label_report.rb +59 -0
- data/lib/rigor/effects.rb +47 -0
- data/lib/rigor/environment/rbs_loader.rb +34 -0
- data/lib/rigor/environment.rb +8 -1
- data/lib/rigor/flow_contribution/element.rb +1 -0
- data/lib/rigor/flow_contribution/merge_result.rb +5 -3
- data/lib/rigor/flow_contribution/merger.rb +16 -1
- data/lib/rigor/flow_contribution.rb +20 -4
- data/lib/rigor/inference/expression_typer.rb +18 -4
- data/lib/rigor/inference/pre_eval_constants.rb +189 -0
- data/lib/rigor/inference/scope_indexer.rb +15 -3
- data/lib/rigor/plugin/base.rb +24 -0
- data/lib/rigor/plugin/effect_attribution.rb +208 -0
- data/lib/rigor/plugin/effect_edge.rb +101 -0
- data/lib/rigor/plugin/effect_entry_points.rb +51 -0
- data/lib/rigor/plugin/first_party.rb +57 -0
- data/lib/rigor/plugin/isolation.rb +4 -1
- data/lib/rigor/plugin/manifest.rb +103 -3
- data/lib/rigor/plugin/registry.rb +48 -0
- data/lib/rigor/plugin.rb +1 -0
- data/lib/rigor/rbs_extended/envelope_scanner.rb +160 -0
- data/lib/rigor/rbs_extended.rb +168 -0
- data/lib/rigor/reflection.rb +131 -30
- data/lib/rigor/version.rb +1 -1
- data/lib/rigor.rb +1 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/effects.rb +90 -0
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +7 -1
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/effects.rb +85 -0
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +8 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/effects.rb +152 -0
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +9 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +156 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/recurring_scan.rb +113 -0
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +68 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +186 -0
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +12 -1
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +145 -0
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/effects.rb +77 -0
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +6 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +143 -0
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +9 -1
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +385 -28
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +30 -2
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/authorization_scan.rb +151 -0
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit.rb +46 -3
- data/plugins/rigor-rails/lib/rigor-rails.rb +1 -0
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/effects.rb +47 -0
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb +7 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/acronyms.rb +81 -0
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb +13 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +202 -15
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +43 -3
- data/plugins/rigor-railties/lib/rigor/plugin/railties/effects.rb +171 -0
- data/plugins/rigor-railties/lib/rigor/plugin/railties.rb +62 -0
- data/plugins/rigor-railties/lib/rigor-railties.rb +3 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb +122 -0
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +56 -3
- data/sig/rigor/analysis/fact_store.rbs +1 -0
- data/sig/rigor/inference.rbs +2 -0
- data/sig/rigor/rbs_extended.rbs +6 -0
- data/sig/rigor.rbs +17 -1
- data/skills/rigor-unused-adjudicate/SKILL.md +90 -0
- metadata +79 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
|
|
5
|
+
module Rigor
|
|
6
|
+
module Plugin
|
|
7
|
+
class Sidekiq < Rigor::Plugin::Base
|
|
8
|
+
# ADR-102 WD3 / #367 — which workers does this project enqueue by NAME, from schedule configuration?
|
|
9
|
+
#
|
|
10
|
+
# This is the one genuinely Sidekiq-specific reachability root, and the reason it is worth reading YAML
|
|
11
|
+
# for: a cron-scheduled worker is enqueued from `config/schedule.yml` as the string `"HardWorker"`, so
|
|
12
|
+
# the repository may contain no `HardWorker.perform_async` anywhere. The constant scan sees nothing, and
|
|
13
|
+
# `rigor unused` reports a worker that runs every night as dead code.
|
|
14
|
+
#
|
|
15
|
+
# Two layouts, one key. `sidekiq-cron` writes the schedule as the whole document
|
|
16
|
+
# (`{ name => { "cron" =>, "class" => } }`); `sidekiq-scheduler` nests the same entries under
|
|
17
|
+
# `config/sidekiq.yml`'s `:scheduler: :schedule:` block. Both name the worker under `class:`, and
|
|
18
|
+
# `class:` is the ONLY key read here.
|
|
19
|
+
#
|
|
20
|
+
# **What this refuses to read is the queue list.** `:queues:` in `sidekiq.yml` holds queue names, and a
|
|
21
|
+
# queue name is not a class name — inflecting `report_worker` into `ReportWorker` would manufacture a
|
|
22
|
+
# root out of a naming coincidence, which is precisely the over-supply this plugin declined in #350. An
|
|
23
|
+
# over-claiming root source silently hides real dead code (ADR-102 § Consequences), and nothing
|
|
24
|
+
# downstream can tell you it happened. So a queue contributes nothing, deliberately.
|
|
25
|
+
#
|
|
26
|
+
# Names are not trusted either: the caller intersects them with the workers {WorkerDiscoverer} actually
|
|
27
|
+
# found, so a typo or an out-of-tree class costs coverage rather than manufacturing a root, and the
|
|
28
|
+
# report's `matched no declaration` counter stays meaningful.
|
|
29
|
+
#
|
|
30
|
+
# Fail-soft throughout, because this reads user-authored config that Rigor does not own: an absent file,
|
|
31
|
+
# an unreadable one, a YAML syntax error, or a document that is not a Hash contributes nothing rather
|
|
32
|
+
# than raising. `rigor unused` is a report a human reads, and refusing to print it because one
|
|
33
|
+
# `sidekiq.yml` has a stray tab is a bad trade.
|
|
34
|
+
class ScheduleScan
|
|
35
|
+
# The key naming the worker, in both layouts. Symbol keys are accepted because `sidekiq.yml` is
|
|
36
|
+
# conventionally written with them (`:scheduler:`, `:schedule:`), and Psych parses `:class:` as the
|
|
37
|
+
# Symbol `:class`.
|
|
38
|
+
CLASS_KEY = "class"
|
|
39
|
+
|
|
40
|
+
# Where a schedule block hides inside a document. `[]` is the document itself — `sidekiq-cron`'s
|
|
41
|
+
# `schedule.yml` IS the schedule map — and the nested paths are `sidekiq-scheduler`'s, whose entries
|
|
42
|
+
# live under `:scheduler: :schedule:` (with the bare `:schedule:` form kept for pre-3.0 layouts).
|
|
43
|
+
SCHEDULE_BLOCK_KEY_PATHS = [[], %w[scheduler schedule], %w[schedule]].freeze
|
|
44
|
+
|
|
45
|
+
# Errno classes that mean "this path is not readable as a schedule" — swallowed so one bad path does
|
|
46
|
+
# not cost the roots the other paths supply.
|
|
47
|
+
IO_ERRORS = [Errno::ENOENT, Errno::EACCES, Errno::EISDIR].freeze
|
|
48
|
+
|
|
49
|
+
def initialize(io_boundary:, schedule_paths:)
|
|
50
|
+
@io_boundary = io_boundary
|
|
51
|
+
@schedule_paths = schedule_paths
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @return [Array<String>] the class names named by a `class:` key in a schedule entry, sorted and
|
|
55
|
+
# unique. NOT yet intersected with the discovered workers — the caller does that.
|
|
56
|
+
def worker_names
|
|
57
|
+
names = Set.new
|
|
58
|
+
@schedule_paths.each do |path|
|
|
59
|
+
document = load_document(path)
|
|
60
|
+
next unless document.is_a?(Hash)
|
|
61
|
+
|
|
62
|
+
SCHEDULE_BLOCK_KEY_PATHS.each { |keys| collect_entries(dig_block(document, keys), names) }
|
|
63
|
+
end
|
|
64
|
+
names.to_a.sort
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def load_document(path)
|
|
70
|
+
absolute = File.expand_path(path.to_s)
|
|
71
|
+
return nil unless File.file?(absolute)
|
|
72
|
+
|
|
73
|
+
contents = read_safely(absolute)
|
|
74
|
+
contents && parse_safely(contents)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def read_safely(path)
|
|
78
|
+
@io_boundary.read_file(path)
|
|
79
|
+
rescue Plugin::AccessDeniedError, *IO_ERRORS
|
|
80
|
+
nil
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# `safe_load` with no permitted classes beyond Symbol: a schedule file is data, and Rigor never loads
|
|
84
|
+
# the Rails environment or the sidekiq runtime to read it. `aliases: true` because YAML anchors are
|
|
85
|
+
# ordinary style in a hand-maintained schedule.
|
|
86
|
+
def parse_safely(contents)
|
|
87
|
+
YAML.safe_load(contents, aliases: true, permitted_classes: [Symbol])
|
|
88
|
+
rescue Psych::Exception
|
|
89
|
+
nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Walks one of {SCHEDULE_BLOCK_KEY_PATHS} into the document. String and Symbol keys are both tried because
|
|
93
|
+
# `sidekiq.yml` is written with Symbol keys and `schedule.yml` with String ones.
|
|
94
|
+
def dig_block(document, keys)
|
|
95
|
+
keys.reduce(document) do |node, key|
|
|
96
|
+
return nil unless node.is_a?(Hash)
|
|
97
|
+
|
|
98
|
+
fetch_either(node, key)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# A schedule block maps an arbitrary job NAME to an entry Hash. Only the entry's own `class:` is read
|
|
103
|
+
# — no recursion into the value, so a nested option that happens to be called `class` cannot enter,
|
|
104
|
+
# and neither can anything under `:queues:`, whose values are Strings and Arrays rather than entries.
|
|
105
|
+
def collect_entries(block, names)
|
|
106
|
+
return unless block.is_a?(Hash)
|
|
107
|
+
|
|
108
|
+
block.each_value do |entry|
|
|
109
|
+
next unless entry.is_a?(Hash)
|
|
110
|
+
|
|
111
|
+
value = fetch_either(entry, CLASS_KEY)
|
|
112
|
+
names << value if value.is_a?(String) && !value.empty?
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def fetch_either(hash, key)
|
|
117
|
+
hash.fetch(key) { hash[key.to_sym] }
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -4,6 +4,7 @@ require "rigor/plugin"
|
|
|
4
4
|
|
|
5
5
|
require_relative "sidekiq/worker_index"
|
|
6
6
|
require_relative "sidekiq/worker_discoverer"
|
|
7
|
+
require_relative "sidekiq/schedule_scan"
|
|
7
8
|
require_relative "sidekiq/analyzer"
|
|
8
9
|
|
|
9
10
|
module Rigor
|
|
@@ -22,6 +23,7 @@ module Rigor
|
|
|
22
23
|
# config:
|
|
23
24
|
# worker_search_paths: ["app/workers", "app/sidekiq"] # default; optional
|
|
24
25
|
# worker_marker_modules: ["Sidekiq::Job", "Sidekiq::Worker"] # default; optional
|
|
26
|
+
# schedule_paths: ["config/schedule.yml", "config/sidekiq.yml"] # default; optional
|
|
25
27
|
#
|
|
26
28
|
# ## What it checks
|
|
27
29
|
#
|
|
@@ -30,6 +32,11 @@ module Rigor
|
|
|
30
32
|
# schedule and forward the rest. Mismatches emit `wrong-arity`.
|
|
31
33
|
# 2. **Missing schedule** — `perform_in()` / `perform_at()` with zero arguments emit `missing-schedule`.
|
|
32
34
|
#
|
|
35
|
+
# ## What it contributes to `rigor unused`
|
|
36
|
+
#
|
|
37
|
+
# The workers a schedule file names under `class:` and nothing else (ADR-102 WD3 / #367) — see
|
|
38
|
+
# {#prepare} and {ScheduleScan}.
|
|
39
|
+
#
|
|
33
40
|
# ## Limitations (v0.1.0)
|
|
34
41
|
#
|
|
35
42
|
# - Direct `include` matches only against the configured marker modules. Indirect includes via a
|
|
@@ -41,12 +48,21 @@ module Rigor
|
|
|
41
48
|
class Sidekiq < Rigor::Plugin::Base
|
|
42
49
|
manifest(
|
|
43
50
|
id: "sidekiq",
|
|
44
|
-
|
|
51
|
+
# Bumped 2026-08-16 — publishes `:reachability_roots` for `rigor unused` (ADR-102 WD3): the workers
|
|
52
|
+
# a schedule file enqueues by name, which no `perform_async` call site writes down.
|
|
53
|
+
version: "0.2.0",
|
|
45
54
|
description: "Validates Sidekiq `Worker.perform_async` argument arity.",
|
|
46
55
|
config_schema: {
|
|
47
56
|
"worker_search_paths" => { kind: :array, default: ["app/workers", "app/sidekiq"] },
|
|
48
|
-
"worker_marker_modules" => { kind: :array, default: %w[Sidekiq::Job Sidekiq::Worker] }
|
|
49
|
-
|
|
57
|
+
"worker_marker_modules" => { kind: :array, default: %w[Sidekiq::Job Sidekiq::Worker] },
|
|
58
|
+
# `schedule_paths` — the schedule configuration {ScheduleScan} reads for the reachability roots
|
|
59
|
+
# below. The two defaults are the conventional locations of the two schedule layouts in the wild:
|
|
60
|
+
# `sidekiq-cron`'s `config/schedule.yml` and `sidekiq-scheduler`'s `:scheduler: :schedule:` block
|
|
61
|
+
# inside `config/sidekiq.yml`. A project that keeps its schedule elsewhere lists the file itself;
|
|
62
|
+
# these are file paths, not directories, because a schedule is a named document rather than a tree.
|
|
63
|
+
"schedule_paths" => { kind: :array, default: ["config/schedule.yml", "config/sidekiq.yml"] }
|
|
64
|
+
},
|
|
65
|
+
produces: [:reachability_roots]
|
|
50
66
|
)
|
|
51
67
|
|
|
52
68
|
producer :worker_index, watch: -> { [[@worker_search_paths, "**/*.rb"]] } do |_params|
|
|
@@ -57,9 +73,46 @@ module Rigor
|
|
|
57
73
|
).discover
|
|
58
74
|
end
|
|
59
75
|
|
|
76
|
+
# Cached separately from `:worker_index` because the two invalidate on different files: editing a
|
|
77
|
+
# schedule changes which workers are reached without touching `app/workers` at all. The `watch:` roots
|
|
78
|
+
# the glob at the working directory so that CREATING a schedule file — not just editing one — is seen.
|
|
79
|
+
producer :scheduled_workers, watch: -> { [[".", *@schedule_paths]] } do |_params|
|
|
80
|
+
ScheduleScan.new(
|
|
81
|
+
io_boundary: io_boundary,
|
|
82
|
+
schedule_paths: @schedule_paths
|
|
83
|
+
).worker_names
|
|
84
|
+
end
|
|
85
|
+
|
|
60
86
|
def init(_services)
|
|
61
87
|
@worker_search_paths = Array(config.fetch("worker_search_paths")).map(&:to_s)
|
|
62
88
|
@worker_marker_modules = Array(config.fetch("worker_marker_modules")).map(&:to_s)
|
|
89
|
+
@schedule_paths = Array(config.fetch("schedule_paths")).map(&:to_s)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# ADR-102 WD3 — publishes the workers a schedule file enqueues BY NAME, for `rigor unused`.
|
|
93
|
+
#
|
|
94
|
+
# `MyWorker.perform_async(...)` writes the worker's name as an ordinary constant, so the report's scan
|
|
95
|
+
# already records that edge and a root would add nothing. A worker named only as the string
|
|
96
|
+
# `class: "MyWorker"` in `config/schedule.yml` is the opposite case: it runs every night and the
|
|
97
|
+
# constant appears nowhere, so it reads as dead.
|
|
98
|
+
#
|
|
99
|
+
# The intersection is what keeps the contribution honest, exactly as in `rigor-pundit`. {ScheduleScan}
|
|
100
|
+
# says which names the schedule WRITES; {WorkerDiscoverer} says which workers EXIST. A `class:` value
|
|
101
|
+
# matching no discovered worker — a typo, a renamed class, a job living outside `worker_search_paths` —
|
|
102
|
+
# is dropped rather than published, so the failure mode is a missing root (a candidate row a human can
|
|
103
|
+
# judge) instead of a spurious one (silence where dead code used to be).
|
|
104
|
+
#
|
|
105
|
+
# Publishing the discovered worker set instead would have been one line and is what this refuses to do:
|
|
106
|
+
# "a file exists under `app/workers`" is not evidence that anything enqueues it.
|
|
107
|
+
def prepare(services)
|
|
108
|
+
index = producer_value(:worker_index)
|
|
109
|
+
scheduled = producer_value(:scheduled_workers)
|
|
110
|
+
return if index.nil? || scheduled.nil?
|
|
111
|
+
|
|
112
|
+
roots = scheduled.select { |name| index.known?(name) }
|
|
113
|
+
return if roots.empty?
|
|
114
|
+
|
|
115
|
+
services.fact_store.publish(plugin_id: manifest.id, name: :reachability_roots, value: roots)
|
|
63
116
|
end
|
|
64
117
|
|
|
65
118
|
# File-level only: the load-error emission. The per-call arity validation runs over the engine-owned
|
|
@@ -5,6 +5,7 @@ module Rigor
|
|
|
5
5
|
def self?.build_node_collectors: (String path, untyped scope_index) -> Hash[Symbol, untyped]
|
|
6
6
|
def self?.node_collector_driver: (Hash[Symbol, untyped] collectors) -> untyped
|
|
7
7
|
def self?.shadow_verify_converged_collectors: (String path, untyped root, untyped scope_index, Hash[Symbol, untyped]? collectors) -> void
|
|
8
|
+
def self?.filter_suppressed: (Array[Diagnostic] diagnostics, comments: untyped, disabled_rules: Array[String]) -> Array[Diagnostic]
|
|
8
9
|
end
|
|
9
10
|
|
|
10
11
|
class FactStore
|
data/sig/rigor/inference.rbs
CHANGED
|
@@ -163,6 +163,8 @@ module Rigor
|
|
|
163
163
|
module ScopeIndexer
|
|
164
164
|
def self?.index: (untyped root, default_scope: Scope) -> Hash[untyped, Scope]
|
|
165
165
|
def self?.build_declaration_overrides: (untyped root) -> Hash[untyped, Type::t]
|
|
166
|
+
def self?.build_declaration_artifacts: (untyped root) -> [Hash[untyped, Type::t], Hash[String, Type::t]]
|
|
167
|
+
def self?.build_in_source_constants: (untyped root, Scope default_scope) -> Hash[String, Type::t]
|
|
166
168
|
def self?.record_declarations: (untyped node, Array[String] qualified_prefix, Hash[untyped, Type::t] identity_table, Hash[String, Type::t] discovered) -> void
|
|
167
169
|
def self?.discovered_classes_for_paths: (Array[String] paths, ?buffer: untyped) -> Hash[String, Type::t]
|
|
168
170
|
def self?.discovered_def_index_for_paths: (Array[String] paths, ?buffer: untyped) -> Hash[Symbol, untyped]
|
data/sig/rigor/rbs_extended.rbs
CHANGED
|
@@ -47,6 +47,12 @@ module Rigor
|
|
|
47
47
|
|
|
48
48
|
def self?.parse_conforms_to_annotation: (String? string) -> String?
|
|
49
49
|
|
|
50
|
+
# ADR-103 #383 — the effect-envelope reader. `annotations` is any list of RBS annotation nodes
|
|
51
|
+
# (`RBS::Definition::Method#annotations`, or a declaration / member's own `#annotations`); the result
|
|
52
|
+
# is a `Rigor::Effects::Envelope`, or nil when the list carries neither purity spelling.
|
|
53
|
+
def self?.pure_annotation?: (String? string) -> bool
|
|
54
|
+
def self?.read_effect_envelope: (untyped annotations, owner_key: String, ?source: Symbol, ?registry: untyped, ?reporter: untyped) -> untyped?
|
|
55
|
+
|
|
50
56
|
class ParamOverride
|
|
51
57
|
attr_reader param_name: Symbol
|
|
52
58
|
attr_reader type: Type::t
|
data/sig/rigor.rbs
CHANGED
|
@@ -14,8 +14,12 @@ module Rigor
|
|
|
14
14
|
def self.load: (?String? path) -> Configuration
|
|
15
15
|
def self.discover: () -> String?
|
|
16
16
|
def self.load_with_includes: (String path, ?visited: Set[String]) -> Hash[String, untyped]
|
|
17
|
-
def initialize: (?Hash[String, untyped] data) -> void
|
|
17
|
+
def initialize: (?Hash[String, untyped] data, ?bool effects_key_present) -> void
|
|
18
18
|
def to_h: () -> Hash[String, untyped]
|
|
19
|
+
# ADR-103 WD13 — the `effects:` block, nil when the key was absent. Presence is the opt-in.
|
|
20
|
+
attr_reader effects: Hash[String, untyped]?
|
|
21
|
+
def effects_enabled?: () -> bool
|
|
22
|
+
def with_effects_enabled: () -> Rigor::Configuration
|
|
19
23
|
end
|
|
20
24
|
|
|
21
25
|
class CLI
|
|
@@ -125,6 +129,18 @@ module Rigor
|
|
|
125
129
|
def analysis_file_set: (?Array[String] paths) -> Array[String]
|
|
126
130
|
def file_dependents: () -> Hash[String, untyped]
|
|
127
131
|
def prepare_project_scan: (?paths: Array[String]) -> untyped
|
|
132
|
+
# ADR-103 — the propagated effect graph and the merged per-file collections behind it. A report
|
|
133
|
+
# surface: never a diagnostic, empty when the configuration carries no `effects:` block. Typed
|
|
134
|
+
# `untyped` for the same reason `cache_store` is — `Rigor::Effects` is not sig-covered yet
|
|
135
|
+
# (`spec/rigor/public_api_drift_spec.rb`), and a named reference would raise `RBS::UnknownTypeName`.
|
|
136
|
+
def effect_table: () -> untyped
|
|
137
|
+
def effect_collection: () -> untyped
|
|
138
|
+
# #381 — `{ "Class#m" => [path] }`, which the snapshot's `reach:` globs match against. Same
|
|
139
|
+
# `untyped` reasoning as its two siblings above.
|
|
140
|
+
def effect_sources: () -> untyped
|
|
141
|
+
# #387 — the loaded plugins' compiled effect contributions, read by `rigor effects` so the snapshot's
|
|
142
|
+
# vocabulary is the one the collection window scanned under. Same `untyped` reasoning again.
|
|
143
|
+
def effect_plugin_facts: () -> untyped
|
|
128
144
|
end
|
|
129
145
|
end
|
|
130
146
|
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rigor-unused-adjudicate
|
|
3
|
+
description: |
|
|
4
|
+
Find dead code in a Ruby project with `rigor unused` — establish what the report can see on THIS project first, then adjudicate every row before proposing any deletion. Use this whenever someone asks to find or remove dead code, unused classes, unused constants, or "code nobody calls", whenever they ask what a `rigor unused` report means or which rows are safe to delete, and whenever a dead-code cleanup, codebase inventory, or legacy audit comes up — even if they never say "rigor". The report is a review queue and not a defect list; on an adjudicated corpus target only 4 of 57 rows were genuinely dead, so acting on it directly produces mostly wrong deletions. NOT for deleting a specific class you already know is dead, and NOT for `rigor check` diagnostics (those are ordinary type errors).
|
|
5
|
+
license: MPL-2.0
|
|
6
|
+
metadata:
|
|
7
|
+
version: 0.2.0
|
|
8
|
+
homepage: https://github.com/rigortype/rigor
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Adjudicating `rigor unused`
|
|
12
|
+
|
|
13
|
+
`rigor unused` answers *which project classes and modules does no reachable
|
|
14
|
+
code name?* — not *what can I delete*. Closing that gap is the work, and the
|
|
15
|
+
manual chapter has the method:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
rigor docs 18-removing-dead-code
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Read it before adjudicating anything. It carries the false-positive shapes with
|
|
22
|
+
their measured frequencies, the pre-deletion checklist, and how to report the
|
|
23
|
+
result. This skill exists for the part the chapter cannot do for you: **work out
|
|
24
|
+
what the report can and cannot see on this particular project, before you trust
|
|
25
|
+
a single row.**
|
|
26
|
+
|
|
27
|
+
Do that first, because every check below changes how the output should be read —
|
|
28
|
+
and skipping one is how a live class ends up on a deletion list.
|
|
29
|
+
|
|
30
|
+
## Establish the ground first
|
|
31
|
+
|
|
32
|
+
Run the report and answer these against the project in front of you.
|
|
33
|
+
|
|
34
|
+
**Are framework roots actually supplied?** The summary prints
|
|
35
|
+
`roots: N (M from plugins, …)`. On a framework application `0 from plugins`
|
|
36
|
+
means nothing is naming your controllers, jobs or policies, so most of the
|
|
37
|
+
report is noise. Stop and fix the plugin configuration — `rigor docs
|
|
38
|
+
07-plugins` — rather than adjudicating hundreds of rows.
|
|
39
|
+
|
|
40
|
+
**Does the project ship signatures?** If `signature_paths:` is configured, also
|
|
41
|
+
run with it emptied and compare:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
rigor unused # normal
|
|
45
|
+
rigor unused --config /tmp/no-sig.yml # a copy of your config with signature_paths: []
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Adjudicate the union. On one application the signature-free run surfaced three
|
|
49
|
+
genuinely dead classes that the default run never showed. Rows that appear only
|
|
50
|
+
without signatures are still worth checking — signatures reference classes, and
|
|
51
|
+
a reference the report counts is not always one a human would.
|
|
52
|
+
|
|
53
|
+
**What do `paths:` actually cover?** Only Ruby under those paths is analysed.
|
|
54
|
+
Views are the common gap: a helper called from `app/views/**/*.erb` has no Ruby
|
|
55
|
+
caller at all, and will land in the report looking unused. Before believing any
|
|
56
|
+
helper or presenter row, grep the view tree for it.
|
|
57
|
+
|
|
58
|
+
**Is the git history usable?** The chapter's checklist uses "when did this file
|
|
59
|
+
last change" as evidence. In a shallow clone, or one whose history is all
|
|
60
|
+
dependency bumps, that signal is empty — notice it and say so rather than
|
|
61
|
+
reporting a bot commit as the file's age.
|
|
62
|
+
|
|
63
|
+
## Then hand off to the chapter
|
|
64
|
+
|
|
65
|
+
With that established, follow the chapter. Two things worth holding onto as you
|
|
66
|
+
go, because they are what the report's own design is built around:
|
|
67
|
+
|
|
68
|
+
**Framework conventions and configuration reach code without naming it.** The
|
|
69
|
+
chapter lists the shapes; the ones that recur hardest are a class named as a
|
|
70
|
+
*string* in `config/*.yml` (a recurring-job schedule, a queue definition), a
|
|
71
|
+
convention that derives one name from another (`FooHelper` from
|
|
72
|
+
`FooController`, a decorator from a model, a join model from
|
|
73
|
+
`has_many :speakers_talks`), and a registration DSL called inside the class
|
|
74
|
+
body. None of these appear as a constant anywhere.
|
|
75
|
+
|
|
76
|
+
**Wrong rows cascade.** A class used only by a wrongly-classified class follows
|
|
77
|
+
it into the report. When a row turns out to be live, re-check what it
|
|
78
|
+
references before treating those rows as independent findings.
|
|
79
|
+
|
|
80
|
+
## Two habits that keep the answer honest
|
|
81
|
+
|
|
82
|
+
**A search that finds nothing proves nothing until it has found something.**
|
|
83
|
+
Before concluding a name appears nowhere, run the same search against a name you
|
|
84
|
+
know is used. Silence from a broken command and silence from dead code look
|
|
85
|
+
identical.
|
|
86
|
+
|
|
87
|
+
**Over-claiming hides dead code; under-claiming does not.** If you cannot settle
|
|
88
|
+
a row, leave it in the report and say you could not settle it. A row left on the
|
|
89
|
+
list is visible to a human; a row you dismissed on a hunch is invisible to
|
|
90
|
+
everyone.
|
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.3.
|
|
4
|
+
version: 0.3.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rigor contributors
|
|
@@ -292,6 +292,8 @@ files:
|
|
|
292
292
|
- data/core_overlay/psych.rbs
|
|
293
293
|
- data/core_overlay/resolv.rbs
|
|
294
294
|
- data/core_overlay/string_scanner.rbs
|
|
295
|
+
- data/effects/core.yml
|
|
296
|
+
- data/effects/registry.yml
|
|
295
297
|
- data/gem_overlay/activesupport/core_ext.rbs
|
|
296
298
|
- data/vendored_gem_sigs/ast/ast.rbs
|
|
297
299
|
- data/vendored_gem_sigs/bcrypt/bcrypt.rbs
|
|
@@ -357,6 +359,7 @@ files:
|
|
|
357
359
|
- docs/manual/15-type-protection-coverage.md
|
|
358
360
|
- docs/manual/16-rbs-extended-annotations.md
|
|
359
361
|
- docs/manual/17-driving-improvement.md
|
|
362
|
+
- docs/manual/18-removing-dead-code.md
|
|
360
363
|
- docs/manual/README.md
|
|
361
364
|
- docs/manual/ci-templates/README.md
|
|
362
365
|
- docs/manual/plugins/README.md
|
|
@@ -425,6 +428,11 @@ files:
|
|
|
425
428
|
- lib/rigor/analysis/path_expansion.rb
|
|
426
429
|
- lib/rigor/analysis/plugin_fact_fingerprint.rb
|
|
427
430
|
- lib/rigor/analysis/project_scan.rb
|
|
431
|
+
- lib/rigor/analysis/reachability/graph.rb
|
|
432
|
+
- lib/rigor/analysis/reachability/plugin_roots.rb
|
|
433
|
+
- lib/rigor/analysis/reachability/project_files.rb
|
|
434
|
+
- lib/rigor/analysis/reachability/scan.rb
|
|
435
|
+
- lib/rigor/analysis/reachability/signature_scan.rb
|
|
428
436
|
- lib/rigor/analysis/result.rb
|
|
429
437
|
- lib/rigor/analysis/rule_catalog.rb
|
|
430
438
|
- lib/rigor/analysis/run_cache_key.rb
|
|
@@ -432,7 +440,11 @@ files:
|
|
|
432
440
|
- lib/rigor/analysis/run_stats.rb
|
|
433
441
|
- lib/rigor/analysis/runner.rb
|
|
434
442
|
- lib/rigor/analysis/runner/buffer_pool_dispatcher.rb
|
|
443
|
+
- lib/rigor/analysis/runner/declaration_position.rb
|
|
435
444
|
- lib/rigor/analysis/runner/diagnostic_aggregator.rb
|
|
445
|
+
- lib/rigor/analysis/runner/effect_annotation_residual_pass.rb
|
|
446
|
+
- lib/rigor/analysis/runner/effect_envelope_pass.rb
|
|
447
|
+
- lib/rigor/analysis/runner/envelope_messages.rb
|
|
436
448
|
- lib/rigor/analysis/runner/pool_coordinator.rb
|
|
437
449
|
- lib/rigor/analysis/runner/project_pre_passes.rb
|
|
438
450
|
- lib/rigor/analysis/runner/run_snapshots.rb
|
|
@@ -477,6 +489,12 @@ files:
|
|
|
477
489
|
- lib/rigor/cli/diff_command.rb
|
|
478
490
|
- lib/rigor/cli/docs_command.rb
|
|
479
491
|
- lib/rigor/cli/doctor_command.rb
|
|
492
|
+
- lib/rigor/cli/effects_command.rb
|
|
493
|
+
- lib/rigor/cli/effects_diff_renderer.rb
|
|
494
|
+
- lib/rigor/cli/effects_explain_renderer.rb
|
|
495
|
+
- lib/rigor/cli/effects_renderer.rb
|
|
496
|
+
- lib/rigor/cli/effects_report.rb
|
|
497
|
+
- lib/rigor/cli/effects_snapshot_command.rb
|
|
480
498
|
- lib/rigor/cli/explain_command.rb
|
|
481
499
|
- lib/rigor/cli/fused_protection_renderer.rb
|
|
482
500
|
- lib/rigor/cli/fused_protection_report.rb
|
|
@@ -509,11 +527,48 @@ files:
|
|
|
509
527
|
- lib/rigor/cli/type_scan_command.rb
|
|
510
528
|
- lib/rigor/cli/type_scan_renderer.rb
|
|
511
529
|
- lib/rigor/cli/type_scan_report.rb
|
|
530
|
+
- lib/rigor/cli/unused_command.rb
|
|
512
531
|
- lib/rigor/cli/upgrade_command.rb
|
|
513
532
|
- lib/rigor/config_audit.rb
|
|
514
533
|
- lib/rigor/configuration.rb
|
|
515
534
|
- lib/rigor/configuration/dependencies.rb
|
|
516
535
|
- lib/rigor/configuration/severity_profile.rb
|
|
536
|
+
- lib/rigor/effects.rb
|
|
537
|
+
- lib/rigor/effects/attribution.rb
|
|
538
|
+
- lib/rigor/effects/catalog.rb
|
|
539
|
+
- lib/rigor/effects/collector.rb
|
|
540
|
+
- lib/rigor/effects/config_envelopes.rb
|
|
541
|
+
- lib/rigor/effects/discharge.rb
|
|
542
|
+
- lib/rigor/effects/effect_table.rb
|
|
543
|
+
- lib/rigor/effects/entry_points.rb
|
|
544
|
+
- lib/rigor/effects/envelope.rb
|
|
545
|
+
- lib/rigor/effects/envelope_check.rb
|
|
546
|
+
- lib/rigor/effects/envelope_index.rb
|
|
547
|
+
- lib/rigor/effects/file_collection.rb
|
|
548
|
+
- lib/rigor/effects/framework_units.rb
|
|
549
|
+
- lib/rigor/effects/identity.rb
|
|
550
|
+
- lib/rigor/effects/label.rb
|
|
551
|
+
- lib/rigor/effects/label_intent.rb
|
|
552
|
+
- lib/rigor/effects/label_set.rb
|
|
553
|
+
- lib/rigor/effects/liskov_check.rb
|
|
554
|
+
- lib/rigor/effects/local_ownership.rb
|
|
555
|
+
- lib/rigor/effects/method_key.rb
|
|
556
|
+
- lib/rigor/effects/mutation_classifier.rb
|
|
557
|
+
- lib/rigor/effects/narrowing.rb
|
|
558
|
+
- lib/rigor/effects/origin.rb
|
|
559
|
+
- lib/rigor/effects/path_finder.rb
|
|
560
|
+
- lib/rigor/effects/plugin_facts.rb
|
|
561
|
+
- lib/rigor/effects/propagator.rb
|
|
562
|
+
- lib/rigor/effects/registry.rb
|
|
563
|
+
- lib/rigor/effects/scanner.rb
|
|
564
|
+
- lib/rigor/effects/signature_sources.rb
|
|
565
|
+
- lib/rigor/effects/snapshot.rb
|
|
566
|
+
- lib/rigor/effects/snapshot_diff.rb
|
|
567
|
+
- lib/rigor/effects/summary.rb
|
|
568
|
+
- lib/rigor/effects/taint_cause.rb
|
|
569
|
+
- lib/rigor/effects/unit_scan.rb
|
|
570
|
+
- lib/rigor/effects/unknown_label_check.rb
|
|
571
|
+
- lib/rigor/effects/unknown_label_report.rb
|
|
517
572
|
- lib/rigor/environment.rb
|
|
518
573
|
- lib/rigor/environment/bundle_sig_discovery.rb
|
|
519
574
|
- lib/rigor/environment/class_registry.rb
|
|
@@ -609,6 +664,7 @@ files:
|
|
|
609
664
|
- lib/rigor/inference/optimistic_origin.rb
|
|
610
665
|
- lib/rigor/inference/origin_lookup.rb
|
|
611
666
|
- lib/rigor/inference/parameter_inference_collector.rb
|
|
667
|
+
- lib/rigor/inference/pre_eval_constants.rb
|
|
612
668
|
- lib/rigor/inference/precision_scanner.rb
|
|
613
669
|
- lib/rigor/inference/project_patched_methods.rb
|
|
614
670
|
- lib/rigor/inference/project_patched_scanner.rb
|
|
@@ -652,7 +708,11 @@ files:
|
|
|
652
708
|
- lib/rigor/plugin/base.rb
|
|
653
709
|
- lib/rigor/plugin/blueprint.rb
|
|
654
710
|
- lib/rigor/plugin/box.rb
|
|
711
|
+
- lib/rigor/plugin/effect_attribution.rb
|
|
712
|
+
- lib/rigor/plugin/effect_edge.rb
|
|
713
|
+
- lib/rigor/plugin/effect_entry_points.rb
|
|
655
714
|
- lib/rigor/plugin/fact_store.rb
|
|
715
|
+
- lib/rigor/plugin/first_party.rb
|
|
656
716
|
- lib/rigor/plugin/inflector.rb
|
|
657
717
|
- lib/rigor/plugin/io_boundary.rb
|
|
658
718
|
- lib/rigor/plugin/isolation.rb
|
|
@@ -683,6 +743,7 @@ files:
|
|
|
683
743
|
- lib/rigor/protection/test_suite_oracle.rb
|
|
684
744
|
- lib/rigor/rbs_extended.rb
|
|
685
745
|
- lib/rigor/rbs_extended/conformance_checker.rb
|
|
746
|
+
- lib/rigor/rbs_extended/envelope_scanner.rb
|
|
686
747
|
- lib/rigor/rbs_extended/hkt_directives.rb
|
|
687
748
|
- lib/rigor/rbs_extended/reporter.rb
|
|
688
749
|
- lib/rigor/reflection.rb
|
|
@@ -758,9 +819,11 @@ files:
|
|
|
758
819
|
- plugins/rigor-actioncable/lib/rigor/plugin/actioncable/analyzer.rb
|
|
759
820
|
- plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb
|
|
760
821
|
- plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb
|
|
822
|
+
- plugins/rigor-actioncable/lib/rigor/plugin/actioncable/effects.rb
|
|
761
823
|
- plugins/rigor-actionmailer/lib/rigor-actionmailer.rb
|
|
762
824
|
- plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb
|
|
763
825
|
- plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/analyzer.rb
|
|
826
|
+
- plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/effects.rb
|
|
764
827
|
- plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb
|
|
765
828
|
- plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb
|
|
766
829
|
- plugins/rigor-actionpack/lib/rigor-actionpack.rb
|
|
@@ -768,14 +831,18 @@ files:
|
|
|
768
831
|
- plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb
|
|
769
832
|
- plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_discoverer.rb
|
|
770
833
|
- plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb
|
|
834
|
+
- plugins/rigor-actionpack/lib/rigor/plugin/actionpack/effects.rb
|
|
771
835
|
- plugins/rigor-activejob/lib/rigor-activejob.rb
|
|
772
836
|
- plugins/rigor-activejob/lib/rigor/plugin/activejob.rb
|
|
773
837
|
- plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb
|
|
838
|
+
- plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb
|
|
774
839
|
- plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb
|
|
775
840
|
- plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb
|
|
841
|
+
- plugins/rigor-activejob/lib/rigor/plugin/activejob/recurring_scan.rb
|
|
776
842
|
- plugins/rigor-activerecord/lib/rigor-activerecord.rb
|
|
777
843
|
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb
|
|
778
844
|
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb
|
|
845
|
+
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb
|
|
779
846
|
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb
|
|
780
847
|
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb
|
|
781
848
|
- plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb
|
|
@@ -787,8 +854,10 @@ files:
|
|
|
787
854
|
- plugins/rigor-activestorage/lib/rigor/plugin/activestorage/analyzer.rb
|
|
788
855
|
- plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb
|
|
789
856
|
- plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb
|
|
857
|
+
- plugins/rigor-activestorage/lib/rigor/plugin/activestorage/effects.rb
|
|
790
858
|
- plugins/rigor-activesupport-core-ext/lib/rigor-activesupport-core-ext.rb
|
|
791
859
|
- plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb
|
|
860
|
+
- plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb
|
|
792
861
|
- plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs
|
|
793
862
|
- plugins/rigor-devise/lib/rigor-devise.rb
|
|
794
863
|
- plugins/rigor-devise/lib/rigor/plugin/devise.rb
|
|
@@ -826,15 +895,18 @@ files:
|
|
|
826
895
|
- plugins/rigor-pundit/lib/rigor-pundit.rb
|
|
827
896
|
- plugins/rigor-pundit/lib/rigor/plugin/pundit.rb
|
|
828
897
|
- plugins/rigor-pundit/lib/rigor/plugin/pundit/analyzer.rb
|
|
898
|
+
- plugins/rigor-pundit/lib/rigor/plugin/pundit/authorization_scan.rb
|
|
829
899
|
- plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb
|
|
830
900
|
- plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_index.rb
|
|
831
901
|
- plugins/rigor-rails-i18n/lib/rigor-rails-i18n.rb
|
|
832
902
|
- plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n.rb
|
|
833
903
|
- plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb
|
|
904
|
+
- plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/effects.rb
|
|
834
905
|
- plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb
|
|
835
906
|
- plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb
|
|
836
907
|
- plugins/rigor-rails-routes/lib/rigor-rails-routes.rb
|
|
837
908
|
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb
|
|
909
|
+
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/acronyms.rb
|
|
838
910
|
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb
|
|
839
911
|
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb
|
|
840
912
|
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/doorkeeper_routes.rb
|
|
@@ -843,6 +915,9 @@ files:
|
|
|
843
915
|
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_table.rb
|
|
844
916
|
- plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb
|
|
845
917
|
- plugins/rigor-rails/lib/rigor-rails.rb
|
|
918
|
+
- plugins/rigor-railties/lib/rigor-railties.rb
|
|
919
|
+
- plugins/rigor-railties/lib/rigor/plugin/railties.rb
|
|
920
|
+
- plugins/rigor-railties/lib/rigor/plugin/railties/effects.rb
|
|
846
921
|
- plugins/rigor-rbs-inline/lib/rigor-rbs-inline.rb
|
|
847
922
|
- plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb
|
|
848
923
|
- plugins/rigor-rspec-rails/lib/rigor-rspec-rails.rb
|
|
@@ -862,6 +937,7 @@ files:
|
|
|
862
937
|
- plugins/rigor-sidekiq/lib/rigor-sidekiq.rb
|
|
863
938
|
- plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb
|
|
864
939
|
- plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/analyzer.rb
|
|
940
|
+
- plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/schedule_scan.rb
|
|
865
941
|
- plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_discoverer.rb
|
|
866
942
|
- plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq/worker_index.rb
|
|
867
943
|
- plugins/rigor-sinatra/lib/rigor-sinatra.rb
|
|
@@ -946,6 +1022,7 @@ files:
|
|
|
946
1022
|
- skills/rigor-project-init/references/05-jit-performance.md
|
|
947
1023
|
- skills/rigor-protection-uplift/SKILL.md
|
|
948
1024
|
- skills/rigor-rbs-setup/SKILL.md
|
|
1025
|
+
- skills/rigor-unused-adjudicate/SKILL.md
|
|
949
1026
|
- skills/rigor-upgrade/SKILL.md
|
|
950
1027
|
homepage: https://github.com/rigortype/rigor
|
|
951
1028
|
licenses:
|
|
@@ -988,6 +1065,7 @@ require_paths:
|
|
|
988
1065
|
- plugins/rigor-rails/lib
|
|
989
1066
|
- plugins/rigor-rails-i18n/lib
|
|
990
1067
|
- plugins/rigor-rails-routes/lib
|
|
1068
|
+
- plugins/rigor-railties/lib
|
|
991
1069
|
- plugins/rigor-rbs-inline/lib
|
|
992
1070
|
- plugins/rigor-rspec/lib
|
|
993
1071
|
- plugins/rigor-rspec-rails/lib
|