coverage-reporter 0.2.0 → 0.3.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: c646220bc7af144054d14538534b4fdc0ee3dc6a0f0e3bcea0b26bf1611a9839
4
- data.tar.gz: 644b7b1431164971025b9f5e2dcfd0d25a9ce9164764e76341080d597816be17
3
+ metadata.gz: 13b5ede2585f67e28da56541940a417c9a2266f334a836d8ba4aae949f35a7aa
4
+ data.tar.gz: a23afcc6d059da70d2b0857e9a06af23177b0058690d66695596f7b7e0f774df
5
5
  SHA512:
6
- metadata.gz: '089653dbdbdb8d9ff0321afdfc4fd5c01765045f51a949f2f37e08677f540dd10e1ed2a5b977edb81b0cf111ed78e7943de246977ca21c9c194cdc06e5a55b88'
7
- data.tar.gz: 4c7e4d2379a58d932a6b06387b53a0e114b58b7124ad0a2f7ed4e64aef22e6e1a3170cefa4ec9d58d64356c42a122a686a7f322113134f2e2d6687824b6d313a
6
+ metadata.gz: 29ba80d86581dd7f99b7141cec2e3a9a1fd81ae41dcff5d82d9305556b2a63489121946a9279cb92e905b24b983352ceb690c50ef1946f82ba7a95a2201dd25e
7
+ data.tar.gz: 592e4e220fea3f616aa7ca89938638fa463bb3a7a1ab5a3dce42ce4c0c9923baf44cba5fb2e7bfda525d5e30e524903a42c17296b0c44a547b9e02e611925cd7
data/README.md CHANGED
@@ -59,7 +59,7 @@ gem install coverage-reporter
59
59
 
60
60
  3. **Run the coverage reporter**:
61
61
  ```bash
62
- coverage-reporter
62
+ coverage-reporter report
63
63
  ```
64
64
 
65
65
  The tool will automatically:
@@ -1,10 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "optparse"
4
+
3
5
  module CoverageReporter
4
6
  class CLI
5
7
  def self.start(argv)
6
- options = Options.parse(argv)
7
- Runner.new(options).run
8
+ case argv.first
9
+ when nil
10
+ show_usage_and_exit
11
+ when "report"
12
+ # Report command
13
+ options = Options::Report.parse(argv[1..])
14
+ Runner.new(options).run
15
+ when "collate"
16
+ collate_options = Options::Collate.parse(argv[1..])
17
+ CoverageCollator.new(collate_options).call
18
+ else
19
+ show_unknown_command_error(argv.first)
20
+ end
21
+ end
22
+
23
+ private_class_method def self.show_usage_and_exit
24
+ puts "Usage: coverage-reporter <command> [options]"
25
+ print_commands_list
26
+ exit 1
27
+ end
28
+
29
+ private_class_method def self.show_unknown_command_error(command)
30
+ puts "Unknown command: #{command}"
31
+ print_commands_list
32
+ exit 1
33
+ end
34
+
35
+ private_class_method def self.print_commands_list
36
+ puts ""
37
+ puts "Commands:"
38
+ puts " report Generate coverage report and post comments"
39
+ puts " collate Collate multiple coverage files"
40
+ puts ""
41
+ puts "Use 'coverage-reporter <command> --help' for command-specific options"
8
42
  end
9
43
  end
