Class: CovLoupe::CoverageCLI

Inherits:
Object
  • Object
show all
Defined in:
lib/cov_loupe/cli.rb

Overview

Command-line interface for cov-loupe.

Parses global options (resultset path, format, sort order, etc.) and dispatches to subcommand classes via CommandFactory. When no subcommand is given, the default report (equivalent to list) is shown.

Option parsing uses order! so that global options before the subcommand are consumed and the subcommand name + its arguments remain in argv. Global options placed after the subcommand trigger a helpful error message.

Constant Summary collapse

HORIZONTAL_RULE =
'-' * 79
SUBCOMMANDS =

Valid CLI subcommands.

%w[list summary raw uncovered detailed totals validate].freeze
SUBCOMMAND_ABBREVIATIONS =

Optional single-character abbreviations for subcommands.

{
  'd' => 'detailed',
  'l' => 'list',
  'r' => 'raw',
  's' => 'summary',
  't' => 'totals',
  'u' => 'uncovered',
  'v' => 'validate',
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(error_handler: nil) ⇒ CoverageCLI

Initialize CLI for pure CLI usage only. Always runs as CLI, no mode detection needed.



44
45
46
47
48
49
50
# File 'lib/cov_loupe/cli.rb', line 44

def initialize(error_handler: nil)
  @config = AppConfig.new
  @cmd = nil
  @cmd_args = []
  @custom_error_handler = error_handler # Store custom handler if provided
  @error_handler = nil # Will be created after parsing options
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



40
41
42
# File 'lib/cov_loupe/cli.rb', line 40

def config
  @config
end

Instance Method Details

#run(argv) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/cov_loupe/cli.rb', line 52

def run(argv)
  context = nil
  # argv should already include environment options (merged by caller)
  # Pre-scan for error-mode to ensure early errors are logged with correct verbosity
  pre_scan_error_mode(argv)
  parse_options!(argv)

  context = CovLoupe.create_context(
    error_handler: error_handler, # construct after options to respect --error-mode
    log_target:    config.log_file.nil? ? CovLoupe.context.log_target : config.log_file,
    mode:          :cli
  )

  CovLoupe.with_context(context) do
    log_cli_params
    if @cmd
      run_subcommand(@cmd, @cmd_args)
    else
      show_default_report(sort_order: config.sort_order)
    end
  end
rescue OptionParser::ParseError => e
  # Handle any option parsing errors (invalid option/argument) without relying on
  # @error_handler, which is not guaranteed to be initialized yet.
  with_context_if_available(context) { handle_option_parser_error(e, argv: argv) }
rescue CovLoupe::Error => e
  with_context_if_available(context) { handle_user_facing_error(e) }
end

#show_default_report(sort_order: :descending, output: $stdout) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/cov_loupe/cli.rb', line 96

def show_default_report(sort_order: :descending, output: $stdout)
  model = CoverageModel.new(**config.model_options)
  presenter = Presenters::ProjectCoveragePresenter.new(
    model:          model,
    sort_order:     sort_order,
    raise_on_stale: config.raise_on_stale,
    tracked_globs:  config.tracked_globs
  )

  if config.format == :table
    file_summaries = presenter.relative_files
    output.puts model.format_table(
      file_summaries,
      sort_order:     sort_order,
      raise_on_stale: config.raise_on_stale,
      tracked_globs:  nil,
      output_chars:   config.output_chars
    )
    show_exclusions_summary(presenter, $stderr)
    warn_missing_timestamps(presenter, $stderr)
  else
    require_relative 'formatters/formatters'
    output.puts Formatters.format(presenter.relativized_payload, config.format,
      output_chars: config.output_chars)
  end

  warn_skipped_rows(presenter)
  warn_missing_timestamps(presenter)
end