kettle-jem 7.1.21 → 7.1.23

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: 683eb5054612a2b6b31db5e9edb84218e8f9af95a11683c873d1cc854412aa90
4
- data.tar.gz: 7533b06602be3246bde2f16435a26e67cc01ae88b05e48d24af88de67b14655a
3
+ metadata.gz: 8b44bfaa2d3dc87b533330ef926a348487a57912fcd4f5c3c75f2f39b5f3d6f0
4
+ data.tar.gz: a42faa5fb58ce8fc630dacebbd9c7cabd75641791236fb405a4471accf7e0b7b
5
5
  SHA512:
6
- metadata.gz: 764654bb020c4b4cc10c38a18c27fc8fa59a15efcf90d51f0577fdb89bb94bb82a4bfd517162c32d4ea26d1c7f1a55a1f199123e2c793329e12c1e490e4c9cf6
7
- data.tar.gz: 44d4ffb1f84faffb6172178cbb741bc97367a4da9b9d96fd9cbff41722d4cc8326dc3702a3de5834401229c2fe0080b736bfdc7666ff28b073e911b571512fbd
6
+ metadata.gz: 0f692b668c282c7657c5af5bfb3de195d996d2f9eda582b8bb55ee39ed9d31a863b66fd17b82b75925ed949092336d5e74a66539a7d4a9efd91974b0ec4c5bb3
7
+ data.tar.gz: 0f7d11313e632476917ee8b3a4afd492998d82f9bd8c8535a6e195cb5185c8caa167f5fd2ac295cb0e0f28a4d7e86443b47e054faba8488825213185d6206377
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
+ ## [7.1.23] - 2026-09-07
34
+
35
+ - TAG: [v7.1.23][7.1.23t]
36
+ - COVERAGE: 93.66% -- 11251/12013 lines in 16 files
37
+ - BRANCH COVERAGE: 77.07% -- 4789/6214 branches in 16 files
38
+ - 18.13% documented
39
+
40
+ ### Changed
41
+
42
+ - [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
43
+ - kettle-dev (>= 3.0.32 -> >= 3.0.33)
44
+
45
+ ### Fixed
46
+
47
+ - Externalize active template tooling from gemspecs, remove legacy gem-release declarations from managed Gemfiles and gemspecs, and enforce self-test divergence thresholds inclusively.
48
+
49
+ - Load Bundler before JSON in maintenance executables so Ruby 4 default JSON activation cannot conflict with the project bundle.
50
+
51
+ - Declare JSON v2 as a Kettle Jem development dependency for repository-local maintenance executables.
52
+
53
+ - Keep managed dependency reconciliation specs aligned with their declared requirements.
54
+
55
+ ## [7.1.22] - 2026-09-07
56
+
57
+ - TAG: [v7.1.22][7.1.22t]
58
+ - COVERAGE: 93.66% -- 11247/12008 lines in 16 files
59
+ - BRANCH COVERAGE: 77.06% -- 4787/6212 branches in 16 files
60
+ - 18.04% documented
61
+
62
+ ### Fixed
63
+
64
+ - Reconcile managed template-tool dependency requirements in their existing declarations before template bootstrapping, and maintain their floors with kettle-jem-deps-floor.
65
+
66
+ - Derive injected kettle-jem template requirements from VersionGem major, minor, and current version so releases cannot leave a stale self-dependency floor.
67
+
33
68
  ## [7.1.21] - 2026-09-07
34
69
 
35
70
  - TAG: [v7.1.21][7.1.21t]
@@ -1915,7 +1950,11 @@ Please file a bug if you notice a violation of semantic versioning.
1915
1950
  - Released kettle-jem as part of the initial StructuredMerge Ruby 7.0.0 gem set.
1916
1951
  - Included packaged templates and parser-backed merge support for Ruby gem templating.
1917
1952
 
1918
- [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.21...HEAD
1953
+ [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.23...HEAD
1954
+ [7.1.23]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.22...v7.1.23
1955
+ [7.1.23t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.23
1956
+ [7.1.22]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.21...v7.1.22
1957
+ [7.1.22t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.22
1919
1958
  [7.1.21]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.20...v7.1.21
1920
1959
  [7.1.21t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.21
1921
1960
  [7.1.20]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.19...v7.1.20
data/README.md CHANGED
@@ -655,6 +655,26 @@ The `kettle:jem:*` rake tasks are internal targets used by the executable after
655
655
  it prepares the templating environment; call `kettle-jem` directly for normal
656
656
  templating work.
657
657
 
658
+ ### Template Dependency Transitions
659
+
660
+ Before Bundler prepares a destination, `kettle-jem` reconciles its managed
661
+ template-tool dependencies where they are already declared: the root Gemfile,
662
+ root `*.gemfile` files, gemspecs, and modular Gemfile fragments. It updates the
663
+ complete requirement set in place; it never moves a declaration, adds a missing
664
+ dependency, or uses a local path as a compatibility fallback. A managed
665
+ dependency with non-static version requirements is rejected before Bundler runs.
666
+
667
+ The managed dependency registry is owned by `kettle-jem`. Run
668
+ `kettle-jem-deps-floor --write` to raise its requirement floors together with
669
+ the template dependency floors. The registry may declare a Ruby-version
670
+ requirement, so a bootstrap only updates dependencies active for the current
671
+ Ruby.
672
+
673
+ `kettle-jem` itself is not a dependency floor. Generated templating Gemfiles
674
+ derive its pessimistic requirement from `Kettle::Jem::Version.major` and
675
+ `.minor`, and use the running full version as the minimum. This makes a major
676
+ release emit the matching major requirement without a second version to update.
677
+
658
678
  ## 🔐 Security
659
679
 
660
680
  See [SECURITY.md][🔐security].
@@ -879,7 +899,7 @@ Thanks for RTFM. ☺️
879
899
  [📌gitmoji]: https://gitmoji.dev
880
900
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
881
901
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
882
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.937-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
902
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-12.013-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
883
903
  [🔐security]: https://github.com/structuredmerge/structuredmerge-ruby/blob/main/SECURITY.md
884
904
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
885
905
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -12,6 +12,7 @@ module Kettle
12
12
  PREPARE_ONLY_PATHS = [
13
13
  Kettle::Jem::KETTLE_CONFIG_PATH,
14
14
  "Gemfile",
15
+ "*.gemspec",
15
16
  # Gemfile evaluates these fragments immediately. Preparing only the
16
17
  # templating pair leaves a newly migrated project with references to
17
18
  # files that do not exist yet, so Bundler cannot perform the bootstrap.
@@ -36,6 +37,7 @@ module Kettle
36
37
  Kettle::Jem.apply_project(project_root, env: env, run_options: prepare_run_options)
37
38
  end
38
39
  report = merge_supplemental_prepare_report(report, supplemental_report)
40
+ transition_step = reconcile_template_managed_dependencies_step(project_root, events: events)
39
41
  nomono_bootstrap_step = normalize_existing_local_gemfile_bootstraps_step(project_root, events: events)
40
42
  setup_env = Kettle::Jem::Tasks::InstallTask.setup_command_env(project_root, env)
41
43
  setup_env["BUNDLE_DISABLE_CHECKSUM_VALIDATION"] = "true"
@@ -81,9 +83,10 @@ module Kettle
81
83
  %w[skipped succeeded].include?(reset_step.fetch(:status)) &&
82
84
  %w[skipped succeeded].include?(bundle_step.fetch(:status)),
83
85
  prepare_only: PREPARE_ONLY_PATHS,
84
- prepare_steps: [profile_sync_step, nomono_bootstrap_step, reset_step, bootstrap_step, bundle_step].compact,
86
+ prepare_steps: [profile_sync_step, transition_step, nomono_bootstrap_step, reset_step, bootstrap_step, bundle_step].compact,
85
87
  changed_files: (
86
88
  report.fetch(:changed_files, []) +
89
+ transition_step.fetch(:changed_files, []) +
87
90
  nomono_bootstrap_step.fetch(:changed_files, []) +
88
91
  reset_step.fetch(:changed_files, []) +
89
92
  bootstrap_step.fetch(:changed_files, []) +
@@ -136,6 +139,30 @@ module Kettle
136
139
  step
137
140
  end
138
141
 
142
+ def reconcile_template_managed_dependencies_step(project_root, events:)
143
+ paths = [
144
+ File.join(project_root.to_s, "Gemfile"),
145
+ *Dir.glob(File.join(project_root.to_s, "*.gemfile")),
146
+ *Dir.glob(File.join(project_root.to_s, "*.gemspec")),
147
+ *Dir.glob(File.join(project_root.to_s, "gemfiles/modular/**/*.gemfile"))
148
+ ].select { |path| File.file?(path) }.sort
149
+ changed_files = paths.filter_map do |path|
150
+ before = File.read(path)
151
+ after = Kettle::Jem.reconcile_template_managed_dependencies(before)
152
+ next if after == before
153
+
154
+ File.write(path, after)
155
+ Pathname.new(path).relative_path_from(Pathname.new(project_root.to_s)).to_s
156
+ end
157
+ step = {
158
+ name: "reconcile_template_managed_dependencies",
159
+ status: changed_files.empty? ? "already_current" : "applied",
160
+ changed_files: changed_files
161
+ }
162
+ Kettle::Jem.emit_step_event(events, "command_step", step, phase: "prepare")
163
+ step
164
+ end
165
+
139
166
  def reset_release_lockfiles_step(project_root:, setup_env:, quiet:, command_runner:, events:)
140
167
  if local_path_development_env?(setup_env)
141
168
  return {
@@ -191,7 +218,7 @@ module Kettle
191
218
  end
192
219
 
193
220
  def bundle_update_templating_bootstrap_command(project_root = Dir.pwd)
194
- %w[bundle update] + CRITICAL_TEMPLATING_GEMS + locked_templating_gems(project_root)
221
+ %w[bundle update] + managed_bootstrap_gems(project_root) + locked_templating_gems(project_root)
195
222
  end
196
223
 
197
224
  def templating_bootstrap_command(project_root = Dir.pwd)
@@ -211,12 +238,33 @@ module Kettle
211
238
  return false unless File.file?(lock_path)
212
239
 
213
240
  locked_gem_names(project_root).then do |names|
214
- CRITICAL_TEMPLATING_GEMS.all? { |gem_name| names.include?(gem_name) }
241
+ managed_bootstrap_gems(project_root).all? { |gem_name| names.include?(gem_name) }
215
242
  end
216
243
  rescue Bundler::LockfileError
217
244
  false
218
245
  end
219
246
 
247
+ def managed_bootstrap_gems(project_root)
248
+ declared = declared_managed_dependency_names(project_root)
249
+ (CRITICAL_TEMPLATING_GEMS + Kettle::Jem.template_bootstrap_dependency_names.select do |name|
250
+ declared.include?(name)
251
+ end).uniq
252
+ end
253
+
254
+ def declared_managed_dependency_names(project_root)
255
+ paths = [
256
+ File.join(project_root.to_s, "Gemfile"),
257
+ *Dir.glob(File.join(project_root.to_s, "*.gemfile")),
258
+ *Dir.glob(File.join(project_root.to_s, "*.gemspec")),
259
+ *Dir.glob(File.join(project_root.to_s, "gemfiles/modular/**/*.gemfile"))
260
+ ].select { |path| File.file?(path) }
261
+ paths.flat_map do |path|
262
+ Kettle::Jem.ruby_call_records(File.read(path), nil).filter_map do |call|
263
+ Kettle::Jem.ruby_string_argument(call) if Kettle::Jem.template_managed_dependency_call?(call)
264
+ end
265
+ end.uniq
266
+ end
267
+
220
268
  def bundle_install_after_bootstrap_step(project_root:, setup_env:, quiet:, command_runner:, events:, bootstrap_command:)
221
269
  if bootstrap_command == %w[bundle install]
222
270
  return {
@@ -79,8 +79,8 @@ module Kettle
79
79
  min_divergence_threshold: threshold,
80
80
  drift: drift
81
81
  }
82
- if threshold && divergence > threshold
83
- raise Kettle::Jem::Error, "selftest divergence #{divergence}% exceeds threshold #{threshold}%"
82
+ if threshold && divergence >= threshold
83
+ raise Kettle::Jem::Error, "selftest divergence #{divergence}% reaches or exceeds threshold #{threshold}%"
84
84
  end
85
85
  result
86
86
  end
@@ -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.32") # ruby >= {KJ|MIN_TEST_RUBY}
121
+ spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.33") # 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
@@ -18,7 +18,7 @@ end
18
18
 
19
19
  if structuredmerge_remote
20
20
  # Merge recipes for released installs.
21
- gem "kettle-jem", ">= 7.0"
21
+ gem "kettle-jem", {KJ|KETTLE_JEM_DEPENDENCY_ARGUMENTS}
22
22
  end
23
23
 
24
24
  if kettle_remote
@@ -30,7 +30,7 @@ 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.32") # ruby >= {KJ|MIN_TEST_RUBY}
33
+ spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.33") # ruby >= {KJ|MIN_TEST_RUBY}
34
34
 
35
35
  # Tasks
36
36
  spec.add_development_dependency "rake", "~> 13.0"
@@ -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.21"
8
+ VERSION = "7.1.23"
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
data/lib/kettle/jem.rb CHANGED
@@ -52,6 +52,19 @@ module Kettle
52
52
  GEMSPEC_DEPENDENCY_MINIMUM_REQUIREMENTS = {
53
53
  "rspec-stubbed_env" => ">= 1.0.6"
54
54
  }.freeze
55
+ # Template dependency transitions are location-independent. Prepare finds
56
+ # declarations in the destination and reconciles their complete requirement
57
+ # set in place before Bundler is allowed to evaluate that destination.
58
+ TEMPLATE_MANAGED_DEPENDENCIES = [
59
+ {name: "nomono", requirements: ["~> 1.1", ">= 1.1.5"], bootstrap: true},
60
+ {name: "kettle-dev", requirements: ["~> 3.0", ">= 3.0.33"], bootstrap: true},
61
+ {
62
+ name: "kettle-changelog",
63
+ requirements: ["~> 1.0", ">= 1.0.7"],
64
+ bootstrap: true,
65
+ ruby_requirement: ">= 4.0.0"
66
+ }
67
+ ].freeze
55
68
  DEFAULT_GEMSPEC_METADATA_VALUES = {
56
69
  "allowed_push_host" => "TODO: Set to your gem server 'https://example.com'"
57
70
  }.freeze
@@ -76,7 +89,13 @@ module Kettle
76
89
  ].freeze
77
90
  DEFAULT_ENGINES = %w[ruby jruby truffleruby].freeze
78
91
  DEFAULT_OPENCOLLECTIVE_ORG = "galtzo-floss"
79
- RETIRED_GEMSPEC_DEVELOPMENT_DEPENDENCIES = %w[kettle-drift kettle-soup-cover rubocop-rspec yard-junk].freeze
92
+ # These tools remain active, but their dependency ownership belongs to the
93
+ # generated modular Gemfiles rather than a destination gemspec.
94
+ EXTERNALIZED_GEMSPEC_DEVELOPMENT_DEPENDENCIES = %w[kettle-drift kettle-soup-cover rubocop-rspec yard-junk].freeze
95
+ # These legacy release tools must not be retained in any managed dependency
96
+ # declaration. Kettle Dev owns release workflows.
97
+ PROHIBITED_GEMSPEC_DEPENDENCIES = %w[gem-release].freeze
98
+ PROHIBITED_GEMFILE_DEPENDENCIES = PROHIBITED_GEMSPEC_DEPENDENCIES.freeze
80
99
  FILE_DELETION_PRIMITIVES = %w[
81
100
  supplied_obsolete_file_deletion
82
101
  supplied_opt_in_workflow_deletion
@@ -5428,7 +5447,10 @@ module Kettle
5428
5447
  end
5429
5448
 
5430
5449
  def ensure_monorepo_root_gemfile_dependencies(content)
5431
- updated = ensure_trailing_newline(content.to_s.empty? ? %(source "https://gem.coop"\n) : content.to_s).dup
5450
+ updated = reconcile_template_managed_dependencies(
5451
+ ensure_trailing_newline(content.to_s.empty? ? %(source "https://gem.coop"\n) : content.to_s).dup
5452
+ )
5453
+ updated = remove_gemfile_dependency_blocks(updated, PROHIBITED_GEMFILE_DEPENDENCIES)
5432
5454
  monorepo_root_gemfile_dependency_lines.each do |line|
5433
5455
  next if gemfile_declares_gem?(updated, line.fetch(:name))
5434
5456
 
@@ -5442,10 +5464,10 @@ module Kettle
5442
5464
  [
5443
5465
  {name: "appraisal2", source: %(gem "appraisal2", "~> 3.2", ">= 3.2.3"\n)},
5444
5466
  {name: "bundler-audit", source: %(gem "bundler-audit", "~> 0.9.3"\n)},
5445
- {name: "kettle-dev", source: %(gem "kettle-dev", "~> 3.0", ">= 3.0.32"\n)},
5467
+ {name: "kettle-dev", source: %(gem "kettle-dev", "~> 3.0", ">= 3.0.33"\n)},
5446
5468
  {name: "kettle-drift", source: %(gem "kettle-drift", "~> 1.0", ">= 1.0.13"\n)},
5447
5469
  {name: "kettle-family", source: %(gem "kettle-family", "~> 1.2", ">= 1.2.95"\n)},
5448
- {name: "kettle-jem", source: %(gem "kettle-jem", "~> 7.1", ">= 7.1.20"\n)},
5470
+ {name: PACKAGE_NAME, source: kettle_jem_dependency_source},
5449
5471
  {name: "kettle-test", source: %(gem "kettle-test", "~> 2.0", ">= 2.0.21"\n)},
5450
5472
  {name: "rake", source: %(gem "rake", "~> 13.0"\n)},
5451
5473
  {name: "rspec", source: %(gem "rspec", "~> 3.0"\n)},
@@ -5469,6 +5491,17 @@ module Kettle
5469
5491
  end
5470
5492
  end
5471
5493
 
5494
+ def kettle_jem_dependency_requirements(version_module: Version)
5495
+ require_relative "jem/version_gem" unless version_module.respond_to?(:major)
5496
+
5497
+ ["~> #{version_module.major}.#{version_module.minor}", ">= #{version_module::VERSION}"]
5498
+ end
5499
+
5500
+ def kettle_jem_dependency_source(version_module: Version)
5501
+ requirements = kettle_jem_dependency_requirements(version_module: version_module)
5502
+ %(gem #{PACKAGE_NAME.inspect}, #{requirements.map(&:inspect).join(", ")}\n)
5503
+ end
5504
+
5472
5505
  def gemspec_path_declares_gem?(path, gem_name)
5473
5506
  normalized_path = path.to_s.delete_suffix("/")
5474
5507
  normalized_path == "gems/#{gem_name}"
@@ -9349,7 +9382,7 @@ module Kettle
9349
9382
 
9350
9383
  def merge_gemfile_template_policy(content, facts:, template_content: nil, preserve_self_word_entries: false)
9351
9384
  package_name = facts.dig(:package, :name).to_s if facts
9352
- removable_gems = ["appraisal"]
9385
+ removable_gems = ["appraisal", *PROHIBITED_GEMFILE_DEPENDENCIES]
9353
9386
  removable_gems << package_name unless package_name.to_s.empty?
9354
9387
  removable_gems.concat(package_runtime_dependency_names(facts))
9355
9388
  removable_gems << "version_gem" unless version_gem_enabled?(facts)
@@ -9889,6 +9922,76 @@ module Kettle
9889
9922
  end
9890
9923
  end
9891
9924
 
9925
+ def template_managed_dependency(name)
9926
+ TEMPLATE_MANAGED_DEPENDENCIES.find { |dependency| dependency.fetch(:name) == name.to_s }
9927
+ end
9928
+
9929
+ def template_managed_dependency_requirements(name, version_module: Version)
9930
+ return kettle_jem_dependency_requirements(version_module: version_module) if name.to_s == PACKAGE_NAME
9931
+
9932
+ template_managed_dependency(name)&.fetch(:requirements)
9933
+ end
9934
+
9935
+ def template_managed_dependency_names(bootstrap: nil, ruby_version: RUBY_VERSION)
9936
+ TEMPLATE_MANAGED_DEPENDENCIES.filter_map do |dependency|
9937
+ next if !bootstrap.nil? && dependency.fetch(:bootstrap) != bootstrap
9938
+ next unless template_managed_dependency_active?(dependency, ruby_version)
9939
+
9940
+ dependency.fetch(:name)
9941
+ end
9942
+ end
9943
+
9944
+ def template_bootstrap_dependency_names(ruby_version: RUBY_VERSION)
9945
+ ([PACKAGE_NAME] + template_managed_dependency_names(bootstrap: true, ruby_version: ruby_version)).uniq
9946
+ end
9947
+
9948
+ def template_managed_dependency_active?(dependency, ruby_version = RUBY_VERSION)
9949
+ requirement = dependency[:ruby_requirement]
9950
+ return true unless requirement
9951
+
9952
+ Gem::Requirement.new(requirement).satisfied_by?(Gem::Version.new(ruby_version))
9953
+ end
9954
+
9955
+ def reconcile_template_managed_dependencies(source)
9956
+ replacements = ruby_call_records(source, nil).filter_map do |call|
9957
+ next unless template_managed_dependency_call?(call)
9958
+
9959
+ name = ruby_string_argument(call)
9960
+ requirements = template_managed_dependency_requirements(name)
9961
+ next unless requirements
9962
+
9963
+ requirement_nodes = Array(call.arguments&.arguments).drop(1).reject do |argument|
9964
+ argument.is_a?(::Prism::KeywordHashNode)
9965
+ end
9966
+ if requirement_nodes.empty?
9967
+ raise Error, "Managed template dependency #{name} must use static version requirements"
9968
+ end
9969
+ requirement_nodes.each do |argument|
9970
+ value = ruby_static_string_value(argument)
9971
+ next if value && Gem::Requirement::OPS.keys.any? { |operator| value.start_with?(operator) }
9972
+
9973
+ raise Error, "Managed template dependency #{name} must use static version requirements"
9974
+ end
9975
+
9976
+ expected = requirements
9977
+ current = requirement_nodes.map { |argument| ruby_static_string_value(argument) }
9978
+ next if current == expected
9979
+
9980
+ {
9981
+ start_offset: requirement_nodes.first.location.start_offset,
9982
+ end_offset: requirement_nodes.last.location.end_offset,
9983
+ replacement: expected.map { |requirement| JSON.generate(requirement) }.join(", ")
9984
+ }
9985
+ end
9986
+ replace_source_offsets(source, replacements)
9987
+ end
9988
+
9989
+ def template_managed_dependency_call?(call)
9990
+ return call.receiver.nil? && call.name == :gem if call.name == :gem
9991
+
9992
+ %i[add_dependency add_runtime_dependency add_development_dependency].include?(call.name)
9993
+ end
9994
+
9892
9995
  def ruby_keyword_string_argument(call, key)
9893
9996
  keyword_hash = Array(call&.arguments&.arguments).find { |argument| argument.is_a?(::Prism::KeywordHashNode) }
9894
9997
  assoc = keyword_hash&.elements&.find do |element|
@@ -10590,6 +10693,11 @@ module Kettle
10590
10693
  template_declares_version_gem: gemspec_dependency_names(template_content).include?("version_gem")
10591
10694
  )
10592
10695
  merged = remove_gemspec_version_gem_dependency_when_non_default_entrypoint(merged, facts, receiver: template_receiver)
10696
+ merged = remove_gemspec_dependency_lines(
10697
+ merged,
10698
+ receiver: template_receiver,
10699
+ names: PROHIBITED_GEMSPEC_DEPENDENCIES
10700
+ )
10593
10701
  # Yard owns the documentation dependency graph. A direct gemspec rdoc
10594
10702
  # development dependency creates an unnecessary second owner and can
10595
10703
  # conflict with the documentation modular Gemfile.
@@ -11727,7 +11835,7 @@ module Kettle
11727
11835
  enforce_gemspec_dependency_minimum_requirements(normalized, receiver: template_receiver)
11728
11836
  end
11729
11837
  destination_dependencies = destination_dependencies.reject do |key, _source|
11730
- retired_gemspec_development_dependency_key?(key)
11838
+ excluded_gemspec_dependency_key?(key)
11731
11839
  end
11732
11840
  return template_content if destination_dependencies.empty?
11733
11841
 
@@ -12127,9 +12235,11 @@ module Kettle
12127
12235
  [record.fetch(:kind), record.fetch(:name)]
12128
12236
  end
12129
12237
 
12130
- def retired_gemspec_development_dependency_key?(key)
12238
+ def excluded_gemspec_dependency_key?(key)
12239
+ return true if PROHIBITED_GEMSPEC_DEPENDENCIES.include?(key.last)
12240
+
12131
12241
  key.first == "add_development_dependency" &&
12132
- RETIRED_GEMSPEC_DEVELOPMENT_DEPENDENCIES.include?(key.last)
12242
+ EXTERNALIZED_GEMSPEC_DEVELOPMENT_DEPENDENCIES.include?(key.last)
12133
12243
  end
12134
12244
 
12135
12245
  def gemspec_dependency_source_newer?(candidate_source, current_source, receiver:)
@@ -14341,7 +14451,7 @@ module Kettle
14341
14451
  root: ["src", "my", "kettle-dev"]
14342
14452
  )
14343
14453
  elsif Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("4.0.0")
14344
- gem "kettle-changelog", "~> 1.0", ">= 1.0.7"
14454
+ gem "kettle-changelog", #{template_managed_dependency("kettle-changelog").fetch(:requirements).map(&:inspect).join(", ")}
14345
14455
  end
14346
14456
  end
14347
14457
  RUBY
@@ -15035,6 +15145,7 @@ module Kettle
15035
15145
  compact_hash(
15036
15146
  freeze_token: config.dig("defaults", "freeze_token").to_s.empty? ? "kettle-jem" : config.dig("defaults", "freeze_token").to_s,
15037
15147
  kettle_jem_version: VERSION,
15148
+ kettle_jem_dependency_arguments: kettle_jem_dependency_requirements.map(&:inspect).join(", "),
15038
15149
  template_run_date: run_timestamp.strftime("%Y-%m-%d"),
15039
15150
  template_run_year: run_timestamp.year.to_s,
15040
15151
  kettle_dev_local_gems: kettle_dev_local_gems(config),
@@ -15358,6 +15469,7 @@ module Kettle
15358
15469
  {
15359
15470
  "KJ|FREEZE_TOKEN" => project_runtime[:freeze_token].to_s,
15360
15471
  "KJ|KETTLE_JEM_VERSION" => project_runtime[:kettle_jem_version].to_s,
15472
+ "KJ|KETTLE_JEM_DEPENDENCY_ARGUMENTS" => project_runtime[:kettle_jem_dependency_arguments].to_s,
15361
15473
  "KJ|TEMPLATE_RUN_DATE" => project_runtime[:template_run_date].to_s,
15362
15474
  "KJ|TEMPLATE_RUN_YEAR" => project_runtime[:template_run_year].to_s,
15363
15475
  "KJ|KETTLE_DEV_LOCAL_GEMS" => project_runtime[:kettle_dev_local_gems].to_s,
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kettle-jem
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.21
4
+ version: 7.1.23
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -593,6 +593,26 @@ dependencies:
593
593
  - - "~>"
594
594
  - !ruby/object:Gem::Version
595
595
  version: 0.9.3
596
+ - !ruby/object:Gem::Dependency
597
+ name: json
598
+ requirement: !ruby/object:Gem::Requirement
599
+ requirements:
600
+ - - "~>"
601
+ - !ruby/object:Gem::Version
602
+ version: '2.0'
603
+ - - ">="
604
+ - !ruby/object:Gem::Version
605
+ version: 2.21.2
606
+ type: :development
607
+ prerelease: false
608
+ version_requirements: !ruby/object:Gem::Requirement
609
+ requirements:
610
+ - - "~>"
611
+ - !ruby/object:Gem::Version
612
+ version: '2.0'
613
+ - - ">="
614
+ - !ruby/object:Gem::Version
615
+ version: 2.21.2
596
616
  - !ruby/object:Gem::Dependency
597
617
  name: rake
598
618
  requirement: !ruby/object:Gem::Requirement
@@ -976,10 +996,10 @@ licenses:
976
996
  - PolyForm-Small-Business-1.0.0
977
997
  metadata:
978
998
  homepage_uri: https://structuredmerge.org
979
- source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.21
980
- changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.21/CHANGELOG.md
999
+ source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.23
1000
+ changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.23/CHANGELOG.md
981
1001
  bug_tracker_uri: https://github.com/structuredmerge/structuredmerge-ruby/issues
982
- documentation_uri: https://www.rubydoc.info/gems/kettle-jem/7.1.21
1002
+ documentation_uri: https://www.rubydoc.info/gems/kettle-jem/7.1.23
983
1003
  funding_uri: https://github.com/sponsors/pboling
984
1004
  wiki_uri: https://github.com/structuredmerge/structuredmerge-ruby/wiki
985
1005
  news_uri: https://www.railsbling.com/tags/kettle-jem
metadata.gz.sig CHANGED
Binary file