10
44
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoverageReporter
4
+ class CoverageCollator
5
+ def initialize(options={})
6
+ @coverage_dir = options[:coverage_dir]
7
+ end
8
+
9
+ def call
10
+ require "simplecov"
11
+ require "simplecov_json_formatter"
12
+ require "coverage_reporter/simple_cov/patches/result_hash_formatter_patch"
13
+
14
+ # Collate JSON coverage reports and generate both HTML and JSON outputs
15
+ files = Dir["#{coverage_dir}/resultset-*.json"]
16
+ abort "No coverage JSON files found to collate" if files.empty?
17
+
18
+ puts "Collate coverage files: #{files.join(', ')}"
19
+
20
+ ::SimpleCov.collate(files) do
21
+ formatter ::SimpleCov::Formatter::MultiFormatter.new(
22
+ [
23
+ ::SimpleCov::Formatter::HTMLFormatter,
24
+ ::SimpleCov::Formatter::JSONFormatter
25
+ ]
26
+ )
27
+ end
28
+
29
+ puts "✅ Coverage merged and report generated."
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :coverage_dir
35
+ end
36
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoverageReporter
4
+ module Options
5
+ # Interface class that defines the contract for option classes
6
+ class Base
7
+ # Returns a hash of default options
8
+ def self.defaults
9
+ raise NotImplementedError, "Subclasses must implement #{__method__}"
10
+ end
11
+
12
+ # Parses command line arguments and returns a hash of options
13
+ # @param argv [Array<String>] Command line arguments
14
+ # @return [Hash] Parsed options
15
+ def self.parse(argv)
16
+ raise NotImplementedError, "Subclasses must implement #{__method__}"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+
5
+ module CoverageReporter
6
+ module Options
7
+ class Collate < Base
8
+ def self.defaults
9
+ {
10
+ coverage_dir: "coverage"
11
+ }
12
+ end
13
+
14
+ def self.parse(argv)
15
+ opts = defaults.dup
16
+
17
+ parser = OptionParser.new do |o|
18
+ o.banner = "Usage: coverage-reporter collate [options]"
19
+ o.on("--coverage-dir DIR", "Directory containing coverage files (default: coverage)") do |v|
20
+ opts[:coverage_dir] = v
21
+ end
22
+ o.on_tail("-h", "--help", "Show help") do
23
+ puts o
24
+ exit 0
25
+ end
26
+ end
27
+
28
+ parser.parse!(argv)
29
+ opts
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+
5
+ module CoverageReporter
6
+ module Options
7
+ class Report < Base
8
+ def self.defaults
9
+ {
10
+ commit_sha: ENV.fetch("COMMIT_SHA", nil),
11
+ coverage_report_path: ENV.fetch("COVERAGE_REPORT_PATH", "coverage/coverage.json"),
12
+ github_token: ENV.fetch("GITHUB_TOKEN", nil),
13
+ pr_number: ENV.fetch("PR_NUMBER", nil),
14
+ repo: normalize_repo(ENV.fetch("REPO", nil)),
15
+ report_url: ENV.fetch("REPORT_URL", nil)
16
+ }
17
+ end
18
+
19
+ # rubocop:disable Metrics/AbcSize
20
+ # rubocop:disable Metrics/MethodLength
21
+ def self.parse(argv)
22
+ opts = defaults.dup
23
+
24
+ parser = OptionParser.new do |o|
25
+ o.banner = "Usage: coverage-reporter [options]"
26
+ o.on("--report-url URL", "Report URL used for links (default: $REPORT_URL)") do |v|
27
+ opts[:report_url] = v
28
+ end
29
+ o.on("--commit-sha SHA", "GitHub commit SHA (default: $COMMIT_SHA)") do |v|
30
+ opts[:commit_sha] = v
31
+ end
32
+ o.on(
33
+ "--coverage-report-path PATH",
34
+ "Path to merged SimpleCov coverage.json (default: coverage/coverage.json)"
35
+ ) do |v|
36
+ opts[:coverage_report_path] = v
37
+ end
38
+ o.on("--github-token TOKEN", "GitHub token (default: $GITHUB_TOKEN)") { |v| opts[:github_token] = v }
39
+ o.on("--pr-number NUMBER", "GitHub pull request number (default: $PR_NUMBER)") do |v|
40
+ opts[:pr_number] = v
41
+ end
42
+ o.on("--repo REPO", "GitHub repository (default: $REPO)") do |v|
43
+ opts[:repo] = normalize_repo(v)
44
+ end
45
+ o.on_tail("-h", "--help", "Show help") do
46
+ puts o
47
+ exit 0
48
+ end
49
+ end
50
+ # rubocop:enable Metrics/AbcSize
51
+ # rubocop:enable Metrics/MethodLength
52
+ parser.parse!(argv)
53
+
54
+ validate!(opts)
55
+ opts
56
+ end
57
+
58
+ def self.validate!(opts)
59
+ missing = collect_missing_options(opts)
60
+ return if missing.empty?
61
+
62
+ abort "coverage-reporter: missing required option(s): #{missing.join(', ')}"
63
+ end
64
+
65
+ def self.collect_missing_options(opts)
66
+ required_options = {
67
+ github_token: "--github-token or $GITHUB_TOKEN",
68
+ repo: "--repo or $REPO",
69
+ pr_number: "--pr-number or $PR_NUMBER",
70
+ commit_sha: "--commit-sha or $COMMIT_SHA"
71
+ }
72
+
73
+ required_options.filter_map do |key, message|
74
+ message if opts[key].to_s.strip.empty?
75
+ end
76
+ end
77
+
78
+ def self.normalize_repo(repo)
79
+ return repo if repo.nil? || repo.strip.empty?
80
+
81
+ repo.strip
82
+ .gsub(%r{^(https://github\.com/|git@github\.com:)}, "")
83
+ .gsub(/\.git$/, "")
84
+ end
85
+ end
86
+ end
87
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CoverageReporter
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -34,6 +34,7 @@ module CoverageReporter
34
34
  end
35
35
 
36
36
  require_relative "coverage_reporter/coverage_analyzer"
37
+ require_relative "coverage_reporter/coverage_collator"
37
38
  require_relative "coverage_reporter/coverage_report_loader"
38
39
  require_relative "coverage_reporter/global_comment"
39
40
  require_relative "coverage_reporter/global_comment_poster"
@@ -41,7 +42,9 @@ module CoverageReporter
41
42
  require_relative "coverage_reporter/inline_comment_factory"
42
43
  require_relative "coverage_reporter/inline_comment_poster"
43
44
  require_relative "coverage_reporter/modified_ranges_extractor"
44
- require_relative "coverage_reporter/options"
45
+ require_relative "coverage_reporter/options/base"
46
+ require_relative "coverage_reporter/options/collate"
47
+ require_relative "coverage_reporter/options/report"
45
48
  require_relative "coverage_reporter/pull_request"
46
49
  require_relative "coverage_reporter/runner"
47
50
  require_relative "coverage_reporter/uncovered_ranges_extractor"
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.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriel Taylor Russ
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-10-20 00:00:00.000000000 Z
10
+ date: 2025-10-21 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: octokit
@@ -23,6 +23,20 @@ dependencies:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
25
  version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: simplecov
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
26
40
  - !ruby/object:Gem::Dependency
27
41
  name: simplecov_json_formatter
28
42
  requirement: !ruby/object:Gem::Requirement
@@ -50,6 +64,7 @@ files:
50
64
  - lib/coverage_reporter.rb
51
65
  - lib/coverage_reporter/cli.rb
52
66
  - lib/coverage_reporter/coverage_analyzer.rb
67
+ - lib/coverage_reporter/coverage_collator.rb
53
68
  - lib/coverage_reporter/coverage_report_loader.rb
54
69
  - lib/coverage_reporter/global_comment.rb
55
70
  - lib/coverage_reporter/global_comment_poster.rb
@@ -57,7 +72,9 @@ files:
57
72
  - lib/coverage_reporter/inline_comment_factory.rb
58
73
  - lib/coverage_reporter/inline_comment_poster.rb
59
74
  - lib/coverage_reporter/modified_ranges_extractor.rb
60
- - lib/coverage_reporter/options.rb
75
+ - lib/coverage_reporter/options/base.rb
76
+ - lib/coverage_reporter/options/collate.rb
77
+ - lib/coverage_reporter/options/report.rb
61
78
  - lib/coverage_reporter/pull_request.rb
62
79
  - lib/coverage_reporter/runner.rb
63
80
  - lib/coverage_reporter/simple_cov/patches/result_hash_formatter_patch.rb
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "optparse"
4
-
5
- module CoverageReporter
6
- class Options
7
- def self.defaults
8
- {
9
- commit_sha: ENV.fetch("COMMIT_SHA", nil),
10
- coverage_report_path: ENV.fetch("COVERAGE_REPORT_PATH", "coverage/coverage.json"),
11
- github_token: ENV.fetch("GITHUB_TOKEN", nil),
12
- pr_number: ENV.fetch("PR_NUMBER", nil),
13
- repo: normalize_repo(ENV.fetch("REPO", nil)),
14
- report_url: ENV.fetch("REPORT_URL", nil)
15
- }
16
- end
17
-
18
- # rubocop:disable Metrics/AbcSize
19
- # rubocop:disable Metrics/MethodLength
20
- def self.parse(argv)
21
- opts = defaults.dup
22
-
23
- parser = OptionParser.new do |o|
24
- o.banner = "Usage: coverage-reporter [options]"
25
- o.on("--report-url URL", "Report URL used for links (default: $REPORT_URL)") do |v|
26
- opts[:report_url] = v
27
- end
28
- o.on("--commit-sha SHA", "GitHub commit SHA (default: $COMMIT_SHA)") do |v|
29
- opts[:commit_sha] = v
30
- end
31
- o.on(
32
- "--coverage-report-path PATH",
33
- "Path to merged SimpleCov coverage.json (default: coverage/coverage.json)"
34
- ) do |v|
35
- opts[:coverage_report_path] = v
36
- end
37
- o.on("--github-token TOKEN", "GitHub token (default: $GITHUB_TOKEN)") { |v| opts[:github_token] = v }
38
- o.on("--pr-number NUMBER", "GitHub pull request number (default: $PR_NUMBER)") do |v|
39
- opts[:pr_number] = v
40
- end
41
- o.on("--repo REPO", "GitHub repository (default: $REPO)") do |v|
42
- opts[:repo] = normalize_repo(v)
43
- end
44
- o.on_tail("-h", "--help", "Show help") do
45
- puts o
46
- exit 0
47
- end
48
- end
49
- # rubocop:enable Metrics/AbcSize
50
- # rubocop:enable Metrics/MethodLength
51
- parser.parse!(argv)
52
-
53
- validate!(opts)
54
- opts
55
- end
56
-
57
- def self.validate!(opts)
58
- missing = collect_missing_options(opts)
59
- return if missing.empty?
60
-
61
- abort "coverage-reporter: missing required option(s): #{missing.join(', ')}"
62
- end
63
-
64
- def self.collect_missing_options(opts)
65
- required_options = {
66
- github_token: "--github-token or $GITHUB_TOKEN",
67
- repo: "--repo or $REPO",
68
- pr_number: "--pr-number or $PR_NUMBER",
69
- commit_sha: "--commit-sha or $COMMIT_SHA"
70
- }
71
-
72
- required_options.filter_map do |key, message|
73
- message if opts[key].to_s.strip.empty?
74
- end
75
- end
76
-
77
- def self.normalize_repo(repo)
78
- return repo if repo.nil? || repo.strip.empty?
79
-
80
- repo.strip
81
- .gsub(%r{^(https://github\.com/|git@github\.com:)}, "")
82
- .gsub(/\.git$/, "")
83
- end
84
- end
85
- end