Module: SimpleCov::CLI::History

Extended by:
CommandHelpers, History
Included in:
History
Defined in:
lib/simplecov/cli/history.rb,
lib/simplecov/cli/history/output.rb

Overview

simplecov history: the recorded coverage trend in the terminal, a sparkline per measured criterion with the run rows beneath, and --file PATH for one file's trajectory instead of the totals.

Defined Under Namespace

Modules: Output

Constant Summary

Constants included from CommandHelpers

CommandHelpers::STATS_ROW_FORMAT

Instance Method Summary collapse

Methods included from CommandHelpers

build_parser, command_name, common_options, error, error_nil, on_help, one?, parse_common, quiet_option, recorded_contexts, stats_row

Instance Method Details

#default_inputObject

The history file, not coverage.json: this command reads the sibling artifact the exit tasks append to.



37
38
39
# File 'lib/simplecov/cli/history.rb', line 37

def default_input
  File.join(CLI.coverage_dir, ".history.json")
end

#file_recorded?(entries, opts, stderr) ⇒ Boolean

A --file for a path no entry recorded deserves a loud answer, not an empty sparkline that reads as "0% forever".

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
# File 'lib/simplecov/cli/history.rb', line 57

def file_recorded?(entries, opts, stderr)
  file = opts.fetch(:file)
  return true unless file
  return true if entries.any? { |entry| entry.instance_of?(Hash) && entry.dig("files", file).instance_of?(Hash) }

  error(stderr, "no recorded coverage for #{file} in #{opts.fetch(:input)}")
  false
end

#load_entries(path, stderr) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/simplecov/cli/history.rb', line 41

def load_entries(path, stderr)
  document = JSON.parse(File.read(path))
  entries = document.dig(SimpleCov::History::ENVELOPE, "entries") if document.instance_of?(Hash)
  return entries if entries.instance_of?(Array)

  error_nil(stderr, "#{path} is not a SimpleCov history file")
rescue Errno::ENOENT
  error_nil(stderr, "#{path} not found (the history is recorded automatically each time a suite reports)")
rescue JSON::ParserError => e
  error_nil(stderr, "#{path} is not valid JSON (#{e.message.lines.first.to_s.strip})")
rescue SystemCallError => e
  error_nil(stderr, "#{path} could not be read (#{e})")
end

#parse(args, stderr) ⇒ Object



26
27
28
29
30
31
32
33
# File 'lib/simplecov/cli/history.rb', line 26

def parse(args, stderr)
  opts, rest = parse_common(args, input: default_input, file: nil) do |parser, options|
    parser.on("--file PATH") { |v| options[:file] = v }
  end
  return error_nil(stderr, "unexpected argument #{rest.first.inspect}") unless rest.empty?

  opts
end

#run(args, stdout:, stderr:) ⇒ Object



17
18
19
20
21
22
23
24
# File 'lib/simplecov/cli/history.rb', line 17

def run(args, stdout:, stderr:, **)
  opts = parse(args, stderr) or return 1
  entries = load_entries(opts.fetch(:input), stderr) or return 1
  return 1 unless file_recorded?(entries, opts, stderr)

  Output.emit(stdout, opts, entries, color: CLI.color_enabled?(opts, stdout))
  0
end