kettle-dev 3.0.10 → 3.0.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: 1e670b2a9da64f848886da0112d47c757607895c073ae8e0063583f9893c05a8
4
- data.tar.gz: 9c395946450a91ee862b55922a1f5bf9bce6208c700098093d7c6050c535488b
3
+ metadata.gz: 778a9528095541a29e4c6a15022c1fe312cf32ccb8f336972c046b02134bae32
4
+ data.tar.gz: bcc27b14726e3f17ad56b4e305e324c4ccb38df57df754f5f41b73e121f33a41
5
5
  SHA512:
6
- metadata.gz: a9fd3e50a9f6315eec633c43dabd4447f0d2507e6b74ad9b17b3eb03497d4194895c65aa56010098e9a229e01115b4e0d3c1b3beefbaad26c76f4a6862e883c9
7
- data.tar.gz: e493aa3febc35c6840001eca3b7f7ec127784b83c57e42feac1ab791a0aaac272e9094fb4589c18ba5e7e98cafb9d3fc256f059147c06f23f687768cb8191e52
6
+ metadata.gz: 4f4b916aeb6714071d76ab84ae57e08650e42fe0607df2e7b366855932c66019ad3f8a2ba37befa0089b9261eb38092ab3bc33cce61237b0d9880139da3399de
7
+ data.tar.gz: 238a0802ae743f219f919a9fbdd2d1500aeea06ad8a756e5e377c4bc8c275e0d80bf07911f9a78b94e0095e9809afbb8eaeb9f98d9ee2e6db72242cfc2aa5fd9
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,34 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [3.0.12] - 2026-08-25
34
+
35
+ - TAG: [v3.0.12][3.0.12t]
36
+ - COVERAGE: 91.48% -- 5754/6290 lines in 47 files
37
+ - BRANCH COVERAGE: 76.34% -- 2207/2891 branches in 47 files
38
+ - 50.74% documented
39
+
40
+ ### Changed
41
+
42
+ - Expose shared lockfile section inspection primitives for family release validation.
43
+
44
+ ### Fixed
45
+
46
+ - Skip unresolved Kettle-Jem template image URLs during pre-release validation.
47
+
48
+ ## [3.0.11] - 2026-08-24
49
+
50
+ - TAG: [v3.0.11][3.0.11t]
51
+ - COVERAGE: 91.27% -- 5699/6244 lines in 47 files
52
+ - BRANCH COVERAGE: 76.11% -- 2176/2859 branches in 47 files
53
+ - 51.11% documented
54
+
55
+ ### Fixed
56
+
57
+ - Run release changelog coverage against the registry-backed dependency graph instead of inheriting local templating paths.
58
+
59
+ - Reset dynamic Bundler parent markers before switching a child process to another Gemfile, so release changelog coverage runs the target project specs.
60
+
33
61
  ## [3.0.10] - 2026-08-23
34
62
 
35
63
  - TAG: [v3.0.10][3.0.10t]
@@ -3529,7 +3557,11 @@ Please file a bug if you notice a violation of semantic versioning.
3529
3557
  - Selecting will run the selected workflow via `act`
3530
3558
  - This may move to its own gem in the future.
3531
3559
 
3532
- [Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.10...HEAD
3560
+ [Unreleased]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.12...HEAD
3561
+ [3.0.12]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.11...v3.0.12
3562
+ [3.0.12t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.0.12
3563
+ [3.0.11]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.10...v3.0.11
3564
+ [3.0.11t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.0.11
3533
3565
  [3.0.10]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.9...v3.0.10
3534
3566
  [3.0.10t]: https://github.com/kettle-dev/kettle-dev/releases/tag/v3.0.10
3535
3567
  [3.0.9]: https://github.com/kettle-dev/kettle-dev/compare/v3.0.8...v3.0.9
data/README.md CHANGED
@@ -635,10 +635,12 @@ versions that are newer than the latest released version.
635
635
  - Checks:
636
636
  - 1) Validate GitHub Actions workflow action refs with `kettle-gha-sha-pins --check`; if pins are stale, it prints an outdated-actions summary, exits non-zero, and recommends `kettle-gha-sha-pins --write --upgrade patch`.
637
637
  - 2) Normalize Markdown image URLs.
638
- - 3) Validate that all image URLs referenced by Markdown files resolve (HTTP HEAD).
638
+ - 3) Validate Markdown references and local heading targets.
639
+ - 4) Validate that all image URLs referenced by Markdown files resolve (HTTP HEAD).
639
640
  - Image URL skips:
640
641
  - Star-history image API URLs are skipped by default because they are volatile.
641
- - Add project-specific shell-style URL patterns in `.kettle-family.yml` or a config path pointed to by `KETTLE_FAMILY_CONFIG`:
642
+ - Unresolved Kettle-Jem template tokens are skipped because they are not URLs until templating completes.
643
+ - Add project-specific shell-style URL patterns in `.kettle-family.yml` or a config path pointed to by `KETTLE_FAMILY_CONFIG`. `kettle-family` passes this path through when it orchestrates a member release, but `kettle-dev` owns the matching and validation:
642
644
  ```yaml
643
645
  pre_release:
644
646
  image_url_skip_patterns:
@@ -1012,7 +1014,7 @@ Thanks for RTFM. ☺️
1012
1014
  [📌gitmoji]: https://gitmoji.dev
1013
1015
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
1014
1016
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
1015
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-6.240-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1017
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-6.290-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1016
1018
  [🔐security]: https://github.com/kettle-dev/kettle-dev/blob/main/SECURITY.md
1017
1019
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
1018
1020
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -12,6 +12,14 @@ module Kettle
12
12
  BUNDLER_VERSION
13
13
  ].freeze
14
14
 
15
+ # Bundler uses these markers to restore the environment of the parent
16
+ # bundle. They are not inert when a child explicitly selects another
17
+ # Gemfile: Bundler can use BUNDLER_ORIG_BUNDLE_GEMFILE to reselect the
18
+ # parent bundle. Clear the dynamic keys along with RESET_ENV_KEYS.
19
+ RESET_ENV_PREFIXES = %w[
20
+ BUNDLER_ORIG_
21
+ ].freeze
22
+
15
23
  INERT_ENV_KEYS = %w[
16
24
  BUNDLE_DEBUG
17
25
  BUNDLE_QUIET
@@ -22,16 +30,18 @@ module Kettle
22
30
  BUNDLER_DEBUG
23
31
  ].freeze
24
32
 
25
- INERT_ENV_PREFIXES = %w[
26
- BUNDLER_ORIG_
27
- ].freeze
28
-
29
33
  module_function
30
34
 
31
35
  def unbundled_env
32
- RESET_ENV_KEYS.each_with_object({}) do |key, env|
36
+ env = RESET_ENV_KEYS.each_with_object({}) do |key, result|
37
+ result[key] = nil
38
+ end
39
+ ENV.each_key do |key|
40
+ next unless RESET_ENV_PREFIXES.any? { |prefix| key.start_with?(prefix) }
41
+
33
42
  env[key] = nil
34
43
  end
44
+ env
35
45
  end
36
46
 
37
47
  def warn_unexpected_env!(stream: $stderr)
@@ -45,6 +55,7 @@ module Kettle
45
55
  )
46
56
  end
47
57
 
58
+ # rubocop:disable ThreadSafety/ClassInstanceVariable -- warning state is intentionally shared by module functions.
48
59
  def reset_warning_cache!
49
60
  @warned_unexpected_env_keys = {}
50
61
  end
@@ -56,7 +67,7 @@ module Kettle
56
67
  def expected_env_key?(key)
57
68
  RESET_ENV_KEYS.include?(key) ||
58
69
  INERT_ENV_KEYS.include?(key) ||
59
- INERT_ENV_PREFIXES.any? { |prefix| key.start_with?(prefix) }
70
+ RESET_ENV_PREFIXES.any? { |prefix| key.start_with?(prefix) }
60
71
  end
61
72
 
62
73
  def warned_unexpected_env?(keys)
@@ -67,6 +78,7 @@ module Kettle
67
78
  @warned_unexpected_env_keys[signature] = true
68
79
  false
69
80
  end
81
+ # rubocop:enable ThreadSafety/ClassInstanceVariable
70
82
  end
71
83
  end
72
84
  end
@@ -28,6 +28,84 @@ module Kettle
28
28
  RUBYOPT
29
29
  ]).freeze
30
30
 
31
+ class << self
32
+ def local_path_remote_lines_from_source(lockfile_source)
33
+ in_path = false
34
+ lockfile_source.each_line.with_index(1).filter_map do |line, index|
35
+ stripped = line.strip
36
+ if stripped.match?(/\A[A-Z][A-Z ]*\z/)
37
+ in_path = stripped == "PATH"
38
+ next
39
+ end
40
+ next unless in_path
41
+ next unless stripped.start_with?("remote:")
42
+ next if stripped == "remote: ."
43
+ next unless stripped.start_with?("remote: /", "remote: ./", "remote: ../")
44
+
45
+ index
46
+ end
47
+ end
48
+
49
+ def checksum_entries_from_source(lockfile_source)
50
+ in_checksums = false
51
+ entries = {}
52
+ lockfile_source.each_line do |line|
53
+ stripped = line.chomp
54
+ if stripped == "CHECKSUMS"
55
+ in_checksums = true
56
+ next
57
+ end
58
+ next unless in_checksums
59
+ break if !stripped.empty? && stripped == stripped.upcase && !stripped.start_with?(" ")
60
+ next unless stripped.start_with?(" ")
61
+
62
+ parsed = parse_lockfile_spec_line(stripped)
63
+ entries[[parsed.fetch(:name), parsed.fetch(:version)]] = parsed.fetch(:suffix) if parsed
64
+ end
65
+ in_checksums ? entries : nil
66
+ end
67
+
68
+ def gem_specs_from_source(lockfile_source)
69
+ in_gem = false
70
+ in_specs = false
71
+ specs = []
72
+ lockfile_source.each_line do |line|
73
+ stripped = line.chomp
74
+ if stripped == "GEM"
75
+ in_gem = true
76
+ in_specs = false
77
+ next
78
+ end
79
+ next unless in_gem
80
+ break if !stripped.empty? && stripped == stripped.upcase && !stripped.start_with?(" ")
81
+
82
+ if stripped == " specs:"
83
+ in_specs = true
84
+ next
85
+ end
86
+ next unless in_specs
87
+ next unless line.start_with?(" ") && !line.start_with?(" ")
88
+
89
+ parsed = parse_lockfile_spec_line(stripped)
90
+ specs << [parsed.fetch(:name), parsed.fetch(:version)] if parsed
91
+ end
92
+ specs.uniq
93
+ end
94
+
95
+ private
96
+
97
+ def parse_lockfile_spec_line(line)
98
+ stripped = line.to_s.strip
99
+ return nil if stripped.empty? || !stripped.include?(" (")
100
+
101
+ name, remainder = stripped.split(" (", 2)
102
+ version, suffix = remainder.to_s.split(")", 2)
103
+ return nil if name.to_s.empty? || version.to_s.empty?
104
+
105
+ {name: name, version: version, suffix: suffix.to_s.strip}
106
+ end
107
+ end
108
+
31
109
  def initialize(root:, command_runner:)
32
110
  @root = root
33
111
  @command_runner = command_runner
@@ -248,20 +326,7 @@ module Kettle
248
326
  end
249
327
 
250
328
  def local_path_remote_lines(path)
251
- in_path = false
252
- File.readlines(path).filter_map.with_index(1) do |line, index|
253
- stripped = line.strip
254
- if stripped.match?(/\A[A-Z][A-Z ]*\z/)
255
- in_path = stripped == "PATH"
256
- next
257
- end
258
- next unless in_path
259
- next unless stripped.start_with?("remote:")
260
- next if stripped == "remote: ."
261
- next unless stripped.start_with?("remote: /", "remote: ./", "remote: ../")
262
-
263
- index
264
- end
329
+ self.class.local_path_remote_lines_from_source(File.read(path))
265
330
  end
266
331
 
267
332
  def empty_registry_checksums(path)
@@ -511,6 +511,9 @@ module Kettle
511
511
  end
512
512
 
513
513
  def configured_image_url_skip_patterns
514
+ # Keep generic release safety in kettle-dev. Family-specific patterns
515
+ # are optional policy loaded from the family config when present, so a
516
+ # standalone kettle-release remains complete without kettle-family.
514
517
  DEFAULT_IMAGE_URL_SKIP_PATTERNS + family_configured_image_url_skip_patterns
515
518
  end
516
519
 
@@ -539,6 +542,10 @@ module Kettle
539
542
  end
540
543
 
541
544
  def image_url_skipped?(url)
545
+ # Unresolved Kettle-Jem tokens are valid in template source files and
546
+ # are not real URLs until templating. This rule must live here because
547
+ # direct kettle-dev releases do not run through kettle-family.
548
+ return true if url.to_s.include?("{KJ|")
542
549
  return true if github_actions_badge_for_local_workflow?(url)
543
550
 
544
551
  @image_url_skip_patterns.any? do |pattern|
@@ -902,7 +902,10 @@ module Kettle
902
902
  escaped_gemfile = Shellwords.escape(gemfile)
903
903
  command = +"env -u BUNDLE_GEMFILE -u BUNDLE_LOCKFILE"
904
904
  if (local_root = release_changelog_local_root)
905
- command << " KETTLE_DEV_DEV=false KETTLE_CHANGELOG_DEV_ROOT=#{Shellwords.escape(local_root)}"
905
+ # Changelog coverage runs before the release lockfile reset. Keep it
906
+ # on the registry-backed release graph instead of reintroducing local
907
+ # sibling paths through the inherited templating switch.
908
+ command << " KETTLE_DEV_DEV=false K_JEM_TEMPLATING=false KETTLE_CHANGELOG_DEV_ROOT=#{Shellwords.escape(local_root)}"
906
909
  end
907
910
  command << " BUNDLE_GEMFILE=#{escaped_gemfile} bundle exec kettle-changelog"
908
911
  command
@@ -5,7 +5,7 @@ module Kettle
5
5
  # Version namespace for this gem.
6
6
  module Version
7
7
  # Current gem version.
8
- VERSION = "3.0.10"
8
+ VERSION = "3.0.12"
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
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: 3.0.10
4
+ version: 3.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -400,10 +400,10 @@ licenses:
400
400
  - AGPL-3.0-only
401
401
  metadata:
402
402
  homepage_uri: https://kettle-dev.galtzo.com
403
- source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v3.0.10
404
- changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v3.0.10/CHANGELOG.md
403
+ source_code_uri: https://github.com/kettle-dev/kettle-dev/tree/v3.0.12
404
+ changelog_uri: https://github.com/kettle-dev/kettle-dev/blob/v3.0.12/CHANGELOG.md
405
405
  bug_tracker_uri: https://github.com/kettle-dev/kettle-dev/issues
406
- documentation_uri: https://www.rubydoc.info/gems/kettle-dev/3.0.10
406
+ documentation_uri: https://www.rubydoc.info/gems/kettle-dev/3.0.12
407
407
  funding_uri: https://github.com/sponsors/pboling
408
408
  wiki_uri: https://github.com/kettle-dev/kettle-dev/wiki
409
409
  news_uri: https://www.railsbling.com/tags/kettle-dev
metadata.gz.sig CHANGED
Binary file