kettle-family 1.2.1 → 1.2.3

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: 32b1ff960e0e144e10aecb3030c729660728827d69923dd054d923f8e58e8022
4
- data.tar.gz: fe44fdcc8270d30c80294ed13464e5289b2182612e9af2d252137d4f08260cb3
3
+ metadata.gz: b45c2fb44c1bf149f0a2f9cfd25f9c3ff66223a7d83b1afd29a2ca3e34d899e2
4
+ data.tar.gz: 8b1ec3ef54ac02e16cbd93ede3412d411fd72bd33b69e99885d98152846a724a
5
5
  SHA512:
6
- metadata.gz: 32b3a41cab5ad9c73ff7ddbea85871fb2ee111db1cc1b2b0af20672b49cd2c29ef0ba8c14e5c1eb9ff07d296f8b3ada17f07236bbca829aa233eed7586396ac5
7
- data.tar.gz: eb3c14717ad2c6715653c9749931b3403cc41740ec0b5cb25f7b359febce2d7652e2cd8f2ad793dcf80d5c24ae5d2c3d0765d21113a1648c8377c5a4ea07305b
6
+ metadata.gz: 18ce32a11fcbb38cbeb32476699256a68e51b45786d91aa1eeb173fb1f2d9ffb9b7fce4009aac9d68e51c6ebadd973d5d63942deede6d939800ea80a0870f9a1
7
+ data.tar.gz: 3671daa647afe8e2d93c386793a74b64ed0f43984ed580760c5899706c4516d633fe0a47960810e0082f21147fbe27a1129aa27dd7bb0c77ef5378007e05c3b1
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,41 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [1.2.3] - 2026-07-28
34
+
35
+ - TAG: [v1.2.3][1.2.3t]
36
+ - COVERAGE: 93.83% -- 3617/3855 lines in 27 files
37
+ - BRANCH COVERAGE: 76.18% -- 1369/1797 branches in 27 files
38
+ - 28.01% documented
39
+
40
+ ### Fixed
41
+
42
+ - `kettle-family template` now removes Bundler-reported stale CHECKSUMS entries
43
+ and retries pre-template lockfile normalization, allowing templating to
44
+ recover from local pre-release checksum drift.
45
+ - `kettle-family template` now includes locked template bootstrap gems such as
46
+ `nomono` and `kettle-dev` in pre-template lockfile normalization so legacy
47
+ members can boot current `kettle-jem` preparation before their generated
48
+ templating gemfiles have been refreshed.
49
+ - `kettle-family template` now uses `bundle install` for pre-template lockfile
50
+ preparation when a member has no `Gemfile.lock`, instead of running a
51
+ `bundle update` command before the bundle exists.
52
+
53
+ ## [1.2.2] - 2026-07-28
54
+
55
+ - TAG: [v1.2.2][1.2.2t]
56
+ - COVERAGE: 93.87% -- 3569/3802 lines in 27 files
57
+ - BRANCH COVERAGE: 76.29% -- 1345/1763 branches in 27 files
58
+ - 28.10% documented
59
+
60
+ ### Fixed
61
+
62
+ - `kettle-family template` now runs the `kettle-jem prepare` phase through the
63
+ same member bundle shape as `kettle-jem install`, so local template-stack
64
+ overrides are honored during preparation.
65
+ - Failed template preparation event streams are now summarized instead of being
66
+ dumped raw into the final text report.
67
+
33
68
  ## [1.2.1] - 2026-07-28
34
69
 
35
70
  - TAG: [v1.2.1][1.2.1t]
@@ -1176,7 +1211,11 @@ Please file a bug if you notice a violation of semantic versioning.
1176
1211
  - Fixed CI load failures on engines without compatible `pty` support by falling back to Open3 for interactive release commands.
1177
1212
  - Fixed Ruby 3.2 version-bump support by loading Prism lazily and wiring the Prism gem only for MRI versions that need it.
1178
1213
 
