kettle-dev 2.2.11 → 2.2.12

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: adb949cc424b8cfc26b1a1d98557f027761ce0cf0335b27d11be8b2acc7492fb
4
- data.tar.gz: e0b0f29328cb38c439d60997ef4d2162231c01b3dc086d5444d5e64124324e41
3
+ metadata.gz: 3f039cd2a52c5584b02f93a75f08e79227bbbc5e37f748a1d4a6623996fda1a8
4
+ data.tar.gz: 2ebc57a458091e9f531daafa63d431a1ac9f64f39d8fafb7e03fb802ac511e42
5
5
  SHA512:
6
- metadata.gz: a300fc001ade1936c203f7be54b55da94706f3f70e536eaf24abeae941f1b9522d7a39d72bea83df2c918a6444a783c69c8c640d0c8ee69a3878e9b7b6496c9c
7
- data.tar.gz: ea78dd32142a448c490631571ba4f42bdfa1171d62aa0d7fd414a3e38beae3785c3986b5ed1b6a4cd405f72250a7e8fcab89786e793cc1441e6f37c5c0856ca3
6
+ metadata.gz: dfc81acc32288dff4f6be9d4f84e31779017132a5eecd94f7881d3702ee0da968cb7687eb0ed6cdff31eceb321d30b29891bc2a43341aad6a877ddb93f9fe31f
7
+ data.tar.gz: 59440aa4a9abcbd46b861cb9e403e72d2cddd7dc1d4570423c99f5d82951571033fd22efe0f4b7ad774f3366a920345abb65f949656fba2b92b823a25aadacc2
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,24 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [2.2.12] - 2026-06-18
34
+
35
+ - TAG: [v2.2.12][2.2.12t]
36
+ - COVERAGE: 92.52% -- 3947/4266 lines in 28 files
37
+ - BRANCH COVERAGE: 74.11% -- 1569/2117 branches in 28 files
38
+ - 63.76% documented
39
+
40
+ ### Added
41
+
42
+ - Added `--version VERSION` support to `kettle-changelog` and `kettle-release`
43
+ for shim gems whose release version is intentionally sourced outside the local
44
+ `lib/**/version.rb` file.
45
+
46
+ ### Fixed
47
+
48
+ - Updated `kettle-changelog` and `kettle-pre-release` help text to match current
49
+ coverage generation, documentation stats, and image URL cache behavior.
50
+
33
51
  ## [2.2.11] - 2026-06-17
34
52
 
35
53
  - TAG: [v2.2.11][2.2.11t]
@@ -2152,7 +2170,9 @@ Please file a bug if you notice a violation of semantic versioning.
2152
2170
  - Selecting will run the selected workflow via `act`
2153
2171
  - This may move to its own gem in the future.
2154
2172
 
