Module: SimpleCov::History

Defined in:
lib/simplecov/history.rb,
sig/simplecov.rbs

Overview

A bounded record of past runs, coverage/.history.json (#1267): one entry per reported run carrying the per-criterion totals, the per-group and per-file percentages, a timestamp, and the branch and commit when the project is a git checkout. It is what turns "did the number move since the very last run" into direction of travel.

Entries are capped and written atomically, and a corrupt or foreign file degrades to an empty history with a warning rather than crashing the at_exit hook, the same tolerance .last_run.json has. The file is deliberately plain committable JSON.

Constant Summary collapse

ENVELOPE =

Returns:

  • (String)
"simplecov_history"
FORMAT_VERSION =

Returns:

  • (Integer)
1

Class Method Summary collapse

Class Method Details

.entries_with(result) ⇒ Array[entry]

The recorded entries plus result as the newest, capped, and without writing anything: what the report artifacts embed, so the embedded history includes the run being reported even though recording happens later.

Parameters:

Returns:

  • (Array[entry])


52
53
54
# File 'lib/simplecov/history.rb', line 52

def entries_with(result)
  (read << entry_for(result)).last(SimpleCov.history_limit)
end

.git_info[String?, String?]

A detached HEAD reports its branch as nil rather than the literal "HEAD" most CI checkouts would record.

Returns:

  • ([String?, String?])


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

def git_info
  branch = git("rev-parse", "--abbrev-ref", "HEAD")
  branch = nil if branch.eql?("HEAD")
  [branch, git("rev-parse", "HEAD")]
end

.history_pathString

Returns:

  • (String)


24
25
26
# File 'lib/simplecov/history.rb', line 24

def history_path
  File.join(SimpleCov.coverage_path, ".history.json")
end

.readArray[entry]

Returns:

  • (Array[entry])


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

def read
  return [] unless File.exist?(history_path)

  content = File.read(history_path)
  return [] if content.match?(/\A\s*\z/)

  entries = JSON.parse(content).dig(ENVELOPE, "entries")
  entries.instance_of?(Array) ? entries : invalid_history
rescue JSON::ParserError
  invalid_history
end

.record(result) ⇒ void

This method returns an undefined value.

Parameters:



28
29
30
31
32
33
34
35
# File 'lib/simplecov/history.rb', line 28

def record(result)
  limit = SimpleCov.history_limit
  return if limit.zero?

  entries = read
  entries << entry_for(result)
  write(entries.last(limit))
end