gem_hadar 1.27.0 → 2.0.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: db714afa72ba58c1676c20ec7efdfe235300f384f839ea663880b0ae976a9a0b
4
- data.tar.gz: 6f1ebe9a6446fc600e00d0964a9f3f215cccc264454468bec4dc93e9ff8c674a
3
+ metadata.gz: 461476c530dd6931e016e354762f020bd62cde41cdff6833a409e7f6a9e52a8c
4
+ data.tar.gz: e920f140411d7847dabcba1c6c6e9e4a4f7737a72953498cb76b3d260dd9b531
5
5
  SHA512:
6
- metadata.gz: c89a930270aa72bb13179e6bedd38c4cc5971f8924aba2f86c588925a62baf5141191d065289f6b7a75d1e05f99beb17b91db78f09c23529ab04625d3147b271
7
- data.tar.gz: 5a1eddb1dba0410f324a519b3b445036ec8c6e53c2406968161169133d9f7fd17c1e4e558f9fa72d4b1bdbca4f532ec0e93a4ef616a0796521f2de2d86452dc2
6
+ metadata.gz: e694c32ec183e670a70e1bef998599e5218e523c71c5aeaec9cc21d6424c0ee4b19413ba95877819d993f3a3857d71e9adc5a7da35dfb3fe3f1ac6c67542dc67
7
+ data.tar.gz: f54b76af265cc9da659f577b9d1400cddbd6a23310036c09937a6fa60f623a11e5d01735ad0bbbc39de7b10ff61844e0fcb0a888da8be9a7e13280af36870040
data/README.md CHANGED
@@ -77,7 +77,7 @@ graph TD
77
77
 
78
78
  The source of this library is located at
79
79
 
80
- * http://github.com/flori/gem\_hadar
80
+ * http://github.com/flori/gem_hadar
81
81
 
82
82
  or can be installed via
83
83
 
@@ -112,7 +112,7 @@ The following environment variables can be used to configure `gem_hadar`:
112
112
 
113
113
  To publish gems to RubyGems.org, you'll need to set up an API key:
114
114
 
115
- 1. Generate a new API key at: https://rubygems.org/profile/api\_keys/new
115
+ 1. Generate a new API key at: https://rubygems.org/profile/api_keys/new
116
116
  2. Set the environment variable:
117
117
 