2155
- [Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v2.2.11...HEAD
2173
+ [Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v2.2.12...HEAD
2174
+ [2.2.12]: https://github.com/kettle-dev/kettle-dev/compare/v2.2.11...v2.2.12
2175
+ [2.2.12t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v2.2.12
2156
2176
  [2.2.11]: https://github.com/kettle-dev/kettle-dev/compare/v2.2.10...v2.2.11
2157
2177
  [2.2.11t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v2.2.11
2158
2178
  [2.2.10]: https://github.com/kettle-dev/kettle-dev/compare/v2.2.9...v2.2.10
data/README.md CHANGED
@@ -854,7 +854,7 @@ Thanks for RTFM. ☺️
854
854
  [📌gitmoji]: https://gitmoji.dev
855
855
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
856
856
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
857
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-4.252-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
857
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-4.266-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
858
858
  [🔐security]: https://github.com/kettle-dev/kettle-dev/blob/main/SECURITY.md
859
859
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
860
860
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
data/exe/kettle-changelog CHANGED
@@ -16,9 +16,13 @@
16
16
  # GitLab links to GitHub links, and appends the new [X.Y.Z] and [X.Y.Zt] links.
17
17
  #
18
18
  # Notes:
19
- # - Expects a JSON coverage report at coverage/coverage.json. In strict mode,
20
- # it will generate one with bundle exec kettle-test.
21
- # - Expects `bin/rake yard` to be available.
19
+ # - Strict mode (default) removes stale coverage output, runs `bundle exec
20
+ # kettle-test` with JSON coverage enabled, and reads the freshly generated
21
+ # coverage/coverage.json.
22
+ # - Non-strict mode reads existing coverage JSON when present and leaves
23
+ # unavailable coverage or documentation stats blank with a warning.
24
+ # - Expects `bin/rake yard` or `bin/yard` to be available for documentation stats
25
+ # when strict mode is enabled.
22
26
 
23
27
  $stdout.sync = true
24
28
 
@@ -51,7 +55,7 @@ end
51
55
  begin
52
56
  if ARGV.include?("-h") || ARGV.include?("--help")
53
57
  puts <<~USAGE
54
- Usage: kettle-changelog [--update-prep] [--pending-release] [--release-state] [--json] [--no-strict] [--no-coverage-threshold]
58
+ Usage: kettle-changelog [--version VERSION] [--update-prep] [--pending-release] [--release-state] [--json] [--no-strict] [--no-coverage-threshold]
55
59
 
56
60
  Detects the current version from lib/**/version.rb, the latest live release, and
57
61
  the most recent CHANGELOG.md release section, then prompts to confirm the selected plan:
@@ -61,6 +65,7 @@ begin
61
65
  and update bottom link references to GitHub style.
62
66
 
63
67
  Options:
68
+ --version VERSION Use this version instead of detecting VERSION from lib/**/version.rb
64
69
  --update-prep Force updating the most recent prepared release section in place
65
70
  --pending-release Query whether the changelog has release work pending; exits 0 for yes, 1 for no
66
71
  --release-state,
@@ -74,23 +79,50 @@ begin
74
79
  K_CHANGELOG_COVERAGE_HARD=false Disable coverage threshold hard-failure
75
80
  K_CHANGELOG_VERSION_FILE=path Read VERSION from this file instead of lib/**/version.rb
76
81
 
77
- Prerequisites:
78
- - coverage/coverage.json present (run: bundle exec kettle-test with K_SOUP_COV_FORMATTERS=json to generate)
79
- - yard task available via bin/rake yard
82
+ Data generation:
83
+ Strict mode is the default. Release plans remove stale coverage output,
84
+ run bundle exec kettle-test with JSON coverage enabled, read the resulting
85
+ coverage/coverage.json, and collect documentation stats from bin/rake yard
86
+ or bin/yard.
80
87
 
81
- By default (strict mode), if coverage.json or yard stats are missing, the script will:
82
- 1. Attempt to generate them by running bundle exec kettle-test and bin/rake yard
83
- 2. Fail with an error if generation fails or data is still unavailable
84
- 3. Fail if coverage is below the configured project thresholds
88
+ Strict mode fails if specs fail, coverage JSON is not produced, coverage
89
+ is below the configured project thresholds, or documentation stats cannot
90
+ be collected.
85
91
 
86
- Use --no-strict or K_CHANGELOG_STRICT=false to allow missing data (backward compatible behavior).
87
- Use --no-coverage-threshold or K_CHANGELOG_COVERAGE_HARD=false to bypass coverage threshold failures.
92
+ Non-strict mode does not generate missing coverage or documentation data;
93
+ it warns and leaves unavailable stats blank.
94
+
95
+ Runtime requirements:
96
+ - bundle exec kettle-test available for strict coverage generation
97
+ - bin/rake yard or bin/yard available for strict documentation stats
98
+
99
+ Use --no-strict or K_CHANGELOG_STRICT=false to allow missing data.
100
+ Use --no-coverage-threshold or K_CHANGELOG_COVERAGE_HARD=false to run fresh
101
+ coverage without hard-failing below configured thresholds.
88
102
  USAGE
89
103
  exit(0)
90
104
  end
91
105
  end
92
106
 
93
107
  begin
108
+ def extract_version_arg!(argv)
109
+ version = nil
110
+ if (idx = argv.index("--version"))
111
+ version = argv[idx + 1]
112
+ Kettle::Dev::ExitAdapter.abort("--version requires a VERSION") if version.to_s.empty?
113
+ argv.slice!(idx, 2)
114
+ end
115
+ argv.delete_if do |arg|
116
+ if arg.start_with?("--version=", "version=")
117
+ version = arg.split("=", 2)[1]
118
+ true
119
+ else
120
+ false
121
+ end
122
+ end
123
+ Kettle::Dev::Versioning.normalize_explicit_version(version)
124
+ end
125
+
94
126
  # Determine if strict mode is enabled (default: true)
95
127
  strict_mode = !ARGV.include?("--no-strict") && ENV.fetch("K_CHANGELOG_STRICT", "true").downcase != "false"
96
128
  update_prep = ARGV.delete("--update-prep")
@@ -99,8 +131,9 @@ begin
99
131
  json_output = ARGV.delete("--json")
100
132
  coverage_threshold_disabled = ARGV.include?("--no-coverage-threshold") || ARGV.include?("--no-coverage-thresholds")
101
133
  coverage_hard = !coverage_threshold_disabled && ENV.fetch("K_CHANGELOG_COVERAGE_HARD", "true").downcase != "false"
134
+ version_override = extract_version_arg!(ARGV)
102
135
 
103
- cli = Kettle::Dev::ChangelogCLI.new(strict: strict_mode, enforce_coverage_thresholds: coverage_hard, update_prep: update_prep)
136
+ cli = Kettle::Dev::ChangelogCLI.new(strict: strict_mode, enforce_coverage_thresholds: coverage_hard, update_prep: update_prep, version: version_override)
104
137
  if release_state_query
105
138
  state = cli.release_state
106
139
  puts(json_output ? JSON.pretty_generate(state) : cli.release_state_table(state))
@@ -5,7 +5,8 @@
5
5
 
6
6
  # kettle-pre-release: Run pre-release checks to catch avoidable mistakes.
7
7
  # - Structured as a sequence of checks that can be resumed via check_num
8
- # - Checks GitHub Actions SHA pins and validates Markdown image links.
8
+ # - Checks GitHub Actions SHA pins, normalizes Markdown image URLs, and
9
+ # validates Markdown image links with a global seven-day success cache.
9
10
 
10
11
  require "optparse"
11
12
 
@@ -47,7 +48,13 @@ parser = OptionParser.new do |opts|
47
48
  puts "Checks:"
48
49
  puts " 1) Validate GitHub Actions SHA pins"
49
50
  puts " 2) Normalize Markdown image URLs"
50
- puts " 3) Validate Markdown image links (HTTP HEAD)"
51
+ puts " 3) Validate Markdown image links (cached HTTP HEAD, with GET fallback)"
52
+ puts
53
+ puts "Image URL cache:"
54
+ puts " Successful image URL validations are cached globally for seven days."
55
+ puts " KETTLE_IMAGE_URL_CACHE=/path/to/cache.json Use a custom cache path"
56
+ puts " KETTLE_IMAGE_URL_CACHE=false Disable the image URL cache"
57
+ puts " KETTLE_IMAGE_URL_CACHE_REFRESH=true Ignore cached successes and refresh"
51
58
  exit(0)
52
59
  end
53
60
  end
data/exe/kettle-release CHANGED
@@ -43,7 +43,7 @@ end
43
43
  # Do not guard with __FILE__ == $PROGRAM_NAME because binstubs use Kernel.load.
44
44
  if ARGV.include?("-h") || ARGV.include?("--help")
45
45
  puts <<~USAGE
46
- Usage: kettle-release [--local-ci] [start_step=<1-19>]
46
+ Usage: kettle-release [--version VERSION] [--local-ci] [start_step=<1-19>]
47
47
 
48
48
  Automates the release flow for a Ruby gem in the host project.
49
49
 
@@ -74,6 +74,7 @@ if ARGV.include?("-h") || ARGV.include?("--help")
74
74
 
75
75
  Options:
76
76
  start_step=<number> # Begin at the numbered step above (e.g., 10 to resume at CI monitoring)
77
+ --version VERSION # Use this version instead of detecting VERSION from lib/**/version.rb
77
78
  --local-ci # Sensitive release mode: run act locally, publish before any git push,
78
79
  # create the git tag locally, then push commits and tags after publish
79
80
 
@@ -96,12 +97,31 @@ if ARGV.include?("-h") || ARGV.include?("--help")
96
97
  end
97
98
 
98
99
  # Parse start_step=<n> from ARGV
100
+ def extract_version_arg!(argv)
101
+ version = nil
102
+ if (idx = argv.index("--version"))
103
+ version = argv[idx + 1]
104
+ Kettle::Dev::ExitAdapter.abort("--version requires a VERSION") if version.to_s.empty?
105
+ argv.slice!(idx, 2)
106
+ end
107
+ argv.delete_if do |arg|
108
+ if arg.start_with?("--version=", "version=")
109
+ version = arg.split("=", 2)[1]
110
+ true
111
+ else
112
+ false
113
+ end
114
+ end
115
+ Kettle::Dev::Versioning.normalize_explicit_version(version)
116
+ end
117
+
99
118
  local_ci = ARGV.include?("--local-ci")
100
119
  start_step_arg = ARGV.find { |a| a.start_with?("start_step=") }
101
120
  start_step = start_step_arg ? start_step_arg.split("=", 2)[1].to_i : 1
121
+ version_override = extract_version_arg!(ARGV)
102
122
 
103
123
  begin
104
- Kettle::Dev::ReleaseCLI.new(start_step: start_step, local_ci: local_ci).run
124
+ Kettle::Dev::ReleaseCLI.new(start_step: start_step, local_ci: local_ci, version: version_override).run
105
125
  rescue LoadError => e
106
126
  warn("#{script_basename}: could not load dependency: #{e.class}: #{e.message}")
107
127
  warn(Array(e.backtrace).join("\n")) if ENV["DEBUG"]
@@ -24,13 +24,15 @@ module Kettle
24
24
  # @param strict [Boolean] when true (default), require coverage and yard data; raise errors if unavailable
25
25
  # @param enforce_coverage_thresholds [Boolean] when true, fail strict coverage generation below project thresholds
26
26
  # @param update_prep [Boolean] when true, update the most recent prepared release section in place
27
- def initialize(strict: true, enforce_coverage_thresholds: true, update_prep: false, root: Kettle::Dev::CIHelpers.project_root)
27
+ # @param version [String, nil] explicit version override for gems without a literal VERSION constant
28
+ def initialize(strict: true, enforce_coverage_thresholds: true, update_prep: false, version: nil, root: Kettle::Dev::CIHelpers.project_root)
28
29
  @root = root
29
30
  @changelog_path = File.join(@root, "CHANGELOG.md")
30
31
  @coverage_path = File.join(@root, "coverage", "coverage.json")
31
32
  @strict = strict
32
33
  @enforce_coverage_thresholds = enforce_coverage_thresholds
33
34
  @update_prep = update_prep
35
+ @version_override = Kettle::Dev::Versioning.normalize_explicit_version(version)
34
36
  end
35
37
 
36
38
  # Main entry point to update CHANGELOG.md
@@ -40,7 +42,7 @@ module Kettle
40
42
  #
41
43
  # @return [void]
42
44
  def run
43
- version = Kettle::Dev::Versioning.detect_version(@root)
45
+ version = detect_version
44
46
  today = Time.now.strftime("%Y-%m-%d")
45
47
  owner, repo = Kettle::Dev::CIHelpers.repo_info
46
48
  unless owner && repo
@@ -299,7 +301,7 @@ module Kettle
299
301
 
300
302
  def confirm_plan!(plan)
301
303
  puts "kettle-changelog selected plan: #{plan_label(plan.fetch(:action))}"
302
- puts " version.rb: #{plan.fetch(:version)}"
304
+ puts " #{version_source_label(plan)}: #{plan.fetch(:version)}"
303
305
  puts " latest released: #{plan.fetch(:latest_overall) || "unknown"}"
304
306
  puts " latest released for current series: #{plan.fetch(:latest_for_series) || "unknown"}"
305
307
  puts " latest CHANGELOG.md release: #{plan.fetch(:latest_changelog_version) || "none"}"
@@ -311,6 +313,13 @@ module Kettle
311
313
  abort("Aborting: changelog plan was not confirmed.")
312
314
  end
313
315
 
316
+ def version_source_label(plan)
317
+ return "prepared release" if plan.fetch(:explicit, false)
318
+ return "version override" if @version_override
319
+
320
+ "version.rb"
321
+ end
322
+
314
323
  def plan_label(action)
315
324
  case action
316
325
  when :new_release
@@ -389,7 +398,7 @@ module Kettle
389
398
  end
390
399
 
391
400
  def detect_version
392
- Kettle::Dev::Versioning.detect_version(@root)
401
+ Kettle::Dev::Versioning.detect_version(@root, override: @version_override)
393
402
  end
394
403
 
395
404
  def extract_unreleased(content)
@@ -20,7 +20,7 @@ module Kettle
20
20
  # Checks:
21
21
  # 1) Ensure GitHub Actions workflow actions are pinned to current SHAs.
22
22
  # 2) Normalize Markdown image URLs using Addressable normalization.
23
- # 3) Validate Markdown image links resolve via HTTP(S) HEAD.
23
+ # 3) Validate Markdown image links resolve via cached HTTP(S) HEAD/GET.
24
24
  #
25
25
  # Usage: Kettle::Dev::PreReleaseCLI.new(check_num: 1).run
26
26
  class PreReleaseCLI
@@ -352,10 +352,10 @@ module Kettle
352
352
  nil
353
353
  end
354
354
 
355
- # Check 3: Validate Markdown image links by HTTP HEAD (no rescue for parse failures)
355
+ # Check 3: Validate Markdown image links by cached HTTP HEAD/GET.
356
356
  # @return [void]
357
357
  def check_markdown_images_http!
358
- puts "[kettle-pre-release] Check 3: Validate Markdown image links (HTTP HEAD)"
358
+ puts "[kettle-pre-release] Check 3: Validate Markdown image links (cached HTTP HEAD, with GET fallback)"
359
359
  urls = Markdown.extract_image_urls_from_files
360
360
  puts "[kettle-pre-release] Found #{urls.size} unique image URL(s)."
361
361
  cache = image_url_cache
@@ -70,12 +70,13 @@ module Kettle
70
70
 
71
71
  public
72
72
 
73
- def initialize(start_step: 1, local_ci: false)
73
+ def initialize(start_step: 1, local_ci: false, version: nil)
74
74
  @root = Kettle::Dev::CIHelpers.project_root
75
75
  @git = Kettle::Dev::GitAdapter.new
76
76
  @start_step = (start_step || 1).to_i
77
77
  @start_step = 1 if @start_step < 1
78
78
  @local_ci = !!local_ci
79
+ @version_override = Kettle::Dev::Versioning.normalize_explicit_version(version)
79
80
  end
80
81
 
81
82
  def run
@@ -671,7 +672,7 @@ module Kettle
671
672
  end
672
673
 
673
674
  def detect_version
674
- Kettle::Dev::Versioning.detect_version(@root)
675
+ Kettle::Dev::Versioning.detect_version(@root, override: @version_override)
675
676
  end
676
677
 
677
678
  def detect_gem_name
@@ -3,7 +3,7 @@
3
3
  module Kettle
4
4
  module Dev
5
5
  module Version
6
- VERSION = "2.2.11"
6
+ VERSION = "2.2.12"
7
7
  end
8
8
  VERSION = Version::VERSION # Traditional Constant Location
9
9
  end
@@ -10,8 +10,12 @@ module Kettle
10
10
  # or in K_CHANGELOG_VERSION_FILE when a monorepo/root changelog needs
11
11
  # to point at a representative package version file.
12
12
  # @param root [String] project root
13
+ # @param override [String, nil] explicit version supplied by caller
13
14
  # @return [String] version string
14
- def detect_version(root)
15
+ def detect_version(root, override: nil)
16
+ explicit = normalize_explicit_version(override)
17
+ return explicit if explicit
18
+
15
19
  candidates = version_file_candidates(root)
16
20
  versions = candidates.map do |path|
17
21
  content = File.read(path)
@@ -25,6 +29,16 @@ module Kettle
25
29
  versions.first
26
30
  end
27
31
 
32
+ def normalize_explicit_version(value)
33
+ version = value.to_s.strip
34
+ return nil if version.empty?
35
+
36
+ Gem::Version.new(version)
37
+ version
38
+ rescue ArgumentError
39
+ abort!("Invalid version override: #{version.inspect}")
40
+ end
41
+
28
42
  def version_file_candidates(root)
29
43
  override = ENV.fetch("K_CHANGELOG_VERSION_FILE", "").to_s.strip
30
44
  unless override.empty?
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kettle-dev
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.11
4
+ version: 2.2.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -338,10 +338,10 @@ licenses:
338
338
  - AGPL-3.0-only
339
339
  metadata:
340
340
  homepage_uri: https://kettle-dev.galtzo.com
341
- source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v2.2.11
342
- changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v2.2.11/CHANGELOG.md
341
+ source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v2.2.12
342
+ changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v2.2.12/CHANGELOG.md
343
343
  bug_tracker_uri: https://github.com/kettle-dev/kettle-dev/issues
344
- documentation_uri: https://www.rubydoc.info/gems/kettle-dev/2.2.11
344
+ documentation_uri: https://www.rubydoc.info/gems/kettle-dev/2.2.12
345
345
  funding_uri: https://github.com/sponsors/pboling
346
346
  wiki_uri: https://github.com/kettle-dev/kettle-dev/wiki
347
347
  news_uri: https://www.railsbling.com/tags/kettle-dev
metadata.gz.sig CHANGED
Binary file