1179
- [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.2.1...HEAD
1214
+ [Unreleased]: https://github.com/kettle-dev/kettle-family/compare/v1.2.3...HEAD
1215
+ [1.2.3]: https://github.com/kettle-dev/kettle-family/compare/v1.2.2...v1.2.3
1216
+ [1.2.3t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.2.3
1217
+ [1.2.2]: https://github.com/kettle-dev/kettle-family/compare/v1.2.1...v1.2.2
1218
+ [1.2.2t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.2.2
1180
1219
  [1.2.1]: https://github.com/kettle-dev/kettle-family/compare/v1.2.0...v1.2.1
1181
1220
  [1.2.1t]: https://github.com/kettle-dev/kettle-family/releases/tag/v1.2.1
1182
1221
  [1.2.0]: https://github.com/kettle-dev/kettle-family/compare/v1.1.9...v1.2.0
data/README.md CHANGED
@@ -813,7 +813,7 @@ Thanks for RTFM. ☺️
813
813
  [📌gitmoji]: https://gitmoji.dev
814
814
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
815
815
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
816
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-3.794-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
816
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-3.855-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
817
817
  [🔐security]: https://github.com/kettle-dev/kettle-family/blob/main/SECURITY.md
818
818
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
819
819
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -193,7 +193,7 @@ module Kettle
193
193
  end
194
194
 
195
195
  def template_event_stdout?(result)
196
- command == "template" && result.phase == "template" && template_events(result.stdout).any?
196
+ command == "template" && template_events(result.stdout).any?
197
197
  end
198
198
 
199
199
  def release_event_stdout?(result)
@@ -5,7 +5,7 @@ module Kettle
5
5
  # Version namespace for this gem.
6
6
  module Version
7
7
  # Current gem version.
8
- VERSION = "1.2.1"
8
+ VERSION = "1.2.3"
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
@@ -53,6 +53,7 @@ module Kettle
53
53
  ],
54
54
  "bupb" => %w[bundle update --bundler]
55
55
  }.freeze
56
+ PRE_TEMPLATE_BOOTSTRAP_GEMS = %w[nomono kettle-dev].freeze
56
57
  GIT_SYNC_COMMANDS = {
57
58
  "push" => [["push", %w[git push]]],
58
59
  "pull" => [["pull", %w[git pull --rebase]]],
@@ -1305,11 +1306,24 @@ module Kettle
1305
1306
  end
1306
1307
 
1307
1308
  def template_prepare_command(member)
1308
- command_text = "kettle-jem prepare"
1309
+ command_text = template_prepare_command_from(config.template_command || default_template_command(member))
1309
1310
  command_text = append_template_family_args(command_text)
1310
1311
  append_template_skip_commit(command_text)
1311
1312
  end
1312
1313
 
1314
+ def template_prepare_command_from(command_text)
1315
+ if command_text.is_a?(Array)
1316
+ argv = command_text.map(&:to_s)
1317
+ index = argv.index("install")
1318
+ return argv unless index
1319
+
1320
+ argv[index] = "prepare"
1321
+ argv
1322
+ else
1323
+ command_text.to_s.sub(/\bkettle-jem\s+install\b/, "kettle-jem prepare")
1324
+ end
1325
+ end
1326
+
1313
1327
  def append_template_skip_commit(command_text)
1314
1328
  return command_text if commit
1315
1329
  return command_text if command_text.is_a?(Array) && command_text.include?("--skip-commit")
@@ -1718,12 +1732,102 @@ module Kettle
1718
1732
  result = runner.call(
1719
1733
  member: member,
1720
1734
  phase: phase,
1721
- command: config.normalize_lockfiles_command,
1735
+ command: normalize_lockfiles_command(member: member, phase: phase),
1722
1736
  env: workflow_env
1723
1737
  )
1738
+ if template_prepare_lockfiles_phase?(phase) && repair_checksum_mismatches(member, result)
1739
+ result = runner.call(
1740
+ member: member,
1741
+ phase: phase,
1742
+ command: normalize_lockfiles_command(member: member, phase: phase),
1743
+ env: workflow_env
1744
+ )
1745
+ end
1724
1746
  memo << result
1725
1747
  end
1726
1748
 
1749
+ def normalize_lockfiles_command(member:, phase:)
1750
+ configured = config.normalize_lockfiles_command
1751
+ return configured unless template_prepare_lockfiles_phase?(phase)
1752
+ return %w[bundle install] if bundle_update_command?(configured) && !File.file?(File.join(member.root, "Gemfile.lock"))
1753
+
1754
+ PRE_TEMPLATE_BOOTSTRAP_GEMS.select { |gem_name| member_lockfile_contains_gem?(member, gem_name) }.reduce(configured) do |command_text, gem_name|
1755
+ append_command_arg(command_text, gem_name)
1756
+ end
1757
+ end
1758
+
1759
+ def bundle_update_command?(command_text)
1760
+ argv = command_text.is_a?(Array) ? command_text.map(&:to_s) : Shellwords.split(command_text.to_s)
1761
+ bundle_index = argv.index("bundle")
1762
+ bundle_index && argv[bundle_index + 1] == "update"
1763
+ rescue ArgumentError
1764
+ false
1765
+ end
1766
+
1767
+ def append_command_arg(command_text, arg)
1768
+ return command_text if normalize_command_includes_arg?(command_text, arg)
1769
+
1770
+ argv = command_text.is_a?(Array) ? command_text.map(&:to_s) : Shellwords.split(command_text.to_s)
1771
+ update_index = argv.index("update")
1772
+ if update_index
1773
+ option_index = argv[(update_index + 1)..]&.index { |token| token.start_with?("-") }
1774
+ insert_index = option_index ? update_index + 1 + option_index : argv.length
1775
+ argv.insert(insert_index, arg)
1776
+ else
1777
+ argv << arg
1778
+ end
1779
+ return argv if command_text.is_a?(Array)
1780
+
1781
+ argv.shelljoin
1782
+ rescue ArgumentError
1783
+ "#{command_text} #{Shellwords.escape(arg)}"
1784
+ end
1785
+
1786
+ def normalize_command_includes_arg?(command_text, arg)
1787
+ argv = if command_text.is_a?(Array)
1788
+ command_text.map(&:to_s)
1789
+ else
1790
+ Shellwords.split(command_text.to_s)
1791
+ end
1792
+ argv.include?(arg)
1793
+ rescue ArgumentError
1794
+ false
1795
+ end
1796
+
1797
+ def member_lockfile_contains_gem?(member, gem_name)
1798
+ lockfile = File.join(member.root, "Gemfile.lock")
1799
+ return false unless File.file?(lockfile)
1800
+
1801
+ File.readlines(lockfile).any? { |line| line.match?(/\A #{Regexp.escape(gem_name)} \(/) }
1802
+ end
1803
+
1804
+ def template_prepare_lockfiles_phase?(phase)
1805
+ command == "template" && phase == "prepare_lockfiles"
1806
+ end
1807
+
1808
+ def repair_checksum_mismatches(member, result)
1809
+ return false unless execute
1810
+ return false if result.ok?
1811
+
1812
+ line_numbers = checksum_mismatch_lockfile_lines(result.stderr)
1813
+ return false if line_numbers.empty?
1814
+
1815
+ lockfile = File.join(member.root, "Gemfile.lock")
1816
+ return false unless File.file?(lockfile)
1817
+
1818
+ lines = File.readlines(lockfile)
1819
+ line_numbers.sort.reverse_each do |line_number|
1820
+ index = line_number - 1
1821
+ lines.delete_at(index) if index >= 0 && index < lines.length
1822
+ end
1823
+ File.write(lockfile, lines.join)
1824
+ true
1825
+ end
1826
+
1827
+ def checksum_mismatch_lockfile_lines(output)
1828
+ output.to_s.scan(/from the lockfile CHECKSUMS at Gemfile\.lock:(\d+):\d+/).flatten.map(&:to_i).uniq
1829
+ end
1830
+
1727
1831
  def prepare_template_dependencies(member:, runner:, memo:)
1728
1832
  command_text = config.template_command || default_template_command(member)
1729
1833
  return true unless kettle_jem_template_command?(command_text)
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kettle-family
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -341,10 +341,10 @@ licenses:
341
341
  - AGPL-3.0-only
342
342
  metadata:
343
343
  homepage_uri: https://kettle-family.galtzo.com
344
- source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.2.1
345
- changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.2.1/CHANGELOG.md
344
+ source_code_uri: https://github.com/kettle-dev/kettle-family/tree/v1.2.3
345
+ changelog_uri: https://github.com/kettle-dev/kettle-family/blob/v1.2.3/CHANGELOG.md
346
346
  bug_tracker_uri: https://github.com/kettle-dev/kettle-family/issues
347
- documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.2.1
347
+ documentation_uri: https://www.rubydoc.info/gems/kettle-family/1.2.3
348
348
  funding_uri: https://github.com/sponsors/pboling
349
349
  wiki_uri: https://github.com/kettle-dev/kettle-family/wiki
350
350
  news_uri: https://www.railsbling.com/tags/kettle-family
metadata.gz.sig CHANGED
Binary file