undercover 0.6.6 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d4fbea540abf1922afa393179a770aa7468bb030085495c4be1daad89bafaaa
4
- data.tar.gz: a815eb262c6b848fe21420d1626ba4e1b43dadf025e095380acb7b0fb6fe5e07
3
+ metadata.gz: 440dce283cf6e85e2f59930af7e1c25f40fa1b2f2d67ba881d03435dcd206787
4
+ data.tar.gz: 04fc58376332676fb2ba14571510bd55529fa26ca6b5c5377691c0f91032f394
5
5
  SHA512:
6
- metadata.gz: 625346ca6e5b042b1658e58e82be45e4c5a5528843f4a7112b079fd244b99282965e96f47f67ff54cd341e2ce7e8d2d16c559bfbbda9d5483ed44a6ed847c814
7
- data.tar.gz: 307d626ae101ae1d7136f2fa6247f317b9a3bd072c7f0da936f32dc0d7910ada7b9c9f8b04fe66ae2cc79fe0387cc0575f303af06bf67e729fd6e9174f3aacd4
6
+ metadata.gz: b59a9e99fd2dea093b43a4cba70f64f2c10490c42c7ccf1fe7ed74a943daba3e4f960cbabff9e6fc6da2f97fb863ea75511d2d2335d9cff8d44f9f4217829017
7
+ data.tar.gz: 42721ec8490eb12828a2afc31578bc9747a6ae45ed99b90abcefe71bdb652de1331153a0cb24bec5a12cb4615594482052347f6a19547d286ca175fa7fe568e3
@@ -25,18 +25,18 @@ jobs:
25
25
  undercover --compare master
26
26
  - uses: actions/upload-artifact@v4
27
27
  with:
28
- name: undercover-${{ matrix.ruby }}.lcov
29
- path: coverage/lcov/undercover.lcov
28
+ name: undercover-${{ matrix.ruby }}-coverage
29
+ path: coverage/undercover_coverage.json
30
30
  coverage:
31
31
  runs-on: ubuntu-latest
32
32
  needs: build
33
33
  steps:
34
34
  - uses: actions/download-artifact@v4
35
35
  with:
36
- name: undercover-3.4.lcov
36
+ name: undercover-3.4-coverage
37
37
  - name: Upload coverage
38
38
  run: |
39
39
  ruby -e "$(curl -s https://undercover-ci.com/uploader.rb)" -- \
40
40
  --repo grodowski/undercover \
41
41
  --commit ${{ github.event.pull_request.head.sha || github.sha }} \
42
- --lcov /home/runner/work/undercover/undercover/undercover.lcov
42
+ --simplecov /home/runner/work/undercover/undercover/undercover_coverage.json
data/.tool-versions CHANGED
@@ -1 +1,2 @@
1
1
  ruby 3.4.2
