rigortype 0.4.7 → 0.4.8
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 +3 -1
- data/data/core_overlay/bigdecimal.rbs +33 -0
- data/data/core_overlay/resolv.rbs +30 -0
- data/data/gem_overlay/activesupport/core_ext.rbs +29 -0
- data/data/gem_overlay/addressable/addressable.rbs +40 -0
- data/docs/handbook/01-getting-started.md +1 -1
- data/docs/handbook/11-sig-gen.md +35 -0
- data/docs/install.md +20 -0
- data/docs/manual/01-installation.md +67 -26
- data/docs/manual/02-cli-reference.md +307 -91
- data/docs/manual/03-configuration.md +41 -3
- data/docs/manual/04-diagnostics.md +5 -4
- data/docs/manual/08-skills.md +11 -0
- data/docs/manual/09-editor-integration.md +8 -0
- data/docs/manual/14-rails-quickstart.md +1 -1
- data/docs/manual/19-effect-labels.md +3 -4
- data/docs/manual/plugins/rigor-actionpack.md +15 -6
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +3 -0
- data/docs/manual/plugins/rigor-sorbet.md +17 -3
- data/lib/rigor/analysis/check_rules/always_raises_shield.rb +147 -0
- data/lib/rigor/analysis/check_rules/call_facts.rb +58 -0
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +8 -0
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +13 -2
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +6 -0
- data/lib/rigor/analysis/check_rules/plugin_api_surface.rb +195 -0
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +40 -11
- data/lib/rigor/analysis/check_rules/rbs_receiver_surface.rb +27 -1
- data/lib/rigor/analysis/check_rules/replaced_singleton_defs.rb +96 -0
- data/lib/rigor/analysis/check_rules/rule_ids.rb +8 -1
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules.rb +598 -99
- data/lib/rigor/analysis/crash_signature.rb +43 -1
- data/lib/rigor/analysis/dependency_recorder.rb +233 -76
- data/lib/rigor/analysis/incremental.rb +11 -1
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +2 -1
- data/lib/rigor/analysis/incremental_session.rb +279 -37
- data/lib/rigor/analysis/reachability/plugin_roots.rb +6 -3
- data/lib/rigor/analysis/rule_catalog.rb +37 -1
- data/lib/rigor/analysis/run_cache_key.rb +27 -3
- data/lib/rigor/analysis/run_disclosure_credit.rb +26 -6
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +4 -0
- data/lib/rigor/analysis/runner/declaration_position.rb +7 -7
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +72 -20
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +3 -8
- data/lib/rigor/analysis/runner/pool_coordinator.rb +26 -5
- data/lib/rigor/analysis/runner/project_pre_passes.rb +4 -37
- data/lib/rigor/analysis/runner.rb +222 -39
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +61 -22
- data/lib/rigor/analysis/worker_session.rb +42 -41
- data/lib/rigor/bleeding_edge.rb +19 -4
- data/lib/rigor/cache/file_digest.rb +39 -31
- data/lib/rigor/cache/incremental_snapshot.rb +66 -7
- data/lib/rigor/cache/rbs_descriptor.rb +37 -2
- data/lib/rigor/cache/rbs_environment.rb +5 -1
- data/lib/rigor/cli/baseline_command.rb +15 -2
- data/lib/rigor/cli/check_command.rb +4 -2
- data/lib/rigor/cli/effects_snapshot_command.rb +8 -1
- data/lib/rigor/cli/lens_command.rb +17 -2
- data/lib/rigor/cli/sig_gen_command.rb +8 -0
- data/lib/rigor/cli/skill_describe.rb +1 -0
- data/lib/rigor/cli.rb +5 -2
- data/lib/rigor/config_audit.rb +32 -18
- data/lib/rigor/configuration/severity_profile.rb +9 -0
- data/lib/rigor/configuration.rb +32 -5
- data/lib/rigor/effects/collector.rb +53 -21
- data/lib/rigor/environment/bundle_sig_discovery.rb +63 -28
- data/lib/rigor/environment/constant_type_cache_holder.rb +5 -0
- data/lib/rigor/environment/default_libraries.rb +17 -0
- data/lib/rigor/environment/deferred_signature_plan.rb +104 -6
- data/lib/rigor/environment/hkt_registry_holder.rb +6 -0
- data/lib/rigor/environment/rbs_collection_discovery.rb +123 -8
- data/lib/rigor/environment/rbs_coverage_report.rb +12 -11
- data/lib/rigor/environment/rbs_hierarchy.rb +6 -0
- data/lib/rigor/environment/rbs_loader.rb +312 -63
- data/lib/rigor/environment.rb +131 -35
- data/lib/rigor/inference/acceptance.rb +50 -15
- data/lib/rigor/inference/alias_mutation_floor/foreign_locals.rb +117 -0
- data/lib/rigor/inference/alias_mutation_floor/memos.rb +85 -0
- data/lib/rigor/inference/alias_mutation_floor/reach.rb +119 -0
- data/lib/rigor/inference/alias_mutation_floor/site_collector.rb +252 -0
- data/lib/rigor/inference/alias_mutation_floor.rb +339 -0
- data/lib/rigor/inference/anonymous_meta_class.rb +18 -0
- data/lib/rigor/inference/block_auto_splat.rb +1 -1
- data/lib/rigor/inference/block_run_count.rb +9 -2
- data/lib/rigor/inference/builtins/array_catalog.rb +2 -2
- data/lib/rigor/inference/callee_mutation_chain.rb +1 -1
- data/lib/rigor/inference/captured_locals.rb +2 -0
- data/lib/rigor/inference/census_foreign_block.rb +354 -0
- data/lib/rigor/inference/clause_widening.rb +1 -1
- data/lib/rigor/inference/closure_escape_analyzer.rb +11 -4
- data/lib/rigor/inference/construction_escape.rb +56 -15
- data/lib/rigor/inference/declaration_walk.rb +4 -0
- data/lib/rigor/inference/def_node_resolver.rb +32 -14
- data/lib/rigor/inference/def_return_typer.rb +1 -1
- data/lib/rigor/inference/definer_resolution.rb +15 -7
- data/lib/rigor/inference/definers_index.rb +72 -16
- data/lib/rigor/inference/error_info.rb +16 -0
- data/lib/rigor/inference/expression_typer.rb +1459 -287
- data/lib/rigor/inference/flow_tracer.rb +31 -14
- data/lib/rigor/inference/fork_map.rb +3 -0
- data/lib/rigor/inference/fresh_frame_blocks.rb +52 -1
- data/lib/rigor/inference/global_write_census.rb +8 -6
- data/lib/rigor/inference/in_effect_refinements.rb +7 -0
- data/lib/rigor/inference/indexed_narrowing.rb +57 -8
- data/lib/rigor/inference/ivar_writer_census.rb +106 -11
- data/lib/rigor/inference/key_presence_guard.rb +51 -25
- data/lib/rigor/inference/last_line/self_evidence.rb +30 -0
- data/lib/rigor/inference/last_line.rb +5 -2
- data/lib/rigor/inference/loop_value_record.rb +63 -15
- data/lib/rigor/inference/match_rebinding/frame.rb +11 -0
- data/lib/rigor/inference/match_rebinding/yielding_match.rb +74 -18
- data/lib/rigor/inference/match_rebinding.rb +21 -8
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +43 -29
- data/lib/rigor/inference/method_dispatcher/class_keyed_block_params.rb +65 -0
- data/lib/rigor/inference/method_dispatcher/core_enumerable_receiver.rb +44 -0
- data/lib/rigor/inference/method_dispatcher/declared_constructor.rb +151 -0
- data/lib/rigor/inference/method_dispatcher/facet_distribution.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/imprecise_argument.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/interface_shape.rb +181 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +12 -0
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +409 -67
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +384 -64
- data/lib/rigor/inference/method_dispatcher/singleton_type_params.rb +104 -0
- data/lib/rigor/inference/method_dispatcher.rb +66 -18
- data/lib/rigor/inference/method_parameter_binder.rb +136 -56
- data/lib/rigor/inference/module_function_state/spellings.rb +2 -2
- data/lib/rigor/inference/module_function_state.rb +13 -2
- data/lib/rigor/inference/multi_target_binder.rb +1 -1
- data/lib/rigor/inference/mutation_widening.rb +44 -4
- data/lib/rigor/inference/narrowing.rb +201 -27
- data/lib/rigor/inference/operand_effects.rb +43 -2
- data/lib/rigor/inference/optimistic_origin.rb +133 -8
- data/lib/rigor/inference/origin_lookup.rb +1 -1
- data/lib/rigor/inference/precision_scanner.rb +1 -1
- data/lib/rigor/inference/project_method_ownership.rb +28 -10
- data/lib/rigor/inference/project_patched_methods.rb +65 -13
- data/lib/rigor/inference/project_patched_scanner.rb +120 -25
- data/lib/rigor/inference/project_patched_visibility.rb +39 -3
- data/lib/rigor/inference/rbs_type_translator.rb +68 -15
- data/lib/rigor/inference/receiver_writer_call.rb +67 -0
- data/lib/rigor/inference/recursion_rebinding.rb +157 -0
- data/lib/rigor/inference/refined_dispatch/constructed_class.rb +56 -18
- data/lib/rigor/inference/refined_dispatch/own_method.rb +51 -17
- data/lib/rigor/inference/refined_dispatch.rb +13 -0
- data/lib/rigor/inference/reflective_ivar_write.rb +19 -11
- data/lib/rigor/inference/remover_holder_scan.rb +76 -22
- data/lib/rigor/inference/scope_indexer/class_cvars_collector.rb +13 -6
- data/lib/rigor/inference/scope_indexer/declared_param_writes.rb +12 -11
- data/lib/rigor/inference/scope_indexer/ivar_contributions.rb +188 -28
- data/lib/rigor/inference/scope_indexer/mixin_accumulator.rb +136 -9
- data/lib/rigor/inference/scope_indexer.rb +2079 -183
- data/lib/rigor/inference/self_call_ivar_writes.rb +26 -7
- data/lib/rigor/inference/self_preserving_block.rb +87 -0
- data/lib/rigor/inference/singleton_hook_decline.rb +41 -6
- data/lib/rigor/inference/singleton_object_constant.rb +32 -2
- data/lib/rigor/inference/statement_evaluator.rb +970 -250
- data/lib/rigor/inference/string_mutation.rb +14 -0
- data/lib/rigor/inference/synthetic_method_scanner.rb +35 -11
- data/lib/rigor/inference/toplevel_def_census.rb +14 -6
- data/lib/rigor/inference/unknown_store_widening.rb +1 -1
- data/lib/rigor/inference/untyped_rejoin.rb +1 -1
- data/lib/rigor/inference/void_tail_summary.rb +29 -10
- data/lib/rigor/lens/claims/comparison.rb +78 -0
- data/lib/rigor/lens/claims/request.rb +131 -0
- data/lib/rigor/lens/claims/type_reader.rb +216 -0
- data/lib/rigor/lens/claims.rb +208 -0
- data/lib/rigor/lens/contract_reader.rb +5 -0
- data/lib/rigor/lens/document.rb +1 -1
- data/lib/rigor/lens/file_reader.rb +21 -8
- data/lib/rigor/lens/run.rb +8 -0
- data/lib/rigor/lens.rb +1 -1
- data/lib/rigor/library_probe.rb +68 -0
- data/lib/rigor/memo_audit.rb +282 -0
- data/lib/rigor/plugin/base.rb +15 -2
- data/lib/rigor/plugin/io_boundary.rb +25 -3
- data/lib/rigor/plugin/manifest.rb +7 -3
- data/lib/rigor/plugin/registry.rb +13 -2
- data/lib/rigor/plugin/trust_policy.rb +46 -0
- data/lib/rigor/protection/mutation_cache.rb +4 -1
- data/lib/rigor/reflection/constant_ancestors.rb +79 -22
- data/lib/rigor/reflection/declaration_collectors.rb +55 -0
- data/lib/rigor/reflection/declarations.rb +58 -0
- data/lib/rigor/reflection/project_method.rb +177 -0
- data/lib/rigor/reflection.rb +2 -0
- data/lib/rigor/rooted_glob.rb +18 -1
- data/lib/rigor/run_scoped_slots.rb +20 -20
- data/lib/rigor/scope/discovery_index.rb +149 -2
- data/lib/rigor/scope/resolution_chain/relevance.rb +14 -1
- data/lib/rigor/scope/resolution_chain.rb +900 -55
- data/lib/rigor/scope.rb +307 -34
- data/lib/rigor/sig_gen/bot_proposal_guard.rb +306 -0
- data/lib/rigor/sig_gen/classification.rb +14 -1
- data/lib/rigor/sig_gen/generator.rb +222 -13
- data/lib/rigor/sig_gen/method_candidate.rb +14 -0
- data/lib/rigor/sig_gen/observation_collector.rb +11 -2
- data/lib/rigor/sig_gen/platform_guarded_files.rb +184 -0
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +47 -0
- data/lib/rigor/sig_gen/writer.rb +21 -0
- data/lib/rigor/sig_gen.rb +1 -0
- data/lib/rigor/source/forwardable_delegators.rb +122 -0
- data/lib/rigor/source/node_children.rb +13 -0
- data/lib/rigor/type/combinator.rb +164 -8
- data/lib/rigor/type/interface.rb +60 -0
- data/lib/rigor/type.rb +1 -0
- data/lib/rigor/type_of_memo/serving.rb +99 -0
- data/lib/rigor/type_of_memo/stats.rb +43 -0
- data/lib/rigor/type_of_memo.rb +337 -0
- data/lib/rigor/typing_state.rb +1094 -0
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +2 -2
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +57 -25
- data/plugins/rigor-active-model-serializers/lib/rigor/plugin/active_model_serializers.rb +3 -6
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/analyzer.rb +25 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_discoverer.rb +16 -6
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/job_index.rb +4 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/analyzer.rb +2 -1
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +130 -30
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +20 -5
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/structure_sql_parser.rb +7 -4
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +49 -13
- data/plugins/rigor-activerecord/sig/active_record/relation.rbs +19 -5
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +4 -2
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +13 -5
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +29 -0
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_collector.rb +15 -21
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_discoverer.rb +1 -6
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +4 -2
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql.rb +12 -2
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +6 -0
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +199 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +3 -2
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +4 -4
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +209 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog_walker.rb +146 -7
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/type_translator.rb +52 -34
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +80 -3
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_collector.rb +16 -16
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_discoverer.rb +1 -6
- data/sig/rigor/analysis/check_rules/rule_walk.rbs +6 -0
- data/sig/rigor/analysis/fact_store.rbs +2 -3
- data/sig/rigor/cache/descriptor.rbs +14 -0
- data/sig/rigor/environment.rbs +4 -1
- data/sig/rigor/plugin/base.rbs +53 -19
- data/sig/rigor/plugin/interfaces.rbs +51 -0
- data/sig/rigor/plugin/io_boundary.rbs +2 -3
- data/sig/rigor/plugin/node_context.rbs +21 -0
- data/sig/rigor/reflection.rbs +37 -0
- data/sig/rigor/scope.rbs +22 -3
- data/sig/rigor/trinary.rbs +1 -0
- data/sig/rigor/type.rbs +9 -3
- data/sig/rigor.rbs +3 -2
- data/skills/rigor-ask/SKILL.md +1 -0
- data/skills/rigor-project-init/references/01-detect.md +1 -0
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +5 -1
- data/skills/rigor-project-init/references/06-agent-contract.md +4 -4
- data/skills/rigor-rbs-contract/SKILL.md +147 -0
- data/skills/rigor-rbs-contract/references/01-finding-candidates.md +212 -0
- data/skills/rigor-rbs-contract/references/02-contract-rules.md +157 -0
- data/skills/rigor-rbs-contract/references/03-target-own-code.md +90 -0
- data/skills/rigor-rbs-contract/references/04-target-gem-rbs-collection.md +210 -0
- data/skills/rigor-rbs-contract/references/05-declaration-mutants.md +182 -0
- data/skills/rigor-rbs-setup/SKILL.md +3 -1
- data/skills/rigor-type-oracle/SKILL.md +26 -1
- data/skills/rigor-type-oracle/references/02-agents-md-fragment.md +4 -3
- metadata +48 -2
- data/lib/rigor/inference/memo_audit.rb +0 -55
|
@@ -4,6 +4,7 @@ require "tmpdir"
|
|
|
4
4
|
|
|
5
5
|
require_relative "../../environment"
|
|
6
6
|
require_relative "../../runtime/jit"
|
|
7
|
+
require_relative "../../type_of_memo"
|
|
7
8
|
|
|
8
9
|
module Rigor
|
|
9
10
|
module Analysis
|
|
@@ -164,10 +165,13 @@ module Rigor
|
|
|
164
165
|
# `exit!` skips `at_exit` / stdio flush; the payload is already durable on disk by then.
|
|
165
166
|
def run_fork_worker(slice, out_path)
|
|
166
167
|
Runtime::Jit.rearm_after_fork
|
|
168
|
+
TypeOfMemo.forked
|
|
167
169
|
results = slice.to_h { |binding, index| [index, run_one(binding)] }
|
|
168
170
|
File.binwrite(out_path, Marshal.dump(results))
|
|
171
|
+
TypeOfMemo.write_report
|
|
169
172
|
exit!(0)
|
|
170
173
|
rescue StandardError
|
|
174
|
+
TypeOfMemo.write_report
|
|
171
175
|
exit!(1)
|
|
172
176
|
end
|
|
173
177
|
|
|
@@ -8,25 +8,25 @@ module Rigor
|
|
|
8
8
|
# The declaration, not the method: this is a fact about what the author wrote, and the fix is on
|
|
9
9
|
# that line. A `.rbs` position is the right answer here even though its sibling deliberately avoids
|
|
10
10
|
# one (the `rbs_extended.unsatisfied-conformance` precedent) — there is no Ruby `def` that could
|
|
11
|
-
# carry the typo. A value written in configuration has no location at all and lands at
|
|
12
|
-
# `.rigor.yml
|
|
11
|
+
# carry the typo. A value written in configuration has no location at all and lands at the loaded
|
|
12
|
+
# configuration file's `1:1` (`.rigor.yml` when none was loaded — #2742), the
|
|
13
|
+
# `rbs.coverage.quarantined-signature` precedent.
|
|
13
14
|
# A declaration's `location` is already the position a reader can open, `.rbs` and rbs-inline
|
|
14
15
|
# alike: the synthesized-buffer line is re-anchored onto the Ruby file where the envelope is
|
|
15
16
|
# built ({Rigor::Effects::InlineAnchor}, #432), so this module only has to split it. Doing the
|
|
16
17
|
# re-anchoring here as well used to be the fix, and it could not tell two identically-spelled
|
|
17
18
|
# annotations in one file apart — every finding in it landed on the first.
|
|
18
19
|
module DeclarationPosition
|
|
19
|
-
CONFIG_PATH = ".rigor.yml"
|
|
20
|
-
|
|
21
20
|
module_function
|
|
22
21
|
|
|
22
|
+
# @param config_path — the path a config-value finding lands at ({Rigor::Configuration#config_display_path}).
|
|
23
23
|
# @return the path and the one-based line of the finding
|
|
24
|
-
def of(finding)
|
|
24
|
+
def of(finding, config_path)
|
|
25
25
|
location = finding.location
|
|
26
|
-
return [
|
|
26
|
+
return [config_path, 1] if location.nil?
|
|
27
27
|
|
|
28
28
|
path, _, raw_line = location.rpartition(":")
|
|
29
|
-
return [
|
|
29
|
+
return [config_path, 1] if path.empty?
|
|
30
30
|
|
|
31
31
|
line = raw_line.to_i
|
|
32
32
|
[path, line.positive? ? line : 1]
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative "../check_rules/rule_ids"
|
|
4
4
|
require_relative "../crash_signature"
|
|
5
5
|
require_relative "../diagnostic"
|
|
6
|
+
require_relative "../run_cache_key"
|
|
6
7
|
require_relative "../severity_stamp"
|
|
7
8
|
|
|
8
9
|
module Rigor
|
|
@@ -99,6 +100,7 @@ module Rigor
|
|
|
99
100
|
dependency_source_budget_diagnostics +
|
|
100
101
|
dependency_source_config_conflict_diagnostics +
|
|
101
102
|
rbs_coverage_diagnostics +
|
|
103
|
+
rbs_collection_setup_hint_diagnostics +
|
|
102
104
|
rbs_inline_annotation_hint_diagnostics(expansion) +
|
|
103
105
|
expansion.fetch(:errors)
|
|
104
106
|
end
|
|
@@ -115,7 +117,7 @@ module Rigor
|
|
|
115
117
|
next if File.file?(path)
|
|
116
118
|
|
|
117
119
|
Diagnostic.new(
|
|
118
|
-
path:
|
|
120
|
+
path: @configuration.config_display_path, line: 1, column: 1,
|
|
119
121
|
message: "pre_eval entry not found: #{path.inspect}. " \
|
|
120
122
|
"Pre-evaluation requires the file to exist on disk; remove the entry " \
|
|
121
123
|
"or create the file before re-running analysis.",
|
|
@@ -163,7 +165,7 @@ module Rigor
|
|
|
163
165
|
def plugin_load_diagnostics
|
|
164
166
|
plugin_registry.load_errors.map do |error|
|
|
165
167
|
Diagnostic.new(
|
|
166
|
-
path:
|
|
168
|
+
path: @configuration.config_display_path,
|
|
167
169
|
line: 1,
|
|
168
170
|
column: 1,
|
|
169
171
|
message: plugin_load_error_message(error),
|
|
@@ -192,7 +194,7 @@ module Rigor
|
|
|
192
194
|
def dependency_source_diagnostics
|
|
193
195
|
dependency_source_index.unresolvable.map do |entry|
|
|
194
196
|
Diagnostic.new(
|
|
195
|
-
path:
|
|
197
|
+
path: @configuration.config_display_path,
|
|
196
198
|
line: 1,
|
|
197
199
|
column: 1,
|
|
198
200
|
message: "dependencies.source_inference[].gem #{entry.gem_name.inspect} could not be " \
|
|
@@ -217,7 +219,7 @@ module Rigor
|
|
|
217
219
|
def dependency_source_config_conflict_diagnostics
|
|
218
220
|
@configuration.dependencies.warnings.map do |message|
|
|
219
221
|
Diagnostic.new(
|
|
220
|
-
path:
|
|
222
|
+
path: @configuration.config_display_path,
|
|
221
223
|
line: 1,
|
|
222
224
|
column: 1,
|
|
223
225
|
message: message,
|
|
@@ -232,7 +234,7 @@ module Rigor
|
|
|
232
234
|
budget = @configuration.dependencies.budget_per_gem
|
|
233
235
|
dependency_source_index.budget_exceeded.map do |gem_name|
|
|
234
236
|
Diagnostic.new(
|
|
235
|
-
path:
|
|
237
|
+
path: @configuration.config_display_path,
|
|
236
238
|
line: 1,
|
|
237
239
|
column: 1,
|
|
238
240
|
message: "dependencies.source_inference[].gem #{gem_name.inspect} exceeded the per-gem " \
|
|
@@ -248,7 +250,8 @@ module Rigor
|
|
|
248
250
|
|
|
249
251
|
# O4 Layer 3 slice 3 — graceful-degradation coverage report. When the project has a `Gemfile.lock`
|
|
250
252
|
# (slice 1) and one or more locked gems are not covered by ANY of the four RBS resolution paths
|
|
251
|
-
# (`DEFAULT_LIBRARIES
|
|
253
|
+
# (the resolved library list — `DEFAULT_LIBRARIES` + `libraries:` + the collection lockfile's stdlib
|
|
254
|
+
# entries, `data/vendored_gem_sigs/`, slice-1 bundle-shipped `sig/`, slice-2
|
|
252
255
|
# `rbs_collection.lock.yaml`), emit a single `:info` diagnostic summarising the uncovered set so the
|
|
253
256
|
# user can act on it (run `rbs collection install`, opt the gem into `dependencies.source_inference:`,
|
|
254
257
|
# or accept the `Dynamic[T]` fallback).
|
|
@@ -279,7 +282,7 @@ module Rigor
|
|
|
279
282
|
)
|
|
280
283
|
rows = Environment::RbsCoverageReport.classify(
|
|
281
284
|
locked_gems: locked,
|
|
282
|
-
default_libraries:
|
|
285
|
+
default_libraries: resolved_default_libraries,
|
|
283
286
|
bundle_sig_paths: bundle_sig_paths,
|
|
284
287
|
rbs_collection_paths: collection_paths
|
|
285
288
|
)
|
|
@@ -289,6 +292,55 @@ module Rigor
|
|
|
289
292
|
[build_rbs_coverage_missing_diagnostic(missing)]
|
|
290
293
|
end
|
|
291
294
|
|
|
295
|
+
# Issue #3030 — one `:info` when the run found no `rbs_collection.lock.yaml` but the directory looks set up for
|
|
296
|
+
# one ({Environment::RbsCollectionDiscovery.missing_lockfile_hint}): the dependency RBS a collection would
|
|
297
|
+
# load is absent, and Rigor does not resolve it from `manifest.yaml` or a gemspec itself.
|
|
298
|
+
def rbs_collection_setup_hint_diagnostics
|
|
299
|
+
# The run-result key and the `--incremental` fingerprint carry the same answer ({RunCacheKey}).
|
|
300
|
+
hint = RunCacheKey.collection_setup_hint(@configuration)
|
|
301
|
+
return [] if hint.nil?
|
|
302
|
+
|
|
303
|
+
[build_rbs_collection_setup_hint_diagnostic(hint)]
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
RBS_COLLECTION_SETUP_STEPS = {
|
|
307
|
+
collection_test_dir: "This looks like a gem_rbs_collection test directory: run the collection's " \
|
|
308
|
+
"`bin/test` setup for this gem first (it writes the lockfile and " \
|
|
309
|
+
"`.gem_rbs_collection/`), then run Rigor here again.",
|
|
310
|
+
collection_config: "An `rbs_collection.yaml` is here: run `rbs collection install` to write the " \
|
|
311
|
+
"lockfile, then run Rigor again."
|
|
312
|
+
}.freeze
|
|
313
|
+
private_constant :RBS_COLLECTION_SETUP_STEPS
|
|
314
|
+
|
|
315
|
+
def build_rbs_collection_setup_hint_diagnostic(hint)
|
|
316
|
+
Diagnostic.new(
|
|
317
|
+
path: @configuration.config_display_path,
|
|
318
|
+
line: 1,
|
|
319
|
+
column: 1,
|
|
320
|
+
message: "No `rbs_collection.lock.yaml` was found, so no `rbs collection` RBS was loaded: the signatures " \
|
|
321
|
+
"of this directory's gem dependencies are absent and calls into them read `Dynamic[top]`. " \
|
|
322
|
+
"#{RBS_COLLECTION_SETUP_STEPS.fetch(hint)}",
|
|
323
|
+
severity: :info,
|
|
324
|
+
rule: "rbs.coverage.collection-not-installed",
|
|
325
|
+
source_family: :builtin
|
|
326
|
+
)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# Issue #2962 — the library list is {Environment::BaseLibraries.resolve}'s, the same merge
|
|
330
|
+
# `Environment.for_project` loads, so a gem covered through `libraries:` or a lockfile stdlib
|
|
331
|
+
# entry is not reported missing. Only the names the environment loads count ({LibraryProbe.loadable}): a
|
|
332
|
+
# locked gem named there that RBS has no library for is still missing.
|
|
333
|
+
def resolved_default_libraries
|
|
334
|
+
resolved = Environment::BaseLibraries.resolve(
|
|
335
|
+
@configuration.libraries,
|
|
336
|
+
rbs_collection_lockfile: @configuration.rbs_collection_lockfile,
|
|
337
|
+
rbs_collection_auto_detect: @configuration.rbs_collection_auto_detect,
|
|
338
|
+
root: Dir.pwd
|
|
339
|
+
)
|
|
340
|
+
LibraryProbe.loadable(resolved)
|
|
341
|
+
end
|
|
342
|
+
private :resolved_default_libraries
|
|
343
|
+
|
|
292
344
|
# Issue #2441 — the same project-own set `Environment.for_project` skips the collection copy of.
|
|
293
345
|
def project_own_gem_names(locked)
|
|
294
346
|
Environment::ProjectPathGems.names(
|
|
@@ -345,7 +397,7 @@ module Rigor
|
|
|
345
397
|
|
|
346
398
|
def build_rbs_inline_unsynthesized_diagnostic(sample_path)
|
|
347
399
|
Diagnostic.new(
|
|
348
|
-
path:
|
|
400
|
+
path: @configuration.config_display_path,
|
|
349
401
|
line: 1,
|
|
350
402
|
column: 1,
|
|
351
403
|
message: "Inline rbs-inline annotations (`# @rbs …`, `#: <type>`) are present in your project " \
|
|
@@ -575,7 +627,7 @@ module Rigor
|
|
|
575
627
|
sample = quarantined.first(sample_size).map { |path, _first_line| relative_signature_path(path) }
|
|
576
628
|
suffix = quarantined.size > sample_size ? ", and #{quarantined.size - sample_size} more" : ""
|
|
577
629
|
Diagnostic.new(
|
|
578
|
-
path:
|
|
630
|
+
path: @configuration.config_display_path,
|
|
579
631
|
line: 1,
|
|
580
632
|
column: 1,
|
|
581
633
|
message: "#{quarantined.size} RBS file(s) under `signature_paths:` were SKIPPED " \
|
|
@@ -598,7 +650,7 @@ module Rigor
|
|
|
598
650
|
suffix = files.size > sample_size ? ", and #{files.size - sample_size} more" : ""
|
|
599
651
|
conflicts = sample.empty? ? "" : " Conflicting signature file(s): #{sample.join(', ')}#{suffix}."
|
|
600
652
|
Diagnostic.new(
|
|
601
|
-
path:
|
|
653
|
+
path: @configuration.config_display_path,
|
|
602
654
|
line: 1,
|
|
603
655
|
column: 1,
|
|
604
656
|
message: "The RBS environment failed to build (#{error_class}): #{first_line}.#{conflicts} " \
|
|
@@ -637,7 +689,7 @@ module Rigor
|
|
|
637
689
|
files = failures.flat_map { |failure| Array(failure[3]) }
|
|
638
690
|
.map { |name| signature_source_label(name.to_s) }.uniq.sort
|
|
639
691
|
Diagnostic.new(
|
|
640
|
-
path:
|
|
692
|
+
path: @configuration.config_display_path,
|
|
641
693
|
line: 1,
|
|
642
694
|
column: 1,
|
|
643
695
|
message: "#{failures.size} RBS class definition(s) failed to build: " \
|
|
@@ -834,7 +886,7 @@ module Rigor
|
|
|
834
886
|
frame_clause = relative_frame ? " at #{relative_frame}" : ""
|
|
835
887
|
raised = "(#{error_class}): #{first_line}#{frame_clause}."
|
|
836
888
|
Diagnostic.new(
|
|
837
|
-
path:
|
|
889
|
+
path: @configuration.config_display_path,
|
|
838
890
|
line: 1,
|
|
839
891
|
column: 1,
|
|
840
892
|
message: stage == :overlay ? hkt_overlay_failed_message(raised) : hkt_scan_failed_message(raised),
|
|
@@ -889,7 +941,7 @@ module Rigor
|
|
|
889
941
|
sample = synthesized.first(sample_size)
|
|
890
942
|
suffix = synthesized.size > sample_size ? ", and #{synthesized.size - sample_size} more" : ""
|
|
891
943
|
Diagnostic.new(
|
|
892
|
-
path:
|
|
944
|
+
path: @configuration.config_display_path,
|
|
893
945
|
line: 1,
|
|
894
946
|
column: 1,
|
|
895
947
|
message: "#{synthesized.size} RBS namespace(s) under `signature_paths:` are " \
|
|
@@ -908,7 +960,7 @@ module Rigor
|
|
|
908
960
|
path, class_name, existing_arity, incoming_arity, existing_file = entry
|
|
909
961
|
displaced_by = displacing_source_phrase(existing_file)
|
|
910
962
|
Diagnostic.new(
|
|
911
|
-
path:
|
|
963
|
+
path: @configuration.config_display_path,
|
|
912
964
|
line: 1,
|
|
913
965
|
column: 1,
|
|
914
966
|
message: "`#{relative_signature_path(path.to_s)}` (a signature file a plugin contributes) declares " \
|
|
@@ -937,7 +989,7 @@ module Rigor
|
|
|
937
989
|
"`#{declaration}`#{cause}"
|
|
938
990
|
end
|
|
939
991
|
Diagnostic.new(
|
|
940
|
-
path:
|
|
992
|
+
path: @configuration.config_display_path,
|
|
941
993
|
line: 1,
|
|
942
994
|
column: 1,
|
|
943
995
|
message: "`#{relative_signature_path(path.to_s)}` (a signature file a plugin contributes) loaded without " \
|
|
@@ -956,7 +1008,7 @@ module Rigor
|
|
|
956
1008
|
def build_rbs_vendored_signature_stood_down_diagnostic(entry)
|
|
957
1009
|
dir, declarations, whole = entry
|
|
958
1010
|
Diagnostic.new(
|
|
959
|
-
path:
|
|
1011
|
+
path: @configuration.config_display_path,
|
|
960
1012
|
line: 1,
|
|
961
1013
|
column: 1,
|
|
962
1014
|
message: vendored_standdown_message(dir, declarations, whole),
|
|
@@ -1035,7 +1087,7 @@ module Rigor
|
|
|
1035
1087
|
sample = missing.first(sample_size).map(&:gem_name)
|
|
1036
1088
|
suffix = missing.size > sample_size ? ", and #{missing.size - sample_size} more" : ""
|
|
1037
1089
|
Diagnostic.new(
|
|
1038
|
-
path:
|
|
1090
|
+
path: @configuration.config_display_path,
|
|
1039
1091
|
line: 1,
|
|
1040
1092
|
column: 1,
|
|
1041
1093
|
message: "#{missing.size} gem(s) in Gemfile.lock have no RBS available: " \
|
|
@@ -1201,7 +1253,7 @@ module Rigor
|
|
|
1201
1253
|
|
|
1202
1254
|
@boundary_cross_reporter.entries.map do |entry|
|
|
1203
1255
|
Diagnostic.new(
|
|
1204
|
-
path:
|
|
1256
|
+
path: @configuration.config_display_path, line: 1, column: 1,
|
|
1205
1257
|
message: "`#{entry.class_name}##{entry.method_name}` is contributed by both " \
|
|
1206
1258
|
"RBS (#{entry.rbs_display}) and the `mode: :full` opt-in gem " \
|
|
1207
1259
|
"`#{entry.gem_name}`. RBS wins on dispatch; verify the gem source " \
|
|
@@ -1328,7 +1380,7 @@ module Rigor
|
|
|
1328
1380
|
|
|
1329
1381
|
def run_disclosure_diagnostic(record)
|
|
1330
1382
|
Diagnostic.new(
|
|
1331
|
-
path:
|
|
1383
|
+
path: @configuration.config_display_path, line: 1, column: 1,
|
|
1332
1384
|
message: record.fetch(:message),
|
|
1333
1385
|
severity: record.fetch(:severity),
|
|
1334
1386
|
rule: record.fetch(:rule),
|
|
@@ -1371,7 +1423,7 @@ module Rigor
|
|
|
1371
1423
|
def plugin_trust_refusal_diagnostic(plugin, summary)
|
|
1372
1424
|
plugin_id = plugin.manifest.id
|
|
1373
1425
|
Diagnostic.new(
|
|
1374
|
-
path:
|
|
1426
|
+
path: @configuration.config_display_path, line: 1, column: 1,
|
|
1375
1427
|
message: "plugin #{plugin_id.inspect} had #{summary[:count]} read(s) refused by the trust " \
|
|
1376
1428
|
"policy; first refused path: #{summary[:first_path].inspect}, outside read root " \
|
|
1377
1429
|
"#{summary[:nearest_root].inspect}. Spell the path the way that read root spells it " \
|
|
@@ -52,11 +52,6 @@ module Rigor
|
|
|
52
52
|
LISKOV_RULE = CheckRules::RULE_EFFECT_LISKOV_WIDENED
|
|
53
53
|
UNKNOWN_LABEL_RULE = CheckRules::RULE_EFFECT_UNKNOWN_LABEL
|
|
54
54
|
|
|
55
|
-
# Where a diagnostic about a configuration value is positioned when the loader cannot say
|
|
56
|
-
# which line the key was written on — the `rbs.coverage.quarantined-signature` precedent.
|
|
57
|
-
CONFIG_PATH = ".rigor.yml"
|
|
58
|
-
private_constant :CONFIG_PATH
|
|
59
|
-
|
|
60
55
|
RUBY_EXTENSION = ".rb"
|
|
61
56
|
private_constant :RUBY_EXTENSION
|
|
62
57
|
|
|
@@ -222,7 +217,7 @@ module Rigor
|
|
|
222
217
|
end
|
|
223
218
|
|
|
224
219
|
def position_of(finding)
|
|
225
|
-
DeclarationPosition.of(finding)
|
|
220
|
+
DeclarationPosition.of(finding, @configuration.config_display_path)
|
|
226
221
|
end
|
|
227
222
|
|
|
228
223
|
# The vocabulary an unknown label is judged against: the shipped registry plus whatever
|
|
@@ -299,7 +294,7 @@ module Rigor
|
|
|
299
294
|
|
|
300
295
|
def build_diagnostic(finding)
|
|
301
296
|
Diagnostic.new(
|
|
302
|
-
path: finding.path || unit_source_path(finding.key) ||
|
|
297
|
+
path: finding.path || unit_source_path(finding.key) || @configuration.config_display_path,
|
|
303
298
|
line: finding.line,
|
|
304
299
|
column: 1,
|
|
305
300
|
message: message_for(finding),
|
|
@@ -323,7 +318,7 @@ module Rigor
|
|
|
323
318
|
|
|
324
319
|
def build_liskov_diagnostic(finding)
|
|
325
320
|
Diagnostic.new(
|
|
326
|
-
path: finding.path ||
|
|
321
|
+
path: finding.path || @configuration.config_display_path,
|
|
327
322
|
line: finding.line,
|
|
328
323
|
column: 1,
|
|
329
324
|
message: EnvelopeMessages.liskov(finding),
|
|
@@ -10,6 +10,7 @@ require_relative "../run_stats"
|
|
|
10
10
|
require_relative "../../effects/signature_sources"
|
|
11
11
|
require_relative "../../rbs_extended/conformance_checker"
|
|
12
12
|
require_relative "../../runtime/jit"
|
|
13
|
+
require_relative "../../type_of_memo"
|
|
13
14
|
require_relative "../../cache/engine_source"
|
|
14
15
|
require_relative "run_level_facts"
|
|
15
16
|
require_relative "worker_payload"
|
|
@@ -198,6 +199,18 @@ module Rigor
|
|
|
198
199
|
@buffer.nil?
|
|
199
200
|
end
|
|
200
201
|
|
|
202
|
+
# ADR-130 WD2/WD5 — `RbsTypeTranslator.with_interface_erasure` and `RbsDispatch.without_interface_dispatch`
|
|
203
|
+
# are per-thread switches, which a Ractor worker would not see: a pooled run under either would analyse with
|
|
204
|
+
# the default engine and pass as the erasure baseline or the dispatch-off mode.
|
|
205
|
+
def refuse_pool_under_interface_switches
|
|
206
|
+
if Rigor::Inference::RbsTypeTranslator.interface_erasure?
|
|
207
|
+
raise ArgumentError, "RbsTypeTranslator.with_interface_erasure supports only a sequential run (workers: 0)"
|
|
208
|
+
end
|
|
209
|
+
return if Rigor::Inference::MethodDispatcher::RbsDispatch.interface_dispatch?
|
|
210
|
+
|
|
211
|
+
raise ArgumentError, "RbsDispatch.without_interface_dispatch supports only a sequential run (workers: 0)"
|
|
212
|
+
end
|
|
213
|
+
|
|
201
214
|
# ADR-15 Phase 4b — routes per-file analysis to either the sequential coordinator-side Environment
|
|
202
215
|
# (legacy path, default) or a Ractor worker pool built around {WorkerSession} (opt-in via
|
|
203
216
|
# `workers:`). The sequential path is bit-for-bit unchanged from v0.1.4 / earlier; the pool path is
|
|
@@ -225,6 +238,7 @@ module Rigor
|
|
|
225
238
|
source_files = project_files || files
|
|
226
239
|
result =
|
|
227
240
|
if pool_mode?
|
|
241
|
+
refuse_pool_under_interface_switches
|
|
228
242
|
dispatch_pool(files, source_files: source_files)
|
|
229
243
|
else
|
|
230
244
|
environment ||= resolve_sequential_environment(source_files: source_files)
|
|
@@ -483,8 +497,8 @@ module Rigor
|
|
|
483
497
|
# runner's fresh per-run reporter pair attached so dispatcher events route to THIS runner's
|
|
484
498
|
# diagnostics) when present; otherwise builds a fresh Environment per-call via
|
|
485
499
|
# {#build_runner_environment} — preserving the pre-override behaviour bit-for-bit.
|
|
486
|
-
def resolve_sequential_environment(source_files: [])
|
|
487
|
-
return build_runner_environment(source_files: source_files) unless @environment_override
|
|
500
|
+
def resolve_sequential_environment(source_files: [], eager: true)
|
|
501
|
+
return build_runner_environment(source_files: source_files, eager: eager) unless @environment_override
|
|
488
502
|
|
|
489
503
|
@environment_override.attach_reporters!(
|
|
490
504
|
rbs_extended_reporter: @rbs_extended_reporter,
|
|
@@ -546,8 +560,9 @@ module Rigor
|
|
|
546
560
|
# loaded plugin's `source_rbs_synthesizer` callable per project source file at env-build time.
|
|
547
561
|
# Defaults to `[]` for callers that don't have a file list yet (e.g. pre-pass-only build paths); in
|
|
548
562
|
# that case no synthesised RBS is contributed.
|
|
549
|
-
def build_runner_environment(source_files: [])
|
|
563
|
+
def build_runner_environment(source_files: [], eager: true)
|
|
550
564
|
Environment.for_project(
|
|
565
|
+
eager: eager,
|
|
551
566
|
libraries: @configuration.libraries,
|
|
552
567
|
signature_paths: @configuration.signature_paths,
|
|
553
568
|
cache_store: @cache_store,
|
|
@@ -719,6 +734,9 @@ module Rigor
|
|
|
719
734
|
# so the worker's own table is the only place a disclosure exists, and it is complete only
|
|
720
735
|
# once the worker has finished its files.
|
|
721
736
|
main.send([:done, Rigor::Analysis::Runner::WorkerPayload.harvest(session)])
|
|
737
|
+
# `Ractor#send` answers the Ractor; the worker's own value is unread (`join` only), and G3 reads a
|
|
738
|
+
# messaging call as an address only while its value is discarded.
|
|
739
|
+
nil
|
|
722
740
|
end
|
|
723
741
|
end
|
|
724
742
|
|
|
@@ -933,12 +951,15 @@ module Rigor
|
|
|
933
951
|
# mode is opted into for large projects, so a slice reliably outlasts the remainder; a small-project
|
|
934
952
|
# worker finishes first and stays at no-YJIT parity, exactly as the sequential path would.
|
|
935
953
|
Runtime::Jit.rearm_after_fork
|
|
954
|
+
TypeOfMemo.forked
|
|
936
955
|
results = slice.to_h { |path| [path, session.analyze(path)] }
|
|
937
956
|
# ADR-103 WD13 — the effects slot is filled only on a collecting run.
|
|
938
957
|
payload = WorkerPayload.harvest(session, results: results, record_effects: @record_effects)
|
|
939
958
|
File.binwrite(out_path, Marshal.dump(payload))
|
|
959
|
+
TypeOfMemo.write_report
|
|
940
960
|
exit!(0)
|
|
941
961
|
rescue StandardError
|
|
962
|
+
TypeOfMemo.write_report
|
|
942
963
|
exit!(1)
|
|
943
964
|
end
|
|
944
965
|
|
|
@@ -986,7 +1007,7 @@ module Rigor
|
|
|
986
1007
|
# process — so they say so the same way, naming which backend it was (#414).
|
|
987
1008
|
def pool_degraded_diagnostic(count, backend)
|
|
988
1009
|
Diagnostic.new(
|
|
989
|
-
path:
|
|
1010
|
+
path: @configuration.config_display_path, line: 1, column: 1,
|
|
990
1011
|
message: "#{backend} pool degraded: #{count} file(s) re-analysed in-process " \
|
|
991
1012
|
"after a worker exited abnormally",
|
|
992
1013
|
severity: :warning, rule: "pool-degraded", source_family: :builtin
|
|
@@ -1069,7 +1090,7 @@ module Rigor
|
|
|
1069
1090
|
harvest_stats { environment }
|
|
1070
1091
|
diagnostics.unshift(
|
|
1071
1092
|
Diagnostic.new(
|
|
1072
|
-
path:
|
|
1093
|
+
path: @configuration.config_display_path, line: 1, column: 1,
|
|
1073
1094
|
message: "pool mode degraded to sequential: #{reason}",
|
|
1074
1095
|
severity: :warning, rule: "pool-degraded", source_family: :builtin
|
|
1075
1096
|
)
|
|
@@ -375,43 +375,10 @@ module Rigor
|
|
|
375
375
|
end
|
|
376
376
|
end
|
|
377
377
|
|
|
378
|
-
#
|
|
379
|
-
#
|
|
380
|
-
# project's signature_paths, and each trusted gem's `Gem::Specification#full_gem_path`, plus any
|
|
381
|
-
# extras the user listed under `plugins_io.allowed_paths`. `network_policy` is `plugins_io.network`
|
|
382
|
-
# (`:disabled` or `:allowlist`).
|
|
378
|
+
# The run's {Rigor::Plugin::TrustPolicy}: {Rigor::Plugin::TrustPolicy.for_configuration} is the single
|
|
379
|
+
# derivation `rigor check`, pooled workers and `rigor unused`'s plugin roots share (#2586).
|
|
383
380
|
def build_trust_policy
|
|
384
|
-
|
|
385
|
-
roots = [Dir.pwd]
|
|
386
|
-
Array(@configuration.signature_paths).each { |sp| roots << File.absolute_path(sp) }
|
|
387
|
-
trusted_gems.each do |gem_name|
|
|
388
|
-
path = trusted_gem_root(gem_name)
|
|
389
|
-
roots << path if path
|
|
390
|
-
end
|
|
391
|
-
@configuration.plugins_io_allowed_paths.each { |p| roots << File.absolute_path(p) }
|
|
392
|
-
|
|
393
|
-
Plugin::TrustPolicy.new(
|
|
394
|
-
trusted_gems: trusted_gems,
|
|
395
|
-
allowed_read_roots: roots,
|
|
396
|
-
network_policy: @configuration.plugins_io_network,
|
|
397
|
-
allowed_url_hosts: @configuration.plugins_io_allowed_url_hosts
|
|
398
|
-
)
|
|
399
|
-
end
|
|
400
|
-
|
|
401
|
-
def trusted_gem_name(entry)
|
|
402
|
-
case entry
|
|
403
|
-
when String then entry
|
|
404
|
-
when Hash then entry["gem"] || entry["id"]
|
|
405
|
-
end
|
|
406
|
-
end
|
|
407
|
-
|
|
408
|
-
def trusted_gem_root(gem_name)
|
|
409
|
-
return nil if gem_name.nil? || gem_name.empty?
|
|
410
|
-
|
|
411
|
-
spec = Gem.loaded_specs[gem_name]
|
|
412
|
-
spec&.full_gem_path
|
|
413
|
-
rescue StandardError
|
|
414
|
-
nil
|
|
381
|
+
Plugin::TrustPolicy.for_configuration(@configuration)
|
|
415
382
|
end
|
|
416
383
|
|
|
417
384
|
# ADR-9 slice 3 — invokes every loaded plugin's `#prepare` hook once per run, after the loader's
|
|
@@ -438,7 +405,7 @@ module Rigor
|
|
|
438
405
|
def plugin_prepare_error_diagnostic(plugin, error)
|
|
439
406
|
plugin_id = safe_plugin_id(plugin)
|
|
440
407
|
Diagnostic.new(
|
|
441
|
-
path:
|
|
408
|
+
path: @configuration.config_display_path,
|
|
442
409
|
line: 1,
|
|
443
410
|
column: 1,
|
|
444
411
|
message: "plugin #{plugin_id.inspect} raised during prepare: " \
|