118
118
  ```bash
@@ -476,7 +476,51 @@ $ rake -T
476
476
  - `rake github:release` - Create a new GitHub release for the current version
477
477
  with AI-generated changelog
478
478
 
479
- ### Update Version
479
+ ### Code Coverage with SimpleCov
480
+
481
+ To enable detailed code coverage reporting in your project using `GemHadar`,
482
+ follow these steps:
483
+
484
+ 1. **Install Required Dependencies**
485
+
486
+ Ensure that `simplecov` is included in your `Gemfile`:
487
+
488
+ ```ruby
489
+ gem 'simplecov'
490
+ ```
491
+
492
+ 2. **Initialize Coverage in Your Test Setup**
493
+
494
+ Add this line to the top of your test helper file (e.g., `spec_helper.rb`,
495
+ `test_helper.rb`):
496
+
497
+ ```ruby
498
+ require 'gem_hadar/simplecov'
499
+ GemHadar::SimpleCov.start
500
+ ```
501
+
502
+ 3. **Enable Coverage Reporting**
503
+
504
+ Run tests with the environment variable `START_SIMPLECOV=1`:
505
+
506
+ ```bash
507
+ START_SIMPLECOV=1 bundle exec rspec
508
+ ```
509
+
510
+ This will generate coverage reports in both HTML and JSON formats.
511
+
512
+ 4. **Viewing Reports**
513
+
514
+ After running tests, you can view:
515
+ - **HTML Report**: `coverage/index.html`
516
+ - **JSON Context**: `coverage/coverage_context.json`
517
+
518
+ > 🧪 *Tip:* Enable coverage reporting by setting the `START_SIMPLECOV`
519
+ > environment variable to `1`. The JSON output includes detailed line and
520
+ > branch coverage statistics per file, making it ideal for integration with CI
521
+ > tools or custom dashboards.
522
+
523
+ ### Update Gem Version
480
524
 
481
525
  Use one of the following rake tasks to bump the version:
482
526
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.27.0
1
+ 2.0.0
data/gem_hadar.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: gem_hadar 1.27.0 ruby lib
2
+ # stub: gem_hadar 2.0.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "gem_hadar".freeze
6
- s.version = "1.27.0".freeze
6
+ s.version = "2.0.0".freeze
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
12
12
  s.description = "This library contains some useful functionality to support the development of Ruby Gems".freeze
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.executables = ["gem_hadar".freeze]
15
- s.extra_rdoc_files = ["README.md".freeze, "lib/gem_hadar.rb".freeze, "lib/gem_hadar/github.rb".freeze, "lib/gem_hadar/prompt_template.rb".freeze, "lib/gem_hadar/setup.rb".freeze, "lib/gem_hadar/template_compiler.rb".freeze, "lib/gem_hadar/utils.rb".freeze, "lib/gem_hadar/version.rb".freeze]
16
- s.files = [".gitignore".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/gem_hadar".freeze, "gem_hadar.gemspec".freeze, "lib/gem_hadar.rb".freeze, "lib/gem_hadar/github.rb".freeze, "lib/gem_hadar/prompt_template.rb".freeze, "lib/gem_hadar/setup.rb".freeze, "lib/gem_hadar/template_compiler.rb".freeze, "lib/gem_hadar/utils.rb".freeze, "lib/gem_hadar/version.rb".freeze]
15
+ s.extra_rdoc_files = ["README.md".freeze, "lib/gem_hadar.rb".freeze, "lib/gem_hadar/github.rb".freeze, "lib/gem_hadar/prompt_template.rb".freeze, "lib/gem_hadar/setup.rb".freeze, "lib/gem_hadar/simplecov.rb".freeze, "lib/gem_hadar/template_compiler.rb".freeze, "lib/gem_hadar/utils.rb".freeze, "lib/gem_hadar/version.rb".freeze]
16
+ s.files = [".gitignore".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/gem_hadar".freeze, "gem_hadar.gemspec".freeze, "lib/gem_hadar.rb".freeze, "lib/gem_hadar/github.rb".freeze, "lib/gem_hadar/prompt_template.rb".freeze, "lib/gem_hadar/setup.rb".freeze, "lib/gem_hadar/simplecov.rb".freeze, "lib/gem_hadar/template_compiler.rb".freeze, "lib/gem_hadar/utils.rb".freeze, "lib/gem_hadar/version.rb".freeze]
17
17
  s.homepage = "https://github.com/flori/gem_hadar".freeze
18
18
  s.licenses = ["MIT".freeze]
19
19
  s.rdoc_options = ["--title".freeze, "GemHadar - Library for the development of Ruby Gems".freeze, "--main".freeze, "README.md".freeze]
@@ -0,0 +1,182 @@
1
+ require 'term/ansicolor'
2
+ require 'tins/xt/secure_write'
3
+ require 'fileutils'
4
+ require 'pathname'
5
+
6
+ class GemHadar
7
+ end
8
+
9
+ module GemHadar::SimpleCov
10
+ module WarnModule
11
+ # The warn method displays warning messages using orange colored output.
12
+ #
13
+ # This method takes an array of message strings, applies orange color
14
+ # formatting to each message, and then passes them to the superclass's warn
15
+ # method for display. The uplevel: 1 option ensures that the warning
16
+ # originates from the caller's context rather than from within this method
17
+ # itself.
18
+ #
19
+ # @param msgs [ Array<String> ] the array of message strings to display as warnings
20
+ def warn(*msgs)
21
+ msgs.map! { |m| color(208) { m } }
22
+ super(*msgs, uplevel: 1)
23
+ end
24
+ end
25
+
26
+ class ContextFormatter
27
+ include FileUtils
28
+
29
+ # The format method processes code coverage results and generates a
30
+ # detailed JSON report.
31
+ #
32
+ # This method takes a SimpleCov result object and transforms its coverage
33
+ # data into a structured format that includes both line and branch coverage
34
+ # statistics for individual files, as well as overall project coverage
35
+ # metrics. It calculates various percentages and counts, then writes the
36
+ # complete coverage data to a JSON file in the coverage directory.
37
+ #
38
+ # @param result [ SimpleCov::Result ] the coverage result object containing files and statistics
39
+ #
40
+ # @return [ String ] an empty string, as the method's primary purpose is to write data to a file
41
+ def format(result)
42
+ files = result.files.map do |file|
43
+ line_coverage_statistics = extract_coverage_info(file.coverage_statistics[:line])
44
+ branch_coverage_statistics = extract_coverage_info(file.coverage_statistics[:branch])
45
+ {
46
+ filename: file.filename,
47
+ line_coverage_statistics:,
48
+ branch_coverage_statistics:,
49
+ }
50
+ end
51
+ covered_files = result.files.count { |file| file.coverage_statistics[:line].covered > 0 }
52
+ uncovered_files = result.files.count { |file| file.coverage_statistics[:line].covered == 0 }
53
+ files_count = result.files.length
54
+ files_covered_percent = files_count > 0 ? (100 * covered_files.to_f / files_count).round(2) : 0
55
+ branch_covered_percent =
56
+ result.total_branches > 0 ? (result.covered_branches.to_f / result.total_branches * 100).round(2) : 0
57
+ coverage_data = {
58
+ project_name:,
59
+ version:,
60
+ timestamp: Time.now.iso8601,
61
+ files:,
62
+ overall_coverage: {
63
+ covered_percent: result.covered_percent.round(2),
64
+ total_lines: result.total_lines,
65
+ covered_lines: result.covered_lines,
66
+ missed_lines: result.missed_lines,
67
+ branch_covered_percent:,
68
+ total_branches: result.total_branches,
69
+ covered_branches: result.covered_branches,
70
+ missed_branches: result.missed_branches,
71
+ coverage_strength: result.covered_strength.round(2),
72
+ least_covered_file: result.least_covered_file,
73
+ covered_files:,
74
+ uncovered_files:,
75
+ files_count:,
76
+ files_covered_percent:,
77
+ },
78
+ }
79
+
80
+ # Write to a dedicated coverage data file,
81
+ coverage_dir = Pathname.new('coverage')
82
+ mkdir_p coverage_dir
83
+ filename = File.expand_path(coverage_dir + 'coverage_context.json')
84
+ File.secure_write(filename, JSON.pretty_generate(coverage_data))
85
+ STDERR.puts "Wrote detailed coverage context to #{filename.to_s.inspect}."
86
+ ""
87
+ end
88
+
89
+ private
90
+
91
+ include WarnModule
92
+
93
+ # The project_name method retrieves the name of the current working
94
+ # directory.
95
+ #
96
+ # This method obtains the absolute path of the current working directory
97
+ # and extracts its basename, returning it as a string. It is typically used
98
+ # to identify the project name based on the directory structure.
99
+ #
100
+ # @return [ String ] the name of the current working directory
101
+ def project_name
102
+ Pathname.pwd.basename.to_s # I hope…
103
+ end
104
+
105
+ # The version method reads and returns the current version string from the
106
+ # VERSION file.
107
+ #
108
+ # This method attempts to read the contents of the VERSION file, removing
109
+ # any trailing whitespace. If the VERSION file does not exist, it returns
110
+ # the string 'unknown' instead.
111
+ #
112
+ # @return [ String ] the version string read from the VERSION file, or
113
+ # 'unknown' if the file is missing
114
+ def version
115
+ File.read('VERSION').chomp
116
+ rescue Errno::ENOENT => e
117
+ warn "Using version 'unknown', caught #{e.class}: #{e}"
118
+ 'unknown'
119
+ end
120
+
121
+ # The extract_coverage_info method transforms coverage statistics into a
122
+ # structured hash format.
123
+ #
124
+ # This method takes a coverage statistics object and extracts specific
125
+ # attributes into a new hash, making the data more accessible for reporting
126
+ # and analysis.
127
+ #
128
+ # @param coverage_statistics [ SimpleCov::CoverageStatistics ] the coverage
129
+ # statistics object to process
130
+ #
131
+ # @return [ Hash ] a hash containing the extracted coverage metrics with
132
+ # keys :total, :covered, :missed, :strength, and :percent
133
+ def extract_coverage_info(coverage_statistics)
134
+ %i[ total covered missed strength percent ].each_with_object({}) do |attr, hash|
135
+ hash[attr] = coverage_statistics.send(attr)
136
+ end
137
+ end
138
+ end
139
+
140
+ class << self
141
+ include Term::ANSIColor
142
+
143
+ # The start method initializes and configures SimpleCov for code coverage
144
+ # analysis.
145
+ #
146
+ # This method checks if the START_SIMPLECOV environment variable is set to
147
+ # 1 before proceeding with SimpleCov setup. If disabled, it outputs a
148
+ # message indicating that SimpleCov startup is skipped. When enabled, it
149
+ # requires the simplecov gem, configures coverage to include branch
150
+ # coverage, adds a filter based on the caller's directory, and sets up
151
+ # multiple formatters including SimpleFormatter, HTMLFormatter, and a
152
+ # custom ContextFormatter.
153
+ def start
154
+ if ENV['START_SIMPLECOV'].to_i != 1
155
+ STDERR.puts color(226) {
156
+ "Skip starting Simplecov for code coverage, "\
157
+ "enable by setting env var: START_SIMPLECOV=1"
158
+ }
159
+ return
160
+ end
161
+ require 'simplecov'
162
+ STDERR.puts color(76) { "Configuring Simplecov for code coverage." }
163
+ filter = "#{File.basename(File.dirname(caller.first))}/"
164
+ SimpleCov.start do
165
+ enable_coverage :branch
166
+ add_filter filter
167
+ formatter SimpleCov::Formatter::MultiFormatter.new([
168
+ SimpleCov::Formatter::SimpleFormatter,
169
+ SimpleCov::Formatter::HTMLFormatter,
170
+ GemHadar::SimpleCov::ContextFormatter,
171
+ ])
172
+ end
173
+ rescue LoadError => e
174
+ warn "Caught #{e.class}: #{e}"
175
+ STDERR.puts "Install with: gem install simplecov"
176
+ end
177
+
178
+ private
179
+
180
+ include WarnModule
181
+ end
182
+ end
@@ -1,6 +1,6 @@
1
1
  class GemHadar
2
2
  # GemHadar version
3
- VERSION = '1.27.0'
3
+ VERSION = '2.0.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
data/lib/gem_hadar.rb CHANGED
@@ -1525,19 +1525,6 @@ class GemHadar
1525
1525
  remotes_uris.find { |uri| uri.hostname == 'github.com' }
1526
1526
  end
1527
1527
  end
1528
-
1529
- class << self
1530
- # The start_simplecov method initializes SimpleCov and configures it to
1531
- # ignore coverage data from the directory containing the caller. This can be
1532
- # called from a test or spec helper.
1533
- def start_simplecov
1534
- defined? SimpleCov or return
1535
- filter = "#{File.basename(File.dirname(caller.first))}/"
1536
- SimpleCov.start do
1537
- add_filter filter
1538
- end
1539
- end
1540
- end
1541
1528
  end
1542
1529
 
1543
1530
  def GemHadar(&block)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem_hadar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.27.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
@@ -119,6 +119,7 @@ extra_rdoc_files:
119
119
  - lib/gem_hadar/github.rb
120
120
  - lib/gem_hadar/prompt_template.rb
121
121
  - lib/gem_hadar/setup.rb
122
+ - lib/gem_hadar/simplecov.rb
122
123
  - lib/gem_hadar/template_compiler.rb
123
124
  - lib/gem_hadar/utils.rb
124
125
  - lib/gem_hadar/version.rb
@@ -135,6 +136,7 @@ files:
135
136
  - lib/gem_hadar/github.rb
136
137
  - lib/gem_hadar/prompt_template.rb
137
138
  - lib/gem_hadar/setup.rb
139
+ - lib/gem_hadar/simplecov.rb
138
140
  - lib/gem_hadar/template_compiler.rb
139
141
  - lib/gem_hadar/utils.rb
140
142
  - lib/gem_hadar/version.rb