2
+ nodejs 20.12.2
data/CHANGELOG.md CHANGED
@@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ # [0.7.0] - 2025-07-03
10
+
11
+ ### Added
12
+ - New native SimpleCov formatter that generates coverage data directly without requiring LCOV conversion ([#223](https://github.com/grodowski/undercover/pull/223))
13
+ - `--simplecov -s` CLI option to specify coverage JSON file path as an alternative to LCOV and future default ([#223](https://github.com/grodowski/undercover/pull/223))
14
+ - Improved path handling for projects running in nested subdirectories or monorepo setups ([#223](https://github.com/grodowski/undercover/pull/223))
15
+
16
+ ### Fixed
17
+ - `:nocov:` support to skip coverage analysis for specific code blocks works again after a regression in `0.6+` ([#223](https://github.com/grodowski/undercover/pull/223))
18
+
9
19
  # [0.6.6] - 2025-07-01
10
20
 
11
21
  - Bugfix in `max_warnings_limit` following ([#229](https://github.com/grodowski/undercover/pull/229))
@@ -157,7 +167,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
157
167
  ### Added
158
168
  - First release of `undercover` 🎉
159
169
 
160
- [Unreleased]: https://github.com/grodowski/undercover/compare/v0.6.6...HEAD
170
+ [Unreleased]: https://github.com/grodowski/undercover/compare/v0.7.0...HEAD
171
+ [0.7.0]: https://github.com/grodowski/undercover/compare/v0.6.6...v0.7.0
161
172
  [0.6.6]: https://github.com/grodowski/undercover/compare/v0.6.5...0.6.6
162
173
  [0.6.5]: https://github.com/grodowski/undercover/compare/v0.6.4...0.6.5
163
174
  [0.6.4]: https://github.com/grodowski/undercover/compare/v0.6.3...v0.6.4
data/Gemfile CHANGED
@@ -12,5 +12,6 @@ gem 'rspec', '~> 3.0'
12
12
  gem 'rubocop'
13
13
  gem 'simplecov'
14
14
  gem 'simplecov-html'
15
- gem 'simplecov-lcov', '~> 0.8'
15
+ gem 'simplecov_json_formatter'
16
+ gem 'simplecov-lcov'
16
17
  gem 'timecop'
data/README.md CHANGED
@@ -35,34 +35,58 @@ Or install it yourself as:
35
35
 
36
36
  $ gem install undercover
37
37
 
38
- ## Setting up required LCOV reporting
38
+ ## Setting up coverage reporting
39
39
 
40
- To make your specs or tests compatible with `undercover` by providing an LCOV report, please add `simplecov` and `simplecov-lcov` to your test setup.
40
+ To make your specs or tests compatible with `undercover`, please add `undercover` to your gemfile to use the undercover formatter the test helper.
41
41
 
42
42
  ```ruby
43
43
  # Gemfile
44
44
  group :test do
45
- gem 'simplecov'
46
- gem 'simplecov-lcov'
45
+ gem 'undercover'
47
46
  end
48
47
 
49
48
  # the very top of spec_helper.rb
50
49
  require 'simplecov'
51
- require 'simplecov-lcov'
52
- SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
53
- SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
50
+ require 'undercover/simplecov_formatter'
51
+
52
+ # optional, will default to coverage.json
53
+ SimpleCov::Formatter::Undercover.output_filename = 'my_project_coverage.json'
54
+ SimpleCov.formatter = SimpleCov::Formatter::Undercover
55
+
54
56
  SimpleCov.start do
55
57
  add_filter(/^\/spec\//) # For RSpec
56
58
  add_filter(/^\/test\//) # For Minitest
57
59
  enable_coverage(:branch) # Report branch coverage to trigger branch-level undercover warnings
58
60
  end
61
+ # ...
62
+ ```
59
63
 
60
- require 'undercover'
64
+ Then run your test suite once through to generate the initial coverage file before you can run the `undercover` command.
61
65
 
62
- # ...
66
+ ## Upgrading from pre-0.7.0
67
+
68
+ If you're upgrading from an older version of undercover that used LCOV, you can migrate to the new SimpleCov formatter:
69
+
70
+ 1. Add `gem 'undercover'` to your test group
71
+ 2. Replace the LCOV formatter setup with the new SimpleCov formatter
72
+
73
+ ```ruby
74
+ # Gemfile
75
+ group :test do
76
+ gem 'simplecov'
77
+ gem 'simplecov_json_formatter'
78
+ gem 'undercover'
79
+ end
80
+
81
+ # spec_helper.rb
82
+ require 'simplecov'
83
+ require 'undercover/simplecov_formatter'
84
+ SimpleCov.formatter = SimpleCov::Formatter::Undercover
63
85
  ```
64
86
 
65
- Then run your test suite once through to generate the initial `coverage/lcov/*.lcov` file before you can run the `undercover` command
87
+ 3. Update CLI usage: Use `--simplecov` flag instead of `--lcov`, or rely on auto-detection of `coverage/coverage.json`
88
+
89
+ Note: LCOV support will be deprecated in a future release, but remains fully functional for existing projects.
66
90
 
67
91
  ## Usage
68
92
 
@@ -79,11 +103,10 @@ undercover --compare origin/master
79
103
  ```
80
104
 
81
105
  Check out `docs/` for CI configuration examples:
82
- - [Travis CI](docs/travis.yml)
106
+ - [GitHub Actions](docs/actions.yml)
83
107
  - [CircleCI - simple](docs/circleci_config.yml)
84
108
  - [CircleCI - advanced](docs/circleci_advanced.yml)
85
109
  - [Semaphore](docs/semaphore.yml)
86
- - [Codeship](docs/codeship.md)
87
110
 
88
111
  Merging coverage results ([sample gist](https://gist.github.com/grodowski/9744ff91034dce8df20c2a8210409fb0)) is required for parallel tests before processing with `undercover`.
89
112
 
@@ -104,7 +127,8 @@ Options can be passed when running the command from the command line:
104
127
 
105
128
  ```sh
106
129
  Usage: undercover [options]
107
- -l, --lcov path LCOV report file path
130
+ -s, --simplecov path SimpleCov JSON report file
131
+ -l, --lcov path LCOV report file path (to be deprecated)
108
132
  -p, --path path Project directory
109
133
  -g, --git-dir dir Override `.git` with a custom directory
110
134
  -c, --compare ref Generate coverage warnings for all changes after `ref`
data/docs/actions.yml ADDED
@@ -0,0 +1,19 @@
1
+ name: Tests & Undercover
2
+ on: [push, pull_request]
3
+ jobs:
4
+ build:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@v4
8
+ - name: Set up Ruby 3.4
9
+ uses: ruby/setup-ruby@v1
10
+ with:
11
+ ruby-version: 3.4
12
+ - name: Build and test
13
+ env:
14
+ RAILS_ENV: test
15
+ run: |
16
+ gem install bundler
17
+ bundle install --jobs 4 --retry 3
18
+ bundle exec rake test
19
+ undercover --simplecov coverage/coverage.json --compare origin/master
@@ -20,7 +20,7 @@ jobs:
20
20
  bundle exec rspec
21
21
  - run:
22
22
  name: Store coverage report
23
- command: mv coverage/lcov/project.lcov /tmp/coverage/
23
+ command: mv coverage/coverage.json /tmp/coverage/
24
24
  - persist_to_workspace:
25
25
  root: /tmp/coverage
26
26
  paths: .
@@ -33,13 +33,13 @@ jobs:
33
33
  steps:
34
34
  - checkout
35
35
  - attach_workspace:
36
- at: /tmp/coverage # gives access to project's LCOV report
36
+ at: /tmp/coverage # gives access to project's coverage report
37
37
  - run:
38
38
  name: Check coverage
39
39
  command: |
40
40
  sudo apt-get install cmake
41
41
  gem install undercover
42
- undercover --lcov /tmp/coverage/project.lcov \
42
+ undercover --simplecov /tmp/coverage/coverage.json \
43
43
  --compare origin/master
44
44
 
45
45
  workflows:
@@ -1,5 +1,5 @@
1
1
  # Simple CircleCI config.yml example.
2
- # See workflow_config.yml for a more advanced example,
2
+ # See circleci_advanced.yml for a more advanced example,
3
3
  # that includes sharing data between containers.
4
4
 
5
5
  version: 2
@@ -43,7 +43,6 @@ module Undercover
43
43
  end
44
44
  end
45
45
 
46
- # TODO: refactor to a standalone validator (depending on changeset AND lcov)
47
46
  def validate(lcov_report_path)
48
47
  return :no_changes if full_diff.deltas.empty?
49
48
 
@@ -24,7 +24,7 @@ module Undercover
24
24
  def self.run_report(opts)
25
25
  report = Undercover::Report.new(changeset(opts), opts).build
26
26
 
27
- error = report.validate(opts.lcov)
27
+ error = report.validate(opts.simplecov_resultset || opts.lcov)
28
28
  if error
29
29
  puts(WARNINGS_TO_S[error])
30
30
  return 0 if error == :no_changes
@@ -1,19 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'undercover/root_to_relative_paths'
4
+
3
5
  module Undercover
4
6
  LcovParseError = Class.new(StandardError)
5
7
 
6
8
  class LcovParser
9
+ include RootToRelativePaths
10
+
7
11
  attr_reader :io, :source_files
8
12
 
9
- def initialize(lcov_io)
13
+ def initialize(lcov_io, opts)
10
14
  @io = lcov_io
11
15
  @source_files = {}
16
+ @code_dir = opts&.path
12
17
  end
13
18
 
14
- def self.parse(lcov_report_path)
19
+ def self.parse(lcov_report_path, opts = nil)
15
20
  lcov_io = File.open(lcov_report_path)
16
- new(lcov_io).parse
21
+ new(lcov_io, opts).parse
17
22
  end
18
23
 
19
24
  def parse
@@ -24,7 +29,7 @@ module Undercover
24
29
 
25
30
  def coverage(filepath)
26
31
  _filename, coverage = source_files.find do |relative_path, _|
27
- relative_path == filepath
32
+ relative_path == fix_relative_filepath(filepath)
28
33
  end
29
34
  coverage || []
30
35
  end
@@ -47,6 +52,11 @@ module Undercover
47
52
  total_f.round(3)
48
53
  end
49
54
 
55
+ def skipped?(_filepath, _line_no)
56
+ # this is why lcov parser will be deprecated
57
+ false
58
+ end
59
+
50
60
  private
51
61
 
52
62
  # rubocop:disable Metrics/MethodLength, Style/SpecialGlobalVars, Metrics/AbcSize
@@ -34,6 +34,7 @@ module Undercover
34
34
  DEFAULT_FILE_EXCLUDE_GLOBS = %w[test/* spec/* db/* config/* *_test.rb *_spec.rb].freeze
35
35
 
36
36
  attr_accessor :lcov,
37
+ :simplecov_resultset,
37
38
  :path,
38
39
  :git_dir,
39
40
  :compare,
@@ -68,11 +69,14 @@ module Undercover
68
69
  end
69
70
 
70
71
  opts.on_tail('--version', 'Show version') do
72
+ # :nocov:
71
73
  puts VERSION
72
74
  exit
75
+ # :nocov:
73
76
  end
74
77
 
75
78
  lcov_path_option(opts)
79
+ resultset_path_option(opts)
76
80
  project_path_option(opts)
77
81
  git_dir_option(opts)
78
82
  compare_option(opts)
@@ -81,6 +85,7 @@ module Undercover
81
85
  file_filters(opts)
82
86
  end.parse(args)
83
87
 
88
+ guess_resultset_path unless simplecov_resultset
84
89
  guess_lcov_path unless lcov
85
90
  self
86
91
  end
@@ -112,6 +117,13 @@ module Undercover
112
117
  end
113
118
  end
114
119
 
120
+ def resultset_path_option(parser)
121
+ desc = 'SimpleCov::Formatter::Undercover output file path (alternative to LCOV that will become default)'
122
+ parser.on('-s', '--simplecov path', desc) do |path|
123
+ self.simplecov_resultset = path
124
+ end
125
+ end
126
+
115
127
  def project_path_option(parser)
116
128
  parser.on('-p', '--path path', 'Project directory') do |path|
117
129
  self.path = path
@@ -147,6 +159,12 @@ module Undercover
147
159
  end
148
160
  end
149
161
 
162
+ def guess_resultset_path
163
+ cwd = Pathname.new(File.expand_path(path))
164
+ try_path = File.join(cwd, 'coverage', 'coverage.json')
165
+ self.simplecov_resultset = try_path if File.exist?(try_path)
166
+ end
167
+
150
168
  def guess_lcov_path
151
169
  cwd = Pathname.new(File.expand_path(path))
152
170
  self.lcov = File.join(cwd, 'coverage', 'lcov', "#{cwd.split.last}.lcov")
@@ -3,15 +3,18 @@
3
3
  require 'forwardable'
4
4
 
5
5
  module Undercover
6
- class Result
6
+ class Result # rubocop:disable Metrics/ClassLength
7
7
  extend Forwardable
8
8
 
9
- attr_reader :node, :coverage, :file_path
9
+ attr_reader :node, :coverage, :coverage_adapter, :file_path
10
10
 
11
11
  def_delegators :node, :first_line, :last_line, :name
12
+ def_delegators :coverage_adapter, :skipped?
12
13
 
13
- def initialize(node, file_cov, file_path) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
14
+ def initialize(node, coverage_adapter, file_path) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
14
15
  @node = node
16
+ @coverage_adapter = coverage_adapter
17
+ file_cov = coverage_adapter.coverage(file_path)
15
18
  @coverage = file_cov.select do |ln, _|
16
19
  if first_line == last_line
17
20
  ln == first_line
@@ -21,6 +24,7 @@ module Undercover
21
24
  ln > first_line && ln < last_line
22
25
  end
23
26
  end
27
+
24
28
  @file_path = file_path
25
29
  @flagged = false
26
30
  end
@@ -33,7 +37,8 @@ module Undercover
33
37
  @flagged
34
38
  end
35
39
 
36
- def uncovered?(line_no)
40
+ def uncovered?(line_no) # rubocop:disable Metrics/AbcSize
41
+ return false if skipped?(file_path, line_no)
37
42
  return true if coverage.empty?
38
43
 
39
44
  # check branch coverage for line_no
@@ -55,6 +60,11 @@ module Undercover
55
60
 
56
61
  lines = {}
57
62
  coverage.each do |ln, block_or_line_cov, _, branch_cov|
63
+ if skipped?(file_path, ln)
64
+ lines[ln] = 1
65
+ next
66
+ end
67
+
58
68
  lines[ln] = 1 unless lines.key?(ln)
59
69
  if branch_cov
60
70
  lines[ln] = 0 if branch_cov.zero?
@@ -93,6 +103,9 @@ module Undercover
93
103
  formatted_line = "#{num.to_s.rjust(pad)}: #{line}"
94
104
  if line.strip.empty?
95
105
  Rainbow(formatted_line).darkgray.dark
106
+ elsif skipped?(file_path, num)
107
+ Rainbow(formatted_line).darkgray.dark +
108
+ Rainbow(' skipped with :nocov:').italic.darkgray.dark
96
109
  elsif covered.nil?
97
110
  Rainbow(formatted_line).darkgray.dark +
98
111
  Rainbow(' hits: n/a').italic.darkgray.dark
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Undercover
4
+ module RootToRelativePaths
5
+ # Needed if undercover is running inside nested subdirectories (e.g. in a monorepo app), where
6
+ # the git paths are rooted deeper than the paths in the coverage report.
7
+ # If that is the case, trim the git filepath to match the local relative path, assumming undercover is
8
+ # running in the correct directory (has to be equal to SimpleCov.root for paths to match)
9
+ # @param filepath[String]
10
+ # @return String
11
+ def fix_relative_filepath(filepath)
12
+ return filepath unless @code_dir
13
+
14
+ code_dir_abs = File.expand_path(@code_dir)
15
+
16
+ if Pathname.new(Dir.pwd).ascend.any? { |p| p.to_s == code_dir_abs }
17
+ prefix_to_skip = Pathname.new(Dir.pwd).relative_path_from(code_dir_abs).to_s
18
+ return filepath.delete_prefix(prefix_to_skip).gsub(/\A\//, '')
19
+ end
20
+
21
+ filepath
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'simplecov_json_formatter'
4
+
5
+ # Patch ResultExporter to allow setting a custom export_path
6
+ module SimpleCovJSONFormatter
7
+ class ResultExporter
8
+ def export_path
9
+ # :nocov:
10
+ File.join(SimpleCov.coverage_path, SimpleCov::Formatter::Undercover.output_filename || FILENAME)
11
+ # :nocov:
12
+ end
13
+ end
14
+ end
15
+
16
+ module Undercover
17
+ class ResultHashFormatterWithRoot < SimpleCovJSONFormatter::ResultHashFormatter
18
+ def format
19
+ formatted_result[:meta] = {timestamp: @result.created_at.to_i}
20
+ format_files
21
+ add_undercover_meta_fields
22
+ formatted_result
23
+ end
24
+
25
+ private
26
+
27
+ def add_undercover_meta_fields
28
+ formatted_result.tap do |result|
29
+ result[:meta].merge!(simplecov_root: SimpleCov.root)
30
+ end
31
+ end
32
+
33
+ # format_files uses relative path as keys, as opposed to the superclass method
34
+ def format_files
35
+ formatted_result[:coverage] ||= {}
36
+ @result.files.each do |source_file|
37
+ path = source_file.project_filename.delete_prefix('/')
38
+ formatted_result[:coverage][path] = format_source_file(source_file)
39
+ end
40
+ end
41
+ end
42
+
43
+ class UndercoverSimplecovFormatter < SimpleCov::Formatter::JSONFormatter
44
+ class << self
45
+ attr_accessor :output_filename
46
+ end
47
+
48
+ def format_result(result)
49
+ result_hash_formater = ResultHashFormatterWithRoot.new(result)
50
+ result_hash_formater.format
51
+ end
52
+ end
53
+ end
54
+
55
+ module SimpleCov
56
+ module Formatter
57
+ Undercover = ::Undercover::UndercoverSimplecovFormatter
58
+ end
59
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'undercover/root_to_relative_paths'
4
+
5
+ module Undercover
6
+ class SimplecovResultAdapter
7
+ include RootToRelativePaths
8
+
9
+ attr_reader :simplecov_result
10
+
11
+ # @param file[File] JSON file supplied by SimpleCov::Formatter::Undercover
12
+ # @return SimplecovResultAdapter
13
+ def self.parse(file, opts = nil)
14
+ # :nocov:
15
+ result_h = JSON.parse(file.read)
16
+ raise ArgumentError, 'empty SimpleCov' if result_h.empty?
17
+
18
+ new(result_h, opts)
19
+ # :nocov:
20
+ end
21
+
22
+ # @param simplecov_result[SimpleCov::Result]
23
+ def initialize(simplecov_result, opts)
24
+ @simplecov_result = simplecov_result
25
+ @code_dir = opts&.path
26
+ end
27
+
28
+ # @param filepath[String]
29
+ # @return Array tuples (lines) and quadruples (branches) compatible with LcovParser
30
+ def coverage(filepath) # rubocop:disable Metrics/MethodLength
31
+ source_file = find_file(filepath)
32
+
33
+ return [] unless source_file
34
+
35
+ lines = source_file['lines'].map.with_index do |line_coverage, idx|
36
+ [idx + 1, line_coverage] if line_coverage
37
+ end.compact
38
+ branch_idx = 0
39
+ branches = source_file['branches'].map do |branch|
40
+ branch_idx += 1
41
+ [branch['start_line'], 0, branch_idx, branch['coverage']]
42
+ end
43
+ lines + branches
44
+ end
45
+
46
+ def skipped?(filepath, line_no)
47
+ source_file = find_file(filepath)
48
+ return false unless source_file
49
+
50
+ source_file['lines'][line_no - 1] == 'ignored'
51
+ end
52
+
53
+ # unused for now
54
+ def total_coverage; end
55
+ def total_branch_coverage; end
56
+
57
+ private
58
+
59
+ def find_file(filepath)
60
+ simplecov_result['coverage'][fix_relative_filepath(filepath)]
61
+ end
62
+ end
63
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Undercover
4
- VERSION = '0.6.6'
4
+ VERSION = '0.7.0'
5
5
  end
data/lib/undercover.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  $LOAD_PATH << 'lib'
4
+ require 'json'
4
5
  require 'imagen'
5
6
  require 'rainbow'
6
7
  require 'bigdecimal'
7
8
  require 'forwardable'
9
+ require 'simplecov'
8
10
 
9
11
  require 'undercover/lcov_parser'
10
12
  require 'undercover/result'
@@ -13,6 +15,7 @@ require 'undercover/changeset'
13
15
  require 'undercover/formatter'
14
16
  require 'undercover/options'
15
17
  require 'undercover/filter_set'
18
+ require 'undercover/simplecov_result_adapter'
16
19
  require 'undercover/version'
17
20
 
18
21
  module Undercover
@@ -22,6 +25,7 @@ module Undercover
22
25
 
23
26
  attr_reader :changeset,
24
27
  :lcov,
28
+ :simplecov_resultset,
25
29
  :results,
26
30
  :code_dir,
27
31
  :filter_set,
@@ -32,7 +36,11 @@ module Undercover
32
36
  # @param changeset [Undercover::Changeset]
33
37
  # @param opts [Undercover::Options]
34
38
  def initialize(changeset, opts)
35
- @lcov = LcovParser.parse(File.open(opts.lcov))
39
+ if opts.simplecov_resultset
40
+ @simplecov_resultset = SimplecovResultAdapter.parse(File.open(opts.simplecov_resultset), opts)
41
+ end
42
+ @lcov = LcovParser.parse(File.open(opts.lcov), opts)
43
+
36
44
  @code_dir = opts.path
37
45
  @changeset = changeset
38
46
  @filter_set = FilterSet.new(opts.glob_allow_filters, opts.glob_reject_filters)
@@ -102,9 +110,6 @@ module Undercover
102
110
  def load_and_parse_file(filepath)
103
111
  key = filepath.gsub(/^\.\//, '')
104
112
  return if loaded_files[key]
105
-
106
- coverage = lcov.coverage(filepath)
107
-
108
113
  return unless include_file?(filepath)
109
114
 
110
115
  root_ast = Imagen::Node::Root.new.build_from_file(
@@ -112,6 +117,9 @@ module Undercover
112
117
  )
113
118
  return if root_ast.children.empty?
114
119
 
120
+ # lcov will be deprecated at some point and we'll be able to refactor harder
121
+ coverage = simplecov_resultset || lcov
122
+
115
123
  loaded_files[key] = []
116
124
  root_ast.find_all(->(node) { !node.is_a?(Imagen::Node::Root) }).each do |imagen_node|
117
125
  loaded_files[key] << Result.new(imagen_node, coverage, filepath)
data/undercover.gemspec CHANGED
@@ -32,4 +32,6 @@ Gem::Specification.new do |spec|
32
32
  spec.add_dependency 'imagen', '>= 0.2.0'
33
33
  spec.add_dependency 'rainbow', '>= 2.1', '< 4.0'
34
34
  spec.add_dependency 'rugged', '>= 0.27', '< 1.10'
35
+ spec.add_dependency 'simplecov'
36
+ spec.add_dependency 'simplecov_json_formatter'
35
37
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: undercover
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.6
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Grodowski
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-07-01 00:00:00.000000000 Z
10
+ date: 2025-07-03 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: base64
@@ -91,6 +91,34 @@ dependencies:
91
91
  - - "<"
92
92
  - !ruby/object:Gem::Version
93
93
  version: '1.10'
94
+ - !ruby/object:Gem::Dependency
95
+ name: simplecov
96
+ requirement: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ type: :runtime
102
+ prerelease: false
103
+ version_requirements: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ - !ruby/object:Gem::Dependency
109
+ name: simplecov_json_formatter
110
+ requirement: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ type: :runtime
116
+ prerelease: false
117
+ version_requirements: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
94
122
  email:
95
123
  - jgrodowski@gmail.com
96
124
  executables:
@@ -112,13 +140,12 @@ files:
112
140
  - README.md
113
141
  - Rakefile
114
142
  - bin/undercover
143
+ - docs/actions.yml
115
144
  - docs/circleci_advanced.yml
116
145
  - docs/circleci_config.yml
117
- - docs/codeship.md
118
146
  - docs/screenshot_success.png
119
147
  - docs/screenshot_warnings.png
120
148
  - docs/semaphore.yml
121
- - docs/travis.yml
122
149
  - lib/undercover.rb
123
150
  - lib/undercover/changeset.rb
124
151
  - lib/undercover/cli.rb
@@ -127,6 +154,9 @@ files:
127
154
  - lib/undercover/lcov_parser.rb
128
155
  - lib/undercover/options.rb
129
156
  - lib/undercover/result.rb
157
+ - lib/undercover/root_to_relative_paths.rb
158
+ - lib/undercover/simplecov_formatter.rb
159
+ - lib/undercover/simplecov_result_adapter.rb
130
160
  - lib/undercover/version.rb
131
161
  - undercover.gemspec
132
162
  homepage: https://github.com/grodowski/undercover
data/docs/codeship.md DELETED
@@ -1,19 +0,0 @@
1
- Sample configuration to run `undercover` in Codeship CI. Edit these fields in **Project Settings**.
2
-
3
- **Setup commands**
4
-
5
- ```
6
- rvm use 2.5.3 --install
7
- bundle install
8
- gem install undercover
9
- ```
10
-
11
- **Test pipeline**
12
-
13
- ```
14
- bundle exec rspec --format documentation --color
15
- # fetch origin/master to have a ref to compare against
16
- git remote set-branches --add origin master
17
- git fetch
18
- undercover -c origin/master
19
- ```
data/docs/travis.yml DELETED
@@ -1,13 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.6.2
4
- - 2.5.5
5
- - 2.4.5
6
- - 2.3.7
7
- before_install:
8
- - gem install bundler undercover --no-doc
9
- - gem update --system
10
- script:
11
- - bundle exec rake
12
- - git fetch origin master:master
13
- - undercover --compare master