rigortype 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -3
- data/docs/handbook/08-understanding-errors.md +3 -2
- data/docs/install.md +87 -15
- data/docs/manual/02-cli-reference.md +2 -2
- data/docs/manual/03-configuration.md +5 -0
- data/docs/manual/08-skills.md +4 -3
- data/docs/manual/12-caching.md +43 -4
- data/docs/manual/14-rails-quickstart.md +19 -11
- data/lib/rigor/analysis/check_rules/source_arity.rb +163 -59
- data/lib/rigor/analysis/check_rules.rb +118 -87
- data/lib/rigor/analysis/dependency_recorder.rb +200 -18
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +266 -0
- data/lib/rigor/analysis/incremental_run_slot.rb +171 -0
- data/lib/rigor/analysis/incremental_session.rb +273 -49
- data/lib/rigor/analysis/plugin_fact_fingerprint.rb +24 -13
- data/lib/rigor/analysis/reachability/scan_cache.rb +2 -1
- data/lib/rigor/analysis/run_cache_key.rb +27 -8
- data/lib/rigor/analysis/run_stats.rb +2 -2
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +1 -1
- data/lib/rigor/analysis/runner/pool_coordinator.rb +2 -2
- data/lib/rigor/analysis/runner/project_pre_passes.rb +21 -13
- data/lib/rigor/analysis/runner.rb +337 -46
- data/lib/rigor/analysis/shadow_harness.rb +27 -0
- data/lib/rigor/analysis/source_rbs_gate.rb +157 -0
- data/lib/rigor/analysis/template_unit_paths.rb +6 -4
- data/lib/rigor/analysis/template_units.rb +15 -5
- data/lib/rigor/analysis/worker_session.rb +4 -3
- data/lib/rigor/cache/descriptor.rb +40 -1
- data/lib/rigor/cache/file_digest.rb +28 -0
- data/lib/rigor/cache/incremental_snapshot.rb +70 -8
- data/lib/rigor/cache/store.rb +63 -3
- data/lib/rigor/cache/value_digest.rb +325 -0
- data/lib/rigor/cli/check_command.rb +83 -13
- data/lib/rigor/cli/doctor_command.rb +1 -1
- data/lib/rigor/cli/effects_report.rb +2 -2
- data/lib/rigor/cli/unused_command.rb +3 -3
- data/lib/rigor/cli.rb +1 -1
- data/lib/rigor/config_audit.rb +3 -2
- data/lib/rigor/config_path.rb +29 -0
- data/lib/rigor/configuration/severity_profile.rb +5 -0
- data/lib/rigor/configuration.rb +6 -5
- data/lib/rigor/effects/plugin_facts.rb +6 -6
- data/lib/rigor/environment/bundle_sig_discovery.rb +5 -3
- data/lib/rigor/environment/lockfile_resolver.rb +10 -1
- data/lib/rigor/environment/rbs_collection_discovery.rb +10 -1
- data/lib/rigor/environment/rbs_loader.rb +1 -1
- data/lib/rigor/environment/source_rbs_synthesis.rb +147 -0
- data/lib/rigor/environment.rb +13 -70
- data/lib/rigor/inference/block_parameter_binder.rb +29 -13
- data/lib/rigor/inference/captured_locals.rb +7 -1
- data/lib/rigor/inference/declaration_walk/context.rb +195 -0
- data/lib/rigor/inference/declaration_walk/errors.rb +18 -0
- data/lib/rigor/inference/declaration_walk/shadow.rb +147 -0
- data/lib/rigor/inference/declaration_walk/traversal.rb +441 -0
- data/lib/rigor/inference/declaration_walk.rb +7 -0
- data/lib/rigor/inference/def_node_resolver.rb +3 -2
- data/lib/rigor/inference/definer_resolution.rb +266 -0
- data/lib/rigor/inference/expression_typer.rb +136 -45
- data/lib/rigor/inference/external_ancestor_resolution.rb +13 -16
- data/lib/rigor/inference/guard_rebinding.rb +53 -12
- data/lib/rigor/inference/macro_block_self_type.rb +14 -2
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +46 -26
- data/lib/rigor/inference/module_function_state.rb +213 -0
- data/lib/rigor/inference/multi_target_binder.rb +21 -16
- data/lib/rigor/inference/narrowing.rb +147 -17
- data/lib/rigor/inference/parameter_inference_collector.rb +10 -9
- data/lib/rigor/inference/scope_indexer/certainty.rb +176 -0
- data/lib/rigor/inference/scope_indexer/class_cvars_collector.rb +35 -0
- data/lib/rigor/inference/scope_indexer/def_nestings_collector.rb +47 -0
- data/lib/rigor/inference/scope_indexer/layered_def_nestings.rb +36 -0
- data/lib/rigor/inference/scope_indexer/member_layouts_collector.rb +61 -0
- data/lib/rigor/inference/scope_indexer/mixin_accumulator.rb +130 -0
- data/lib/rigor/inference/scope_indexer/superclasses_collector.rb +64 -0
- data/lib/rigor/inference/scope_indexer.rb +1443 -295
- data/lib/rigor/inference/singleton_hook_decline.rb +253 -0
- data/lib/rigor/inference/statement_evaluator.rb +80 -14
- data/lib/rigor/plugin/base.rb +28 -8
- data/lib/rigor/plugin/io_boundary.rb +82 -4
- data/lib/rigor/plugin/isolation.rb +1 -1
- data/lib/rigor/plugin/trust_policy.rb +3 -3
- data/lib/rigor/protection/discovery_seed.rb +18 -9
- data/lib/rigor/protection/mutation_cache.rb +3 -3
- data/lib/rigor/reflection/constant_ancestors.rb +96 -47
- data/lib/rigor/reflection/constant_path.rb +22 -7
- data/lib/rigor/reflection.rb +2 -3
- data/lib/rigor/scope/discovery_index.rb +218 -2
- data/lib/rigor/scope/resolution_chain/relevance.rb +165 -0
- data/lib/rigor/scope/resolution_chain.rb +884 -0
- data/lib/rigor/scope.rb +295 -322
- data/lib/rigor/sig_gen/alias_index.rb +1 -1
- data/lib/rigor/sig_gen/effect_annotation.rb +2 -2
- data/lib/rigor/sig_gen/generator.rb +22 -16
- data/lib/rigor/type/combinator.rb +25 -1
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +10 -0
- data/sig/rigor/environment.rbs +2 -0
- data/sig/rigor/plugin/io_boundary.rbs +1 -0
- data/sig/rigor/scope.rbs +43 -1
- data/skills/rigor-project-init/SKILL.md +37 -11
- data/skills/rigor-project-init/references/02-configure.md +7 -2
- metadata +25 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "digest"
|
|
4
4
|
require_relative "runner"
|
|
5
|
+
require_relative "../cache/value_digest"
|
|
5
6
|
|
|
6
7
|
module Rigor
|
|
7
8
|
module Analysis
|
|
@@ -98,9 +99,9 @@ module Rigor
|
|
|
98
99
|
def digest_registry(registry)
|
|
99
100
|
return Result.new(digest: nil, opaque_plugin_ids: [].freeze) if registry.nil? || registry.empty?
|
|
100
101
|
|
|
101
|
-
facts_by_plugin = facts_by_plugin(registry.plugins.first&.services&.fact_store)
|
|
102
|
-
parts = fact_parts(facts_by_plugin)
|
|
103
102
|
opaque = []
|
|
103
|
+
facts_by_plugin = facts_by_plugin(registry, opaque)
|
|
104
|
+
parts = fact_parts(facts_by_plugin)
|
|
104
105
|
registry.plugins.each { |plugin| collect_plugin_parts(plugin, facts_by_plugin, parts, opaque) }
|
|
105
106
|
# Sort the parts so the digest is independent of plugin registration / iteration order.
|
|
106
107
|
Result.new(
|
|
@@ -129,16 +130,25 @@ module Rigor
|
|
|
129
130
|
|
|
130
131
|
# `{ plugin_id => ["name=digest", ...] }` for every ADR-9 published fact (channel a). A plugin that
|
|
131
132
|
# published nothing does not appear.
|
|
132
|
-
|
|
133
|
+
#
|
|
134
|
+
# A fact the fingerprint cannot digest is an input it cannot see, so its publisher is opaque, whether or
|
|
135
|
+
# not the publisher contributes a type itself: other plugins read its facts. A fact store that cannot be
|
|
136
|
+
# read at all makes every plugin opaque. Both force the full run; dropping the facts instead would let a
|
|
137
|
+
# plugin with another surface reuse a snapshot its facts no longer match.
|
|
138
|
+
def facts_by_plugin(registry, opaque)
|
|
133
139
|
result = Hash.new { |hash, key| hash[key] = [] }
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
140
|
+
fact_store = registry.plugins.first&.services&.fact_store
|
|
141
|
+
fact_store&.each_fact do |fact|
|
|
142
|
+
plugin_id = fact.plugin_id.to_s
|
|
143
|
+
begin
|
|
144
|
+
result[plugin_id] << "#{fact.name}=#{digest_value(fact.value)}"
|
|
145
|
+
rescue StandardError
|
|
146
|
+
opaque << plugin_id
|
|
147
|
+
end
|
|
138
148
|
end
|
|
139
149
|
result
|
|
140
150
|
rescue StandardError
|
|
141
|
-
|
|
151
|
+
registry.plugins.each { |plugin| opaque << safe_id(plugin) }
|
|
142
152
|
Hash.new { |hash, key| hash[key] = [] }
|
|
143
153
|
end
|
|
144
154
|
|
|
@@ -175,12 +185,13 @@ module Rigor
|
|
|
175
185
|
true
|
|
176
186
|
end
|
|
177
187
|
|
|
178
|
-
# A
|
|
179
|
-
#
|
|
180
|
-
#
|
|
181
|
-
#
|
|
188
|
+
# A digest of a fact / producer / hook value that depends on the value alone (issue #1574). A producer's
|
|
189
|
+
# value is computed on one run and served from its ADR-45 cache entry on the next; the two are equal but
|
|
190
|
+
# do not share the same objects, so a digest of their `Marshal.dump` bytes differed and invalidated the
|
|
191
|
+
# snapshot on every such switch. {Cache::ValueDigest} reads no identity. A value it cannot digest raises
|
|
192
|
+
# to the caller, which marks the plugin opaque (never a silent wrong-value digest).
|
|
182
193
|
def digest_value(value)
|
|
183
|
-
|
|
194
|
+
Cache::ValueDigest.hexdigest(value)
|
|
184
195
|
end
|
|
185
196
|
|
|
186
197
|
def contributes_types?(plugin)
|
|
@@ -5,6 +5,7 @@ require "fileutils"
|
|
|
5
5
|
require "zlib"
|
|
6
6
|
|
|
7
7
|
require_relative "../../version"
|
|
8
|
+
require_relative "../../cache/store"
|
|
8
9
|
|
|
9
10
|
module Rigor
|
|
10
11
|
module Analysis
|
|
@@ -94,7 +95,7 @@ module Rigor
|
|
|
94
95
|
keep = @entries.merge(@live).select { |(_, path), _| File.exist?(path) }
|
|
95
96
|
FileUtils.mkdir_p(File.dirname(@path))
|
|
96
97
|
tmp = "#{@path}.#{Process.pid}.tmp"
|
|
97
|
-
File.binwrite(tmp, Zlib::Deflate.deflate(Marshal.dump([@header, keep])))
|
|
98
|
+
File.binwrite(tmp, Zlib::Deflate.deflate(Marshal.dump([@header, keep]), Cache::Store::DEFLATE_LEVEL))
|
|
98
99
|
File.rename(tmp, @path)
|
|
99
100
|
nil
|
|
100
101
|
rescue StandardError
|
|
@@ -21,6 +21,7 @@ require_relative "../environment/default_libraries"
|
|
|
21
21
|
# lockfile paths without loading `rigor/environment` or the RBS machinery.
|
|
22
22
|
require_relative "../environment/lockfile_resolver"
|
|
23
23
|
require_relative "../environment/rbs_collection_discovery"
|
|
24
|
+
require_relative "shadow_harness"
|
|
24
25
|
|
|
25
26
|
module Rigor
|
|
26
27
|
module Analysis
|
|
@@ -93,7 +94,7 @@ module Rigor
|
|
|
93
94
|
Cache::Descriptor.new(
|
|
94
95
|
gems: [Cache::RbsDescriptor.rbs_gem_entry],
|
|
95
96
|
configs: rbs_config_entries + engine_source_entries + lockfile_entries(configuration) +
|
|
96
|
-
template_unit_entries(template_units_digest) + [
|
|
97
|
+
template_unit_entries(template_units_digest) + shadow_harness_entries + [
|
|
97
98
|
config_entry("configuration", Marshal.dump(configuration.to_h)),
|
|
98
99
|
config_entry("engine",
|
|
99
100
|
"#{Rigor::VERSION}:#{Cache::Descriptor::SCHEMA_VERSION}:#{explain}"),
|
|
@@ -116,6 +117,15 @@ module Rigor
|
|
|
116
117
|
digest.nil? ? [] : [config_entry("template-units", digest)]
|
|
117
118
|
end
|
|
118
119
|
|
|
120
|
+
# ADR-116 WD5 — a run under `RIGOR_SHADOW_RULE_WALK` compares every table and rule collector with its
|
|
121
|
+
# legacy oracle, and a divergence is a row of the result. Keying on it keeps a warm hit from answering
|
|
122
|
+
# for a run the harness never checked, and a divergence row from replaying into a run without it. No
|
|
123
|
+
# slot with the harness off, so no existing key moves.
|
|
124
|
+
def shadow_harness_entries
|
|
125
|
+
identity = ShadowHarness.cache_identity
|
|
126
|
+
identity.nil? ? [] : [config_entry("shadow-harness", identity)]
|
|
127
|
+
end
|
|
128
|
+
|
|
119
129
|
def engine_source_entries
|
|
120
130
|
Cache::EngineSource.key_config_entries
|
|
121
131
|
end
|
|
@@ -137,16 +147,25 @@ module Rigor
|
|
|
137
147
|
# Content-only — the resolved PATH is deliberately not in the payload, so a checkout that moves (a CI
|
|
138
148
|
# runner's workspace, a renamed directory) still hits with an identical lockfile.
|
|
139
149
|
def lockfile_entries(configuration)
|
|
140
|
-
bundler =
|
|
141
|
-
lockfile_path: configuration.bundler_lockfile, auto_detect: configuration.bundler_auto_detect
|
|
142
|
-
)
|
|
143
|
-
collection = Environment::RbsCollectionDiscovery.resolve_lockfile_path(
|
|
144
|
-
lockfile_path: configuration.rbs_collection_lockfile,
|
|
145
|
-
auto_detect: configuration.rbs_collection_auto_detect
|
|
146
|
-
)
|
|
150
|
+
bundler, collection = resolved_lockfile_paths(configuration)
|
|
147
151
|
[lockfile_entry("bundler.lockfile", bundler), lockfile_entry("rbs_collection.lockfile", collection)]
|
|
148
152
|
end
|
|
149
153
|
|
|
154
|
+
# The one resolution of the two dependency lockfiles — `[bundler, rbs_collection]`, each a Pathname or nil
|
|
155
|
+
# — shared by this key and by {Cache::IncrementalSnapshot.fingerprint} so the two caches identify the gem
|
|
156
|
+
# set by the same files (issue #1532): `bundler.lockfile:` / `rbs_collection.lockfile:` and auto-detection.
|
|
157
|
+
def resolved_lockfile_paths(configuration)
|
|
158
|
+
[
|
|
159
|
+
Environment::LockfileResolver.resolve_lockfile_path(
|
|
160
|
+
lockfile_path: configuration.bundler_lockfile, auto_detect: configuration.bundler_auto_detect
|
|
161
|
+
),
|
|
162
|
+
Environment::RbsCollectionDiscovery.resolve_lockfile_path(
|
|
163
|
+
lockfile_path: configuration.rbs_collection_lockfile,
|
|
164
|
+
auto_detect: configuration.rbs_collection_auto_detect
|
|
165
|
+
)
|
|
166
|
+
]
|
|
167
|
+
end
|
|
168
|
+
|
|
150
169
|
# `nil` — no lockfile resolves — is itself part of the identity, so it carries its own sentinel rather
|
|
151
170
|
# than dropping the slot: "absent" and "present but empty" must not key the same.
|
|
152
171
|
ABSENT_LOCKFILE = "\0absent"
|
|
@@ -95,12 +95,12 @@ module Rigor
|
|
|
95
95
|
# with any of the signature path prefixes (after expansion to absolute paths); `bundled` is the
|
|
96
96
|
# remainder.
|
|
97
97
|
def self.partition_classes(class_decl_paths:, signature_paths:)
|
|
98
|
-
prefixes = Array(signature_paths).map { |p| File.
|
|
98
|
+
prefixes = Array(signature_paths).map { |p| File.absolute_path(p.to_s) }
|
|
99
99
|
return [0, class_decl_paths.size] if prefixes.empty?
|
|
100
100
|
|
|
101
101
|
project = 0
|
|
102
102
|
class_decl_paths.each_value do |path|
|
|
103
|
-
expanded = File.
|
|
103
|
+
expanded = File.absolute_path(path)
|
|
104
104
|
project += 1 if prefixes.any? { |prefix| expanded.start_with?("#{prefix}/") || expanded == prefix }
|
|
105
105
|
end
|
|
106
106
|
[project, class_decl_paths.size - project]
|
|
@@ -965,7 +965,7 @@ module Rigor
|
|
|
965
965
|
|
|
966
966
|
# Issue #959 — surfaces the {Plugin::IoBoundary} refusal history each loaded plugin accumulated over
|
|
967
967
|
# the whole run (prepare AND every per-file call: `#io_boundary` is memoised per plugin instance, so
|
|
968
|
-
# one boundary sees both). `TrustPolicy#allow_read?` stays `File.
|
|
968
|
+
# one boundary sees both). `TrustPolicy#allow_read?` stays `File.absolute_path`-only per ADR-2 — a
|
|
969
969
|
# project rooted under a symlink (macOS' `/tmp` → `/private/tmp` is the common case) can have every
|
|
970
970
|
# plugin read fall outside its own read roots with nothing said about it. One `:info` row per plugin
|
|
971
971
|
# that hit this, never one per path, naming the count and the first path so the row stays legible on
|
|
@@ -287,10 +287,10 @@ module Rigor
|
|
|
287
287
|
buffers = failure.is_a?(Array) ? failure[3] : nil
|
|
288
288
|
return false if buffers.nil?
|
|
289
289
|
|
|
290
|
-
closure_paths = closure.to_set { |path| File.
|
|
290
|
+
closure_paths = closure.to_set { |path| File.absolute_path(path.to_s) }
|
|
291
291
|
Array(buffers).any? do |name|
|
|
292
292
|
path = virtual_buffer_path(name)
|
|
293
|
-
!path.nil? && closure_paths.include?(File.
|
|
293
|
+
!path.nil? && closure_paths.include?(File.absolute_path(path))
|
|
294
294
|
end
|
|
295
295
|
end
|
|
296
296
|
|
|
@@ -23,7 +23,7 @@ module Rigor
|
|
|
23
23
|
# ivar surface, preserving the exact assignment order and timing the inline body had. The `pool_mode`
|
|
24
24
|
# predicate is injected (it keys on `@workers` / `@buffer`, owned by the Runner) so this collaborator
|
|
25
25
|
# never calls back into it.
|
|
26
|
-
class ProjectPrePasses
|
|
26
|
+
class ProjectPrePasses # rubocop:disable Metrics/ClassLength -- the Discovery slots are one declaration per table
|
|
27
27
|
# Frozen bundle of the EAGER (env-input) project-wide state the pre-passes produce — the slots whose
|
|
28
28
|
# products feed the RBS environment build. Mirrors the env-input ivars `apply_pre_passes_result`
|
|
29
29
|
# sets on the {Runner}. The cross-file discovery tables live in the separate {Discovery} bundle
|
|
@@ -53,12 +53,13 @@ module Rigor
|
|
|
53
53
|
# consumes them and so never pays the double parse (see {#discover} + `Runner#ensure_project_discovery`).
|
|
54
54
|
# The slot names mirror the discovery half of {Result} exactly.
|
|
55
55
|
Discovery = Data.define(
|
|
56
|
-
:discovered_classes, :discovered_def_nodes, :discovered_def_nestings,
|
|
57
|
-
:
|
|
58
|
-
:
|
|
59
|
-
:
|
|
56
|
+
:discovered_classes, :discovered_def_nodes, :discovered_def_nestings, :discovered_singleton_def_nodes,
|
|
57
|
+
:discovered_def_sources, :discovered_singleton_def_sources, :discovered_superclasses,
|
|
58
|
+
:discovered_header_nestings, :discovered_includes, :discovered_prepends, :discovered_extends,
|
|
59
|
+
:unpositioned_mixins, :discovered_class_sources, :constant_values, :constant_sources, :constant_writes,
|
|
60
60
|
:discovered_method_visibilities, :discovered_methods, :discovered_parameter_envelopes, :data_member_layouts,
|
|
61
|
-
:struct_member_layouts, :discovered_deferred_ranges, :discovered_refinements, :
|
|
61
|
+
:struct_member_layouts, :discovered_deferred_ranges, :discovered_refinements, :siblings,
|
|
62
|
+
:discovered_global_write_census
|
|
62
63
|
)
|
|
63
64
|
|
|
64
65
|
# Internal: drives every EAGER project-wide pre-pass — the ones whose products feed the RBS
|
|
@@ -172,7 +173,7 @@ module Rigor
|
|
|
172
173
|
discovered_prepends: def_index.fetch(:prepends),
|
|
173
174
|
# Issue #898 — the singleton-side mixin table, kept beside the instance-side one so a class
|
|
174
175
|
# object's `extend`s reach `Narrowing` from a sibling file the way its `include`s already do.
|
|
175
|
-
discovered_extends: def_index.fetch(:extends),
|
|
176
|
+
discovered_extends: def_index.fetch(:extends), unpositioned_mixins: def_index.fetch(:unpositioned_mixins),
|
|
176
177
|
discovered_class_sources: def_index.fetch(:class_sources),
|
|
177
178
|
# Issue #644 — the cross-file value-constant publication table and its write attribution.
|
|
178
179
|
constant_values: def_index.fetch(:constant_values), constant_sources: def_index.fetch(:constant_sources),
|
|
@@ -186,7 +187,8 @@ module Rigor
|
|
|
186
187
|
# `*_def_shadows_call?` predicates order `sig`-shadowing defs against.
|
|
187
188
|
discovered_deferred_ranges: def_index.fetch(:deferred_ranges),
|
|
188
189
|
discovered_refinements: def_index.fetch(:refinements), # Issue #1120
|
|
189
|
-
|
|
190
|
+
# Issue #1367 — the census; ADR-119 WD1 — `{sibling name => table}` for `DiscoveryIndex::SIBLINGS`.
|
|
191
|
+
discovered_global_write_census: def_index.fetch(:global_write_census), siblings: def_index.fetch(:siblings)
|
|
190
192
|
)
|
|
191
193
|
end
|
|
192
194
|
|
|
@@ -233,13 +235,19 @@ module Rigor
|
|
|
233
235
|
# {Rigor::Plugin::Registry} WITHOUT the synthetic-method / dependency-source / pre-eval scanners. The
|
|
234
236
|
# incremental fact-surface fingerprint probe ({Analysis::PluginFactFingerprint}) uses this to read the
|
|
235
237
|
# ADR-9 fact store + drive the ADR-60 producers without paying for the full pre-pass or building the RBS
|
|
236
|
-
# environment. `prepare` runs
|
|
238
|
+
# environment. `prepare` runs whatever the pool mode — the probe is always sequential (its `pool_mode?`
|
|
237
239
|
# reader returns false), so the pool-mode skip in {#run} does not apply. Prepare diagnostics are
|
|
238
240
|
# discarded: a plugin that raises in `#prepare` publishes no facts, so its surface is simply absent from
|
|
239
241
|
# the fingerprint, exactly as it would be absent from analysis.
|
|
240
|
-
|
|
242
|
+
#
|
|
243
|
+
# Issue #1536 — `prepare: false` loads the plugins without running `#prepare`, for a caller that reads
|
|
244
|
+
# only what a manifest declares: the incremental session reads each plugin's `source_rbs_synthesizer`
|
|
245
|
+
# before its recheck runner exists. A synthesizer's output is a function of the file, the plugin's
|
|
246
|
+
# config and the engine — the key its `Cache::Store` entry already rests on — so `#prepare` has
|
|
247
|
+
# nothing to add to it, and skipping it keeps that read off every plugin's prepare-time scans.
|
|
248
|
+
def prepared_registry(prepare: true)
|
|
241
249
|
registry = load_plugins
|
|
242
|
-
plugin_prepare_diagnostics(registry)
|
|
250
|
+
plugin_prepare_diagnostics(registry) if prepare && !registry.empty?
|
|
243
251
|
registry
|
|
244
252
|
end
|
|
245
253
|
|
|
@@ -288,12 +296,12 @@ module Rigor
|
|
|
288
296
|
def build_trust_policy
|
|
289
297
|
trusted_gems = @configuration.plugins.map { |entry| trusted_gem_name(entry) }.uniq
|
|
290
298
|
roots = [Dir.pwd]
|
|
291
|
-
Array(@configuration.signature_paths).each { |sp| roots << File.
|
|
299
|
+
Array(@configuration.signature_paths).each { |sp| roots << File.absolute_path(sp) }
|
|
292
300
|
trusted_gems.each do |gem_name|
|
|
293
301
|
path = trusted_gem_root(gem_name)
|
|
294
302
|
roots << path if path
|
|
295
303
|
end
|
|
296
|
-
@configuration.plugins_io_allowed_paths.each { |p| roots << File.
|
|
304
|
+
@configuration.plugins_io_allowed_paths.each { |p| roots << File.absolute_path(p) }
|
|
297
305
|
|
|
298
306
|
Plugin::TrustPolicy.new(
|
|
299
307
|
trusted_gems: trusted_gems,
|