Module: SimpleCov::CLI::Ratchet

Extended by:
CommandHelpers, Ratchet
Included in:
Ratchet
Defined in:
lib/simplecov/cli/ratchet.rb,
lib/simplecov/cli/ratchet/output.rb

Overview

simplecov ratchet: rewrite the checked-in per-file coverage baseline (#1268) from the current report. Floors only ever tighten, entries for files the report no longer carries are pruned, and files without an entry are never given one, so new code stays answerable to the global thresholds rather than to a floor cut at whatever it launched with. --init regenerates the whole file from the current state.

The baseline path follows the project's .simplecov baseline_file setting when one is present, the same way the read-only commands follow coverage_dir.

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

#compute(opts, current) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/simplecov/cli/ratchet.rb', line 70

def compute(opts, current)
  existing = Baseline.read_if_exists(opts.fetch(:baseline)) unless opts.fetch(:init)
  return [existing.ratchet(current), false] if existing

  none = [] #: Array[String]
  outcome = Baseline::Outcome.new(
    baseline: Baseline.generate(current),
    tightened: none, pruned: none, regressed: none, unchanged: none
  )
  [outcome, true]
end

#current_floors(coverage) ⇒ Object

Only criteria the report carries for a file appear, so a line-only report leaves existing branch floors alone.



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/simplecov/cli/ratchet.rb', line 52

def current_floors(coverage)
  initial = {} #: Baseline::current_floors
  coverage.each_with_object(initial) do |(path, entry), floors|
    criteria = CoverageFile::CRITERIA.filter_map do |criterion, keys|
      percent = entry[keys.fetch(:percent)]
      missed = entry[keys.fetch(:missed)]
      [criterion, {percent: SimpleCov.round_coverage(percent), missed: missed}] if usable?(percent, missed)
    end.to_h
    floors[path] = criteria unless criteria.empty?
  end
end

#parse(args, stderr) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/simplecov/cli/ratchet.rb', line 38

def parse(args, stderr)
  opts, rest = parse_common(args, init: false, dry_run: false) do |parser, options|
    parser.on("--baseline PATH") { |v| options[:baseline] = v }
    parser.on("--init") { options[:init] = true }
    parser.on("--dry-run") { options[:dry_run] = true }
  end
  return error_nil(stderr, "unexpected argument #{rest.first.inspect}") unless rest.empty?

  opts[:baseline] ||= Dotfile.baseline_file
  opts
end

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



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/simplecov/cli/ratchet.rb', line 25

def run(args, stdout:, stderr:, **)
  require "simplecov"
  opts = parse(args, stderr) or return 1
  coverage = CoverageFile.load_coverage(opts.fetch(:input), command: "ratchet", stderr: stderr) or return 1

  outcome, generated = compute(opts, current_floors(coverage))
  AtomicFile.write(opts.fetch(:baseline), outcome.baseline.to_yaml) unless opts.fetch(:dry_run)
  Output.emit(stdout, opts, outcome, generated)
  0
rescue ConfigurationError => e
  error(stderr, e)
end

#usable?(percent, missed) ⇒ Boolean

A report row from another tool may be missing counts; only a complete pair can become a floor.

Returns:

  • (Boolean)


66
67
68
# File 'lib/simplecov/cli/ratchet.rb', line 66

def usable?(percent, missed)
  percent.is_a?(Numeric) && missed.instance_of?(Integer)
end