kettle-jem 7.1.1 → 7.1.4

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: 332ff145199ec3a4f39506cdcdfcf5517d9eab1fb5145ac32c9e1468d9789305
4
- data.tar.gz: c7f5fc56417b4802f9608525bbf8699ef6d34911e630e8b99e5f05707c8a403d
3
+ metadata.gz: 3900eae88b47a873cae6083d0465467ebd57842a12ed7e4b8cab28d37092fef7
4
+ data.tar.gz: a0df0ddab136eb1079901cda7ee1715ddb574b5392d2ee314196fd54b2042d7c
5
5
  SHA512:
6
- metadata.gz: 4973314437e5d2d1cfdbede91915f68540effce4de9336c8e9f9ba3ea188f9c0afd0304f87d6c0bf1ce18d7aa42475837ba7017b513c646779c088e6f74da7f8
7
- data.tar.gz: bcef0d250bfa17745271cd768de5eefe0d6f942d92d4f3fb577abf05b4fbea63ad4e822fa889b9719611f7dd41495fa046a50abb74515e69ffde3bf1b8664c2a
6
+ metadata.gz: 47a922c1ad1fdd9f57838b74de337777129ed2127752c5d579f0070b084fd7973c50ea68f7dd7258cad159229958d611185e4ef3470557f86412a9b53af77211
7
+ data.tar.gz: e05ba9400554b325770fcad5bc79c94180c626188c41d003fc1dbd368c322e474fb4ea9484b97fc717e6d8e4b4f6c4b94cda5d29543d5f9418bcd544d7abbb6b
checksums.yaml.gz.sig CHANGED
@@ -1,3 +1,4 @@
1
- W(���f6|�5�݃{F;��O�-l(�|�I�n؟�@Һ�g>��{l��*��W��.z[��=Xc�,�<`BK��;��5,>�@�|3��M(��$�
2
- Iwb�u�,�_�vc��s�6o`����p�T��� �ᮎ�n�;��������r �S�R���`��ii�Z����WCU����:�����y�u;I�{Ȋј��Wh��n���W F<�n�\�[t�>�K8|N h��#��]Ѡpp�Z�qA 7G�������d#"T"vٜ���8��;pypn[� ME��%^�R����q,1�h��8[��i�$�of
3
- ���� �K���…3����}9�מ�[
1
+ F��(m�T���>�0���o#HCe�(�5S���
2
+ W"��b-����3��7�?��+Y ���U)Z��)��E�,�gnd9 ��b���i]%N���hA².we��i���MB
3
+ 'A�s�A�y����<&f�.��Z��-o���j� 8����:�־jܦO��~-������)&r^�.M6b����:�NַB
4
+ ��6�5 � ���Ti�'��xH�Է�-�w�]E�#� ���
data/CHANGELOG.md CHANGED
@@ -30,6 +30,112 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [7.1.4] - 2026-08-12
34
+
35
+ - TAG: [v7.1.4][7.1.4t]
36
+ - COVERAGE: 93.57% -- 10753/11492 lines in 16 files
37
+ - BRANCH COVERAGE: 77.10% -- 4599/5965 branches in 16 files
38
+ - 18.00% documented
39
+
40
+ ### Changed
41
+
42
+ - Write-mode dependency-floor and workflow-pin maintenance tools now document their updates in CHANGELOG.md by default.
43
+
44
+ - [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
45
+ - kettle-dev (~> 3.0, >= 3.0.0 -> ~> 3.0, >= 3.0.6)
46
+ - kettle-family (~> 1.2, >= 1.2.44 -> ~> 1.2, >= 1.2.51)
47
+ - kettle-jem (~> 7.1, >= 7.1.1 -> ~> 7.1, >= 7.1.3)
48
+ - yard-lint (~> 1.10, >= 1.10.3 -> ~> 1.11, >= 1.11.0)
49
+
50
+ - [kc] kettle-jem-workflow-pins: Update pinned GitHub Actions in kettle-jem templates:
51
+ - github/codeql-action/analyze v4.37.4 (f205ea1c3313d32999d8d6a48b4f6530d4437b38) -> v4.37.6 (5595ccaf912efad79be6eef63a5619ff05969be3)
52
+ - github/codeql-action/autobuild v4.37.4 (f205ea1c3313d32999d8d6a48b4f6530d4437b38) -> v4.37.6 (5595ccaf912efad79be6eef63a5619ff05969be3)
53
+ - github/codeql-action/init v4.37.4 (f205ea1c3313d32999d8d6a48b4f6530d4437b38) -> v4.37.6 (5595ccaf912efad79be6eef63a5619ff05969be3)
54
+
55
+ - Declare kettle-changelog as a runtime dependency for packaged maintenance commands.
56
+
57
+ - 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.
58
+
59
+ ### Fixed
60
+
61
+ - Restore source-checkout loading for the repository-local dependency-floor and workflow-pin maintenance tools.
62
+
63
+ ## [7.1.3] - 2026-08-11
64
+
65
+ - TAG: [v7.1.3][7.1.3t]
66
+ - COVERAGE: 93.99% -- 10757/11445 lines in 15 files
67
+ - BRANCH COVERAGE: 77.39% -- 4605/5950 branches in 15 files
68
+ - 18.01% documented
69
+
70
+ ### Changed
71
+
72
+ - Generate README star-history embeds with the revived star-history.dera.page service.
73
+
74
+ - Generate the README Star History section only for GitHub repositories with at least 150 stars.
75
+
76
+ ### Fixed
77
+
78
+ - Handle comment-only YAML documents while pruning disabled engine workflow jobs.
79
+
80
+ - Remove disabled engine workflow badge references from generated README files.
81
+
82
+ - Gemspec templating now discards untouched Bundler allowed-push-host placeholders while preserving destination-specific metadata.
83
+
84
+ - Prepare profile synchronization now materializes newly added modular Gemfiles before Bundler bootstrapping.
85
+
86
+ - Generate modular changelog Gemfiles with the released kettle-changelog 1.x dependency floor.
87
+
88
+ - Synchronize monorepo subgem profiles with a template-owned Rakefile so legacy generated task blocks are replaced instead of duplicated.
89
+
90
+ - Preserve local Gemfile indentation when removing destination package entries from multiline word arrays.
91
+
92
+ - Add the generated frozen-string-literal comment to Ruby 3.1 extracted stdlib Gemfiles.
93
+
94
+ - Retain the MRI runtime floor when normalizing multi-engine README compatibility text.
95
+
96
+ - Include html-merge in generated StructuredMerge local dependency wiring.
97
+
98
+ ## [7.1.2] - 2026-08-10
99
+
100
+ - TAG: [v7.1.2][7.1.2t]
101
+ - COVERAGE: 93.86% -- 10679/11378 lines in 15 files
102
+ - BRANCH COVERAGE: 77.21% -- 4569/5918 branches in 15 files
103
+ - 18.04% documented
104
+
105
+ ### Added
106
+
107
+ - Template generated projects now receive kettle-changelog as a development dependency; kettle-changelog itself is excluded to avoid a self-dependency.
108
+
109
+ - Local templating dependency wiring now resolves the standalone kettle-changelog development tool alongside the Kettle development stack.
110
+
111
+ ### Changed
112
+
113
+ - Align generated compatibility workflows with the Ruby 4.0 runtime floor by excluding unsupported TruffleRuby targets
114
+
115
+ - Resolve kettle-changelog through a Ruby-compatible modular development Gemfile instead of every generated gemspec.
116
+
117
+ - Keep the standalone kettle-changelog tool in a Ruby-compatible modular Gemfile with explicit local-path wiring, rather than adding it to every generated gemspec.
118
+
119
+ - Allow kettle-jem to resolve kettle-dev 3.x while retaining compatibility with supported kettle-dev 2.x releases.
120
+
121
+ - Allow kettle-jem to update independently within the StructuredMerge 7.1 dependency series instead of requiring every sibling gem to share its patch version.
122
+
123
+ ### Fixed
124
+
125
+ - Preserve enabled engine workflow jobs when pruning disabled jobs from generated YAML
126
+
127
+ - Generate README compatibility prose from the configured Ruby engine set
128
+
129
+ - Honor disabled README integrations after destination content is merged
130
+
131
+ - Temporarily pin generated RuboCop Packaging style Gemfiles to the nested-project config-root fix.
132
+
133
+ - Keep scoped kettle-jem template runs from applying unselected post-template mutations.
134
+
135
+ - Preserve destination-only gemspec metadata when the template does not define that key.
136
+
137
+ - Keep aggregate standard-library Gemfile references available when Ruby-floor pruning would otherwise remove their targets, and generate Appraisal Gemfiles during full kettle-jem installs.
138
+
33
139
  ## [7.1.1] - 2026-08-08
34
140
 
35
141
  - TAG: [v7.1.1][7.1.1t]
@@ -1255,9 +1361,6 @@ Please file a bug if you notice a violation of semantic versioning.
1255
1361
  - kettle-jem-template-20260726-003 - Coverage upload steps now treat Coveralls,
1256
1362
  QLTY, and Codecov as optional, so provider outages do not fail CI when local
1257
1363
  coverage thresholds still pass.
1258
- - kettle-jem-template-20260728-003 - Generated dep-heads workflows now run
1259
- TruffleRuby jobs with current RubyGems and Bundler, avoiding setup failures
1260
- before the test suite starts.
1261
1364
  - kettle-jem-template-20260728-004 - Generated dep-heads workflows now use the
1262
1365
  setup-ruby Bundler install path for direct appraisal Gemfiles, avoiding rv
1263
1366
  lockfile parser failures on Git and path dependencies.
@@ -1421,7 +1524,13 @@ Please file a bug if you notice a violation of semantic versioning.
1421
1524
  - Released kettle-jem as part of the initial StructuredMerge Ruby 7.0.0 gem set.
1422
1525
  - Included packaged templates and parser-backed merge support for Ruby gem templating.
1423
1526
 
1424
- [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.1...HEAD
1527
+ [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.4...HEAD
1528
+ [7.1.4]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.3...v7.1.4
1529
+ [7.1.4t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.4
1530
+ [7.1.3]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.2...v7.1.3
1531
+ [7.1.3t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.3
1532
+ [7.1.2]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.1...v7.1.2
1533
+ [7.1.2t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.2
1425
1534
  [7.1.1]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.0.0...v7.1.1
1426
1535
  [7.1.1t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.1
1427
1536
  [7.0.0]: https://github.com/structuredmerge/structuredmerge-ruby/compare/0aae485e7ca20583b73f8c146f467a64e526ca41...v7.0.0
data/README.md CHANGED
@@ -57,7 +57,7 @@ to build `kettle-jem` extension gems against the supported plugin seam.
57
57
 
58
58
  ### Compatibility
59
59
 
60
- Compatible with MRI Ruby 4.0.0+, and concordant releases of JRuby, and TruffleRuby.
60
+ Compatible with MRI Ruby 4.0.0+, and JRuby.
61
61
  CI workflows and Appraisals are generated for MRI Ruby 4.0.0+.
62
62
  This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and
63
63
  may be higher than the gem's runtime compatibility floor when legacy Rubies are
@@ -584,19 +584,6 @@ Made with [contributors-img][🖐contrib-rocks].
584
584
 
585
585
  Also see GitLab Contributors: [https://gitlab.com/structuredmerge/structuredmerge-ruby/-/graphs/main][🚎contributors-gl]
586
586
 
587
- <details markdown="1">
588
- <summary>⭐️ Star History</summary>
589
-
590
- <a href="https://star-history.com/structuredmerge/structuredmerge-ruby&Date">
591
- <picture>
592
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=structuredmerge/structuredmerge-ruby&type=Date&theme=dark" />
593
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=structuredmerge/structuredmerge-ruby&type=Date" />
594
- <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=structuredmerge/structuredmerge-ruby&type=Date" />
595
- </picture>
596
- </a>
597
-
598
- </details>
599
-
600
587
  ## 📌 Versioning
601
588
 
602
589
  This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical.
@@ -773,7 +760,7 @@ Thanks for RTFM. ☺️
773
760
  [📌gitmoji]: https://gitmoji.dev
774
761
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
775
762
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
776
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.320-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
763
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.492-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
777
764
  [🔐security]: https://github.com/structuredmerge/structuredmerge-ruby/blob/main/SECURITY.md
778
765
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
779
766
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -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,136 @@
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
+ BUNDLER_ENVIRONMENT = %w[
27
+ BUNDLE_BIN_PATH
28
+ BUNDLE_FROZEN
29
+ BUNDLE_GEMFILE
30
+ BUNDLE_LOCKFILE
31
+ BUNDLER_SETUP
32
+ BUNDLER_VERSION
33
+ RUBYLIB
34
+ RUBYOPT
35
+ ].freeze
36
+
37
+ module_function
38
+
39
+ def add_unreleased_entry(project_root:, section:, entry:)
40
+ command = [
41
+ RbConfig.ruby,
42
+ "-rrubygems",
43
+ "-e",
44
+ 'exec Gem.ruby, Gem.bin_path("kettle-changelog", "kettle-changelog"), *ARGV',
45
+ "--",
46
+ "--add-unreleased-entry",
47
+ "--json",
48
+ "--section",
49
+ section.to_s,
50
+ "--entry",
51
+ entry.to_s
52
+ ]
53
+ environment = BUNDLER_ENVIRONMENT.to_h { |key| [key, nil] }
54
+ stdout, stderr, status = Open3.capture3(environment, *command, chdir: project_root)
55
+ unless status.success?
56
+ detail = [stdout, stderr].reject(&:empty?).join("\n")
57
+ raise "kettle-changelog failed (exit #{status.exitstatus}): #{detail}"
58
+ end
59
+
60
+ result = JSON.parse(stdout)
61
+ {
62
+ status: result.fetch("changed") ? "updated" : "unchanged",
63
+ section: result.fetch("section"),
64
+ entry: result.fetch("entry")
65
+ }
66
+ rescue JSON::ParserError => error
67
+ raise "kettle-changelog returned invalid JSON: #{error.message}"
68
+ rescue Gem::Exception => error
69
+ raise "kettle-changelog executable is not installed: #{error.message}"
70
+ end
71
+
72
+ def upsert_unreleased_entry(project_root:, section:, key:, entry:, legacy_prefixes: [])
73
+ result = Kettle::Changelog::KeyedEntryUpserter.new(
74
+ root: project_root,
75
+ section: section,
76
+ key: key,
77
+ entry: entry,
78
+ legacy_prefixes: legacy_prefixes
79
+ ).run
80
+ result.merge(status: result.fetch(:changed) ? "updated" : "unchanged")
81
+ end
82
+
83
+ def record_template_run(project_root:, report:, run_options: {}, label: "Apply kettle-jem templates")
84
+ report = report.to_h
85
+ if template_changelog_disabled?(run_options) || bootstrap_only_report?(report)
86
+ return report.merge(changelog: {status: "skipped", reason: template_changelog_disabled?(run_options) ? "disabled" : "bootstrap_only"})
87
+ end
88
+
89
+ changed_files = template_changed_files(report.fetch(:changed_files, []))
90
+ if changed_files.empty?
91
+ return report.merge(changelog: {status: "skipped", reason: "no_template_changes", changed_files: []})
92
+ end
93
+
94
+ entry = template_run_entry(label, changed_files)
95
+ result = add_unreleased_entry(project_root: project_root, section: "Changed", entry: entry)
96
+ changelog = result.merge(changed_files: changed_files, entry: entry)
97
+ changed_files_with_changelog = if result.fetch(:status) == "updated"
98
+ (Array(report.fetch(:changed_files, [])) + ["CHANGELOG.md"]).uniq.sort
99
+ else
100
+ Array(report.fetch(:changed_files, [])).uniq.sort
101
+ end
102
+ report.merge(changelog: changelog, changed_files: changed_files_with_changelog)
103
+ end
104
+
105
+ def template_changed_files(changed_files)
106
+ Array(changed_files).map(&:to_s).uniq.sort.reject do |path|
107
+ TEMPLATE_CHANGELOG_INTERNAL_PATHS.include?(path)
108
+ end
109
+ end
110
+
111
+ def template_run_entry(label, changed_files)
112
+ counts = changed_files.group_by { |path| template_change_category(path) }
113
+ .sort_by { |category, _paths| category.to_s }
114
+ .map { |category, paths| "#{category.to_s.tr("_", " ")} (#{paths.length})" }
115
+ areas = counts.empty? ? "project files" : counts.join(", ")
116
+ "#{label}: updated #{changed_files.length} project file#{"s" unless changed_files.length == 1} across #{areas}."
117
+ end
118
+
119
+ def template_change_category(path)
120
+ TEMPLATE_CHANGE_CATEGORIES.each do |category, matcher|
121
+ return category if matcher.call(path)
122
+ end
123
+ :other
124
+ end
125
+
126
+ def template_changelog_disabled?(run_options)
127
+ options = run_options.to_h
128
+ DecisionPolicy.value_to_boolean(options[:skip_changelog] || options["skip_changelog"])
129
+ end
130
+
131
+ def bootstrap_only_report?(report)
132
+ report.fetch(:setup_status, "").to_s.start_with?("bootstrap_")
133
+ end
134
+ end
135
+ end
136
+ end
@@ -44,6 +44,7 @@ module Kettle
44
44
  install_steps << rubocop_lts_branch_step if rubocop_lts_branch_step
45
45
  install_steps << run_distinct_bundle_install_step(project_root, env: env, setup_env: setup_env, run_options: effective_run_options, command_runner: command_runner)
46
46
  install_steps.concat(run_bundle_setup_commands(project_root, env: setup_env, run_options: effective_run_options, command_runner: command_runner))
47
+ install_steps << appraisal_generate_step(project_root, env: setup_env, run_options: effective_run_options)
47
48
  install_steps << rubocop_gradual_autocorrect_step(project_root, env: setup_env, run_options: effective_run_options)
48
49
  install_steps << normalize_lockfile_step(project_root, env: setup_env, run_options: effective_run_options)
49
50
  install_steps << bundled_handoff_step(project_root: project_root, env: env, run_options: effective_run_options)
@@ -188,6 +189,7 @@ module Kettle
188
189
  git_drivers
189
190
  rubocop_lts_local_branch
190
191
  bundle_install_requested_env
192
+ appraisal_generate
191
193
  bin_setup_executable
192
194
  bin_setup
193
195
  bundle_binstubs
@@ -629,6 +631,47 @@ module Kettle
629
631
  steps
630
632
  end
631
633
 
634
+ def appraisal_generate_step(project_root, env: nil, run_options: {})
635
+ if Kettle::Jem::DecisionPolicy.value_to_boolean((run_options || {})[:skip_appraisal_generate])
636
+ return {
637
+ name: "appraisal_generate",
638
+ status: "skipped",
639
+ reason: "skip_appraisal_generate"
640
+ }
641
+ end
642
+
643
+ unless Array((run_options || {})[:only]).empty?
644
+ return {
645
+ name: "appraisal_generate",
646
+ status: "skipped",
647
+ reason: "template_selection"
648
+ }
649
+ end
650
+
651
+ unless File.file?(File.join(project_root.to_s, "Appraisals")) && File.file?(File.join(project_root.to_s, "bin", "rake"))
652
+ return {
653
+ name: "appraisal_generate",
654
+ status: "skipped",
655
+ reason: "missing_appraisals_entrypoint"
656
+ }
657
+ end
658
+
659
+ unless rake_task_available?(project_root, "appraisal:generate", env: env)
660
+ return {
661
+ name: "appraisal_generate",
662
+ status: "skipped",
663
+ reason: "missing_appraisal_generate_task"
664
+ }
665
+ end
666
+
667
+ {
668
+ name: "appraisal_generate",
669
+ command: ["bin/rake", "appraisal:generate"],
670
+ status: "ready",
671
+ reason: "post_template_appraisal_generation"
672
+ }
673
+ end
674
+
632
675
  def bundle_binstubs_command(project_root = Dir.pwd, env: ENV)
633
676
  %w[bundle binstubs] + curated_binstub_gems_in_bundle(project_root, env: env)
634
677
  end
@@ -1093,6 +1136,8 @@ module Kettle
1093
1136
  execute_ready_command_step(step, project_root: project_root, env: env, quiet: quiet, command_runner: command_runner)
1094
1137
  when "bundle_install_requested_env"
1095
1138
  execute_ready_command_step(step, project_root: project_root, env: env, quiet: quiet, command_runner: command_runner)
1139
+ when "appraisal_generate"
1140
+ execute_ready_command_step(step, project_root: project_root, env: env, quiet: quiet, command_runner: command_runner)
1096
1141
  when "rubocop_gradual_autocorrect"
1097
1142
  execute_ready_command_step(step, project_root: project_root, env: env, quiet: quiet, command_runner: command_runner)
1098
1143
  when "hook_templates"
@@ -31,6 +31,11 @@ module Kettle
31
31
  )
32
32
  events = Kettle::Jem.event_stream_from_options(effective_run_options)
33
33
  report = Kettle::Jem.apply_project(project_root, env: env, run_options: prepare_run_options)
34
+ profile_sync_step = synchronize_monorepo_subgem_profile_step(project_root, report)
35
+ supplemental_report = if profile_sync_step && profile_sync_step.fetch(:status) == "applied"
36
+ Kettle::Jem.apply_project(project_root, env: env, run_options: prepare_run_options)
37
+ end
38
+ report = merge_supplemental_prepare_report(report, supplemental_report)
34
39
  nomono_bootstrap_step = normalize_existing_local_gemfile_bootstraps_step(project_root, events: events)
35
40
  setup_env = Kettle::Jem::Tasks::InstallTask.setup_command_env(project_root, env)
36
41
  setup_env["BUNDLE_DISABLE_CHECKSUM_VALIDATION"] = "true"
@@ -76,7 +81,7 @@ module Kettle
76
81
  %w[skipped succeeded].include?(reset_step.fetch(:status)) &&
77
82
  %w[skipped succeeded].include?(bundle_step.fetch(:status)),
78
83
  prepare_only: PREPARE_ONLY_PATHS,
79
- prepare_steps: [nomono_bootstrap_step, reset_step, bootstrap_step, bundle_step],
84
+ prepare_steps: [profile_sync_step, nomono_bootstrap_step, reset_step, bootstrap_step, bundle_step].compact,
80
85
  changed_files: (
81
86
  report.fetch(:changed_files, []) +
82
87
  nomono_bootstrap_step.fetch(:changed_files, []) +
@@ -94,6 +99,24 @@ module Kettle
94
99
  final_report
95
100
  end
96
101
 
102
+ def synchronize_monorepo_subgem_profile_step(project_root, report)
103
+ facts = report.fetch(:facts, {})
104
+ return unless Kettle::Jem.send(:monorepo_subgem_template_profile?, facts)
105
+
106
+ Kettle::Jem.send(:monorepo_subgem_kettle_config_profile_sync_step, project_root, report)
107
+ end
108
+
109
+ def merge_supplemental_prepare_report(report, supplemental_report)
110
+ return report unless supplemental_report
111
+
112
+ report.merge(
113
+ changed_files: (
114
+ report.fetch(:changed_files, []) + supplemental_report.fetch(:changed_files, [])
115
+ ).uniq.sort,
116
+ diagnostics: report.fetch(:diagnostics, []) + supplemental_report.fetch(:diagnostics, [])
117
+ )
118
+ end
119
+
97
120
  def normalize_existing_local_gemfile_bootstraps_step(project_root, events:)
98
121
  paths = Dir.glob(File.join(project_root.to_s, "gemfiles/modular/**/*_local.gemfile")).sort
99
122
  changed_files = paths.filter_map do |path|
@@ -66,7 +66,9 @@ module Kettle
66
66
  skip_drift_check: truthy?(env["KETTLE_JEM_SKIP_DRIFT_CHECK"]),
67
67
  skip_rubocop_gradual: truthy?(env["KETTLE_JEM_SKIP_RUBOCOP_GRADUAL"]),
68
68
  skip_binstubs: truthy?(env["KETTLE_JEM_SKIP_BINSTUBS"]),
69
+ skip_appraisal_generate: truthy?(env["KETTLE_JEM_SKIP_APPRAISAL_GENERATE"]),
69
70
  skip_lock_normalization: truthy?(env["KETTLE_JEM_SKIP_LOCK_NORMALIZATION"]),
71
+ skip_changelog: truthy?(env["KETTLE_JEM_SKIP_CHANGELOG"]),
70
72
  checksums: env["KETTLE_JEM_CHECKSUMS"],
71
73
  accept_config: truthy?(env["KETTLE_JEM_ACCEPT_CONFIG"]),
72
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/
@@ -95,7 +95,6 @@ This gem is part of the **StructuredMerge** ecosystem. Key development tools:
95
95
  |-----------|---------|
96
96
  | `kettle-release` | Full gem release workflow |
97
97
  | `kettle-pre-release` | Pre-release validation |
98
- | `kettle-changelog` | Changelog generation |
99
98
  | `kettle-dvcs` | DVCS (git) workflow automation |
100
99
  | `kettle-commit-msg` | Commit message validation |
101
100
  | `kettle-check-eof` | EOF newline validation |
@@ -39,6 +39,9 @@ eval_gemfile "gemfiles/modular/style.gemfile"
39
39
  # Documentation
40
40
  eval_gemfile "gemfiles/modular/documentation.gemfile"
41
41
 
42
+ # Changelog release tooling (available on Ruby versions supported by kettle-changelog)
43
+ eval_gemfile "gemfiles/modular/changelog.gemfile"
44
+
42
45
  # Optional
43
46
  eval_gemfile "gemfiles/modular/optional.gemfile"
44
47
 
@@ -194,8 +194,7 @@ See [SECURITY.md][🔐security].
194
194
  ## 🤝 Contributing
195
195
 
196
196
  If you need some ideas of where to help, you could work on adding more code coverage,
197
- or if it is already 💯 (see [below](#code-coverage)) check [issues][🤝gh-issues] or [PRs][🤝gh-pulls],
198
- or use the gem and think about how it could be better.
197
+ check [issues][🤝gh-issues] or [PRs][🤝gh-pulls], or use the gem and think about how it could be better.
199
198
 
200
199
  We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
201
200
 
@@ -234,11 +233,11 @@ Also see GitLab Contributors: [{KJ|README:GL_CONTRIBUTORS_URL}][🚎contributors
234
233
  <details markdown="1">
235
234
  <summary>⭐️ Star History</summary>
236
235
 
237
- <a href="https://star-history.com/{KJ|README:STAR_HISTORY_REPO}&Date">
236
+ <a href="https://star-history.dera.page/#{KJ|README:STAR_HISTORY_REPO}&type=date&legend=top-left">
238
237
  <picture>
239
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos={KJ|README:STAR_HISTORY_REPO}&type=Date&theme=dark" />
240
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos={KJ|README:STAR_HISTORY_REPO}&type=Date" />
241
- <img alt="Star History Chart" src="https://api.star-history.com/svg?repos={KJ|README:STAR_HISTORY_REPO}&type=Date" />
238
+ <source media="(prefers-color-scheme: dark)" srcset="https://star-history.dera.page/svg?repos={KJ|README:STAR_HISTORY_REPO}&type=date&theme=dark&legend=top-left" />
239
+ <source media="(prefers-color-scheme: light)" srcset="https://star-history.dera.page/svg?repos={KJ|README:STAR_HISTORY_REPO}&type=date&legend=top-left" />
240
+ <img alt="Star History Chart" src="https://star-history.dera.page/svg?repos={KJ|README:STAR_HISTORY_REPO}&type=date&legend=top-left" />
242
241
  </picture>
243
242
  </a>
244
243
 
@@ -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", "~> 2.5", ">= 2.5.24") # ruby >= {KJ|MIN_TEST_RUBY}
121
+ spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.6") # 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
@@ -134,7 +134,7 @@ Gem::Specification.new do |spec|
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
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.4") # ruby >= 2.4.0, default kettle-test runner
137
+ spec.add_development_dependency("turbo_tests2", "~> 3.2", ">= 3.2.5") # 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
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # kettle-changelog depends on the current kettle-dev APIs and the structured
4
+ # Markdown merger. Keep it out of older appraisal jobs whose Ruby cannot load
5
+ # its runtime dependency floor.
6
+ {KJ|KETTLE_CHANGELOG_GEMFILE_DEPENDENCY}
@@ -9,16 +9,16 @@
9
9
  # Documentation
10
10
  gem "kramdown", "~> 2.5", ">= 2.5.2", require: false # Ruby >= 2.5
11
11
  gem "kramdown-parser-gfm", "~> 1.1", require: false # Ruby >= 2.3
12
- gem "yaml-converter", "~> 0.2", ">= 0.2.4", require: false # Ruby >= 3.2
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?
19
- gem "yard-fence", "~> 0.9", ">= 0.9.7", require: false # Ruby >= 3.2
20
- gem "yard-timekeeper", "~> 0.2", ">= 0.2.5", require: false
21
- gem "yard-yaml", "~> 0.2", ">= 0.2.4", require: false
19
+ gem "yard-fence", "~> 0.9", ">= 0.9.8", require: false # Ruby >= 3.2
20
+ gem "yard-timekeeper", "~> 0.2", ">= 0.2.6", require: false
21
+ gem "yard-yaml", "~> 0.2", ">= 0.2.5", require: false
22
22
  else
23
23
  eval_gemfile "documentation_local.gemfile"
24
24
  end
@@ -17,7 +17,9 @@ platform :mri do
17
17
  gem "rubocop-minitest", "~> 0.40", ">= 0.40.0"
18
18
  gem "rubocop-on-rbs", "~> 2.0", ">= 2.0.0" # ruby >= 3.2.0
19
19
  # gem "rubocop", "~> 1.73", ">= 1.73.2" # constrained by standard
20
- gem "rubocop-packaging", "~> 0.6", ">= 0.6.0"
20
+ gem "rubocop-packaging",
21
+ github: "pboling/rubocop-packaging",
22
+ ref: "3539ba858d379740d638566faee9e56b2b854145"
21
23
  gem "standard", "~> 1.56", ">= 1.56.0"
22
24
 
23
25
  if ENV.fetch("RUBOCOP_LTS_LOCAL", "false").casecmp("false").zero?