rigortype 0.4.6 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/data/gem_overlay/activesupport/core_ext.rbs +16 -13
- data/data/vendored_gem_sigs/bundler/bundler.rbs +1 -1
- data/data/vendored_gem_sigs/rubygems/rubygems_extras.rbs +4 -3
- data/docs/handbook/01-getting-started.md +5 -2
- data/docs/handbook/11-sig-gen.md +50 -3
- data/docs/handbook/appendix-phpstan.md +4 -4
- data/docs/manual/02-cli-reference.md +152 -26
- data/docs/manual/03-configuration.md +36 -3
- data/docs/manual/06-baseline.md +6 -4
- data/docs/manual/09-editor-integration.md +13 -2
- data/docs/manual/10-mcp-server.md +38 -2
- data/docs/manual/12-caching.md +4 -3
- data/docs/manual/plugins/rigor-actionpack.md +19 -11
- data/docs/manual/plugins/rigor-activesupport-core-ext.md +20 -1
- data/lib/rigor/analysis/baseline.rb +24 -27
- data/lib/rigor/analysis/check_rules/always_truthy_condition_collector.rb +5 -6
- data/lib/rigor/analysis/check_rules/dead_assignment_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/declaration_sourced_guard.rb +4 -4
- data/lib/rigor/analysis/check_rules/duplicate_hash_key_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/inferred_param_guard.rb +85 -13
- data/lib/rigor/analysis/check_rules/ivar_write_collector.rb +3 -2
- data/lib/rigor/analysis/check_rules/lexical_method_sites.rb +0 -1
- data/lib/rigor/analysis/check_rules/main_pass_collector.rb +5 -8
- data/lib/rigor/analysis/check_rules/published_constant_guard.rb +1 -1
- data/lib/rigor/analysis/check_rules/rebinding_block_callees.rb +3 -3
- data/lib/rigor/analysis/check_rules/return_in_ensure_collector.rb +1 -2
- data/lib/rigor/analysis/check_rules/rule_ids.rb +1 -1
- data/lib/rigor/analysis/check_rules/rule_walk.rb +9 -7
- data/lib/rigor/analysis/check_rules/shadowed_rescue_collector.rb +3 -4
- data/lib/rigor/analysis/check_rules/special_global_setters.rb +3 -3
- data/lib/rigor/analysis/check_rules/unreachable_clause_collector.rb +2 -2
- data/lib/rigor/analysis/check_rules/void_value_use_collector.rb +1 -1
- data/lib/rigor/analysis/check_rules.rb +124 -44
- data/lib/rigor/analysis/crash_signature.rb +2 -2
- data/lib/rigor/analysis/dependency_recorder.rb +4 -4
- data/lib/rigor/analysis/dependency_source_inference/boundary_cross_reporter.rb +14 -3
- data/lib/rigor/analysis/dependency_source_inference/gem_resolver.rb +1 -1
- data/lib/rigor/analysis/dependency_source_inference/index.rb +6 -8
- data/lib/rigor/analysis/dependency_source_inference/walker.rb +4 -4
- data/lib/rigor/analysis/edit_replay.rb +93 -6
- data/lib/rigor/analysis/fact_store.rb +3 -3
- data/lib/rigor/analysis/incremental_run_slot/write_guard.rb +2 -2
- data/lib/rigor/analysis/incremental_run_slot.rb +2 -2
- data/lib/rigor/analysis/incremental_session.rb +27 -16
- data/lib/rigor/analysis/rule_catalog.rb +2 -2
- data/lib/rigor/analysis/run_stats.rb +2 -2
- data/lib/rigor/analysis/runner/buffer_pool_dispatcher.rb +2 -2
- data/lib/rigor/analysis/runner/declaration_position.rb +1 -1
- data/lib/rigor/analysis/runner/diagnostic_aggregator.rb +193 -93
- data/lib/rigor/analysis/runner/effect_envelope_pass.rb +1 -1
- data/lib/rigor/analysis/runner/pool_coordinator.rb +147 -323
- data/lib/rigor/analysis/runner/project_pre_passes.rb +3 -3
- data/lib/rigor/analysis/runner/run_level_facts.rb +304 -0
- data/lib/rigor/analysis/runner/run_snapshots.rb +44 -54
- data/lib/rigor/analysis/runner/worker_payload.rb +36 -0
- data/lib/rigor/analysis/runner.rb +77 -71
- data/lib/rigor/analysis/self_call_resolution_recorder.rb +1 -1
- data/lib/rigor/analysis/template_unit_positions.rb +2 -3
- data/lib/rigor/analysis/template_units.rb +9 -1
- data/lib/rigor/analysis/worker_session.rb +24 -31
- data/lib/rigor/bleeding_edge.rb +3 -6
- data/lib/rigor/builtins/imported_refinements.rb +6 -8
- data/lib/rigor/builtins/predefined_constant_refinements.rb +1 -1
- data/lib/rigor/builtins/regex_refinement.rb +4 -6
- data/lib/rigor/cache/descriptor.rb +6 -5
- data/lib/rigor/cache/incremental_snapshot.rb +31 -12
- data/lib/rigor/cache/rbs_cache_producer.rb +2 -2
- data/lib/rigor/cache/rbs_class_ancestor_table.rb +1 -1
- data/lib/rigor/cache/rbs_class_type_param_names.rb +2 -2
- data/lib/rigor/cache/rbs_constant_table.rb +1 -1
- data/lib/rigor/cache/rbs_descriptor.rb +54 -3
- data/lib/rigor/cache/rbs_environment.rb +4 -1
- data/lib/rigor/cache/rbs_environment_marshal_patch.rb +2 -2
- data/lib/rigor/cache/rbs_known_class_names.rb +1 -1
- data/lib/rigor/cache/store.rb +11 -10
- data/lib/rigor/ci_detector.rb +1 -1
- data/lib/rigor/cli/annotate_command.rb +24 -19
- data/lib/rigor/cli/baseline_command.rb +145 -55
- data/lib/rigor/cli/catalogue.rb +256 -0
- data/lib/rigor/cli/check_command.rb +108 -102
- data/lib/rigor/cli/check_runner_factory.rb +2 -2
- data/lib/rigor/cli/command.rb +15 -1
- data/lib/rigor/cli/coverage_command.rb +21 -8
- data/lib/rigor/cli/coverage_mutation.rb +5 -7
- data/lib/rigor/cli/coverage_renderer.rb +2 -1
- data/lib/rigor/cli/coverage_scan.rb +3 -5
- data/lib/rigor/cli/diff_command.rb +25 -20
- data/lib/rigor/cli/docs_command.rb +1 -2
- data/lib/rigor/cli/doctor_command.rb +12 -12
- data/lib/rigor/cli/effects_command.rb +50 -40
- data/lib/rigor/cli/effects_diff_renderer.rb +18 -17
- data/lib/rigor/cli/effects_explain_renderer.rb +13 -12
- data/lib/rigor/cli/effects_renderer.rb +2 -1
- data/lib/rigor/cli/effects_snapshot_command.rb +18 -17
- data/lib/rigor/cli/explain_command.rb +18 -8
- data/lib/rigor/cli/fused_protection_renderer.rb +2 -1
- data/lib/rigor/cli/json_document.rb +41 -0
- data/lib/rigor/cli/lens_command.rb +12 -8
- data/lib/rigor/cli/lsp_command.rb +250 -23
- data/lib/rigor/cli/mcp_command.rb +12 -7
- data/lib/rigor/cli/mutation_fork_scan.rb +1 -1
- data/lib/rigor/cli/mutation_protection_renderer.rb +3 -2
- data/lib/rigor/cli/options.rb +40 -1
- data/lib/rigor/cli/plugin_command.rb +93 -46
- data/lib/rigor/cli/plugins_command.rb +17 -18
- data/lib/rigor/cli/plugins_renderer.rb +10 -6
- data/lib/rigor/cli/protection_fork_scan.rb +2 -2
- data/lib/rigor/cli/protection_renderer.rb +2 -1
- data/lib/rigor/cli/show_bleedingedge_command.rb +21 -15
- data/lib/rigor/cli/sig_gen_command.rb +84 -27
- data/lib/rigor/cli/skill_command.rb +32 -3
- data/lib/rigor/cli/skill_deep_probe.rb +1 -1
- data/lib/rigor/cli/skill_describe.rb +1 -1
- data/lib/rigor/cli/trace_command.rb +14 -9
- data/lib/rigor/cli/triage_command.rb +10 -11
- data/lib/rigor/cli/triage_renderer.rb +2 -1
- data/lib/rigor/cli/type_of_command.rb +16 -11
- data/lib/rigor/cli/type_of_project_scope.rb +1 -4
- data/lib/rigor/cli/type_of_renderer.rb +4 -1
- data/lib/rigor/cli/type_scan_command.rb +14 -9
- data/lib/rigor/cli/type_scan_renderer.rb +2 -1
- data/lib/rigor/cli/unused_command.rb +27 -17
- data/lib/rigor/cli/upgrade_command.rb +5 -0
- data/lib/rigor/cli.rb +209 -54
- data/lib/rigor/config_audit.rb +1 -1
- data/lib/rigor/configuration/severity_profile.rb +5 -5
- data/lib/rigor/configuration.rb +72 -30
- data/lib/rigor/effects/definition_context.rb +0 -2
- data/lib/rigor/effects/envelope.rb +1 -1
- data/lib/rigor/effects/framework_units.rb +1 -1
- data/lib/rigor/effects/mutation_classifier.rb +4 -7
- data/lib/rigor/effects/propagator.rb +1 -1
- data/lib/rigor/effects/registry.rb +2 -2
- data/lib/rigor/effects/snapshot.rb +1 -1
- data/lib/rigor/effects/taint_cause.rb +0 -2
- data/lib/rigor/effects/unit_scan.rb +9 -13
- data/lib/rigor/environment/bundle_sig_discovery.rb +5 -9
- data/lib/rigor/environment/class_registry.rb +3 -3
- data/lib/rigor/environment/core_root.rb +77 -0
- data/lib/rigor/environment/default_libraries.rb +1 -1
- data/lib/rigor/environment/deferred_signature_plan.rb +283 -0
- data/lib/rigor/environment/gated_signature_guard.rb +1 -1
- data/lib/rigor/environment/gated_signature_plan.rb +5 -2
- data/lib/rigor/environment/lockfile_resolver.rb +28 -12
- data/lib/rigor/environment/member_consistency/comparator.rb +18 -1
- data/lib/rigor/environment/member_consistency.rb +56 -7
- data/lib/rigor/environment/missing_gem_constant_index.rb +3 -2
- data/lib/rigor/environment/project_path_gems.rb +124 -0
- data/lib/rigor/environment/rbs_hierarchy.rb +6 -15
- data/lib/rigor/environment/rbs_loader.rb +480 -67
- data/lib/rigor/environment/reflection.rb +7 -7
- data/lib/rigor/environment/required_features.rb +0 -3
- data/lib/rigor/environment/ruby_library_roots.rb +1 -1
- data/lib/rigor/environment/vendored_signature_plan.rb +153 -0
- data/lib/rigor/environment.rb +41 -10
- data/lib/rigor/flow_contribution/merger.rb +4 -4
- data/lib/rigor/inference/acceptance.rb +93 -32
- data/lib/rigor/inference/block_parameter_binder.rb +2 -3
- data/lib/rigor/inference/block_run_count.rb +178 -0
- data/lib/rigor/inference/budget_trace.rb +8 -2
- data/lib/rigor/inference/builtins/exception_catalog.rb +2 -2
- data/lib/rigor/inference/builtins/numeric_catalog.rb +2 -5
- data/lib/rigor/inference/builtins/random_catalog.rb +2 -2
- data/lib/rigor/inference/callee_mutation_chain.rb +88 -77
- data/lib/rigor/inference/callee_write_census.rb +815 -0
- data/lib/rigor/inference/construction_escape.rb +217 -0
- data/lib/rigor/inference/declaration_walk/traversal.rb +1 -1
- data/lib/rigor/inference/deep_erasure.rb +39 -7
- data/lib/rigor/inference/def_handle.rb +1 -1
- data/lib/rigor/inference/def_node_resolver.rb +1 -1
- data/lib/rigor/inference/def_return_typer.rb +46 -4
- data/lib/rigor/inference/definer_resolution.rb +4 -2
- data/lib/rigor/inference/definers_index.rb +106 -0
- data/lib/rigor/inference/direct_ivar_writes.rb +300 -0
- data/lib/rigor/inference/element_read_widening.rb +49 -3
- data/lib/rigor/inference/expression_typer.rb +116 -49
- data/lib/rigor/inference/external_ancestor_resolution.rb +3 -4
- data/lib/rigor/inference/global_write_census.rb +76 -2
- data/lib/rigor/inference/global_writer_reach.rb +260 -0
- data/lib/rigor/inference/hkt_body.rb +1 -2
- data/lib/rigor/inference/hkt_body_parser.rb +3 -5
- data/lib/rigor/inference/hkt_reducer.rb +2 -2
- data/lib/rigor/inference/hkt_registry.rb +3 -5
- data/lib/rigor/inference/indexed_narrowing.rb +4 -7
- data/lib/rigor/inference/intervening_ivar_reset.rb +26 -4
- data/lib/rigor/inference/ivar_writer_census.rb +51 -0
- data/lib/rigor/inference/key_presence_guard.rb +2 -1
- data/lib/rigor/inference/loop_value_record.rb +8 -4
- data/lib/rigor/inference/match_rebinding/frame.rb +46 -0
- data/lib/rigor/inference/match_rebinding/yielding_match.rb +45 -0
- data/lib/rigor/inference/match_rebinding.rb +11 -1
- data/lib/rigor/inference/memo_audit.rb +55 -0
- data/lib/rigor/inference/method_dispatcher/alias_strict_nominals.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/argument_distribution.rb +40 -0
- data/lib/rigor/inference/method_dispatcher/block_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/constant_folding.rb +3 -3
- data/lib/rigor/inference/method_dispatcher/contested_overloads.rb +89 -0
- data/lib/rigor/inference/method_dispatcher/iterator_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/kernel_dispatch.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/no_match_fallback.rb +54 -0
- data/lib/rigor/inference/method_dispatcher/overload_selector.rb +39 -27
- data/lib/rigor/inference/method_dispatcher/random_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/rbs_dispatch.rb +203 -17
- data/lib/rigor/inference/method_dispatcher/reduce_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher/regexp_folding.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/self_substitute.rb +2 -2
- data/lib/rigor/inference/method_dispatcher/set_folding.rb +9 -7
- data/lib/rigor/inference/method_dispatcher/shape_dispatch.rb +83 -20
- data/lib/rigor/inference/method_dispatcher/singleton_folding.rb +0 -1
- data/lib/rigor/inference/method_dispatcher/singleton_mixin_dispatch.rb +50 -17
- data/lib/rigor/inference/method_dispatcher/struct_folding.rb +5 -5
- data/lib/rigor/inference/method_dispatcher/struct_materialization.rb +4 -6
- data/lib/rigor/inference/method_dispatcher/uri_folding.rb +1 -1
- data/lib/rigor/inference/method_dispatcher.rb +64 -14
- data/lib/rigor/inference/module_function_state.rb +11 -1
- data/lib/rigor/inference/multi_target_binder.rb +1 -1
- data/lib/rigor/inference/mutation_rejoin.rb +240 -4
- data/lib/rigor/inference/mutation_widening.rb +157 -27
- data/lib/rigor/inference/narrowing.rb +47 -33
- data/lib/rigor/inference/optimistic_origin.rb +1 -1
- data/lib/rigor/inference/out_buffer_mutation.rb +72 -0
- data/lib/rigor/inference/parameter_inference_collector.rb +5 -6
- data/lib/rigor/inference/pre_eval_constants.rb +1 -1
- data/lib/rigor/inference/project_method_ownership.rb +6 -3
- data/lib/rigor/inference/project_yielder.rb +11 -17
- data/lib/rigor/inference/receiver_alias.rb +20 -0
- data/lib/rigor/inference/refined_dispatch/constructed_class.rb +3 -1
- data/lib/rigor/inference/refined_dispatch/own_method.rb +2 -1
- data/lib/rigor/inference/remover_holder_scan.rb +233 -0
- data/lib/rigor/inference/remover_narrowing.rb +224 -0
- data/lib/rigor/inference/rewrite_mutation.rb +53 -2
- data/lib/rigor/inference/scope_indexer/certainty.rb +0 -1
- data/lib/rigor/inference/scope_indexer/constant_ivar_value.rb +93 -0
- data/lib/rigor/inference/scope_indexer/declared_param_writes.rb +58 -15
- data/lib/rigor/inference/scope_indexer/derived_param_value.rb +112 -0
- data/lib/rigor/inference/scope_indexer/empty_seed.rb +99 -0
- data/lib/rigor/inference/scope_indexer/ivar_contributions.rb +135 -0
- data/lib/rigor/inference/scope_indexer.rb +137 -46
- data/lib/rigor/inference/self_call_ivar_writes.rb +84 -12
- data/lib/rigor/inference/set_mutation.rb +189 -0
- data/lib/rigor/inference/singleton_hook_decline.rb +1 -2
- data/lib/rigor/inference/statement_evaluator.rb +2328 -138
- data/lib/rigor/inference/struct_fold_safety.rb +4 -6
- data/lib/rigor/inference/synthetic_method_scanner.rb +5 -6
- data/lib/rigor/inference/toplevel_def_census.rb +59 -0
- data/lib/rigor/inference/unknown_store_widening.rb +103 -4
- data/lib/rigor/inference/unthreaded_rebinds.rb +2 -3
- data/lib/rigor/inference/void_tail_summary.rb +2 -1
- data/lib/rigor/language_server/buffer_table.rb +3 -3
- data/lib/rigor/language_server/completion_provider.rb +26 -20
- data/lib/rigor/language_server/config_warning_announcer.rb +28 -0
- data/lib/rigor/language_server/diagnostic_publisher.rb +8 -3
- data/lib/rigor/language_server/document_symbol_provider.rb +1 -1
- data/lib/rigor/language_server/folding_range_provider.rb +1 -2
- data/lib/rigor/language_server/hover_provider.rb +1 -7
- data/lib/rigor/language_server/hover_renderer.rb +6 -8
- data/lib/rigor/language_server/project_context.rb +39 -1
- data/lib/rigor/language_server/publish_batcher.rb +3 -4
- data/lib/rigor/language_server/selection_range_provider.rb +2 -4
- data/lib/rigor/language_server/server.rb +7 -3
- data/lib/rigor/language_server/signature_help_provider.rb +4 -4
- data/lib/rigor/lens/plugins.rb +1 -1
- data/lib/rigor/mcp/server.rb +73 -2
- data/lib/rigor/mcp.rb +1 -1
- data/lib/rigor/plugin/access_denied_error.rb +1 -2
- data/lib/rigor/plugin/bundled_catalog.rb +1 -12
- data/lib/rigor/plugin/io_boundary.rb +1 -1
- data/lib/rigor/plugin/loader.rb +25 -8
- data/lib/rigor/plugin/macro/heredoc_template.rb +7 -8
- data/lib/rigor/plugin/macro/trait_registry.rb +6 -9
- data/lib/rigor/plugin/manifest.rb +9 -13
- data/lib/rigor/plugin/registry.rb +3 -3
- data/lib/rigor/plugin/services.rb +2 -3
- data/lib/rigor/plugin/source_rbs_synthesis_reporter.rb +11 -0
- data/lib/rigor/plugin/trust_policy.rb +2 -2
- data/lib/rigor/plugin/type_node_resolver.rb +2 -4
- data/lib/rigor/plugin.rb +6 -8
- data/lib/rigor/plugin_gap_advisory.rb +5 -1
- data/lib/rigor/project_environment.rb +16 -2
- data/lib/rigor/protection/analysis_guard.rb +1 -1
- data/lib/rigor/protection/discovery_seed.rb +44 -5
- data/lib/rigor/protection/mutator.rb +1 -1
- data/lib/rigor/rbs_extended/envelope_scanner.rb +4 -6
- data/lib/rigor/rbs_extended/hkt_directives.rb +6 -10
- data/lib/rigor/rbs_extended/reporter.rb +27 -3
- data/lib/rigor/rbs_extended.rb +2 -3
- data/lib/rigor/reflection/constant_ancestors.rb +5 -3
- data/lib/rigor/rooted_glob.rb +15 -1
- data/lib/rigor/run_scoped_slots.rb +38 -0
- data/lib/rigor/runtime/jit.rb +1 -1
- data/lib/rigor/scope/discovery_index.rb +19 -6
- data/lib/rigor/scope/resolution_chain.rb +3 -1
- data/lib/rigor/scope.rb +365 -31
- data/lib/rigor/sig_gen/classification.rb +4 -0
- data/lib/rigor/sig_gen/effect_annotation.rb +3 -3
- data/lib/rigor/sig_gen/generator.rb +371 -58
- data/lib/rigor/sig_gen/generic_header_scan.rb +189 -0
- data/lib/rigor/sig_gen/inline_declarations.rb +2 -2
- data/lib/rigor/sig_gen/layout_index.rb +3 -3
- data/lib/rigor/sig_gen/method_candidate.rb +23 -4
- data/lib/rigor/sig_gen/observation_collector.rb +3 -5
- data/lib/rigor/sig_gen/observed_call.rb +1 -1
- data/lib/rigor/sig_gen/path_mapper.rb +6 -0
- data/lib/rigor/sig_gen/renderer.rb +15 -9
- data/lib/rigor/sig_gen/skip_reason_catalog.rb +15 -2
- data/lib/rigor/sig_gen/type_name_qualification.rb +69 -0
- data/lib/rigor/sig_gen/write_reporter.rb +63 -14
- data/lib/rigor/sig_gen/write_result.rb +23 -12
- data/lib/rigor/sig_gen/writer.rb +217 -37
- data/lib/rigor/type/acceptance_router.rb +2 -2
- data/lib/rigor/type/accepts_result.rb +1 -1
- data/lib/rigor/type/app.rb +4 -6
- data/lib/rigor/type/combinator.rb +9 -13
- data/lib/rigor/type/constant.rb +4 -5
- data/lib/rigor/type/hash_shape.rb +21 -40
- data/lib/rigor/type/union.rb +1 -1
- data/lib/rigor/type_node/identifier.rb +1 -2
- data/lib/rigor/type_node/resolver_chain.rb +1 -1
- data/lib/rigor/type_node/string_literal.rb +1 -2
- data/lib/rigor/type_node/symbol_literal.rb +1 -2
- data/lib/rigor/type_node/union.rb +3 -6
- data/lib/rigor/value_semantics.rb +1 -10
- data/lib/rigor/version.rb +1 -1
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_discoverer.rb +2 -2
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable/channel_index.rb +2 -3
- data/plugins/rigor-actioncable/lib/rigor/plugin/actioncable.rb +1 -1
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_discoverer.rb +38 -36
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer/mailer_index.rb +4 -2
- data/plugins/rigor-actionmailer/lib/rigor/plugin/actionmailer.rb +6 -4
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/analyzer.rb +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_index.rb +1 -5
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/controller_scan.rb +0 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/erb_compiler.rb +2 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack/view_assigns.rb +1 -1
- data/plugins/rigor-actionpack/lib/rigor/plugin/actionpack.rb +66 -19
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob/effects.rb +1 -1
- data/plugins/rigor-activejob/lib/rigor/plugin/activejob.rb +4 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/association_roots.rb +3 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/effects.rb +2 -2
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_discoverer.rb +21 -31
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/model_index.rb +10 -16
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_parser.rb +2 -3
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord/schema_table.rb +0 -1
- data/plugins/rigor-activerecord/lib/rigor/plugin/activerecord.rb +5 -4
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_discoverer.rb +3 -4
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage/attachment_index.rb +1 -1
- data/plugins/rigor-activestorage/lib/rigor/plugin/activestorage.rb +7 -12
- data/plugins/rigor-activestorage/lib/rigor-activestorage.rb +1 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/effects.rb +1 -1
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext/symbolize_keys.rb +102 -0
- data/plugins/rigor-activesupport-core-ext/lib/rigor/plugin/activesupport_core_ext.rb +19 -6
- data/plugins/rigor-activesupport-core-ext/sig/active_support/core_ext.rbs +26 -13
- data/plugins/rigor-alba/lib/rigor/plugin/alba/resource_index.rb +3 -3
- data/plugins/rigor-dry-schema/lib/rigor/plugin/dry_schema/schema_scanner.rb +1 -3
- data/plugins/rigor-dry-struct/lib/rigor/plugin/dry_struct.rb +6 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types/alias_scanner.rb +5 -6
- data/plugins/rigor-dry-types/lib/rigor/plugin/dry_types.rb +1 -1
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation/params_shape.rb +2 -3
- data/plugins/rigor-dry-validation/lib/rigor/plugin/dry_validation.rb +5 -8
- data/plugins/rigor-ethon/lib/rigor/plugin/ethon.rb +0 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot/factory_discoverer.rb +1 -1
- data/plugins/rigor-factorybot/lib/rigor/plugin/factorybot.rb +10 -18
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/analyzer.rb +0 -1
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi/discoverer.rb +0 -2
- data/plugins/rigor-ffi/lib/rigor/plugin/ffi.rb +4 -5
- data/plugins/rigor-grape/lib/rigor/plugin/grape.rb +0 -2
- data/plugins/rigor-graphql/lib/rigor/plugin/graphql/type_scanner.rb +6 -7
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami/action_checker.rb +2 -4
- data/plugins/rigor-hanami/lib/rigor/plugin/hanami.rb +2 -5
- data/plugins/rigor-mangrove/lib/rigor/plugin/mangrove.rb +2 -2
- data/plugins/rigor-minitest/lib/rigor/plugin/minitest/assertion_analyzer.rb +6 -6
- data/plugins/rigor-pundit/lib/rigor/plugin/pundit/policy_discoverer.rb +2 -1
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/analyzer.rb +3 -8
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_index.rb +2 -3
- data/plugins/rigor-rails-i18n/lib/rigor/plugin/rails_i18n/locale_loader.rb +5 -8
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/analyzer.rb +1 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/devise_routes.rb +2 -3
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/helper_discoverer.rb +1 -1
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes/routes_parser.rb +4 -11
- data/plugins/rigor-rails-routes/lib/rigor/plugin/rails_routes.rb +1 -1
- data/plugins/rigor-rbs-inline/lib/rigor/plugin/rbs_inline.rb +2 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec/matcher_analyzer.rb +1 -1
- data/plugins/rigor-rspec/lib/rigor/plugin/rspec.rb +2 -2
- data/plugins/rigor-rspec-rails/lib/rigor/plugin/rspec_rails.rb +3 -4
- data/plugins/rigor-shoulda-matchers/lib/rigor/plugin/shoulda_matchers/analyzer.rb +6 -8
- data/plugins/rigor-sidekiq/lib/rigor/plugin/sidekiq.rb +3 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/absurd_recognizer.rb +4 -5
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/assertion_recognizer.rb +6 -7
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/catalog.rb +1 -1
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet/sig_parser.rb +2 -2
- data/plugins/rigor-sorbet/lib/rigor/plugin/sorbet.rb +17 -21
- data/plugins/rigor-statesman/lib/rigor/plugin/statesman.rb +2 -3
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_discoverer.rb +3 -2
- data/plugins/rigor-typelizer/lib/rigor/plugin/typelizer/serializer_index.rb +4 -4
- data/sig/rigor/analysis/baseline.rbs +0 -3
- data/sig/rigor/analysis/fact_store.rbs +1 -0
- data/sig/rigor/analysis/reachability/scan_cache.rbs +1 -1
- data/sig/rigor/cli/diff_command.rbs +1 -1
- data/sig/rigor/cli/explain_command.rbs +1 -1
- data/sig/rigor/effects/registry.rbs +2 -2
- data/sig/rigor/inference.rbs +4 -1
- data/sig/rigor/plugin/additional_initializer.rbs +0 -5
- data/sig/rigor/plugin/base.rbs +1 -0
- data/sig/rigor/plugin/effect_attribution.rbs +3 -3
- data/sig/rigor/plugin/effect_edge.rbs +1 -1
- data/sig/rigor/plugin/effect_entry_points.rbs +3 -3
- data/sig/rigor/plugin/io_boundary.rbs +2 -1
- data/sig/rigor/plugin/manifest.rbs +9 -9
- data/sig/rigor/plugin/protocol_contract.rbs +3 -7
- data/sig/rigor/scope.rbs +23 -3
- data/skills/rigor-plugin-author/SKILL.md +4 -4
- data/skills/rigor-plugin-author/references/02-walker-and-types.md +5 -5
- data/skills/rigor-plugin-review/SKILL.md +3 -3
- data/skills/rigor-project-init/references/03-baseline-and-bugs.md +12 -1
- metadata +36 -3
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "optparse"
|
|
4
|
+
|
|
3
5
|
require_relative "command"
|
|
4
6
|
require_relative "../rooted_glob"
|
|
5
7
|
|
|
@@ -77,6 +79,28 @@ module Rigor
|
|
|
77
79
|
# up.
|
|
78
80
|
SKILLS_ROOT = File.expand_path("../../../skills", __dir__).freeze
|
|
79
81
|
|
|
82
|
+
# The parser of `rigor skill`, built without parsing anything: the catalogue reads its flags from it (ADR-126
|
|
83
|
+
# WD3). The positional grammar is read by hand in {#run}, so this describes the switches and parses nothing.
|
|
84
|
+
def option_parser(options = {})
|
|
85
|
+
OptionParser.new do |opts|
|
|
86
|
+
opts.banner = USAGE.lines.first.chomp
|
|
87
|
+
opts.on("--full NAME", "Print the SKILL.md body and its references/ inline") { |v| options[:full] = v }
|
|
88
|
+
opts.on("--path NAME", "Print the absolute path of the SKILL.md file") { |v| options[:path] = v }
|
|
89
|
+
opts.on("--list", "List bundled skills (name + absolute path)") { options[:list] = true }
|
|
90
|
+
opts.on("--describe", "Report project state and recommend the next skill") { options[:describe] = true }
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# The parser of `rigor skill describe` and `rigor describe`; `banner` is the usage line of the spelling used.
|
|
95
|
+
def self.describe_option_parser(banner = "Usage: rigor skill describe [--deep]", options = {})
|
|
96
|
+
OptionParser.new do |opts|
|
|
97
|
+
opts.banner = banner
|
|
98
|
+
opts.on("--deep", "Run `rigor check` first and route the recommendation on its result") do
|
|
99
|
+
options[:deep] = true
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
80
104
|
# @return CLI exit status.
|
|
81
105
|
def run
|
|
82
106
|
case @argv.first
|
|
@@ -87,7 +111,7 @@ module Rigor
|
|
|
87
111
|
0
|
|
88
112
|
when "describe", "--describe"
|
|
89
113
|
@argv.shift
|
|
90
|
-
run_describe
|
|
114
|
+
run_describe("Usage: rigor skill describe [--deep]")
|
|
91
115
|
when "--list"
|
|
92
116
|
@argv.shift
|
|
93
117
|
run_list
|
|
@@ -176,7 +200,12 @@ module Rigor
|
|
|
176
200
|
# `--deep` is the one opt-in that breaks the "never runs `rigor check`" guarantee — and only for the invocation
|
|
177
201
|
# that asks for it (issue #148 / ADR-73 § "Field-trial follow-ups"). It runs a real check and lets the result
|
|
178
202
|
# pick the headline; the un-flagged command is unchanged, down to loading no analysis code at all.
|
|
179
|
-
def run_describe
|
|
203
|
+
def run_describe(usage)
|
|
204
|
+
if @argv.intersect?(%w[-h --help])
|
|
205
|
+
@out.puts(usage)
|
|
206
|
+
return 0
|
|
207
|
+
end
|
|
208
|
+
|
|
180
209
|
deep = !@argv.delete("--deep").nil?
|
|
181
210
|
unknown = @argv.first
|
|
182
211
|
return usage_error("unknown option for `describe`: #{unknown}") unless unknown.nil?
|
|
@@ -222,7 +251,7 @@ module Rigor
|
|
|
222
251
|
discover_skills.find { |s| s.fetch(:name) == name }
|
|
223
252
|
end
|
|
224
253
|
|
|
225
|
-
# The `references/*.md` files bundled alongside a skill
|
|
254
|
+
# The `references/*.md` files bundled alongside a skill.
|
|
226
255
|
def reference_files(skill)
|
|
227
256
|
dir = File.join(File.dirname(skill.fetch(:path)), "references")
|
|
228
257
|
return [] unless File.directory?(dir)
|
|
@@ -96,7 +96,7 @@ module Rigor
|
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
# The `rigor-doctor` signal
|
|
99
|
+
# The `rigor-doctor` signal: an RBS environment that built to
|
|
100
100
|
# zero classes (analysis is hollow, so every other count is meaningless), or a `configuration-error` the run
|
|
101
101
|
# already emitted. Checked first — with a broken setup the remaining diagnostics are not evidence of anything.
|
|
102
102
|
def broken_environment?(result)
|
|
@@ -361,7 +361,7 @@ module Rigor
|
|
|
361
361
|
end
|
|
362
362
|
|
|
363
363
|
# The one-line essence of a skill's frontmatter `description`, read live from the SKILL.md so the catalogue can
|
|
364
|
-
# never go stale relative to the shipped skill. Drops the `Triggers:`
|
|
364
|
+
# never go stale relative to the shipped skill. Drops the `Triggers:` tail and caps the length.
|
|
365
365
|
def catalog_blurb(path)
|
|
366
366
|
text = frontmatter(path).fetch("description", "").to_s.strip.tr("\n", " ").squeeze(" ")
|
|
367
367
|
head = text.split(/\s*Triggers?:/, 2).first.to_s.strip
|
|
@@ -12,6 +12,7 @@ require_relative "../inference/flow_tracer"
|
|
|
12
12
|
require_relative "../inference/scope_indexer"
|
|
13
13
|
require_relative "command"
|
|
14
14
|
require_relative "trace_renderer"
|
|
15
|
+
require_relative "json_document"
|
|
15
16
|
require_relative "../project_environment"
|
|
16
17
|
|
|
17
18
|
module Rigor
|
|
@@ -43,15 +44,12 @@ module Rigor
|
|
|
43
44
|
execute(file: file, options: options)
|
|
44
45
|
end
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def
|
|
49
|
-
|
|
50
|
-
parser = OptionParser.new do |opts|
|
|
47
|
+
# The parser this command parses with, built without parsing anything: the catalogue reads the
|
|
48
|
+
# flags and formats from it (ADR-126 WD3). `options` is only written by the switches' blocks.
|
|
49
|
+
def option_parser(options = {})
|
|
50
|
+
OptionParser.new do |opts|
|
|
51
51
|
opts.banner = USAGE
|
|
52
|
-
|
|
53
|
-
options[:format] = value
|
|
54
|
-
end
|
|
52
|
+
Options.add_format(opts, options, "Output format: text (animation) or json (raw event stream)")
|
|
55
53
|
opts.on("--delay=SECONDS", Float,
|
|
56
54
|
"Autoplay with SECONDS between frames (default: step on key press)") do |value|
|
|
57
55
|
options[:delay] = value
|
|
@@ -62,7 +60,13 @@ module Rigor
|
|
|
62
60
|
opts.on("--verbose", "Include every expression enter/result frame") { options[:verbose] = true }
|
|
63
61
|
Options.add_config(opts, options)
|
|
64
62
|
end
|
|
65
|
-
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def parse_options
|
|
68
|
+
options = { format: "text", delay: nil, verbose: false, line: nil, config: nil }
|
|
69
|
+
option_parser(options).parse!(@argv)
|
|
66
70
|
options
|
|
67
71
|
end
|
|
68
72
|
|
|
@@ -82,6 +86,7 @@ module Rigor
|
|
|
82
86
|
|
|
83
87
|
if options.fetch(:format) == "json"
|
|
84
88
|
@out.puts(JSON.pretty_generate(frames.map { |event| event_to_h(event) }))
|
|
89
|
+
@err.puts(JsonDocument::SHAPE_NOTICES.fetch(:trace))
|
|
85
90
|
return 0
|
|
86
91
|
end
|
|
87
92
|
|
|
@@ -36,14 +36,13 @@ module Rigor
|
|
|
36
36
|
0
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def
|
|
42
|
-
options = { config: nil, format: "text", top: 10, sections: DEFAULT_SECTIONS, include_info: false }
|
|
39
|
+
# The parser this command parses with, built without parsing anything: the catalogue reads the
|
|
40
|
+
# flags and formats from it (ADR-126 WD3). `options` is only written by the switches' blocks.
|
|
41
|
+
def option_parser(options = {})
|
|
43
42
|
OptionParser.new do |opts|
|
|
44
43
|
opts.banner = USAGE
|
|
45
44
|
Options.add_config(opts, options)
|
|
46
|
-
|
|
45
|
+
Options.add_format(opts, options, "Output format: text (default) or json")
|
|
47
46
|
opts.on("--top=N", Integer, "Hotspot-file count (default 10)") { |v| options[:top] = v }
|
|
48
47
|
opts.on("--include-info",
|
|
49
48
|
"Route info diagnostics into distribution / selectors / hotspots " \
|
|
@@ -57,15 +56,15 @@ module Rigor
|
|
|
57
56
|
opts.on("--selectors-only", "Print only the class/method selectors section") do
|
|
58
57
|
options[:sections] = %i[selectors]
|
|
59
58
|
end
|
|
60
|
-
end
|
|
61
|
-
validate!(options)
|
|
62
|
-
options
|
|
59
|
+
end
|
|
63
60
|
end
|
|
64
61
|
|
|
65
|
-
|
|
66
|
-
return if %w[text json].include?(options.fetch(:format))
|
|
62
|
+
private
|
|
67
63
|
|
|
68
|
-
|
|
64
|
+
def parse_options
|
|
65
|
+
options = { config: nil, format: "text", top: 10, sections: DEFAULT_SECTIONS, include_info: false }
|
|
66
|
+
option_parser(options).parse!(@argv)
|
|
67
|
+
options
|
|
69
68
|
end
|
|
70
69
|
|
|
71
70
|
# Sequential, cache-backed, no run-stats: triage only needs the diagnostic stream, and sequential keeps the rule
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require "json"
|
|
4
4
|
|
|
5
5
|
require_relative "../triage"
|
|
6
|
+
require_relative "json_document"
|
|
6
7
|
|
|
7
8
|
module Rigor
|
|
8
9
|
class CLI
|
|
@@ -17,7 +18,7 @@ module Rigor
|
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def json
|
|
20
|
-
JSON.pretty_generate(Triage.report_to_h(@report))
|
|
21
|
+
JSON.pretty_generate(JsonDocument.stamp(Triage.report_to_h(@report)))
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def text
|
|
@@ -13,6 +13,7 @@ require_relative "../inference/scope_indexer"
|
|
|
13
13
|
require_relative "../inference/precision_scanner"
|
|
14
14
|
require_relative "../source/node_children"
|
|
15
15
|
require_relative "type_of_renderer"
|
|
16
|
+
require_relative "json_document"
|
|
16
17
|
require_relative "type_of_template_probe"
|
|
17
18
|
require_relative "command"
|
|
18
19
|
require_relative "options"
|
|
@@ -29,7 +30,7 @@ module Rigor
|
|
|
29
30
|
# Encapsulating the command in its own class keeps `Rigor::CLI` focused on dispatching and lets us evolve the
|
|
30
31
|
# type-of UX (extra flags, watch mode, streaming output) without bloating the CLI shell. Output formatting is
|
|
31
32
|
# delegated to {TypeOfRenderer}.
|
|
32
|
-
class TypeOfCommand < Command
|
|
33
|
+
class TypeOfCommand < Command # rubocop:disable Metrics/ClassLength
|
|
33
34
|
include TypeOfTemplateProbe
|
|
34
35
|
|
|
35
36
|
USAGE = "Usage: rigor type-of [options] FILE:LINE[:COL] [FILE:LINE[:COL] ...]"
|
|
@@ -65,19 +66,24 @@ module Rigor
|
|
|
65
66
|
execute(targets: targets, options: options, buffer: buffer)
|
|
66
67
|
end
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
parser = OptionParser.new do |opts|
|
|
69
|
+
# The parser this command parses with, built without parsing anything: the catalogue reads the
|
|
70
|
+
# flags and formats from it (ADR-126 WD3). `options` is only written by the switches' blocks.
|
|
71
|
+
def option_parser(options = {})
|
|
72
|
+
OptionParser.new do |opts|
|
|
74
73
|
opts.banner = USAGE
|
|
75
|
-
|
|
74
|
+
Options.add_format(opts, options, "Output format: text or json")
|
|
76
75
|
opts.on("--trace", "Record fail-soft fallbacks via FallbackTracer") { options[:trace] = true }
|
|
77
76
|
Options.add_config(opts, options)
|
|
78
77
|
Options.add_editor_mode(opts, options)
|
|
79
78
|
end
|
|
80
|
-
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
def parse_options
|
|
84
|
+
options = { format: "text", trace: false, config: nil, tmp_file: nil, instead_of: nil }
|
|
85
|
+
|
|
86
|
+
option_parser(options).parse!(@argv)
|
|
81
87
|
|
|
82
88
|
options
|
|
83
89
|
end
|
|
@@ -101,7 +107,7 @@ module Rigor
|
|
|
101
107
|
results = results_by_target.compact.flatten(1)
|
|
102
108
|
return 1 if results.empty?
|
|
103
109
|
|
|
104
|
-
TypeOfRenderer.new(out: @out).render(results, format: options.fetch(:format))
|
|
110
|
+
TypeOfRenderer.new(out: @out, err: @err).render(results, format: options.fetch(:format))
|
|
105
111
|
0
|
|
106
112
|
end
|
|
107
113
|
|
|
@@ -206,7 +212,6 @@ module Rigor
|
|
|
206
212
|
end
|
|
207
213
|
end
|
|
208
214
|
|
|
209
|
-
# `presentation` is the Result's optional `enumeration:` / `location_mapper:`.
|
|
210
215
|
def type_result(file, line, column, node, scope_index, options, **presentation)
|
|
211
216
|
tracer = options[:trace] ? Inference::FallbackTracer.new : nil
|
|
212
217
|
type = scope_index[node].type_of(node, tracer: tracer)
|
|
@@ -16,11 +16,8 @@ module Rigor
|
|
|
16
16
|
module_function
|
|
17
17
|
|
|
18
18
|
def build(environment:, configuration:, buffer: nil)
|
|
19
|
-
base = Scope.empty(environment: environment)
|
|
20
19
|
seed = Protection::DiscoverySeed.from_snapshot(configuration: configuration, buffer: buffer)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
base.with_discovery(base.discovery.with(**seed))
|
|
20
|
+
Protection::DiscoverySeed.seeded_scope(environment: environment, seed: seed)
|
|
24
21
|
end
|
|
25
22
|
end
|
|
26
23
|
end
|
|
@@ -4,6 +4,7 @@ require "json"
|
|
|
4
4
|
require "optionparser"
|
|
5
5
|
|
|
6
6
|
require_relative "renderable"
|
|
7
|
+
require_relative "json_document"
|
|
7
8
|
|
|
8
9
|
module Rigor
|
|
9
10
|
class CLI
|
|
@@ -14,8 +15,9 @@ module Rigor
|
|
|
14
15
|
class TypeOfRenderer
|
|
15
16
|
include Renderable
|
|
16
17
|
|
|
17
|
-
def initialize(out:)
|
|
18
|
+
def initialize(out:, err: nil)
|
|
18
19
|
@out = out
|
|
20
|
+
@err = err
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
private
|
|
@@ -96,6 +98,7 @@ module Rigor
|
|
|
96
98
|
enumerations = line_enumerations(list)
|
|
97
99
|
payload[:line_enumerations] = enumerations unless enumerations.empty?
|
|
98
100
|
@out.puts(JSON.pretty_generate(payload))
|
|
101
|
+
@err&.puts(JsonDocument::SHAPE_NOTICES.fetch(:type_of))
|
|
99
102
|
end
|
|
100
103
|
|
|
101
104
|
def line_enumerations(results)
|
|
@@ -38,15 +38,12 @@ module Rigor
|
|
|
38
38
|
determine_exit(report, options)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
config: nil }
|
|
46
|
-
|
|
47
|
-
parser = OptionParser.new do |opts|
|
|
41
|
+
# The parser this command parses with, built without parsing anything: the catalogue reads the
|
|
42
|
+
# flags and formats from it (ADR-126 WD3). `options` is only written by the switches' blocks.
|
|
43
|
+
def option_parser(options = {})
|
|
44
|
+
OptionParser.new do |opts|
|
|
48
45
|
opts.banner = USAGE
|
|
49
|
-
|
|
46
|
+
Options.add_format(opts, options, "Output format: text or json")
|
|
50
47
|
Options.add_config(opts, options)
|
|
51
48
|
opts.on("--limit=N", Integer, "Max example events to print (text only)") do |value|
|
|
52
49
|
options[:limit] = value
|
|
@@ -58,7 +55,15 @@ module Rigor
|
|
|
58
55
|
options[:threshold] = value
|
|
59
56
|
end
|
|
60
57
|
end
|
|
61
|
-
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def parse_options
|
|
63
|
+
options = { format: "text", limit: 10, show_recognized: false, threshold: nil,
|
|
64
|
+
config: nil }
|
|
65
|
+
|
|
66
|
+
option_parser(options).parse!(@argv)
|
|
62
67
|
|
|
63
68
|
options
|
|
64
69
|
end
|
|
@@ -4,6 +4,7 @@ require "json"
|
|
|
4
4
|
require "optionparser"
|
|
5
5
|
|
|
6
6
|
require_relative "renderable"
|
|
7
|
+
require_relative "json_document"
|
|
7
8
|
|
|
8
9
|
module Rigor
|
|
9
10
|
class CLI
|
|
@@ -100,7 +101,7 @@ module Rigor
|
|
|
100
101
|
end
|
|
101
102
|
|
|
102
103
|
def render_json(report)
|
|
103
|
-
@out.puts(JSON.pretty_generate(json_payload(report)))
|
|
104
|
+
@out.puts(JSON.pretty_generate(JsonDocument.stamp(json_payload(report))))
|
|
104
105
|
end
|
|
105
106
|
|
|
106
107
|
def json_payload(report)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "optionparser"
|
|
4
|
+
require_relative "json_document"
|
|
4
5
|
require "json"
|
|
5
6
|
|
|
6
7
|
require_relative "../configuration"
|
|
@@ -67,6 +68,23 @@ module Rigor
|
|
|
67
68
|
0
|
|
68
69
|
end
|
|
69
70
|
|
|
71
|
+
# The parser this command parses with, built without parsing anything: the catalogue reads the
|
|
72
|
+
# flags and formats from it (ADR-126 WD3). `options` is only written by the switches' blocks.
|
|
73
|
+
def option_parser(options = {})
|
|
74
|
+
OptionParser.new do |opts|
|
|
75
|
+
opts.banner = USAGE
|
|
76
|
+
Options.add_config(opts, options)
|
|
77
|
+
Options.add_format(opts, options, "Output format: text (default) or json")
|
|
78
|
+
opts.on("--entry-point=GLOB", "Treat declarations in files matching GLOB as roots (repeatable)") do |v|
|
|
79
|
+
options[:entry_points] << v
|
|
80
|
+
end
|
|
81
|
+
opts.on("--limit=N", Integer, "Print at most N candidates (default: all)") { |v| options[:limit] = v }
|
|
82
|
+
# WD5 — refuse rather than silently absorb. A reachability answer is sound only over a full run, and a
|
|
83
|
+
# user who asked for the fast path must not silently get the slow one.
|
|
84
|
+
opts.on("--incremental", "(unsupported)") { options[:incremental] = true }
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
70
88
|
private
|
|
71
89
|
|
|
72
90
|
# A scan's role and the spelling it records depend on the root and the working directory (#1760): a role
|
|
@@ -120,20 +138,8 @@ module Rigor
|
|
|
120
138
|
|
|
121
139
|
def parse_options
|
|
122
140
|
options = { config: nil, format: "text", entry_points: [], limit: nil }
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
Options.add_config(opts, options)
|
|
126
|
-
opts.on("--format=FORMAT", "Output format: text (default) or json") { |v| options[:format] = v }
|
|
127
|
-
opts.on("--entry-point=GLOB", "Treat declarations in files matching GLOB as roots (repeatable)") do |v|
|
|
128
|
-
options[:entry_points] << v
|
|
129
|
-
end
|
|
130
|
-
opts.on("--limit=N", Integer, "Print at most N candidates (default: all)") { |v| options[:limit] = v }
|
|
131
|
-
# WD5 — refuse rather than silently absorb. A reachability answer is sound only over a full run, and a
|
|
132
|
-
# user who asked for the fast path must not silently get the slow one.
|
|
133
|
-
opts.on("--incremental", "(unsupported)") { options[:incremental] = true }
|
|
134
|
-
end
|
|
135
|
-
parser.parse!(@argv)
|
|
136
|
-
return usage_error(parser) if options[:incremental]
|
|
141
|
+
option_parser(options).parse!(@argv)
|
|
142
|
+
return usage_error if options[:incremental]
|
|
137
143
|
|
|
138
144
|
options
|
|
139
145
|
rescue OptionParser::ParseError => e
|
|
@@ -141,7 +147,7 @@ module Rigor
|
|
|
141
147
|
:usage_error
|
|
142
148
|
end
|
|
143
149
|
|
|
144
|
-
def usage_error
|
|
150
|
+
def usage_error
|
|
145
151
|
@err.puts("rigor unused does not support --incremental: reachability is only sound over a whole-project " \
|
|
146
152
|
"run, so an incremental pass would report constants as unused merely because the files that " \
|
|
147
153
|
"reference them were served from cache. Re-run without --incremental.")
|
|
@@ -379,6 +385,9 @@ module Rigor
|
|
|
379
385
|
required_features: ProjectEnvironment.required_features(configuration),
|
|
380
386
|
**ProjectEnvironment.dependency_discovery_options(configuration))
|
|
381
387
|
->(fqn) { !env.singleton_for_name(fqn).nil? }
|
|
388
|
+
rescue Environment::CoreRootError
|
|
389
|
+
# Issue #2517 — answering "unknown" for every name would report against no core at all.
|
|
390
|
+
raise
|
|
382
391
|
rescue StandardError
|
|
383
392
|
->(_fqn) { false }
|
|
384
393
|
end
|
|
@@ -413,7 +422,7 @@ module Rigor
|
|
|
413
422
|
end
|
|
414
423
|
|
|
415
424
|
def json(report, options, supply)
|
|
416
|
-
|
|
425
|
+
payload = {
|
|
417
426
|
declared: report.declared, reachable: report.reachable, roots: report.roots, edges: report.edges,
|
|
418
427
|
namespaces: report.namespaces,
|
|
419
428
|
plugin_roots: supply.supplied, plugin_roots_unmatched: supply.unmatched,
|
|
@@ -421,7 +430,8 @@ module Rigor
|
|
|
421
430
|
undecidable: limited(report.undecidable, options).map do |u|
|
|
422
431
|
{ name: u.fqn, path: u.path, line: u.line, reason: u.reason }
|
|
423
432
|
end
|
|
424
|
-
|
|
433
|
+
}
|
|
434
|
+
JSON.pretty_generate(JsonDocument.stamp(payload))
|
|
425
435
|
end
|
|
426
436
|
|
|
427
437
|
def rows_json(rows, options)
|
|
@@ -15,6 +15,11 @@ module Rigor
|
|
|
15
15
|
|
|
16
16
|
# @return CLI exit status.
|
|
17
17
|
def run
|
|
18
|
+
if @argv.intersect?(%w[-h --help])
|
|
19
|
+
@out.puts(USAGE)
|
|
20
|
+
return 0
|
|
21
|
+
end
|
|
22
|
+
|
|
18
23
|
@out.puts("rigor upgrade: No migration target available yet (ADR-50 WD7, queued).")
|
|
19
24
|
@out.puts("Current version: #{Rigor::VERSION}")
|
|
20
25
|
0
|