Module: Docscribe::CLI::Run
- Defined in:
- lib/docscribe/cli/run.rb
Overview
Execute Docscribe from parsed CLI options.
This module handles:
-
config loading and CLI overrides
-
stdin mode
-
file expansion / filtering
-
inspect vs write behavior
-
process exit status
Constant Summary collapse
- INITIAL_RUN_STATE =
{ changed: false, had_errors: false, checked_ok: 0, checked_fail: 0, corrected: 0, corrected_paths: [], #: Array[String] corrected_changes: {}, #: Hash[String, untyped] fail_paths: [], #: Array[String] fail_changes: {}, #: Hash[String, untyped] error_paths: [], #: Array[String] error_messages: {}, #: Hash[String, String] type_mismatch_paths: [], #: Array[String] type_mismatch_changes: {}, #: Hash[String, untyped] total: 0, processed: 0 }.freeze
Class Method Summary collapse
-
.all_fine?(state, checked_error, type_mismatch_count) ⇒ Boolean
Whether no failures, errors, or type mismatches occurred.
-
.append_expanded_path(files, path) ⇒ void
Append a file or recursively expand a directory into the files array.
-
.build_config(options) ⇒ Docscribe::Config
Load and build the effective config from CLI options.
-
.build_failure_line(state, type_mismatch_count, checked_error) ⇒ String
Build the human-readable failure summary line for check output.
-
.change_line_suffix(change) ⇒ String
Format the line number suffix for a change reason string.
-
.change_method_suffix(change) ⇒ String
Format the method name suffix for a change reason string.
-
.core_rbs_provider_for(conf) ⇒ Docscribe::Types::RBS::Provider?
Return the core RBS provider from the config if available.
-
.direct_message_change?(change) ⇒ Boolean
Whether a change type uses its own :message field directly as the reason.
-
.expand_paths(args) ⇒ Array<String>
Expand CLI path arguments into a sorted list of Ruby files.
-
.filtered_paths(argv, conf) ⇒ Array<String>
Expand CLI path arguments and filter through config file patterns.
-
.format_change_reason(change) ⇒ String
Format a structured change record into human-readable CLI output.
-
.mismatch_only?(state, checked_error) ⇒ Boolean
Whether type mismatches exist but no failures or errors.
-
.no_files_found ⇒ Integer
Warn and return exit code when no matching files were found.
-
.print_check_status_line(state) ⇒ void
Print the check-mode status line.
-
.print_corrected_paths(state, options) ⇒ void
Print corrected paths from write-mode summary (stdout).
-
.print_error_paths(state) ⇒ void
Print error paths from check summary.
-
.print_fail_paths(state, options) ⇒ void
Print fail paths from check summary (stdout).
-
.print_type_mismatch_paths(state, options) ⇒ void
Print type mismatch paths from check summary.
-
.print_write_summary(state:, options:) ⇒ void
Print the write-mode summary (files corrected, errors).
-
.run(options:, argv:) ⇒ Integer
Run Docscribe for files or STDIN using the selected mode and strategy.
-
.run_files(options:, conf:, paths:) ⇒ Integer
Process file paths in inspect or write mode.
-
.run_stdin(options:, conf:) ⇒ Integer
Rewrite code from STDIN using the selected strategy and print the result.
-
.stdin_rewrite_result(options, conf) ⇒ Hash<Symbol, Object>
Rewrite STDIN input and return the result report.
Class Method Details
.all_fine?(state, checked_error, type_mismatch_count) ⇒ Boolean
Whether no failures, errors, or type mismatches occurred.
619 620 621 |
# File 'lib/docscribe/cli/run.rb', line 619 def all_fine?(state, checked_error, type_mismatch_count) state[:checked_fail].zero? && checked_error.zero? && type_mismatch_count.zero? end |
.append_expanded_path(files, path) ⇒ void
This method returns an undefined value.
Append a file or recursively expand a directory into the files array.
153 154 155 156 157 158 159 160 161 |
# File 'lib/docscribe/cli/run.rb', line 153 def (files, path) if File.directory?(path) files.concat(Dir.glob(File.join(path, '**', '*.rb'))) elsif File.file?(path) files << path else warn "Skipping missing path: #{path}" end end |
.build_config(options) ⇒ Docscribe::Config
Load and build the effective config from CLI options.
67 68 69 70 71 72 |
# File 'lib/docscribe/cli/run.rb', line 67 def build_config() conf = Docscribe::Config.load([:config]) conf = Docscribe::CLI::ConfigBuilder.build(conf, ) conf.load_plugins! conf end |
.build_failure_line(state, type_mismatch_count, checked_error) ⇒ String
Build the human-readable failure summary line for check output.
638 639 640 641 642 643 644 |
# File 'lib/docscribe/cli/run.rb', line 638 def build_failure_line(state, type_mismatch_count, checked_error) parts = ["#{state[:checked_fail]} need updates"] parts << "#{type_mismatch_count} type mismatches" if type_mismatch_count.positive? parts << "#{checked_error} errors" parts << "#{state[:checked_ok]} ok" "Docscribe: FAILED (#{parts.join(', ')})" end |
.change_line_suffix(change) ⇒ String
Format the line number suffix for a change reason string.
716 717 718 |
# File 'lib/docscribe/cli/run.rb', line 716 def change_line_suffix(change) change[:line] ? " at line #{change[:line]}" : '' end |
.change_method_suffix(change) ⇒ String
Format the method name suffix for a change reason string.
724 725 726 |
# File 'lib/docscribe/cli/run.rb', line 724 def change_method_suffix(change) change[:method] ? " for #{change[:method]}" : '' end |
.core_rbs_provider_for(conf) ⇒ Docscribe::Types::RBS::Provider?
Return the core RBS provider from the config if available.
109 110 111 |
# File 'lib/docscribe/cli/run.rb', line 109 def core_rbs_provider_for(conf) conf.respond_to?(:core_rbs_provider) ? conf.core_rbs_provider : nil end |
.direct_message_change?(change) ⇒ Boolean
Whether a change type uses its own :message field directly as the reason.
732 733 734 735 736 737 738 739 740 741 |
# File 'lib/docscribe/cli/run.rb', line 732 def (change) %i[ missing_param missing_return missing_raise missing_visibility missing_module_function_note insert_full_doc_block ].include?(change[:type]) end |
.expand_paths(args) ⇒ Array<String>
Expand CLI path arguments into a sorted list of Ruby files.
Directories are expanded recursively to ‘*/.rb`. If no arguments are provided, the current directory is used.
137 138 139 140 141 142 143 144 145 146 |
# File 'lib/docscribe/cli/run.rb', line 137 def (args) files = [] #: Array[String] args = ['.'] if args.empty? args.each do |path| (files, path) end files.uniq.sort end |
.filtered_paths(argv, conf) ⇒ Array<String>
Expand CLI path arguments and filter through config file patterns.
118 119 120 |
# File 'lib/docscribe/cli/run.rb', line 118 def filtered_paths(argv, conf) (argv).select { |path| conf.process_file?(path) } end |
.format_change_reason(change) ⇒ String
Format a structured change record into human-readable CLI output.
702 703 704 705 706 707 708 709 710 |
# File 'lib/docscribe/cli/run.rb', line 702 def format_change_reason(change) line = change_line_suffix(change) method = change_method_suffix(change) return "unsorted tags#{line}" if change[:type] == :unsorted_tags return "#{change[:message]}#{method}#{line}" if (change) "#{change[:message] || change[:type].to_s.tr('_', ' ')}#{method}#{line}" end |
.mismatch_only?(state, checked_error) ⇒ Boolean
Whether type mismatches exist but no failures or errors.
628 629 630 |
# File 'lib/docscribe/cli/run.rb', line 628 def mismatch_only?(state, checked_error) state[:checked_fail].zero? && checked_error.zero? end |
.no_files_found ⇒ Integer
Warn and return exit code when no matching files were found.
125 126 127 128 |
# File 'lib/docscribe/cli/run.rb', line 125 def no_files_found warn 'No files found. Pass files or directories (e.g. `docscribe lib`).' 2 end |
.print_check_status_line(state) ⇒ void
This method returns an undefined value.
Print the check-mode status line.
600 601 602 603 604 605 606 607 608 609 610 611 |
# File 'lib/docscribe/cli/run.rb', line 600 def print_check_status_line(state) checked_error = state[:error_paths].size type_mismatch_count = state[:type_mismatch_paths].size if all_fine?(state, checked_error, type_mismatch_count) puts "Docscribe: OK (#{state[:checked_ok]} files checked)" elsif mismatch_only?(state, checked_error) puts "Docscribe: OK (#{state[:checked_ok]} files checked, #{type_mismatch_count} with type mismatches)" else puts build_failure_line(state, type_mismatch_count, checked_error) end end |
.print_corrected_paths(state, options) ⇒ void
This method returns an undefined value.
Print corrected paths from write-mode summary (stdout).
Skips explanations when –verbose showed them inline per-file.
686 687 688 689 690 691 692 693 694 695 696 |
# File 'lib/docscribe/cli/run.rb', line 686 def print_corrected_paths(state, ) state[:corrected_paths].each do |p| puts "Updated: #{p}" next if [:verbose] || [:quiet] Array(state[:corrected_changes][p]).each do |change| puts " - #{format_change_reason(change)}" end end end |
.print_error_paths(state) ⇒ void
This method returns an undefined value.
Print error paths from check summary.
747 748 749 750 751 752 753 754 755 |
# File 'lib/docscribe/cli/run.rb', line 747 def print_error_paths(state) return if state[:error_paths].empty? warn '' state[:error_paths].each do |p| warn "Error processing: #{p}" warn " #{state[:error_messages][p]}" if state[:error_messages][p] end end |
.print_fail_paths(state, options) ⇒ void
This method returns an undefined value.
Print fail paths from check summary (stdout).
Skips explanations when –verbose showed them inline per-file.
584 585 586 587 588 589 590 591 592 593 594 |
# File 'lib/docscribe/cli/run.rb', line 584 def print_fail_paths(state, ) state[:fail_paths].each do |p| puts "Would update: #{p}" next if [:verbose] || [:quiet] Array(state[:fail_changes][p]).each do |change| puts " - #{format_change_reason(change)}" end end end |
.print_type_mismatch_paths(state, options) ⇒ void
This method returns an undefined value.
Print type mismatch paths from check summary.
651 652 653 654 655 656 657 658 659 660 661 |
# File 'lib/docscribe/cli/run.rb', line 651 def print_type_mismatch_paths(state, ) return if [:quiet] return unless [:verbose] || [:explain] state[:type_mismatch_paths].each do |p| warn "Type mismatches: #{p}" Array(state[:type_mismatch_changes][p]).each do |change| warn " - #{format_change_reason(change)}" end end end |
.print_write_summary(state:, options:) ⇒ void
This method returns an undefined value.
Print the write-mode summary (files corrected, errors).
668 669 670 671 672 673 674 675 676 677 |
# File 'lib/docscribe/cli/run.rb', line 668 def print_write_summary(state:, options:) puts puts "Docscribe: updated #{state[:corrected]} file(s)" if state[:corrected].positive? print_corrected_paths(state, ) return unless state[:had_errors] warn "Docscribe: #{state[:error_paths].size} file(s) had errors" print_error_paths(state) end |
.run(options:, argv:) ⇒ Integer
Run Docscribe for files or STDIN using the selected mode and strategy.
Modes:
-
:check => inspect what the selected strategy would change
-
:write => apply the selected strategy in place
-
:stdin => rewrite STDIN and print to STDOUT
Strategies:
-
:safe => merge/add/normalize non-destructively
-
:aggressive => rebuild existing doc blocks
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/docscribe/cli/run.rb', line 52 def run(options:, argv:) conf = build_config() return run_stdin(options: , conf: conf) if [:mode] == :stdin paths = filtered_paths(argv, conf) return no_files_found unless paths.any? run_files(options: , conf: conf, paths: paths) end |
.run_files(options:, conf:, paths:) ⇒ Integer
Process file paths in inspect or write mode.
In inspect mode:
-
prints progress/status
-
exits non-zero if any file would change or if any errors occurred
In write mode:
-
rewrites changed files in place
-
exits non-zero only if errors occurred
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/docscribe/cli/run.rb', line 177 def run_files(options:, conf:, paths:) $stdout.sync = true state = initial_run_state state[:total] = paths.size pwd = Pathname.pwd paths.each do |path| process_one_file(path, options: , conf: conf, pwd: pwd, state: state) end finalize_run(, state) run_exit_code(, state) end |
.run_stdin(options:, conf:) ⇒ Integer
Rewrite code from STDIN using the selected strategy and print the result.
82 83 84 85 86 87 88 |
# File 'lib/docscribe/cli/run.rb', line 82 def run_stdin(options:, conf:) puts stdin_rewrite_result(, conf)[:output] 0 rescue StandardError => e warn "Docscribe: Error processing stdin: #{e.class}: #{e.}" 1 end |
.stdin_rewrite_result(options, conf) ⇒ Hash<Symbol, Object>
Rewrite STDIN input and return the result report.
95 96 97 98 99 100 101 102 103 |
# File 'lib/docscribe/cli/run.rb', line 95 def stdin_rewrite_result(, conf) Docscribe::InlineRewriter.rewrite_with_report( $stdin.read, strategy: [:strategy], config: conf, core_rbs_provider: core_rbs_provider_for(conf), file: '(stdin)' ) end |