uncov 0.4.2 → 0.5.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 +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +21 -4
- data/lib/uncov/cli.rb +2 -2
- data/lib/uncov/configuration/option.rb +10 -4
- data/lib/uncov/configuration.rb +44 -12
- data/lib/uncov/finder/file_system.rb +10 -2
- data/lib/uncov/finder/git.rb +22 -6
- data/lib/uncov/finder/git_base.rb +10 -2
- data/lib/uncov/finder/git_diff.rb +43 -27
- data/lib/uncov/finder/no_cov.rb +10 -4
- data/lib/uncov/finder/simple_cov.rb +17 -2
- data/lib/uncov/finder.rb +64 -13
- data/lib/uncov/formatter/terminal.rb +12 -6
- data/lib/uncov/formatter.rb +1 -1
- data/lib/uncov/report/file/line.rb +22 -3
- data/lib/uncov/report/file.rb +14 -14
- data/lib/uncov/report/generator/diff_files.rb +57 -0
- data/lib/uncov/report/{diff_lines.rb → generator/diff_lines.rb} +4 -2
- data/lib/uncov/report/generator/git_files.rb +57 -0
- data/lib/uncov/report/generator/nocov_lines.rb +67 -0
- data/lib/uncov/report/generator.rb +25 -0
- data/lib/uncov/report.rb +18 -19
- data/lib/uncov/version.rb +1 -1
- data/lib/uncov.rb +20 -4
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 328d5a3a593abb320621afee6841e28c19be46fd4ea1092ae52d6ef513131469
|
4
|
+
data.tar.gz: ba6658737c8230c2f90dd045a568c478dbee86d782d57c5c75e9f0d9303eb796
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abba73e5527b9f48108ecd90757036af35f4dd4f9a8b2c2399e7e9c9c804a5d99195bcc0f6d9117583f5f07e9efa2e94db15ccd3b3f3829c09629dcc9bcac57e
|
7
|
+
data.tar.gz: fdb66c5ff19eb0c3bcacb136147a3d3493ed44400602c071137b91fdc1edacbef6ef6fe13663aa05ae24c9cd68ac773b95080466aed1e4026de6b52a3bcf0a2b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 2025-05-12: [v0.5.0](https://github.com/mpapis/uncov/releases/tag/v0.5.0)
|
4
|
+
|
5
|
+
### Minor
|
6
|
+
|
7
|
+
- [#43](https://github.com/mpapis/uncov/pull/43): Trigger tests on test_file_changes. Add git_files report generator., by [@mpapis](https://github.com/mpapis)
|
8
|
+
- [#45](https://github.com/mpapis/uncov/pull/45): Add diff_files report type, by [@mpapis](https://github.com/mpapis)
|
9
|
+
- [#46](https://github.com/mpapis/uncov/pull/46): Add nocov report filter and flags, by [@mpapis](https://github.com/mpapis)
|
10
|
+
|
11
|
+
### Patch
|
12
|
+
|
13
|
+
- [#44](https://github.com/mpapis/uncov/pull/44): Allow any git revision specification for target, by [@mpapis](https://github.com/mpapis)
|
14
|
+
|
15
|
+
|
16
|
+
|
3
17
|
## 2025-05-10: [v0.4.2](https://github.com/mpapis/uncov/releases/tag/v0.4.2)
|
4
18
|
|
5
19
|
### Patch
|
data/README.md
CHANGED
@@ -36,16 +36,33 @@ uncov
|
|
36
36
|
$ uncov -h
|
37
37
|
Usage: uncov [options]
|
38
38
|
-t, --target TARGET Target branch for comparison, default: "HEAD"
|
39
|
-
-r, --report
|
39
|
+
-r, --report FILTER Report filter to generate file/line list, one_of: "diff_files", "diff_lines"(default), "git_files", "nocov_lines"
|
40
40
|
-o, --output-format FORMAT Output format, one_of: "terminal"(default)
|
41
41
|
-C, --context LINES_NUMBER Additional lines context in output, default: 1
|
42
42
|
--test-command COMMAND Test command that generates SimpleCov, default: "COVERAGE=true bundle exec rake test"
|
43
43
|
--simplecov-file PATH SimpleCov results file, default: "autodetect"
|
44
|
-
--relevant-files
|
44
|
+
--relevant-files FN_GLOB Only show uncov for matching code files AND trigger tests if matching code files are newer than the report, default: "{{bin,exe,exec}/*,{app,lib}/**/*.{rake,rb},Rakefile}"
|
45
|
+
--relevant-tests FN_GLOB Trigger tests if matching test files are newer than the report, default: "{test,spec}/**/*_{test,spec}.rb"
|
46
|
+
--nocov-ignore Ignore :nocov: markers - consider all lines, default: false
|
47
|
+
--nocov-covered Report :nocov: lines that have coverage, default: false
|
45
48
|
--debug Get some insights, default: false
|
46
|
-
-v, --version Show version
|
47
49
|
-h, --help Print this help
|
48
|
-
|
50
|
+
|
51
|
+
Report FILTERs:
|
52
|
+
diff_files - Report missing coverage on added/changed files in the git diff
|
53
|
+
diff_lines - Report missing coverage on added lines in the git diff
|
54
|
+
git_files - Report missing coverage on files tracked with git
|
55
|
+
nocov_lines - Report coverage on nocov lines, requires one or both: --nocov-ignore / --nocov-covered
|
56
|
+
|
57
|
+
Report FILTERs take NOTICE:
|
58
|
+
git*/diff* - filters will not consider new files unless added to the git index with `git add`.
|
59
|
+
nocov* - filters/flags only work with coverage/.resultset.json SimpleCov files,
|
60
|
+
coverage.json does not provide the information needed.
|
61
|
+
|
62
|
+
FN_GLOB: shell filename globing -> https://ruby-doc.org/core-3.1.1/File.html#method-c-fnmatch
|
63
|
+
in bash: `shopt -s extglob dotglob globstar` and test with `ls {app,lib}/**/*.rb`
|
64
|
+
|
65
|
+
uncov 0.5.0 by Michal Papis <mpapis@gmail.com>
|
49
66
|
```
|
50
67
|
|
51
68
|
|
data/lib/uncov/cli.rb
CHANGED
@@ -6,9 +6,9 @@ require 'optparse'
|
|
6
6
|
class Uncov::CLI
|
7
7
|
def self.start(args)
|
8
8
|
Uncov.configure(args)
|
9
|
-
report = Uncov::Report.
|
9
|
+
report = Uncov::Report.generate
|
10
10
|
Uncov::Formatter.output(report)
|
11
|
-
!report.
|
11
|
+
!report.trigger?
|
12
12
|
rescue StandardError => e
|
13
13
|
raise if Uncov.configuration.debug
|
14
14
|
|
@@ -2,16 +2,16 @@
|
|
2
2
|
|
3
3
|
# configuration option
|
4
4
|
class Uncov::Configuration::Option
|
5
|
-
attr_reader :name, :description, :options, :default, :
|
5
|
+
attr_reader :name, :description, :options, :default, :value_parse, :value
|
6
6
|
|
7
7
|
def initialize(name, description, options, default, allowed_values, value_parse)
|
8
8
|
@name = name
|
9
9
|
@description = description
|
10
10
|
@options = Array(options)
|
11
11
|
@default = default.freeze
|
12
|
+
@value = default
|
12
13
|
@allowed_values = allowed_values
|
13
14
|
@value_parse = value_parse
|
14
|
-
self.value = default
|
15
15
|
end
|
16
16
|
|
17
17
|
def value=(value)
|
@@ -41,10 +41,16 @@ class Uncov::Configuration::Option
|
|
41
41
|
if value == default
|
42
42
|
"#{value.inspect}(default)"
|
43
43
|
else
|
44
|
-
# :nocov: for now as there is no case yet in Configuration
|
45
44
|
value.inspect
|
46
|
-
# :nocov:
|
47
45
|
end
|
48
46
|
end
|
49
47
|
end
|
48
|
+
|
49
|
+
def allowed_values
|
50
|
+
if @allowed_values.respond_to?(:call)
|
51
|
+
@allowed_values = @allowed_values.call
|
52
|
+
else
|
53
|
+
@allowed_values
|
54
|
+
end
|
55
|
+
end
|
50
56
|
end
|
data/lib/uncov/configuration.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'formatter'
|
4
|
-
require_relative 'report'
|
4
|
+
require_relative 'report/generator'
|
5
5
|
|
6
6
|
# handle configuration for uncov
|
7
7
|
class Uncov::Configuration
|
8
8
|
CONFIG_FILE = '.uncov'
|
9
|
+
# equivalent of `shopt -s extglob dotglob globstar` for testing with `bash` & `ls`
|
9
10
|
FILE_MATCH_FLAGS = File::FNM_EXTGLOB | File::FNM_PATHNAME | File::FNM_DOTMATCH
|
10
11
|
|
11
12
|
class << self
|
@@ -19,16 +20,23 @@ class Uncov::Configuration
|
|
19
20
|
end
|
20
21
|
|
21
22
|
option 'target', 'Target branch for comparison', options: ['-t', '--target TARGET'], default: 'HEAD'
|
22
|
-
option 'report', 'Report
|
23
|
+
option 'report', 'Report filter to generate file/line list',
|
24
|
+
options: ['-r', '--report FILTER'], default: 'diff_lines', allowed_values: -> { Uncov::Report::Generator.filters.keys }
|
23
25
|
option 'output_format', 'Output format',
|
24
|
-
options: ['-o', '--output-format FORMAT'], default: 'terminal', allowed_values: Uncov::Formatter.formats
|
26
|
+
options: ['-o', '--output-format FORMAT'], default: 'terminal', allowed_values: -> { Uncov::Formatter.formats }
|
25
27
|
option 'context', 'Additional lines context in output',
|
26
28
|
options: ['-C', '--context LINES_NUMBER'], default: 1, value_parse: lambda(&:to_i)
|
27
29
|
option 'test_command', 'Test command that generates SimpleCov',
|
28
30
|
options: '--test-command COMMAND', default: 'COVERAGE=true bundle exec rake test'
|
29
31
|
option 'simplecov_file', 'SimpleCov results file', options: '--simplecov-file PATH', default: 'autodetect'
|
30
|
-
option 'relevant_files', '
|
31
|
-
options: '--relevant-files', default: '{{bin,exe,exec}/*,{app,lib}/**/*.{rake,rb},Rakefile}'
|
32
|
+
option 'relevant_files', 'Only show uncov for matching code files AND trigger tests if matching code files are newer than the report',
|
33
|
+
options: '--relevant-files FN_GLOB', default: '{{bin,exe,exec}/*,{app,lib}/**/*.{rake,rb},Rakefile}'
|
34
|
+
option 'relevant_tests', 'Trigger tests if matching test files are newer than the report',
|
35
|
+
options: '--relevant-tests FN_GLOB', default: '{test,spec}/**/*_{test,spec}.rb'
|
36
|
+
option 'nocov_ignore', 'Ignore :nocov: markers - consider all lines',
|
37
|
+
options: '--nocov-ignore', default: false, value_parse: ->(_value) { true }
|
38
|
+
option 'nocov_covered', 'Report :nocov: lines that have coverage',
|
39
|
+
options: '--nocov-covered', default: false, value_parse: ->(_value) { true }
|
32
40
|
option 'debug', 'Get some insights', options: '--debug', default: false, value_parse: ->(_value) { true }
|
33
41
|
|
34
42
|
def initialize
|
@@ -66,16 +74,40 @@ class Uncov::Configuration
|
|
66
74
|
def parser_header(parser) = parser.banner = 'Usage: uncov [options]'
|
67
75
|
|
68
76
|
def parser_footer(parser)
|
69
|
-
parser.on('-v', '--version', 'Show version') do
|
70
|
-
puts "uncov #{Uncov::VERSION} by Michal Papis <mpapis@gmail.com>"
|
71
|
-
throw :exit, 0
|
72
|
-
end
|
73
77
|
parser.on('-h', '--help', 'Print this help') do
|
74
|
-
puts parser
|
75
|
-
puts "uncov #{Uncov::VERSION} by Michal Papis <mpapis@gmail.com>"
|
78
|
+
puts parser.help
|
76
79
|
throw :exit, 0
|
77
80
|
end
|
81
|
+
footer_extras(parser)
|
78
82
|
end
|
79
83
|
|
80
|
-
def
|
84
|
+
def footer_extras(parser)
|
85
|
+
# TODO: the release workflow does not like ' in help, please avoid it - or fix the workflow
|
86
|
+
parser.separator <<~HELP
|
87
|
+
|
88
|
+
Report FILTERs:
|
89
|
+
#{footer_extras_types}
|
90
|
+
|
91
|
+
Report FILTERs take NOTICE:
|
92
|
+
git*/diff* - filters will not consider new files unless added to the git index with `git add`.
|
93
|
+
nocov* - filters/flags only work with coverage/.resultset.json SimpleCov files,
|
94
|
+
coverage.json does not provide the information needed.
|
95
|
+
|
96
|
+
FN_GLOB: shell filename globing -> https://ruby-doc.org/core-3.1.1/File.html#method-c-fnmatch
|
97
|
+
in bash: `shopt -s extglob dotglob globstar` and test with `ls {app,lib}/**/*.rb`
|
98
|
+
|
99
|
+
uncov #{Uncov::VERSION} by Michal Papis <mpapis@gmail.com>
|
100
|
+
HELP
|
101
|
+
end
|
102
|
+
|
103
|
+
def footer_extras_types
|
104
|
+
report_type_length = Uncov::Report::Generator.filters.keys.map(&:length).max
|
105
|
+
Uncov::Report::Generator.filters.map do |name, config|
|
106
|
+
"#{name.ljust(report_type_length)} - #{config[:description]}"
|
107
|
+
end.join("\n")
|
108
|
+
end
|
109
|
+
|
110
|
+
def options
|
111
|
+
@options ||= {}
|
112
|
+
end
|
81
113
|
end
|
@@ -4,7 +4,11 @@
|
|
4
4
|
class Uncov::Finder::FileSystem
|
5
5
|
include Uncov::Cache
|
6
6
|
|
7
|
-
def files
|
7
|
+
def files
|
8
|
+
all_files.to_h do |file_name|
|
9
|
+
[file_name, lines(file_name)]
|
10
|
+
end
|
11
|
+
end
|
8
12
|
|
9
13
|
private
|
10
14
|
|
@@ -12,7 +16,11 @@ class Uncov::Finder::FileSystem
|
|
12
16
|
Dir.glob(Uncov.configuration.relevant_files, Uncov::Configuration::FILE_MATCH_FLAGS).select { |f| File.file?(f) }
|
13
17
|
end
|
14
18
|
|
15
|
-
def
|
19
|
+
def lines(file_name)
|
20
|
+
cache(file_name) do
|
21
|
+
read_lines(file_name)
|
22
|
+
end
|
23
|
+
end
|
16
24
|
|
17
25
|
def read_lines(file_name)
|
18
26
|
File.readlines(file_name).each_with_index.to_h { |line, line_index| [line_index + 1, line.rstrip] }
|
data/lib/uncov/finder/git.rb
CHANGED
@@ -3,14 +3,30 @@
|
|
3
3
|
require_relative 'git_base'
|
4
4
|
|
5
5
|
# collect list of files stored in git
|
6
|
-
|
7
|
-
|
8
|
-
include Uncov::Finder::GitBase
|
6
|
+
class Uncov::Finder::Git
|
7
|
+
include Uncov::Finder::GitBase
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def code_files
|
10
|
+
cache(:code_files) do
|
11
|
+
all_file_names.filter_map do |file_name|
|
12
|
+
[file_name, true] if relevant_code_file?(file_name)
|
13
13
|
end.to_h
|
14
14
|
end
|
15
15
|
end
|
16
|
+
|
17
|
+
def test_files
|
18
|
+
cache(:test_files) do
|
19
|
+
all_file_names.filter_map do |file_name|
|
20
|
+
[file_name, true] if relevant_test_file?(file_name)
|
21
|
+
end.to_h
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def all_file_names
|
28
|
+
cache(:all_files) do
|
29
|
+
open_repo.ls_files.keys
|
30
|
+
end
|
31
|
+
end
|
16
32
|
end
|
@@ -4,14 +4,22 @@ require 'git'
|
|
4
4
|
|
5
5
|
# common parts for git finders
|
6
6
|
module Uncov::Finder::GitBase
|
7
|
+
include Uncov::Cache
|
8
|
+
|
7
9
|
protected
|
8
10
|
|
9
|
-
def
|
11
|
+
def relevant_code_file?(path)
|
10
12
|
File.fnmatch?(Uncov.configuration.relevant_files, path, Uncov::Configuration::FILE_MATCH_FLAGS)
|
11
13
|
end
|
12
14
|
|
15
|
+
def relevant_test_file?(path)
|
16
|
+
File.fnmatch?(Uncov.configuration.relevant_tests, path, Uncov::Configuration::FILE_MATCH_FLAGS)
|
17
|
+
end
|
18
|
+
|
13
19
|
def open_repo
|
14
|
-
|
20
|
+
cache(:repo) do
|
21
|
+
::Git.open('.')
|
22
|
+
end
|
15
23
|
rescue ArgumentError => e
|
16
24
|
raise Uncov::NotGitRepoError, Uncov.configuration.path if e.message.end_with?(' is not in a git working tree')
|
17
25
|
|
@@ -4,41 +4,57 @@ require_relative 'git_base'
|
|
4
4
|
require 'git_diff_parser'
|
5
5
|
|
6
6
|
# collect list of changed files and their added lines (removed do not impact coverage)
|
7
|
-
|
8
|
-
|
9
|
-
include Uncov::Finder::GitBase
|
7
|
+
class Uncov::Finder::GitDiff
|
8
|
+
include Uncov::Finder::GitBase
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def code_files
|
11
|
+
cache(:code_files) do
|
12
|
+
all_files_diff.filter_map do |file_diff|
|
13
|
+
[file_diff.path, changed_lines(file_diff)] if relevant_code_file?(file_diff.path) && File.exist?(file_diff.path)
|
14
14
|
end.to_h
|
15
15
|
end
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
+
def test_files
|
19
|
+
cache(:test_files) do
|
20
|
+
all_files_diff.filter_map do |file_diff|
|
21
|
+
[file_diff.path, true] if relevant_test_file?(file_diff.path) && File.exist?(file_diff.path)
|
22
|
+
end.to_h
|
23
|
+
end
|
24
|
+
end
|
18
25
|
|
19
|
-
|
20
|
-
GitDiffParser.parse(file_diff.patch).flat_map do |patch|
|
21
|
-
patch.changed_lines.map do |changed_line|
|
22
|
-
next unless changed_line.content[0] == '+'
|
26
|
+
private
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
|
28
|
+
def all_files_diff
|
29
|
+
cache(:all_files) do
|
30
|
+
git_diff
|
27
31
|
end
|
32
|
+
end
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
def changed_lines(file_diff)
|
35
|
+
GitDiffParser.parse(file_diff.patch).flat_map do |patch|
|
36
|
+
patch.changed_lines.map do |changed_line|
|
37
|
+
next unless changed_line.content[0] == '+'
|
38
|
+
|
39
|
+
[changed_line.number, nil]
|
40
|
+
end
|
41
|
+
end.compact.to_h
|
42
|
+
end
|
43
|
+
|
44
|
+
def git_diff
|
45
|
+
repo = open_repo
|
46
|
+
# TODO: resolve the need for verifying the target with git gem
|
47
|
+
git_target = repo.lib.send(:command, 'rev-parse', '--verify', target)
|
48
|
+
repo.diff(git_target)
|
49
|
+
rescue Git::FailedError => e
|
50
|
+
raise Uncov::NotGitObjectError, target if e.result.status.exitstatus == 128 && e.result.stderr.include?('fatal: Needed a single revision')
|
51
|
+
|
52
|
+
# :nocov: when we find a failing example, we can test it
|
53
|
+
raise
|
54
|
+
# :nocov:
|
55
|
+
end
|
41
56
|
|
42
|
-
|
57
|
+
def target
|
58
|
+
Uncov.configuration.target
|
43
59
|
end
|
44
60
|
end
|
data/lib/uncov/finder/no_cov.rb
CHANGED
@@ -5,16 +5,22 @@ class Uncov::Finder::NoCov
|
|
5
5
|
include Uncov::Cache
|
6
6
|
|
7
7
|
def files(all_files)
|
8
|
-
all_files.to_h
|
8
|
+
all_files.to_h do |file_name, lines|
|
9
|
+
[file_name, nocov_lines(file_name, lines)]
|
10
|
+
end
|
9
11
|
end
|
10
12
|
|
11
13
|
private
|
12
14
|
|
13
|
-
def
|
15
|
+
def nocov_lines(file_name, lines)
|
16
|
+
cache(file_name) do
|
17
|
+
read_nocov(lines)
|
18
|
+
end
|
19
|
+
end
|
14
20
|
|
15
|
-
def read_nocov(
|
21
|
+
def read_nocov(lines)
|
16
22
|
nocov = false
|
17
|
-
|
23
|
+
lines.filter_map do |number, line|
|
18
24
|
line_nocov = line.strip.start_with?('# :nocov:')
|
19
25
|
nocov = !nocov if line_nocov
|
20
26
|
[number, true] if nocov || line_nocov # still true on disabling line
|
@@ -8,18 +8,33 @@ module Uncov::Finder::SimpleCov
|
|
8
8
|
def files(trigger_files)
|
9
9
|
regenerate_report if requires_regeneration?(trigger_files)
|
10
10
|
raise_on_missing_coverage_path!
|
11
|
-
coverage.transform_values
|
11
|
+
coverage.transform_values do |file_coverage|
|
12
|
+
covered_lines(file_coverage)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
16
|
private
|
15
17
|
|
16
18
|
def requires_regeneration?(trigger_files)
|
19
|
+
if Uncov.configuration.debug
|
20
|
+
warn("{coverage_path: #{coverage_path}(#{coverage_path && File.exist?(coverage_path) ? 'exist' : 'missing'})}")
|
21
|
+
warn("{trigger_files: #{trigger_files.inspect}}")
|
22
|
+
end
|
17
23
|
return true unless coverage_path
|
18
24
|
return true unless File.exist?(coverage_path)
|
19
25
|
return false if trigger_files.empty?
|
20
26
|
|
27
|
+
changed_files?(trigger_files)
|
28
|
+
end
|
29
|
+
|
30
|
+
def changed_files?(trigger_files)
|
21
31
|
coverage_path_mtime = File.mtime(coverage_path)
|
22
|
-
|
32
|
+
changed_trigger_files =
|
33
|
+
trigger_files.select do |file_name|
|
34
|
+
File.exist?(file_name) && File.mtime(file_name) > coverage_path_mtime
|
35
|
+
end
|
36
|
+
warn("{changed_trigger_files: #{changed_trigger_files.inspect}}") if Uncov.configuration.debug
|
37
|
+
changed_trigger_files.any?
|
23
38
|
end
|
24
39
|
|
25
40
|
def regenerate_report
|
data/lib/uncov/finder.rb
CHANGED
@@ -8,19 +8,24 @@ class Uncov::Finder
|
|
8
8
|
def git_file?(file_name) = git_files[file_name]
|
9
9
|
def git_file_names = git_files.keys
|
10
10
|
def git_diff_file_names = git_diff_files.keys
|
11
|
-
def git_diff_file_line?(file_name, line_number) = git_diff_files[file_name].key?(line_number)
|
12
11
|
def git_diff_file_lines(file_name) = git_diff_files[file_name]
|
13
|
-
def
|
14
|
-
def
|
15
|
-
def
|
12
|
+
def git_diff_file_line?(file_name, line_number) = git_diff_files[file_name]&.key?(line_number)
|
13
|
+
def file_system_file_names = file_system_files.keys
|
14
|
+
def file_system_file_line(file_name, line_number) = file_system_files[file_name]&.dig(line_number)
|
15
|
+
def file_system_file_lines(file_name) = file_system_files[file_name]
|
16
|
+
def no_cov_file_names = no_cov_files.keys
|
17
|
+
def no_cov_file_lines(file_name) = no_cov_files[file_name]
|
18
|
+
def no_cov_file_line?(file_name, line_number) = no_cov_files[file_name]&.dig(line_number)
|
16
19
|
def simple_cov_file_line?(file_name, line_number) = simple_cov_files.dig(file_name, line_number)
|
17
20
|
|
18
21
|
def debug
|
19
22
|
{
|
20
23
|
git_files:,
|
24
|
+
git_test_files:,
|
21
25
|
git_diff_files:,
|
22
|
-
|
23
|
-
|
26
|
+
git_diff_test_files:,
|
27
|
+
file_system_files:,
|
28
|
+
no_cov_files:,
|
24
29
|
simple_cov_files:
|
25
30
|
}
|
26
31
|
end
|
@@ -29,18 +34,64 @@ class Uncov::Finder
|
|
29
34
|
|
30
35
|
attr_reader :simple_cov_trigger
|
31
36
|
|
32
|
-
def git_files
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
def
|
37
|
+
def git_files
|
38
|
+
git_finder.code_files
|
39
|
+
end
|
40
|
+
|
41
|
+
def git_test_files
|
42
|
+
git_finder.test_files
|
43
|
+
end
|
44
|
+
|
45
|
+
def git_finder
|
46
|
+
cache(:git_finder) do
|
47
|
+
Uncov::Finder::Git.new
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def git_diff_files
|
52
|
+
git_diff_finder.code_files
|
53
|
+
end
|
54
|
+
|
55
|
+
def git_diff_test_files
|
56
|
+
git_diff_finder.test_files
|
57
|
+
end
|
58
|
+
|
59
|
+
def git_diff_finder
|
60
|
+
cache(:git_diff_finder) do
|
61
|
+
Uncov::Finder::GitDiff.new
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def file_system_files
|
66
|
+
cache(:file_system_files) do
|
67
|
+
Uncov::Finder::FileSystem.new.files
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def no_cov_files
|
72
|
+
cache(:no_cov_files) do
|
73
|
+
Uncov::Finder::NoCov.new.files(file_system_files)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def simple_cov_files
|
78
|
+
cache(:simple_cov_files) do
|
79
|
+
Uncov::Finder::SimpleCov.files(simple_cov_trigger_files)
|
80
|
+
end
|
81
|
+
end
|
37
82
|
|
38
83
|
def simple_cov_trigger_files
|
39
84
|
case simple_cov_trigger
|
40
85
|
when :git
|
41
|
-
git_file_names
|
86
|
+
git_file_names + git_test_files.keys
|
42
87
|
when :git_diff
|
43
|
-
git_diff_file_names
|
88
|
+
git_diff_file_names + git_diff_test_files.keys
|
89
|
+
when :file_system
|
90
|
+
file_system_file_names
|
91
|
+
else
|
92
|
+
# :nocov:
|
93
|
+
raise Uncov::UnsupportedSimpleCovTriggerError, simple_cov_trigger
|
94
|
+
# :nocov:
|
44
95
|
end
|
45
96
|
end
|
46
97
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'colorize'
|
4
|
-
require 'forwardable'
|
5
4
|
|
6
5
|
# print report to terminal with colors
|
7
6
|
class Uncov::Formatter::Terminal
|
@@ -14,14 +13,19 @@ class Uncov::Formatter::Terminal
|
|
14
13
|
end
|
15
14
|
|
16
15
|
def output
|
17
|
-
puts "Found #{report.
|
16
|
+
puts "Found #{report.display_files.size} files with uncovered changes:".yellow
|
18
17
|
output_files
|
19
18
|
puts
|
20
|
-
puts format(
|
19
|
+
puts format(
|
20
|
+
'Overall coverage of changes: %<coverage>.2f%% (%<covered_lines>d / %<relevant_lines>d)',
|
21
|
+
coverage: report.coverage,
|
22
|
+
covered_lines: report.covered_lines_count,
|
23
|
+
relevant_lines: report.relevant_lines_count
|
24
|
+
).yellow
|
21
25
|
end
|
22
26
|
|
23
27
|
def output_files
|
24
|
-
report.
|
28
|
+
report.display_files.each do |file_coverage|
|
25
29
|
output_file(file_coverage)
|
26
30
|
end
|
27
31
|
end
|
@@ -40,8 +44,8 @@ class Uncov::Formatter::Terminal
|
|
40
44
|
'%<name>s -> %<coverage>.2f%% (%<covered_lines>d / %<relevant_lines>d) changes covered, uncovered lines:',
|
41
45
|
name: file_coverage.file_name,
|
42
46
|
coverage: file_coverage.coverage,
|
43
|
-
covered_lines: file_coverage.
|
44
|
-
relevant_lines: file_coverage.
|
47
|
+
covered_lines: file_coverage.covered_lines_count,
|
48
|
+
relevant_lines: file_coverage.relevant_lines_count
|
45
49
|
).yellow
|
46
50
|
end
|
47
51
|
|
@@ -50,6 +54,8 @@ class Uncov::Formatter::Terminal
|
|
50
54
|
puts format_line(line, max).red
|
51
55
|
elsif line.context
|
52
56
|
puts format_line(line, max).green
|
57
|
+
elsif line.nocov_covered?
|
58
|
+
puts format_line(line, max).blue
|
53
59
|
else
|
54
60
|
# :nocov:
|
55
61
|
raise 'unknown display line' # unreachable code
|
data/lib/uncov/formatter.rb
CHANGED
@@ -2,19 +2,38 @@
|
|
2
2
|
|
3
3
|
# represents file line coverage in report
|
4
4
|
class Uncov::Report::File::Line < Uncov::Struct.new(:number, :content, :simple_cov, :no_cov, :context, :git_diff)
|
5
|
+
def no_cov
|
6
|
+
return false if Uncov.configuration.nocov_ignore
|
7
|
+
|
8
|
+
self[:no_cov]
|
9
|
+
end
|
10
|
+
|
5
11
|
def uncov?
|
6
12
|
simple_cov == false && !no_cov
|
7
13
|
end
|
8
14
|
|
15
|
+
def nocov_covered?
|
16
|
+
# :nocov
|
17
|
+
Uncov.configuration.nocov_covered && simple_cov == true && self[:no_cov]
|
18
|
+
# :nocov
|
19
|
+
end
|
20
|
+
|
9
21
|
def covered?
|
10
|
-
|
22
|
+
return false if Uncov.configuration.nocov_ignore && self[:no_cov]
|
23
|
+
|
24
|
+
(simple_cov == true && !no_cov) ||
|
25
|
+
(Uncov.configuration.nocov_covered && simple_cov == false && self[:no_cov])
|
26
|
+
end
|
27
|
+
|
28
|
+
def trigger?
|
29
|
+
uncov? || nocov_covered?
|
11
30
|
end
|
12
31
|
|
13
32
|
def display?
|
14
|
-
|
33
|
+
trigger? || context
|
15
34
|
end
|
16
35
|
|
17
36
|
def relevant?
|
18
|
-
|
37
|
+
trigger? || covered?
|
19
38
|
end
|
20
39
|
end
|
data/lib/uncov/report/file.rb
CHANGED
@@ -6,27 +6,27 @@ class Uncov::Report::File < Uncov::Struct.new(:file_name, :lines, :git)
|
|
6
6
|
|
7
7
|
def coverage
|
8
8
|
cache(:coverage) do
|
9
|
-
if
|
9
|
+
if relevant_lines_count.zero?
|
10
10
|
100.0
|
11
11
|
else
|
12
|
-
(
|
12
|
+
(covered_lines_count.to_f / relevant_lines_count * 100).round(2)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
|
17
|
+
def trigger?
|
18
|
+
cache(:trigger) do
|
19
|
+
lines.any?(&:trigger?)
|
20
|
+
end
|
19
21
|
end
|
20
22
|
|
21
|
-
def
|
22
|
-
|
23
|
-
lines.select(&:uncov?)
|
24
|
-
end
|
23
|
+
def display?
|
24
|
+
display_lines.any?
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
cache(:
|
29
|
-
lines.
|
27
|
+
def covered_lines_count
|
28
|
+
cache(:covered_lines_count) do
|
29
|
+
lines.count(&:covered?)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -36,9 +36,9 @@ class Uncov::Report::File < Uncov::Struct.new(:file_name, :lines, :git)
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
40
|
-
cache(:
|
41
|
-
lines.
|
39
|
+
def relevant_lines_count
|
40
|
+
cache(:relevant_lines_count) do
|
41
|
+
lines.count(&:relevant?)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# report only files lines from the diff
|
4
|
+
module Uncov::Report::Generator::DiffFiles
|
5
|
+
Uncov::Report::Generator.register(self, :git_diff, 'Report missing coverage on added/changed files in the git diff')
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def files(finder)
|
9
|
+
finder.git_diff_file_names.map do |file_name|
|
10
|
+
Uncov::Report::File.new(
|
11
|
+
file_name:,
|
12
|
+
git: true,
|
13
|
+
lines: lines(finder, file_name)
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def lines(finder, file_name)
|
21
|
+
lines_hash = file_lines(finder, file_name)
|
22
|
+
add_context(lines_hash)
|
23
|
+
lines_hash.sort.to_h.values
|
24
|
+
end
|
25
|
+
|
26
|
+
def file_lines(finder, file_name)
|
27
|
+
finder.file_system_file_lines(file_name).to_h do |line_number, content|
|
28
|
+
[line_number, new_line(finder, file_name, line_number, content)]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_context(lines_hash)
|
33
|
+
return if Uncov.configuration.context.zero?
|
34
|
+
|
35
|
+
line_numbers =
|
36
|
+
lines_hash.filter_map do |line_number, line|
|
37
|
+
line_number if line.trigger?
|
38
|
+
end
|
39
|
+
all_line_numbers = lines_hash.keys
|
40
|
+
context_line_numbers = Uncov::Report::Context.calculate(all_line_numbers, line_numbers, Uncov.configuration.context)
|
41
|
+
context_line_numbers.each do |line_number|
|
42
|
+
lines_hash[line_number].context = true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def new_line(finder, file_name, line_number, content)
|
47
|
+
Uncov::Report::File::Line.new(
|
48
|
+
number: line_number,
|
49
|
+
content:,
|
50
|
+
no_cov: finder.no_cov_file_line?(file_name, line_number),
|
51
|
+
simple_cov: finder.simple_cov_file_line?(file_name, line_number),
|
52
|
+
git_diff: finder.git_diff_file_line?(file_name, line_number),
|
53
|
+
context: false
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# report only files lines from the diff
|
4
|
-
module Uncov::Report::DiffLines
|
4
|
+
module Uncov::Report::Generator::DiffLines
|
5
|
+
Uncov::Report::Generator.register(self, :git_diff, 'Report missing coverage on added lines in the git diff')
|
6
|
+
|
5
7
|
class << self
|
6
8
|
def files(finder)
|
7
9
|
finder.git_diff_file_names.map do |file_name|
|
@@ -32,7 +34,7 @@ module Uncov::Report::DiffLines
|
|
32
34
|
|
33
35
|
line_numbers =
|
34
36
|
lines_hash.filter_map do |line_number, line|
|
35
|
-
line_number if line.
|
37
|
+
line_number if line.trigger?
|
36
38
|
end
|
37
39
|
all_line_numbers = finder.file_system_file_lines(file_name).keys
|
38
40
|
context_line_numbers = Uncov::Report::Context.calculate(all_line_numbers, line_numbers, Uncov.configuration.context)
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# report only files lines from the diff
|
4
|
+
module Uncov::Report::Generator::GitFiles
|
5
|
+
Uncov::Report::Generator.register(self, :git, 'Report missing coverage on files tracked with git')
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def files(finder)
|
9
|
+
finder.git_file_names.map do |file_name|
|
10
|
+
Uncov::Report::File.new(
|
11
|
+
file_name:,
|
12
|
+
git: true,
|
13
|
+
lines: lines(finder, file_name)
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def lines(finder, file_name)
|
21
|
+
lines_hash = file_lines(finder, file_name)
|
22
|
+
add_context(lines_hash)
|
23
|
+
lines_hash.sort.to_h.values
|
24
|
+
end
|
25
|
+
|
26
|
+
def file_lines(finder, file_name)
|
27
|
+
finder.file_system_file_lines(file_name).to_h do |line_number, content|
|
28
|
+
[line_number, new_line(finder, file_name, line_number, content)]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_context(lines_hash)
|
33
|
+
return if Uncov.configuration.context.zero?
|
34
|
+
|
35
|
+
line_numbers =
|
36
|
+
lines_hash.filter_map do |line_number, line|
|
37
|
+
line_number if line.trigger?
|
38
|
+
end
|
39
|
+
all_line_numbers = lines_hash.keys
|
40
|
+
context_line_numbers = Uncov::Report::Context.calculate(all_line_numbers, line_numbers, Uncov.configuration.context)
|
41
|
+
context_line_numbers.each do |line_number|
|
42
|
+
lines_hash[line_number].context = true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def new_line(finder, file_name, line_number, content)
|
47
|
+
Uncov::Report::File::Line.new(
|
48
|
+
number: line_number,
|
49
|
+
content:,
|
50
|
+
no_cov: finder.no_cov_file_line?(file_name, line_number),
|
51
|
+
simple_cov: finder.simple_cov_file_line?(file_name, line_number),
|
52
|
+
git_diff: finder.git_diff_file_line?(file_name, line_number),
|
53
|
+
context: false
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# report only files lines from the diff
|
4
|
+
module Uncov::Report::Generator::NocovLines
|
5
|
+
Uncov::Report::Generator.register(self, :file_system, 'Report coverage on nocov lines, requires one or both: --nocov-ignore / --nocov-covered')
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def files(finder)
|
9
|
+
finder.no_cov_file_names.filter_map do |file_name|
|
10
|
+
next if finder.no_cov_file_lines(file_name).empty?
|
11
|
+
|
12
|
+
Uncov::Report::File.new(
|
13
|
+
file_name:,
|
14
|
+
git: finder.git_file?(file_name),
|
15
|
+
lines: lines(finder, file_name)
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def lines(finder, file_name)
|
23
|
+
lines_hash = nocov_files_lines(finder, file_name)
|
24
|
+
add_context(finder, file_name, lines_hash)
|
25
|
+
lines_hash.sort.to_h.values
|
26
|
+
end
|
27
|
+
|
28
|
+
def nocov_files_lines(finder, file_name)
|
29
|
+
finder.no_cov_file_lines(file_name).keys.to_h do |line_number|
|
30
|
+
[line_number, new_line(finder, file_name, line_number)]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_context(finder, file_name, lines_hash)
|
35
|
+
return if Uncov.configuration.context.zero?
|
36
|
+
|
37
|
+
line_numbers =
|
38
|
+
lines_hash.filter_map do |line_number, line|
|
39
|
+
line_number if line.trigger?
|
40
|
+
end
|
41
|
+
all_line_numbers = finder.file_system_file_lines(file_name).keys
|
42
|
+
context_line_numbers = Uncov::Report::Context.calculate(all_line_numbers, line_numbers, Uncov.configuration.context)
|
43
|
+
context_line_numbers.each do |line_number|
|
44
|
+
context_line(finder, file_name, lines_hash, line_number)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def context_line(finder, file_name, lines_hash, line_number)
|
49
|
+
if lines_hash.key?(line_number)
|
50
|
+
lines_hash[line_number].context = true
|
51
|
+
else
|
52
|
+
lines_hash[line_number] = new_line(finder, file_name, line_number, context: true)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def new_line(finder, file_name, line_number, context: false)
|
57
|
+
Uncov::Report::File::Line.new(
|
58
|
+
number: line_number,
|
59
|
+
content: finder.file_system_file_line(file_name, line_number),
|
60
|
+
no_cov: finder.no_cov_file_line?(file_name, line_number),
|
61
|
+
simple_cov: finder.simple_cov_file_line?(file_name, line_number),
|
62
|
+
git_diff: finder.git_diff_file_line?(file_name, line_number),
|
63
|
+
context:
|
64
|
+
)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../report'
|
4
|
+
|
5
|
+
# generate report files and lines for the configured report type
|
6
|
+
module Uncov::Report::Generator
|
7
|
+
class << self
|
8
|
+
def filters
|
9
|
+
@filters ||= {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def register(generator_class, simple_cov_trigger, description)
|
13
|
+
class_name = generator_class.to_s.split('::').last
|
14
|
+
generator_name = class_name.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
|
15
|
+
filters[generator_name] = { generator_class:, simple_cov_trigger:, description: }
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate
|
19
|
+
raise Uncov::UnsupportedReportTypeError, Uncov.configuration.report unless filters.key?(Uncov.configuration.report)
|
20
|
+
|
21
|
+
filters[Uncov.configuration.report] => { generator_class:, simple_cov_trigger: }
|
22
|
+
generator_class.files(Uncov::Finder.new(simple_cov_trigger))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/uncov/report.rb
CHANGED
@@ -8,38 +8,37 @@ class Uncov::Report < Uncov::Struct.new(:files)
|
|
8
8
|
include Uncov::Cache
|
9
9
|
|
10
10
|
class << self
|
11
|
-
def
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
def build
|
16
|
-
files =
|
17
|
-
case Uncov.configuration.report
|
18
|
-
when 'diff_lines'
|
19
|
-
finder = Uncov::Finder.new(:git_diff)
|
20
|
-
Uncov::Report::DiffLines.files(finder)
|
21
|
-
end
|
22
|
-
new(files:)
|
11
|
+
def generate
|
12
|
+
new(files: Uncov::Report::Generator.generate)
|
23
13
|
end
|
24
14
|
end
|
25
15
|
|
26
|
-
def
|
27
|
-
cache(:
|
28
|
-
files.select(&:
|
16
|
+
def display_files
|
17
|
+
cache(:display_files) do
|
18
|
+
files.select(&:display?)
|
29
19
|
end
|
30
20
|
end
|
31
21
|
|
32
22
|
def coverage
|
33
23
|
cache(:coverage) do
|
34
|
-
if
|
24
|
+
if relevant_lines_count.zero?
|
35
25
|
100.0
|
36
26
|
else
|
37
|
-
(
|
27
|
+
(covered_lines_count.to_f / relevant_lines_count * 100).round(2)
|
38
28
|
end
|
39
29
|
end
|
40
30
|
end
|
41
31
|
|
42
|
-
def
|
43
|
-
|
32
|
+
def relevant_lines_count = files.sum(&:relevant_lines_count)
|
33
|
+
def covered_lines_count = files.sum(&:covered_lines_count)
|
34
|
+
|
35
|
+
def trigger?
|
36
|
+
cache(:trigger) do
|
37
|
+
files.any?(&:trigger?)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def display?
|
42
|
+
display_files.any?
|
44
43
|
end
|
45
44
|
end
|
data/lib/uncov/version.rb
CHANGED
data/lib/uncov.rb
CHANGED
@@ -10,7 +10,7 @@ module Uncov
|
|
10
10
|
def configure(args = [])
|
11
11
|
yield(configuration) if block_given?
|
12
12
|
configuration.parse_cli(args) if args.any?
|
13
|
-
warn({
|
13
|
+
warn("{configuration: #{configuration.options_values.inspect}}") if configuration.debug
|
14
14
|
nil
|
15
15
|
end
|
16
16
|
|
@@ -29,8 +29,10 @@ module Uncov
|
|
29
29
|
|
30
30
|
class ConfigurationError < Error; end
|
31
31
|
class GitError < Error; end
|
32
|
-
class
|
32
|
+
class FinderError < Error; end
|
33
|
+
class SimpleCovError < FinderError; end
|
33
34
|
class FormatterError < Error; end
|
35
|
+
class ReportError < Error; end
|
34
36
|
class OptionValueNotAllowed < ConfigurationError; end
|
35
37
|
|
36
38
|
class NotGitRepoError < GitError
|
@@ -40,11 +42,18 @@ module Uncov
|
|
40
42
|
def message = "#{path.inspect} is not in a git working tree"
|
41
43
|
end
|
42
44
|
|
43
|
-
class
|
45
|
+
class NotGitObjectError < GitError
|
44
46
|
attr_reader :target_branch
|
45
47
|
|
46
48
|
def initialize(target_branch) = @target_branch = target_branch
|
47
|
-
def message = "
|
49
|
+
def message = "Git target #{target_branch.inspect} not found locally"
|
50
|
+
end
|
51
|
+
|
52
|
+
class UnsupportedSimpleCovTriggerError < FinderError
|
53
|
+
attr_reader :trigger
|
54
|
+
|
55
|
+
def initialize(trigger) = @trigger = trigger
|
56
|
+
def message = "#{trigger.inspect} is not a supported simple_cov_trigger type"
|
48
57
|
end
|
49
58
|
|
50
59
|
class FailedToGenerateReport < SimpleCovError
|
@@ -68,4 +77,11 @@ module Uncov
|
|
68
77
|
def initialize(output_format) = @output_format = output_format
|
69
78
|
def message = "#{output_format.inspect} is not a supported formatter"
|
70
79
|
end
|
80
|
+
|
81
|
+
class UnsupportedReportTypeError < ReportError
|
82
|
+
attr_reader :type
|
83
|
+
|
84
|
+
def initialize(type) = @type = type
|
85
|
+
def message = "#{type.inspect} is not a supported report type"
|
86
|
+
end
|
71
87
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uncov
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michał Papis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-05-
|
11
|
+
date: 2025-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -111,9 +111,13 @@ files:
|
|
111
111
|
- lib/uncov/formatter/terminal.rb
|
112
112
|
- lib/uncov/report.rb
|
113
113
|
- lib/uncov/report/context.rb
|
114
|
-
- lib/uncov/report/diff_lines.rb
|
115
114
|
- lib/uncov/report/file.rb
|
116
115
|
- lib/uncov/report/file/line.rb
|
116
|
+
- lib/uncov/report/generator.rb
|
117
|
+
- lib/uncov/report/generator/diff_files.rb
|
118
|
+
- lib/uncov/report/generator/diff_lines.rb
|
119
|
+
- lib/uncov/report/generator/git_files.rb
|
120
|
+
- lib/uncov/report/generator/nocov_lines.rb
|
117
121
|
- lib/uncov/struct.rb
|
118
122
|
- lib/uncov/version.rb
|
119
123
|
homepage: https://github.com/mpapis/uncov
|