coverage-reporter 0.3.2 → 0.3.3
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/lib/coverage_reporter/coverage_collator.rb +6 -6
- data/lib/coverage_reporter/inline_comment_poster.rb +52 -5
- data/lib/coverage_reporter/pull_request.rb +14 -0
- data/lib/coverage_reporter/uncovered_ranges_extractor.rb +39 -4
- data/lib/coverage_reporter/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '084368a5d340a21403c9f358fbbd599cd48dc48dd429aec44a40b6eddfec5b4f'
|
|
4
|
+
data.tar.gz: 4f9f847624fe3f1a5692f757d316254f41eee376643bfb8f790edac4f89a228d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e6aca8f9a84ff71d7570967e115ae2e17652e9c0514f18396f21a069222e30f7343ea7b9f11522a932f62edf1373ef081491a232ed6b8ebabe0c87fd868022cb
|
|
7
|
+
data.tar.gz: 1ffb8d0777fce695e3d32833d9b221c6749c8d59951afb45625a167ab755377c16519848f578037fca5f5238d081dd313bbe81edd4ff52050ea55f443e57cfd0
|
|
@@ -8,6 +8,7 @@ module CoverageReporter
|
|
|
8
8
|
@working_dir = options[:working_dir]
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
# rubocop:disable Metrics/AbcSize
|
|
11
12
|
def call
|
|
12
13
|
require "simplecov"
|
|
13
14
|
require "simplecov_json_formatter"
|
|
@@ -20,13 +21,16 @@ module CoverageReporter
|
|
|
20
21
|
|
|
21
22
|
puts "Collate coverage files: #{coverage_files.join(', ')}"
|
|
22
23
|
|
|
24
|
+
::SimpleCov.root(working_dir) if working_dir
|
|
25
|
+
|
|
23
26
|
::SimpleCov.collate(coverage_files) do
|
|
24
|
-
add_filter(build_filter) if filenames.any?
|
|
27
|
+
add_filter(build_filter) if filenames.any? && working_dir
|
|
25
28
|
formatter(build_formatter)
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
puts "✅ Coverage merged and report generated."
|
|
29
32
|
end
|
|
33
|
+
# rubocop:enable Metrics/AbcSize
|
|
30
34
|
|
|
31
35
|
private
|
|
32
36
|
|
|
@@ -43,13 +47,9 @@ module CoverageReporter
|
|
|
43
47
|
|
|
44
48
|
def build_filter
|
|
45
49
|
lambda do |src_file|
|
|
46
|
-
normalized_filename =
|
|
50
|
+
normalized_filename = src_file.filename.gsub(working_dir, "").gsub(%r{^/}, "")
|
|
47
51
|
filenames.none?(normalized_filename)
|
|
48
52
|
end
|
|
49
53
|
end
|
|
50
|
-
|
|
51
|
-
def normalize_filename(filename)
|
|
52
|
-
working_dir ? filename.gsub(working_dir, "").gsub(%r{^/}, "") : filename
|
|
53
|
-
end
|
|
54
54
|
end
|
|
55
55
|
end
|
|
@@ -80,12 +80,59 @@ module CoverageReporter
|
|
|
80
80
|
|
|
81
81
|
def existing_comment_for_path_and_lines(path, start_line, line)
|
|
82
82
|
existing_coverage_comments.values.find do |comment|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
next false unless comment.path == path
|
|
84
|
+
|
|
85
|
+
# Check if line numbers match
|
|
86
|
+
line_numbers_match = if line == start_line
|
|
87
|
+
comment.line == line
|
|
88
|
+
else
|
|
89
|
+
comment.start_line == start_line && comment.line == line
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
next false unless line_numbers_match
|
|
93
|
+
|
|
94
|
+
# Check if the content of the lines has changed
|
|
95
|
+
content_matches?(comment, path, start_line, line)
|
|
88
96
|
end
|
|
89
97
|
end
|
|
98
|
+
|
|
99
|
+
def content_matches?(existing_comment, path, start_line, line)
|
|
100
|
+
# Extract commit SHA from existing comment body
|
|
101
|
+
existing_commit_sha = extract_commit_sha_from_comment(existing_comment.body)
|
|
102
|
+
return false unless existing_commit_sha
|
|
103
|
+
|
|
104
|
+
# If commit SHA matches current commit, content is the same
|
|
105
|
+
return true if existing_commit_sha == commit_sha
|
|
106
|
+
|
|
107
|
+
# Get file content at both commits
|
|
108
|
+
existing_content = pull_request.file_content(path: path, commit_sha: existing_commit_sha)
|
|
109
|
+
current_content = pull_request.file_content(path: path, commit_sha: commit_sha)
|
|
110
|
+
|
|
111
|
+
return false unless existing_content && current_content
|
|
112
|
+
|
|
113
|
+
# Compare the lines at the specified range
|
|
114
|
+
existing_lines = extract_lines(existing_content, start_line, line)
|
|
115
|
+
current_lines = extract_lines(current_content, start_line, line)
|
|
116
|
+
|
|
117
|
+
existing_lines == current_lines
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def extract_commit_sha_from_comment(comment_body)
|
|
121
|
+
return nil unless comment_body
|
|
122
|
+
|
|
123
|
+
# Extract commit SHA from format: "_Commit: abc123_"
|
|
124
|
+
match = comment_body.match(/_Commit:\s*([a-f0-9]+)_/i)
|
|
125
|
+
match ? match[1] : nil
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def extract_lines(content, start_line, line)
|
|
129
|
+
lines = content.lines
|
|
130
|
+
# Convert to 0-based index
|
|
131
|
+
start_idx = start_line - 1
|
|
132
|
+
end_idx = line - 1
|
|
133
|
+
|
|
134
|
+
# Return the lines in the range (inclusive)
|
|
135
|
+
lines[start_idx..end_idx] || []
|
|
136
|
+
end
|
|
90
137
|
end
|
|
91
138
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "base64"
|
|
4
|
+
|
|
3
5
|
module CoverageReporter
|
|
4
6
|
class PullRequest
|
|
5
7
|
def initialize(github_token:, repo:, pr_number:)
|
|
@@ -59,6 +61,18 @@ module CoverageReporter
|
|
|
59
61
|
@diff ||= client.pull_request(repo, pr_number, accept: "application/vnd.github.v3.diff")
|
|
60
62
|
end
|
|
61
63
|
|
|
64
|
+
def file_content(path:, commit_sha:)
|
|
65
|
+
content = client.contents(repo, path: path, ref: commit_sha)
|
|
66
|
+
# GitHub API returns file content as base64-encoded string
|
|
67
|
+
if content.encoding == "base64" && content.content
|
|
68
|
+
Base64.decode64(content.content)
|
|
69
|
+
elsif content.content
|
|
70
|
+
content.content
|
|
71
|
+
end
|
|
72
|
+
rescue Octokit::NotFound, Octokit::Error
|
|
73
|
+
nil
|
|
74
|
+
end
|
|
75
|
+
|
|
62
76
|
private
|
|
63
77
|
|
|
64
78
|
attr_reader :client, :repo, :pr_number
|
|
@@ -33,14 +33,49 @@ module CoverageReporter
|
|
|
33
33
|
return [] unless lines.is_a?(Array)
|
|
34
34
|
|
|
35
35
|
uncovered_lines = []
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
i = 0
|
|
37
|
+
|
|
38
|
+
while i < lines.length
|
|
39
|
+
if lines[i] == 0
|
|
40
|
+
i = process_uncovered_range(lines, uncovered_lines, i)
|
|
41
|
+
else
|
|
42
|
+
i += 1
|
|
43
|
+
end
|
|
40
44
|
end
|
|
45
|
+
|
|
41
46
|
convert_to_ranges(uncovered_lines)
|
|
42
47
|
end
|
|
43
48
|
|
|
49
|
+
def process_uncovered_range(lines, uncovered_lines, start_index)
|
|
50
|
+
i = start_index
|
|
51
|
+
# Found an uncovered line, start a range (always starts with 0)
|
|
52
|
+
uncovered_lines << (i + 1)
|
|
53
|
+
i += 1
|
|
54
|
+
|
|
55
|
+
# Continue through consecutive 0s and nils
|
|
56
|
+
# Include nil only if it's immediately followed by an uncovered line (0)
|
|
57
|
+
continue_uncovered_range(lines, uncovered_lines, i)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def continue_uncovered_range(lines, uncovered_lines, start_index)
|
|
61
|
+
i = start_index
|
|
62
|
+
while i < lines.length
|
|
63
|
+
break unless should_continue_range?(lines, i)
|
|
64
|
+
|
|
65
|
+
uncovered_lines << (i + 1)
|
|
66
|
+
i += 1
|
|
67
|
+
end
|
|
68
|
+
i
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def should_continue_range?(lines, index)
|
|
72
|
+
return true if lines[index] == 0
|
|
73
|
+
return false unless lines[index].nil?
|
|
74
|
+
|
|
75
|
+
# Include nil only if it's immediately followed by an uncovered line (0)
|
|
76
|
+
index + 1 < lines.length && lines[index + 1] == 0
|
|
77
|
+
end
|
|
78
|
+
|
|
44
79
|
def convert_to_ranges(lines)
|
|
45
80
|
return [] if lines.empty?
|
|
46
81
|
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: coverage-reporter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gabriel Taylor Russ
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2025-11-
|
|
10
|
+
date: 2025-11-17 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: octokit
|