kettle-jem 7.1.3 → 7.1.5

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: 3fb60c644be8bcdb4360d8a26fd07474cd3a0b395b219e4e28acabee18e91df0
4
- data.tar.gz: 946fb2cb8276f4f617be75f6abf674579a850632b85ab78044540b045c6f0c5b
3
+ metadata.gz: 0f18b366b9ef0f969ab98c5990293f6596943008b812a420ac196d55d6513199
4
+ data.tar.gz: a81bf6fa14c21c3f7c17f696d2255f15e2f58c707b257eec15d53a2e70438221
5
5
  SHA512:
6
- metadata.gz: 4d4a66d55400ac8324176d418be9c64f3f09367eed95081dedf95b81c4fc85a112cfe1939743310d82ca68b1b1b01980387667c86ed851854d2d1993f65d9df9
7
- data.tar.gz: 3d233a58e400bf078ad4505423bf0bb8aed22bd50a774288419fa7eaf9761ddc85f47ca69b9dae8e57aa791645b8c1a9a3b43967dffb3622cbfe12f094bf1020
6
+ metadata.gz: 88e5217d202612e369beca997b822afa503b2e0abec7e89dd31b37441a5369894d4885b5ed5f89f202e71bc3b163a25b5a4f8859304826e6e0c3425f92cbb9b0
7
+ data.tar.gz: 56feac9cce546576e41e83a0313cd916f8eb5942ac6307b5f49ac9575461a6a5c99f5b0ab13578463e76f5a2bd70e05649ba01da97f84e0e46b5da3466abbd9e
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,79 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [7.1.5] - 2026-08-24
34
+
35
+ - TAG: [v7.1.5][7.1.5t]
36
+ - COVERAGE: 93.60% -- 10814/11554 lines in 16 files
37
+ - BRANCH COVERAGE: 77.21% -- 4627/5993 branches in 16 files
38
+ - 17.97% documented
39
+
40
+ ### Changed
41
+
42
+ - Template maintenance summaries now use keyed, cumulative [kc] entries with nested file-type counts, so repeated template runs update one changelog entry.
43
+
44
+ - [kc] kettle-jem/funding-platforms: Configure GitHub funding platforms independently, remove disabled destination-only FUNDING.yml entries, and keep README/FUNDING.md badges aligned with the configured policy.
45
+
46
+ - [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
47
+ - kettle-dev (>= 3.0.8 -> >= 3.0.10)
48
+
49
+ - [kc] kettle-jem-workflow-pins: Update pinned GitHub Actions in kettle-jem templates:
50
+ - github/codeql-action/analyze v4.37.6 (5595ccaf912efad79be6eef63a5619ff05969be3) -> v4.37.8 (db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28)
51
+ - github/codeql-action/autobuild v4.37.6 (5595ccaf912efad79be6eef63a5619ff05969be3) -> v4.37.8 (db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28)
52
+ - github/codeql-action/init v4.37.6 (5595ccaf912efad79be6eef63a5619ff05969be3) -> v4.37.8 (db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28)
53
+
54
+ - [kc] kettle-jem/prepare: updated 9 project files:
55
+ - code and tests (1)
56
+ - dependencies (8)
57
+
58
+ - [kc] kettle-jem/template: updated 4 project files:
59
+ - code and tests (1)
60
+ - dependencies (1)
61
+ - documentation (1)
62
+ - other (1)
63
+
64
+ - Document the disposable BUNDLE_LOCKFILE workaround in generated CONTRIBUTING.md release guidance.
65
+
66
+ - Make the repository-local kettle-jem-deps-floor executable bootstrap the consistent StructuredMerge development bundle before loading parser dependencies.
67
+
68
+ ### Fixed
69
+
70
+ - Use Markdown-safe compound keys for automated kettle-jem template changelog entries so release reference validation does not treat their labels as undefined links.
71
+
72
+ - Use a dependency-specific switch when omitting kettle-changelog from release Bundler resolution.
73
+
74
+ - Avoid duplicate tree_sitter_language_pack declarations when templating with a local TSLP override.
75
+
76
+ ## [7.1.4] - 2026-08-12
77
+
78
+ - TAG: [v7.1.4][7.1.4t]
79
+ - COVERAGE: 93.57% -- 10753/11492 lines in 16 files
80
+ - BRANCH COVERAGE: 77.10% -- 4599/5965 branches in 16 files
81
+ - 18.00% documented
82
+
83
+ ### Changed
84
+
85
+ - Write-mode dependency-floor and workflow-pin maintenance tools now document their updates in CHANGELOG.md by default.
86
+
87
+ - [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
88
+ - kettle-dev (~> 3.0, >= 3.0.0 -> ~> 3.0, >= 3.0.6)
89
+ - kettle-family (~> 1.2, >= 1.2.44 -> ~> 1.2, >= 1.2.51)
90
+ - kettle-jem (~> 7.1, >= 7.1.1 -> ~> 7.1, >= 7.1.3)
91
+ - yard-lint (~> 1.10, >= 1.10.3 -> ~> 1.11, >= 1.11.0)
92
+
93
+ - [kc] kettle-jem-workflow-pins: Update pinned GitHub Actions in kettle-jem templates:
94
+ - github/codeql-action/analyze v4.37.4 (f205ea1c3313d32999d8d6a48b4f6530d4437b38) -> v4.37.6 (5595ccaf912efad79be6eef63a5619ff05969be3)
95
+ - github/codeql-action/autobuild v4.37.4 (f205ea1c3313d32999d8d6a48b4f6530d4437b38) -> v4.37.6 (5595ccaf912efad79be6eef63a5619ff05969be3)
96
+ - github/codeql-action/init v4.37.4 (f205ea1c3313d32999d8d6a48b4f6530d4437b38) -> v4.37.6 (5595ccaf912efad79be6eef63a5619ff05969be3)
97
+
98
+ - Declare kettle-changelog as a runtime dependency for packaged maintenance commands.
99
+
100
+ - Main templating commands now record an aggregate Changed entry through kettle-changelog only when template files change, while transfer replay uses kettle-changelog's structural merger.
101
+
102
+ ### Fixed
103
+
104
+ - Restore source-checkout loading for the repository-local dependency-floor and workflow-pin maintenance tools.
105
+
33
106
  ## [7.1.3] - 2026-08-11
34
107
 
35
108
  - TAG: [v7.1.3][7.1.3t]
@@ -1494,7 +1567,11 @@ Please file a bug if you notice a violation of semantic versioning.
1494
1567
  - Released kettle-jem as part of the initial StructuredMerge Ruby 7.0.0 gem set.
1495
1568
  - Included packaged templates and parser-backed merge support for Ruby gem templating.
1496
1569
 
1497
- [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.3...HEAD
1570
+ [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.5...HEAD
1571
+ [7.1.5]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.4...v7.1.5
1572
+ [7.1.5t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.5
1573
+ [7.1.4]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.3...v7.1.4
1574
+ [7.1.4t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.4
1498
1575
  [7.1.3]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.2...v7.1.3
1499
1576
  [7.1.3t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.3
1500
1577
  [7.1.2]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.1...v7.1.2
data/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  `if ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS maintenance is now my full-time job.
12
12
 
13
- [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate at ko-fi.com][🖇kofi-img]][🖇kofi]
13
+ [![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate at ko-fi.com][🖇kofi-img]][🖇kofi]
14
14
 
15
15
  <details markdown="1">
16
16
  <summary>👣 How will this project approach the September 2025 hostile takeover of RubyGems? 🚑️</summary>
@@ -111,7 +111,9 @@ Merge analysis must enter parsing through `tree_haver`. Parser-specific gems reg
111
111
 
112
112
  </details>
113
113
 
114
- ### Enterprise Support [![Tidelift](https://tidelift.com/badges/package/rubygems/kettle-jem)](https://tidelift.com/subscription/pkg/rubygems-kettle-jem?utm_source=rubygems-kettle-jem&utm_medium=referral&utm_campaign=readme)
114
+ ### Enterprise Support
115
+
116
+ [![Tidelift](https://tidelift.com/badges/package/rubygems/kettle-jem)](https://tidelift.com/subscription/pkg/rubygems-kettle-jem?utm_source=rubygems-kettle-jem&utm_medium=referral&utm_campaign=readme)
115
117
 
116
118
  Available as part of the Tidelift Subscription.
117
119
 
@@ -553,8 +555,7 @@ See [SECURITY.md][🔐security].
553
555
  ## 🤝 Contributing
554
556
 
555
557
  If you need some ideas of where to help, you could work on adding more code coverage,
556
- or if it is already 💯 (see [below](#code-coverage)) check [issues][🤝gh-issues] or [PRs][🤝gh-pulls],
557
- or use the gem and think about how it could be better.
558
+ check [issues][🤝gh-issues] or [PRs][🤝gh-pulls], or use the gem and think about how it could be better.
558
559
 
559
560
  We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
560
561
 
@@ -644,7 +645,7 @@ To join the community or get help, use the RubyForum or Discord.
644
645
 
645
646
  To say "thanks!" ☝️ Join the community or 👇️ send money.
646
647
 
647
- [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
648
+ [![Sponsor kettle-dev/kettle-jem on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
648
649
 
649
650
  ### Please give the project a star ⭐ ♥.
650
651
 
@@ -655,6 +656,17 @@ Thanks for RTFM. ☺️
655
656
  [⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat
656
657
  [⛳liberapay-bottom-img]: https://img.shields.io/liberapay/goal/pboling.svg?style=for-the-badge&logo=liberapay&color=a51611
657
658
  [⛳liberapay]: https://liberapay.com/pboling/donate
659
+ [🖇osc-all-img]: https://img.shields.io/opencollective/all/kettle-dev
660
+ [🖇osc-sponsors-img]: https://img.shields.io/opencollective/sponsors/kettle-dev
661
+ [🖇osc-backers-img]: https://img.shields.io/opencollective/backers/kettle-dev
662
+ [🖇osc-backers]: https://opencollective.com/kettle-dev#backer
663
+ [🖇osc-backers-i]: https://opencollective.com/kettle-dev/backers/badge.svg?style=flat
664
+ [🖇osc-sponsors]: https://opencollective.com/kettle-dev#sponsor
665
+ [🖇osc-sponsors-i]: https://opencollective.com/kettle-dev/sponsors/badge.svg?style=flat
666
+ [🖇osc-all-bottom-img]: https://img.shields.io/opencollective/all/kettle-dev?style=for-the-badge
667
+ [🖇osc-sponsors-bottom-img]: https://img.shields.io/opencollective/sponsors/kettle-dev?style=for-the-badge
668
+ [🖇osc-backers-bottom-img]: https://img.shields.io/opencollective/backers/kettle-dev?style=for-the-badge
669
+ [🖇osc]: https://opencollective.com/kettle-dev
658
670
  [🖇sponsor-img]: https://img.shields.io/badge/Sponsor_Me!-pboling.svg?style=social&logo=github
659
671
  [🖇sponsor-bottom-img]: https://img.shields.io/badge/Sponsor_Me!-pboling-blue?style=for-the-badge&logo=github
660
672
  [🖇sponsor]: https://github.com/sponsors/pboling
@@ -760,7 +772,7 @@ Thanks for RTFM. ☺️
760
772
  [📌gitmoji]: https://gitmoji.dev
761
773
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
762
774
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
763
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.445-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
775
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.554-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
764
776
  [🔐security]: https://github.com/structuredmerge/structuredmerge-ruby/blob/main/SECURITY.md
765
777
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
766
778
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -790,5 +802,5 @@ Thanks for RTFM. ☺️
790
802
  | Homepage | https://github.com/structuredmerge/structuredmerge-ruby |
791
803
  | Source | https://github.com/structuredmerge/structuredmerge-ruby |
792
804
  | License | `AGPL-3.0-only` OR `PolyForm-Small-Business-1.0.0` |
793
- | Funding | https://github.com/sponsors/pboling, https://ko-fi.com/pboling, https://liberapay.com/pboling/donate, https://thanks.dev/u/gh/pboling, https://tidelift.com/funding/github/rubygems/kettle-jem, https://www.buymeacoffee.com/pboling |
805
+ | Funding | https://github.com/sponsors/pboling, https://ko-fi.com/pboling, https://liberapay.com/pboling/donate, https://opencollective.com/kettle-dev, https://thanks.dev/u/gh/pboling, https://tidelift.com/funding/github/rubygems/kettle-jem, https://www.buymeacoffee.com/pboling |
794
806
  <!-- kettle-jem:metadata:end -->
@@ -9,13 +9,13 @@ module Kettle
9
9
  module CLI
10
10
  USAGE = <<~USAGE
11
11
  Usage:
12
- kettle-jem [PROJECT_ROOT] [--accept-config] [--bootstrap-mode] [--quiet|--verbose]
13
- kettle-jem setup [PROJECT_ROOT] [--accept-config] [--bootstrap-mode] [--quiet|--verbose]
14
- kettle-jem prepare [PROJECT_ROOT] [--json|--events[=TYPE,...]] [--report PATH] [--accept|--force] [--quiet|--verbose]
12
+ kettle-jem [PROJECT_ROOT] [--accept-config] [--bootstrap-mode] [--changelog|--no-changelog] [--quiet|--verbose]
13
+ kettle-jem setup [PROJECT_ROOT] [--accept-config] [--bootstrap-mode] [--changelog|--no-changelog] [--quiet|--verbose]
14
+ kettle-jem prepare [PROJECT_ROOT] [--json|--events[=TYPE,...]] [--report PATH] [--accept|--force] [--changelog|--no-changelog] [--quiet|--verbose]
15
15
  kettle-jem plan [PROJECT_ROOT] [--json|--events[=TYPE,...]] [--report PATH] [--accept|--force|--interactive] [--failure-mode MODE] [--prompt-answer ID=ACTION]
16
- kettle-jem apply [PROJECT_ROOT] [--json|--events[=TYPE,...]] [--report PATH] [--accept|--force|--interactive] [--failure-mode MODE] [--prompt-answer ID=ACTION]
17
- kettle-jem template [PROJECT_ROOT] [--json|--events[=TYPE,...]] [--report PATH] [--accept|--force|--interactive] [--failure-mode MODE] [--prompt-answer ID=ACTION]
18
- kettle-jem install [PROJECT_ROOT] [--json|--events[=TYPE,...]] [--report PATH] [--accept|--force|--interactive] [--failure-mode MODE] [--prompt-answer ID=ACTION]
16
+ kettle-jem apply [PROJECT_ROOT] [--json|--events[=TYPE,...]] [--report PATH] [--accept|--force|--interactive] [--failure-mode MODE] [--prompt-answer ID=ACTION] [--changelog|--no-changelog]
17
+ kettle-jem template [PROJECT_ROOT] [--json|--events[=TYPE,...]] [--report PATH] [--accept|--force|--interactive] [--failure-mode MODE] [--prompt-answer ID=ACTION] [--changelog|--no-changelog]
18
+ kettle-jem install [PROJECT_ROOT] [--json|--events[=TYPE,...]] [--report PATH] [--accept|--force|--interactive] [--failure-mode MODE] [--prompt-answer ID=ACTION] [--changelog|--no-changelog]
19
19
  kettle-jem manifest [PROJECT_ROOT] [--json]
20
20
  kettle-jem selftest [PROJECT_ROOT] [--json] [--report PATH] [--destination PATH] [--template-root PATH] [--selftest-output PATH]
21
21
  kettle-jem version
@@ -146,6 +146,9 @@ module Kettle
146
146
  opts.on("--skip-rubocop-gradual", "Skip post-template RuboCop Gradual autocorrect.") do
147
147
  options[:run_options][:skip_rubocop_gradual] = true
148
148
  end
149
+ opts.on("--[no-]changelog", "Add a Changed entry summarizing actual template changes (default).") do |value|
150
+ options[:run_options][:skip_changelog] = !value
151
+ end
149
152
  opts.on("--skip-binstubs", "Skip post-template curated Bundler binstub generation.") do
150
153
  options[:run_options][:skip_binstubs] = true
151
154
  end
@@ -199,7 +202,7 @@ module Kettle
199
202
  types: options[:event_types]
200
203
  )
201
204
  end
202
- case command
205
+ result = case command
203
206
  when "setup"
204
207
  Kettle::Jem.setup_project(project_root, env: env, run_options: run_options)
205
208
  when "prepare"
@@ -229,6 +232,14 @@ module Kettle
229
232
  else
230
233
  raise ArgumentError, "Unsupported kettle-jem command #{command.inspect}"
231
234
  end
235
+ return result unless %w[setup prepare apply template install].include?(command)
236
+
237
+ Kettle::Jem::MaintenanceChangelog.record_template_run(
238
+ project_root: project_root,
239
+ report: result,
240
+ run_options: run_options,
241
+ label: (command == "prepare") ? "Prepare project for kettle-jem templates" : "Apply kettle-jem templates"
242
+ )
232
243
  end
233
244
 
234
245
  def scoped_template_run?(run_options)
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "open3"
5
+ require "rbconfig"
6
+ require "rubygems"
7
+
8
+ module Kettle
9
+ module Jem
10
+ module MaintenanceChangelog
11
+ TEMPLATE_CHANGELOG_INTERNAL_PATHS = %w[
12
+ CHANGELOG.md
13
+ .structuredmerge/kettle-jem.lock
14
+ .kettle-jem.lock
15
+ ].freeze
16
+ TEMPLATE_CHANGE_CATEGORIES = {
17
+ workflows: ->(path) { path.start_with?(".github/workflows/") },
18
+ dependencies: ->(path) {
19
+ path == "Gemfile" || path == "Appraisals" || path.end_with?(".gemspec", ".gemfile", ".gemfile.lock") ||
20
+ path.start_with?("gemfiles/")
21
+ },
22
+ documentation: ->(path) { %w[README.md CONTRIBUTING.md SECURITY.md].include?(path) || path.start_with?("docs/") },
23
+ configuration: ->(path) { path.start_with?(".structuredmerge/") || path == "mise.toml" || path == ".gitignore" },
24
+ code_and_tests: ->(path) { path.start_with?("lib/", "spec/", "test/", "bin/") || path == "Rakefile" }
25
+ }.freeze
26
+ TEMPLATE_CHANGELOG_KEYS = {
27
+ "Apply kettle-jem templates" => "kettle-jem/template",
28
+ "Prepare project for kettle-jem templates" => "kettle-jem/prepare"
29
+ }.freeze
30
+ BUNDLER_ENVIRONMENT = %w[
31
+ BUNDLE_BIN_PATH
32
+ BUNDLE_FROZEN
33
+ BUNDLE_GEMFILE
34
+ BUNDLE_LOCKFILE
35
+ BUNDLER_SETUP
36
+ BUNDLER_VERSION
37
+ RUBYLIB
38
+ RUBYOPT
39
+ ].freeze
40
+
41
+ module_function
42
+
43
+ def add_unreleased_entry(project_root:, section:, entry:)
44
+ command = [
45
+ RbConfig.ruby,
46
+ "-rrubygems",
47
+ "-e",
48
+ 'exec Gem.ruby, Gem.bin_path("kettle-changelog", "kettle-changelog"), *ARGV',
49
+ "--",
50
+ "--add-unreleased-entry",
51
+ "--json",
52
+ "--section",
53
+ section.to_s,
54
+ "--entry",
55
+ entry.to_s
56
+ ]
57
+ environment = BUNDLER_ENVIRONMENT.to_h { |key| [key, nil] }
58
+ stdout, stderr, status = Open3.capture3(environment, *command, chdir: project_root)
59
+ unless status.success?
60
+ detail = [stdout, stderr].reject(&:empty?).join("\n")
61
+ raise "kettle-changelog failed (exit #{status.exitstatus}): #{detail}"
62
+ end
63
+
64
+ result = JSON.parse(stdout)
65
+ {
66
+ status: result.fetch("changed") ? "updated" : "unchanged",
67
+ section: result.fetch("section"),
68
+ entry: result.fetch("entry")
69
+ }
70
+ rescue JSON::ParserError => error
71
+ raise "kettle-changelog returned invalid JSON: #{error.message}"
72
+ rescue Gem::Exception => error
73
+ raise "kettle-changelog executable is not installed: #{error.message}"
74
+ end
75
+
76
+ def upsert_unreleased_entry(project_root:, section:, key:, entry:, legacy_prefixes: [])
77
+ result = Kettle::Changelog::KeyedEntryUpserter.new(
78
+ root: project_root,
79
+ section: section,
80
+ key: key,
81
+ entry: entry,
82
+ legacy_prefixes: legacy_prefixes
83
+ ).run
84
+ result.merge(status: result.fetch(:changed) ? "updated" : "unchanged")
85
+ end
86
+
87
+ def record_template_run(project_root:, report:, run_options: {}, label: "Apply kettle-jem templates")
88
+ report = report.to_h
89
+ if template_changelog_disabled?(run_options) || bootstrap_only_report?(report)
90
+ return report.merge(changelog: {status: "skipped", reason: template_changelog_disabled?(run_options) ? "disabled" : "bootstrap_only"})
91
+ end
92
+
93
+ changed_files = template_changed_files(report.fetch(:changed_files, []))
94
+ if changed_files.empty?
95
+ return report.merge(changelog: {status: "skipped", reason: "no_template_changes", changed_files: []})
96
+ end
97
+
98
+ key = TEMPLATE_CHANGELOG_KEYS.fetch(label, "kettle-jem/template")
99
+ entry = ->(matches) { template_run_entry(changed_files, matches) }
100
+ result = upsert_unreleased_entry(project_root: project_root, section: "Changed", key: key, entry: entry)
101
+ changelog = result.merge(changed_files: changed_files, entry: result.fetch(:entry))
102
+ changed_files_with_changelog = if result.fetch(:status) == "updated"
103
+ (Array(report.fetch(:changed_files, [])) + ["CHANGELOG.md"]).uniq.sort
104
+ else
105
+ Array(report.fetch(:changed_files, [])).uniq.sort
106
+ end
107
+ report.merge(changelog: changelog, changed_files: changed_files_with_changelog)
108
+ end
109
+
110
+ def template_changed_files(changed_files)
111
+ Array(changed_files).map(&:to_s).uniq.sort.reject do |path|
112
+ TEMPLATE_CHANGELOG_INTERNAL_PATHS.include?(path)
113
+ end
114
+ end
115
+
116
+ def template_run_entry(changed_files, matches)
117
+ counts = template_entry_counts(matches)
118
+ changed_files.group_by { |path| template_change_category(path) }.each do |category, paths|
119
+ counts[category] = counts.fetch(category, 0) + paths.length
120
+ end
121
+ total = counts.values.sum
122
+ details = counts.sort_by { |category, _count| category.to_s }.map do |category, count|
123
+ " - #{category.to_s.tr("_", " ")} (#{count})"
124
+ end
125
+ ["updated #{total} project file#{"s" unless total == 1}:", *details].join("\n")
126
+ end
127
+
128
+ def template_entry_counts(matches)
129
+ source = Array(matches).first.to_h.fetch(:source, "")
130
+ source.lines.filter_map do |line|
131
+ match = line.match(/\A\s{2,}- (.+?) \((\d+)\)\s*\z/)
132
+ next unless match
133
+
134
+ category = match[1].tr(" ", "_").to_sym
135
+ next unless TEMPLATE_CHANGE_CATEGORIES.key?(category) || category == :other
136
+
137
+ [category, match[2].to_i]
138
+ end.to_h
139
+ end
140
+
141
+ def template_change_category(path)
142
+ TEMPLATE_CHANGE_CATEGORIES.each do |category, matcher|
143
+ return category if matcher.call(path)
144
+ end
145
+ :other
146
+ end
147
+
148
+ def template_changelog_disabled?(run_options)
149
+ options = run_options.to_h
150
+ DecisionPolicy.value_to_boolean(options[:skip_changelog] || options["skip_changelog"])
151
+ end
152
+
153
+ def bootstrap_only_report?(report)
154
+ report.fetch(:setup_status, "").to_s.start_with?("bootstrap_")
155
+ end
156
+ end
157
+ end
158
+ end
@@ -68,6 +68,7 @@ module Kettle
68
68
  skip_binstubs: truthy?(env["KETTLE_JEM_SKIP_BINSTUBS"]),
69
69
  skip_appraisal_generate: truthy?(env["KETTLE_JEM_SKIP_APPRAISAL_GENERATE"]),
70
70
  skip_lock_normalization: truthy?(env["KETTLE_JEM_SKIP_LOCK_NORMALIZATION"]),
71
+ skip_changelog: truthy?(env["KETTLE_JEM_SKIP_CHANGELOG"]),
71
72
  checksums: env["KETTLE_JEM_CHECKSUMS"],
72
73
  accept_config: truthy?(env["KETTLE_JEM_ACCEPT_CONFIG"]),
73
74
  bootstrap_mode: truthy?(env["KETTLE_JEM_BOOTSTRAP_MODE"]),
@@ -5,8 +5,8 @@
5
5
  *.gem
6
6
 
7
7
  # Bundler
8
- /vendor/bundle/
9
8
  /.bundle/
9
+ /vendor/bundle*/
10
10
  /gemfiles/*.lock
11
11
  /gemfiles/**/*.gemfile.lock
12
12
  /gemfiles/.bundle/
@@ -266,6 +266,15 @@ NOTE: To build without signing the gem set `SKIP_GEM_SIGNING` to any value in th
266
266
  14. Run `bundle exec rake release` which will create a git tag for the version,
267
267
  push git commits and tags, and push the `.gem` file to the gem host configured in the gemspec.
268
268
 
269
+ The automated `kettle-release` flow runs the build and release tasks with a
270
+ temporary `BUNDLE_LOCKFILE`. Bundler can rewrite a tracked lockfile while
271
+ reconciling the host platform even after the release lockfile has been
272
+ normalized with `bundle lock --add-platform`; that rewrite trips the clean-tree
273
+ guard in `bundler/gem_tasks`. The disposable lockfile preserves the committed
274
+ release inputs while allowing Bundler's runtime reconciliation. Do not replace
275
+ this with `BUNDLE_FROZEN=true`: frozen mode fails when Bundler needs that
276
+ reconciliation.
277
+
269
278
  [📜src-gl]: {KJ|README:GL_PACKAGE_SOURCE_URL}
270
279
  [📜src-cb]: {KJ|README:CB_PACKAGE_SOURCE_URL}
271
280
  [📜src-gh]: {KJ|README:GH_PACKAGE_SOURCE_URL}
@@ -77,7 +77,11 @@ The _amazing_ test matrix is powered by the kettle-dev stack.
77
77
 
78
78
  </details>
79
79
 
80
- ### Enterprise Support [![Tidelift](https://tidelift.com/badges/package/rubygems/{KJ|GEM_NAME})](https://tidelift.com/subscription/pkg/rubygems-{KJ|GEM_NAME}?utm_source=rubygems-{KJ|GEM_NAME}&utm_medium=referral&utm_campaign=readme)
80
+ ### Enterprise Support
81
+
82
+ <!-- KJ:FUNDING_TIDELIFT:START -->
83
+ [![Tidelift](https://tidelift.com/badges/package/rubygems/{KJ|GEM_NAME})](https://tidelift.com/subscription/pkg/rubygems-{KJ|GEM_NAME}?utm_source=rubygems-{KJ|GEM_NAME}&utm_medium=referral&utm_campaign=readme)
84
+ <!-- KJ:FUNDING_TIDELIFT:END -->
81
85
 
82
86
  Available as part of the Tidelift Subscription.
83
87
 
@@ -118,7 +118,7 @@ Gem::Specification.new do |spec|
118
118
  # and preferably a modular one (see gemfiles/modular/*.gemfile).
119
119
 
120
120
  # Dev, Test, & Release Tasks
121
- spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.0") # ruby >= {KJ|MIN_TEST_RUBY}
121
+ spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.10") # ruby >= {KJ|MIN_TEST_RUBY}
122
122
 
123
123
  # Security
124
124
  spec.add_development_dependency("bundler-audit", "~> 0.9.3") # ruby >= 2.0.0
@@ -133,8 +133,8 @@ Gem::Specification.new do |spec|
133
133
  # Loads version files in anonymous namespaces for coverage without constant redefinition warnings.
134
134
  spec.add_development_dependency("anonymous_loader", "~> 0.1", ">= 0.1.3") # ruby >= 2.2.0
135
135
  spec.add_development_dependency("appraisal2", "~> 3.2", ">= 3.2.2") # ruby >= 1.8.7, for testing against multiple versions of dependencies
136
- spec.add_development_dependency("kettle-test", "~> 2.0", ">= 2.0.19") # ruby >= {KJ|MIN_TEST_RUBY}
137
- spec.add_development_dependency("turbo_tests2", "~> 3.2", ">= 3.2.5") # ruby >= 2.4.0, default kettle-test runner
136
+ spec.add_development_dependency("kettle-test", "~> 2.0", ">= 2.0.20") # ruby >= {KJ|MIN_TEST_RUBY}
137
+ spec.add_development_dependency("turbo_tests2", "~> 3.2", ">= 3.2.6") # ruby >= 2.4.0, default kettle-test runner
138
138
 
139
139
  # Releasing
140
140
  spec.add_development_dependency("ruby-progressbar", "~> 1.13") # ruby >= 0
@@ -150,7 +150,7 @@ Gem::Specification.new do |spec|
150
150
  # This means we have no choice but to use the erb that shipped with Ruby 2.3
151
151
  # /opt/hostedtoolcache/Ruby/2.3.8/x64/lib/ruby/gems/2.3.0/gems/erb-2.2.2/lib/erb.rb:670:in `prepare_trim_mode': undefined method `match?' for "-":String (NoMethodError)
152
152
  # spec.add_development_dependency("erb", ">= 2.2") # ruby >= 2.3.0, not SemVer, old rubies get dropped in a patch.
153
- spec.add_development_dependency("gitmoji-regex", "~> 2.0", ">= 2.0.11") # ruby >= 2.4
153
+ spec.add_development_dependency("gitmoji-regex", "~> 2.0", ">= 2.0.12") # ruby >= 2.4
154
154
 
155
155
  # HTTP recording for deterministic specs
156
156
  # In Ruby 3.5 (HEAD) the CGI library has been pared down, so we also need to depend on gem "cgi" for ruby@head
@@ -12,7 +12,7 @@ gem "kramdown-parser-gfm", "~> 1.1", require: false # Ruby >= 2.3
12
12
  gem "yaml-converter", "~> 0.2", ">= 0.2.5", require: false # Ruby >= 3.2
13
13
  gem "yard", "~> 0.9", ">= 0.9.45", require: false
14
14
  gem "yard-junk", "~> 0.1", ">= 0.1.0", require: false # Ruby >= 3.1
15
- gem "yard-lint", "~> 1.10", ">= 1.10.3", require: false # Ruby >= 3.3
15
+ gem "yard-lint", "~> 1.11", ">= 1.11.0", require: false # Ruby >= 3.3
16
16
  gem "yard-relative_markdown_links", "~> 0.6", require: false
17
17
 
18
18
  if ENV.fetch("GALTZO_FLOSS_DEV", "false").casecmp("false").zero?
@@ -5,14 +5,15 @@ kettle_remote = ENV.fetch("KETTLE_DEV_DEV", "false").casecmp("false").zero?
5
5
 
6
6
  tslp_dev = ENV.fetch("TSLP_DEV", nil).to_s
7
7
  tslp_dev = nil if tslp_dev.empty? || %w[false 0 no off].include?(tslp_dev.downcase)
8
- if tslp_dev.to_s.empty?
9
- if structuredmerge_remote
10
- # Parser dependencies for released installs.
11
- gem "tree_sitter_language_pack", "~> 1.14", ">= 1.14.3"
12
- end
13
- else
14
- # Explicit local override for unreleased TSLP debugging.
15
- gem "tree_sitter_language_pack", path: tslp_dev
8
+ if structuredmerge_remote || !tslp_dev.to_s.empty?
9
+ # Keep one Bundler declaration so the local debugging override cannot be
10
+ # mistaken for a second dependency declaration.
11
+ tslp_requirements = if tslp_dev.to_s.empty?
12
+ ["~> 1.15", ">= 1.15.7"]
13
+ else
14
+ [{ path: tslp_dev }]
15
+ end
16
+ gem "tree_sitter_language_pack", *tslp_requirements
16
17
  end
17
18
 
18
19
  if structuredmerge_remote
@@ -29,6 +29,19 @@ defaults:
29
29
  preference: template
30
30
  add_template_only_nodes: true
31
31
  freeze_token: kettle-jem
32
+ funding:
33
+ buy_me_a_coffee: true
34
+ community_bridge: true
35
+ github: true
36
+ issuehunt: false
37
+ ko_fi: true
38
+ liberapay: true
39
+ open_collective: "example-org"
40
+ patreon: false
41
+ paypal: true
42
+ polar: false
43
+ thanks_dev: true
44
+ tidelift: true
32
45
  patterns:
33
46
  - path: "certs/**"
34
47
  strategy: raw_copy
@@ -30,13 +30,13 @@ Gem::Specification.new do |spec|
30
30
  spec.add_dependency "{KJ|SHIMMED_GEM_NAME}"
31
31
 
32
32
  # Dev, Test, & Release Tasks
33
- spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.0") # ruby >= {KJ|MIN_TEST_RUBY}
33
+ spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.10") # ruby >= {KJ|MIN_TEST_RUBY}
34
34
 
35
35
  # Tasks
36
36
  spec.add_development_dependency "rake", "~> 13.0"
37
37
 
38
38
  # Testing
39
- spec.add_development_dependency("kettle-test", "~> 2.0", ">= 2.0.19") # ruby >= {KJ|MIN_TEST_RUBY}
39
+ spec.add_development_dependency("kettle-test", "~> 2.0", ">= 2.0.20") # ruby >= {KJ|MIN_TEST_RUBY}
40
40
  spec.add_development_dependency "rspec", "~> 3.12"
41
41
 
42
42
  # Releasing
@@ -5,7 +5,7 @@ module Kettle
5
5
  # Version namespace for this gem.
6
6
  module Version
7
7
  # Current gem version.
8
- VERSION = "7.1.3"
8
+ VERSION = "7.1.5"
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location