kettle-jem 7.1.12 → 7.1.14

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: b6e0de622cce8cbeac62c66ab84c8af4299d5f4a045269ac1a8d81f7adf22fb6
4
- data.tar.gz: c10ba7dd6cc3735001d2bb4497ee74cdeeb51bf28deba4f8ed1b5fbb437bfd84
3
+ metadata.gz: e2de3a21e9a9d1fe0ca969b14a89f4345b7ed4fbc327e6f7564eec589876a627
4
+ data.tar.gz: 8347a7586bfe4c4639225f2d0a0e00b196248daa7a6545d9bb7121a5a59b8338
5
5
  SHA512:
6
- metadata.gz: 57beaa915a2392c3aa5b6223d39fb77deb3e01c2107e480f907c569b682973b9fe9fcceb86c6d118658487c26d139d6d8b44b87f264a74ee3ebdc5ab342246da
7
- data.tar.gz: ab9ede849c6d36a1a860ab4a984a45d31869b973796993d6becec68847a818f2f71fd1173ccb22a30045a551ec0f947c37b32623cc97dd3aa2196f2addba2f39
6
+ metadata.gz: dcb29f595007a3416794c42d1c446e5308178409c6ab44aada85c19b723df8aec0ffb9cb66d4836ebaad82f5af73715a525212aea853ffa01a23582da00e7a7d
7
+ data.tar.gz: 498ba447eec84b3a1138b7440ecfe9fa0c7c609553e86227ccd511a352d1d959fce678752cc1f8a4d196d4551065741537576775f72b9df75d53eba11dc5cfea
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,66 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [7.1.14] - 2026-09-01
34
+
35
+ - TAG: [v7.1.14][7.1.14t]
36
+ - COVERAGE: 93.61% -- 11130/11890 lines in 16 files
37
+ - BRANCH COVERAGE: 76.95% -- 4740/6160 branches in 16 files
38
+ - 17.95% documented
39
+
40
+ ### Changed
41
+
42
+ - [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
43
+ - kettle-dev (>= 3.0.24 -> >= 3.0.27)
44
+ - kettle-family (>= 1.2.74 -> >= 1.2.77)
45
+
46
+ - [kc] kettle-jem/template: updated 398 project files:
47
+ - code and tests (20)
48
+ - configuration (12)
49
+ - dependencies (147)
50
+ - documentation (9)
51
+ - other (123)
52
+ - workflows (87)
53
+
54
+ - [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
55
+ - kettle-family (>= 1.2.77 -> >= 1.2.79)
56
+
57
+ ### Fixed
58
+
59
+ - Preserve destination .gitignore rules while adding template ignore rules, retain SSH GitHub sources, and keep Bundler lockfile checksums during template normalization.
60
+
61
+ - Preserve class namespaces and matching RBS declarations when templating version_gem package wrappers.
62
+
63
+ ## [7.1.13] - 2026-08-31
64
+
65
+ - TAG: [v7.1.13][7.1.13t]
66
+ - COVERAGE: 93.62% -- 11103/11860 lines in 16 files
67
+ - BRANCH COVERAGE: 76.97% -- 4728/6143 branches in 16 files
68
+ - 17.96% documented
69
+
70
+ ### Changed
71
+
72
+ - [kc] kettle-jem/template: updated 796 project files:
73
+ - code and tests (40)
74
+ - configuration (24)
75
+ - dependencies (294)
76
+ - documentation (18)
77
+ - other (246)
78
+ - workflows (174)
79
+
80
+ - [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
81
+ - kettle-family (>= 1.2.65 -> >= 1.2.74)
82
+
83
+ ### Fixed
84
+
85
+ - Preserve existing lockfile platforms and add the local host platform during template lockfile normalization.
86
+
87
+ - Preserve locked dependencies while adding the local host platform to template-normalized lockfiles.
88
+
89
+ - Preserved configured per-engine CI commands across workflow template updates.
90
+
91
+ - Invalidate workflow template checksums when a configured per-engine command changes.
92
+
33
93
  ## [7.1.12] - 2026-08-30
34
94
 
35
95
  - TAG: [v7.1.12][7.1.12t]
@@ -1716,7 +1776,11 @@ Please file a bug if you notice a violation of semantic versioning.
1716
1776
  - Released kettle-jem as part of the initial StructuredMerge Ruby 7.0.0 gem set.
1717
1777
  - Included packaged templates and parser-backed merge support for Ruby gem templating.
1718
1778
 
1719
- [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.12...HEAD
1779
+ [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.14...HEAD
1780
+ [7.1.14]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.13...v7.1.14
1781
+ [7.1.14t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.14
1782
+ [7.1.13]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.12...v7.1.13
1783
+ [7.1.13t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.13
1720
1784
  [7.1.12]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.11...v7.1.12
1721
1785
  [7.1.12t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.12
1722
1786
  [7.1.11]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.10...v7.1.11
data/README.md CHANGED
@@ -278,6 +278,21 @@ Neither `appraisal_matrix` nor `framework_matrix` implicitly changes the root
278
278
  local development bundle. Pair either policy with `test_bundle` when the
279
279
  default local test command needs a specific framework or harness.
280
280
 
281
+ ### Per-Engine Workflow Commands
282
+
283
+ Generated workflows use `workflows.exec_cmd` by default. When a legacy engine
284
+ needs a narrower test command but should still receive the normal generated
285
+ workflow maintenance, configure `workflows.engine_exec_cmds` with the exact
286
+ matrix `ruby` value. The override changes only that matrix entry's `exec_cmd`;
287
+ setup, retry, cache, and pin behavior remains template-managed.
288
+
289
+ ```yaml
290
+ workflows:
291
+ exec_cmd: kettle-test --example-status-log .rspec_status
292
+ engine_exec_cmds:
293
+ truffleruby-22.3: kettle-test --tag ~type:acceptance --example-status-log .rspec_status
294
+ ```
295
+
281
296
  ### Default Local Test Bundle
282
297
 
283
298
  The root `Gemfile` is the default bundle for local commands such as
@@ -864,7 +879,7 @@ Thanks for RTFM. ☺️
864
879
  [📌gitmoji]: https://gitmoji.dev
865
880
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
866
881
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
867
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.776-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
882
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.890-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
868
883
  [🔐security]: https://github.com/structuredmerge/structuredmerge-ruby/blob/main/SECURITY.md
869
884
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
870
885
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -47,6 +47,7 @@ module Kettle
47
47
  install_steps.concat(run_bundle_setup_commands(project_root, env: setup_env, run_options: effective_run_options, command_runner: command_runner))
48
48
  install_steps << appraisal_generate_step(project_root, env: setup_env, run_options: effective_run_options)
49
49
  install_steps << rubocop_gradual_autocorrect_step(project_root, env: setup_env, run_options: effective_run_options)
50
+ install_steps << normalize_lockfile_platforms_step(project_root, env: setup_env, run_options: effective_run_options)
50
51
  install_steps << normalize_lockfile_step(project_root, env: setup_env, run_options: effective_run_options)
51
52
  install_steps << bundled_handoff_step(project_root: project_root, env: env, run_options: effective_run_options)
52
53
  install_steps = execute_orchestration_steps(install_steps, project_root: project_root, env: setup_env, run_options: effective_run_options, command_runner: command_runner)
@@ -738,15 +739,64 @@ module Kettle
738
739
 
739
740
  {
740
741
  name: "bundle_lock_normalization",
741
- command: lockfile_normalization_command,
742
+ command: lockfile_normalization_command(project_root),
742
743
  status: "ready",
743
744
  env: normal_lockfile_env(project_root, env),
744
- reason: "bundle_update_without_templating_overrides"
745
+ reason: "bundle_lock_update_preserving_platforms_without_templating_overrides"
745
746
  }
746
747
  end
747
748
 
748
- def lockfile_normalization_command
749
- %w[bundle update]
749
+ def normalize_lockfile_platforms_step(project_root, env:, run_options: {})
750
+ return skipped_lockfile_normalization_step("lockfile_platform_normalization", "skip_lock_normalization") if Kettle::Jem::DecisionPolicy.value_to_boolean((run_options || {})[:skip_lock_normalization])
751
+ return skipped_lockfile_normalization_step("lockfile_platform_normalization", "local_path_development_env") if local_path_development_env?(env)
752
+ return skipped_lockfile_normalization_step("lockfile_platform_normalization", "missing_Gemfile.lock") unless File.file?(File.join(project_root.to_s, "Gemfile.lock"))
753
+
754
+ {
755
+ name: "lockfile_platform_normalization",
756
+ status: "ready",
757
+ reason: "preserve_locked_dependencies_and_add_local_platform"
758
+ }
759
+ end
760
+
761
+ def normalize_lockfile_platforms(project_root)
762
+ lock_path = File.join(project_root.to_s, "Gemfile.lock")
763
+ contents = Bundler.read_file(lock_path)
764
+ platforms = (Bundler::LockfileParser.new(contents).platforms.map(&:to_s) + [Gem::Platform.local.to_s]).reject(&:empty?).uniq.sort
765
+ lines = contents.lines
766
+ platforms_index = lines.index { |line| line == "PLATFORMS\n" }
767
+ raise Bundler::LockfileError, "Gemfile.lock does not contain a PLATFORMS section" unless platforms_index
768
+
769
+ next_section_index = lines.each_index.find do |index|
770
+ index > platforms_index && !lines[index].start_with?(" ") && lines[index] != "\n"
771
+ end
772
+ raise Bundler::LockfileError, "Gemfile.lock PLATFORMS section has no following section" unless next_section_index
773
+
774
+ normalized_section = ["PLATFORMS\n", *platforms.map { |platform| " #{platform}\n" }, "\n"]
775
+ return {changed: false, platforms: platforms} if lines[platforms_index...next_section_index] == normalized_section
776
+
777
+ # Bundler exposes a parser but no public platform-only writer. Keep the
778
+ # locked dependency graph byte-for-byte intact while rewriting this
779
+ # validated, line-oriented section.
780
+ lines[platforms_index...next_section_index] = normalized_section
781
+ File.write(lock_path, lines.join)
782
+ {changed: true, platforms: platforms}
783
+ end
784
+
785
+ def skipped_lockfile_normalization_step(name, reason)
786
+ {name: name, status: "skipped", reason: reason}
787
+ end
788
+
789
+ def lockfile_normalization_command(project_root)
790
+ platforms = lockfile_normalization_platforms(project_root)
791
+ ["bundle", "lock", *platforms.map { |platform| "--add-platform=#{platform}" }, "--update", "--add-checksums"]
792
+ end
793
+
794
+ def lockfile_normalization_platforms(project_root)
795
+ lock_path = File.join(project_root.to_s, "Gemfile.lock")
796
+ existing = Bundler::LockfileParser.new(Bundler.read_file(lock_path)).platforms.map(&:to_s)
797
+ (existing + [Gem::Platform.local.to_s]).reject(&:empty?).uniq.sort
798
+ rescue Bundler::LockfileError, Errno::ENOENT
799
+ [Gem::Platform.local.to_s]
750
800
  end
751
801
 
752
802
  def distinct_bundle_install_step(project_root, env:, setup_env:)
@@ -1152,6 +1202,8 @@ module Kettle
1152
1202
  execute_ready_command_step(step, project_root: project_root, env: env, quiet: quiet, command_runner: command_runner)
1153
1203
  when "bundle_lock_normalization"
1154
1204
  execute_ready_command_step(step, project_root: project_root, env: env, quiet: quiet, command_runner: command_runner)
1205
+ when "lockfile_platform_normalization"
1206
+ execute_lockfile_platform_normalization_step(step, project_root: project_root)
1155
1207
  when "rubocop_lts_local_branch"
1156
1208
  execute_ready_command_step(step, project_root: project_root, env: env, quiet: quiet, command_runner: command_runner)
1157
1209
  when "bundle_install_requested_env"
@@ -1174,6 +1226,19 @@ module Kettle
1174
1226
  end
1175
1227
  end
1176
1228
 
1229
+ def execute_lockfile_platform_normalization_step(step, project_root:)
1230
+ return step unless step.fetch(:status) == "ready"
1231
+
1232
+ result = normalize_lockfile_platforms(project_root)
1233
+ step.merge(
1234
+ status: "succeeded",
1235
+ reason: result.fetch(:changed) ? "local_platform_added" : "local_platform_already_present",
1236
+ platforms: result.fetch(:platforms)
1237
+ )
1238
+ rescue Bundler::LockfileError, Errno::ENOENT => error
1239
+ step.merge(status: "failed", reason: "lockfile_platform_normalization_failed", stderr: error.message)
1240
+ end
1241
+
1177
1242
  def setup_command_env(project_root, env)
1178
1243
  command_env = (env || {}).to_h.dup
1179
1244
  templating_requested = command_env.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero?
@@ -23,9 +23,10 @@ module Kettle
23
23
  setup_env = Kettle::Jem::Tasks::InstallTask.setup_command_env(project_root, env)
24
24
  hook_step = Kettle::Jem::Tasks::InstallTask.hook_templates_step(project_root, effective_run_options)
25
25
  git_drivers_step = Kettle::Jem::Tasks::InstallTask.git_drivers_step(project_root, effective_run_options)
26
+ platform_step = Kettle::Jem::Tasks::InstallTask.normalize_lockfile_platforms_step(project_root, env: setup_env, run_options: effective_run_options)
26
27
  lock_step = Kettle::Jem::Tasks::InstallTask.normalize_lockfile_step(project_root, env: setup_env, run_options: effective_run_options)
27
28
  template_steps = Kettle::Jem::Tasks::InstallTask.execute_orchestration_steps(
28
- [hook_step, git_drivers_step, lock_step],
29
+ [hook_step, git_drivers_step, platform_step, lock_step],
29
30
  project_root: project_root,
30
31
  env: setup_env,
31
32
  run_options: effective_run_options,
@@ -8,6 +8,7 @@
8
8
 
9
9
  source "https://gem.coop"
10
10
 
11
+ git_source(:github) { |repo_name| "git@github.com:#{repo_name}.git" }
11
12
  git_source(:codeberg) { |repo_name| "https://codeberg.org/#{repo_name}" }
12
13
  git_source(:gitlab) { |repo_name| "https://gitlab.com/#{repo_name}" }
13
14
 
@@ -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.18") # ruby >= {KJ|MIN_TEST_RUBY}
121
+ spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.27") # 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
@@ -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.18") # ruby >= {KJ|MIN_TEST_RUBY}
33
+ spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.27") # 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.12"
8
+ VERSION = "7.1.14"
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
@@ -102,6 +102,24 @@ module Kettle
102
102
  ].freeze
103
103
  PACKAGED_TEMPLATE_ROOT = File.expand_path("jem/templates", __dir__)
104
104
  TRANSFER_CHANGELOG_TEMPLATE_PATH = "CHANGELOG.transfer.md"
105
+ TRANSFER_CHANGELOG_FILTER_FIELD_TYPES = {
106
+ "profile" => :enum,
107
+ "topology" => :enum,
108
+ "ruby.min" => :version,
109
+ "engine.jruby" => :boolean,
110
+ "engine.truffleruby" => :boolean,
111
+ "engine.alternates" => :boolean,
112
+ "feature.appraisals" => :boolean,
113
+ "feature.rubyforum" => :boolean,
114
+ "feature.rubyforum_project_tag" => :boolean,
115
+ "feature.corporate_sponsors" => :boolean,
116
+ "feature.organization_logo" => :boolean,
117
+ "feature.structuredmerge_driver" => :boolean,
118
+ "feature.dedicated_version_gem" => :boolean,
119
+ "workflow.dep_heads" => :boolean,
120
+ "workflow.jruby_94" => :boolean,
121
+ "version_gem.mode" => :enum
122
+ }.freeze
105
123
  COPY_ONLY_WHEN_MISSING_TEMPLATE_PATHS = %w[REEK bin/setup].freeze
106
124
  MONOREPO_ROOT_TEMPLATE_PROFILE = "monorepo-root"
107
125
  MONOREPO_SUBGEM_PACKAGE_TEMPLATE_PROFILE = "monorepo-subgem-package"
@@ -3525,6 +3543,7 @@ module Kettle
3525
3543
  provider: "github_actions",
3526
3544
  default_branch: "main",
3527
3545
  exec_cmd: github_actions_exec_cmd(kettle_config, env),
3546
+ engine_exec_cmds: github_actions_engine_exec_cmds(kettle_config),
3528
3547
  recording: project_recording_enabled?(project_root, kettle_config),
3529
3548
  ruby_versions: github_actions_ruby_versions(project_runtime.fetch(:test_min_ruby)),
3530
3549
  test_min_ruby: project_runtime.fetch(:test_min_ruby).to_s,
@@ -4168,9 +4187,32 @@ module Kettle
4168
4187
  if report.fetch(:relative_path).to_s == "spec/spec_helper.rb"
4169
4188
  payload[:spec_helper_template_policy_fingerprint_version] = SPEC_HELPER_TEMPLATE_POLICY_FINGERPRINT_VERSION
4170
4189
  end
4190
+ if report.fetch(:relative_path).to_s.start_with?(".github/workflows/")
4191
+ engine_exec_cmds = github_workflow_engine_exec_cmds_for_template(
4192
+ source_path,
4193
+ report.dig(:request_envelope, :request, :runtime_context, :ci, :engine_exec_cmds) ||
4194
+ report.dig(:request_envelope, :request, :runtime_context, "ci", "engine_exec_cmds") ||
4195
+ {}
4196
+ )
4197
+ payload[:github_workflow_engine_exec_cmds] = engine_exec_cmds unless engine_exec_cmds.empty?
4198
+ end
4171
4199
  payload
4172
4200
  end
4173
4201
 
4202
+ def github_workflow_engine_exec_cmds_for_template(source_path, overrides)
4203
+ return {} unless source_path && File.file?(source_path)
4204
+
4205
+ configured = stringify_keys_for_json(overrides)
4206
+ return {} if configured.empty?
4207
+
4208
+ yaml_mapping_nodes(File.read(source_path)).each_with_object({}) do |mapping, matching|
4209
+ engine = yaml_mapping_scalar_value(mapping, "ruby")
4210
+ matching[engine] = configured[engine] if configured.key?(engine)
4211
+ end
4212
+ rescue Psych::Exception
4213
+ {}
4214
+ end
4215
+
4174
4216
  def version_namespace_template_file?(relative_path)
4175
4217
  basename = File.basename(relative_path.to_s)
4176
4218
  basename == "version.rb" || basename == "version_gem.rb" || basename.end_with?(".gemspec")
@@ -4476,6 +4518,7 @@ module Kettle
4476
4518
  chunks.fetch(offset % chunks.length) << job
4477
4519
  end
4478
4520
  chunks.reject(&:empty?).flat_map do |chunk|
4521
+ # rubocop:disable ThreadSafety/NewThread -- Bounded workers only read shared inputs and are joined below.
4479
4522
  Thread.new do
4480
4523
  thread_id = Thread.current.object_id
4481
4524
  chunk.map do |recipe, index|
@@ -4495,6 +4538,7 @@ module Kettle
4495
4538
  [index, report]
4496
4539
  end
4497
4540
  end
4541
+ # rubocop:enable ThreadSafety/NewThread
4498
4542
  end.flat_map(&:value).to_h
4499
4543
  end
4500
4544
 
@@ -5398,10 +5442,10 @@ module Kettle
5398
5442
  [
5399
5443
  {name: "appraisal2", source: %(gem "appraisal2", "~> 3.2", ">= 3.2.3"\n)},
5400
5444
  {name: "bundler-audit", source: %(gem "bundler-audit", "~> 0.9.3"\n)},
5401
- {name: "kettle-dev", source: %(gem "kettle-dev", "~> 3.0", ">= 3.0.18"\n)},
5445
+ {name: "kettle-dev", source: %(gem "kettle-dev", "~> 3.0", ">= 3.0.27"\n)},
5402
5446
  {name: "kettle-drift", source: %(gem "kettle-drift", "~> 1.0", ">= 1.0.13"\n)},
5403
- {name: "kettle-family", source: %(gem "kettle-family", "~> 1.2", ">= 1.2.65"\n)},
5404
- {name: "kettle-jem", source: %(gem "kettle-jem", "~> 7.1", ">= 7.1.11"\n)},
5447
+ {name: "kettle-family", source: %(gem "kettle-family", "~> 1.2", ">= 1.2.79"\n)},
5448
+ {name: "kettle-jem", source: %(gem "kettle-jem", "~> 7.1", ">= 7.1.13"\n)},
5405
5449
  {name: "kettle-test", source: %(gem "kettle-test", "~> 2.0", ">= 2.0.21"\n)},
5406
5450
  {name: "rake", source: %(gem "rake", "~> 13.0"\n)},
5407
5451
  {name: "rspec", source: %(gem "rspec", "~> 3.0"\n)},
@@ -5493,6 +5537,12 @@ module Kettle
5493
5537
  preferred_path: entrypoint_path
5494
5538
  )
5495
5539
  entrypoint_path = namespace_superclass_details[:path] if namespace_superclass_details[:path]
5540
+ namespace_kinds_override = existing_version_namespace_kinds(
5541
+ project_root,
5542
+ version_path,
5543
+ namespace,
5544
+ entrypoint_path: entrypoint_path
5545
+ )
5496
5546
  version_gem_bootstrap_step_for_paths(
5497
5547
  project_root,
5498
5548
  facts,
@@ -5503,7 +5553,8 @@ module Kettle
5503
5553
  # the generated version file must reopen as that same class.
5504
5554
  manage_version_file: !templated_paths.include?(version_path) ||
5505
5555
  version_namespace_outer_kind_for_template(project_root, facts, entrypoint_path, version_path, namespace) == :class,
5506
- manage_signature_file: !templated_paths.include?(signature_path)
5556
+ manage_signature_file: !templated_paths.include?(signature_path),
5557
+ namespace_kinds_override: namespace_kinds_override
5507
5558
  )
5508
5559
  end
5509
5560
 
@@ -6322,24 +6373,7 @@ module Kettle
6322
6373
  end
6323
6374
 
6324
6375
  def transfer_changelog_filter_field_types
6325
- @transfer_changelog_filter_field_types ||= {
6326
- "profile" => :enum,
6327
- "topology" => :enum,
6328
- "ruby.min" => :version,
6329
- "engine.jruby" => :boolean,
6330
- "engine.truffleruby" => :boolean,
6331
- "engine.alternates" => :boolean,
6332
- "feature.appraisals" => :boolean,
6333
- "feature.rubyforum" => :boolean,
6334
- "feature.rubyforum_project_tag" => :boolean,
6335
- "feature.corporate_sponsors" => :boolean,
6336
- "feature.organization_logo" => :boolean,
6337
- "feature.structuredmerge_driver" => :boolean,
6338
- "feature.dedicated_version_gem" => :boolean,
6339
- "workflow.dep_heads" => :boolean,
6340
- "workflow.jruby_94" => :boolean,
6341
- "version_gem.mode" => :enum
6342
- }.freeze
6376
+ TRANSFER_CHANGELOG_FILTER_FIELD_TYPES
6343
6377
  end
6344
6378
 
6345
6379
  def transfer_changelog_filter_predicate_applies?(type, actual, operator, expected)
@@ -6425,11 +6459,13 @@ module Kettle
6425
6459
  end
6426
6460
 
6427
6461
  def changelog_transfer_line_parser
6428
- @changelog_transfer_line_parser ||= TransferChangelogLineParser.new
6462
+ Thread.current.thread_variable_get(:kettle_jem_transfer_changelog_line_parser) ||
6463
+ Thread.current.thread_variable_set(:kettle_jem_transfer_changelog_line_parser, TransferChangelogLineParser.new)
6429
6464
  end
6430
6465
 
6431
6466
  def changelog_transfer_filter_parser
6432
- @changelog_transfer_filter_parser ||= TransferChangelogFilterParser.new
6467
+ Thread.current.thread_variable_get(:kettle_jem_transfer_changelog_filter_parser) ||
6468
+ Thread.current.thread_variable_set(:kettle_jem_transfer_changelog_filter_parser, TransferChangelogFilterParser.new)
6433
6469
  end
6434
6470
 
6435
6471
  def changelog_transfer_list_item_payload(source)
@@ -7883,6 +7919,8 @@ module Kettle
7883
7919
  end
7884
7920
 
7885
7921
  case file_type
7922
+ when :gitignore
7923
+ return merge_gitignore_template_source(template_content, destination_content)
7886
7924
  when :gemspec
7887
7925
  return merge_gemspec_template_source(template_content, destination_content, facts: facts, env: env)
7888
7926
  when :ruby, :gemfile, :rakefile, :appraisals
@@ -9056,7 +9094,30 @@ module Kettle
9056
9094
  end
9057
9095
 
9058
9096
  def finalize_github_workflow_template(content, facts = nil)
9059
- inject_framework_matrix_workflow_env(update_github_actions_pins(content), facts)
9097
+ output = apply_github_actions_engine_exec_cmd_overrides(content, facts)
9098
+ inject_framework_matrix_workflow_env(update_github_actions_pins(output), facts)
9099
+ end
9100
+
9101
+ def apply_github_actions_engine_exec_cmd_overrides(content, facts)
9102
+ overrides = facts.to_h.dig(:ci, :engine_exec_cmds).to_h
9103
+ return content if overrides.empty?
9104
+
9105
+ lines = content.to_s.lines
9106
+ yaml_mapping_nodes(content).sort_by { |mapping| -mapping.start_line }.each do |mapping|
9107
+ engine = yaml_mapping_scalar_value(mapping, "ruby")
9108
+ command = overrides[engine]
9109
+ next if command.to_s.empty?
9110
+
9111
+ exec_cmd_node = yaml_mapping_scalar_node(mapping, "exec_cmd")
9112
+ next unless exec_cmd_node
9113
+
9114
+ line_index = exec_cmd_node.start_line
9115
+ indent = lines.fetch(line_index).to_s.match(/\A(\s*)/)[1]
9116
+ lines[line_index] = "#{indent}exec_cmd: #{yaml_double_quoted_scalar(command)}\n"
9117
+ end
9118
+ lines.join
9119
+ rescue Psych::Exception
9120
+ content
9060
9121
  end
9061
9122
 
9062
9123
  def inject_framework_matrix_workflow_env(content, facts)
@@ -9075,7 +9136,7 @@ module Kettle
9075
9136
  next unless insert_index
9076
9137
 
9077
9138
  indent = workflow_matrix_env_indent(lines, mapping)
9078
- additions = matrix_env.reject { |key, _value| yaml_mapping_scalar_value(mapping, key) }
9139
+ additions = matrix_env.reject { |key, _value| yaml_mapping_scalar_node(mapping, key) }
9079
9140
  additions.reject! { |key, _value| inserted_locations.include?([insert_index, key.to_s]) }
9080
9141
  next if additions.empty?
9081
9142
 
@@ -9164,21 +9225,25 @@ module Kettle
9164
9225
  end
9165
9226
 
9166
9227
  def prune_workflow_matrix_item?(mapping, minimum)
9167
- ruby = yaml_mapping_scalar_value(mapping, "ruby")
9168
- return true if ruby && Gem::Version.new(ruby) < minimum
9228
+ ruby = yaml_mapping_scalar_value(mapping, "ruby").to_s.strip
9229
+ return true if !ruby.empty? && Gem::Version.new(ruby) < minimum
9169
9230
 
9170
- appraisal_ruby_version = appraisal_ruby_version(yaml_mapping_scalar_value(mapping, "appraisal"))
9171
- appraisal_ruby_version && Gem::Version.new(appraisal_ruby_version) < minimum
9231
+ appraisal_ruby = appraisal_ruby_version(yaml_mapping_scalar_value(mapping, "appraisal")).to_s.strip
9232
+ !appraisal_ruby.empty? && Gem::Version.new(appraisal_ruby) < minimum
9172
9233
  rescue ArgumentError
9173
9234
  false
9174
9235
  end
9175
9236
 
9176
9237
  def yaml_mapping_scalar_value(mapping, key)
9238
+ yaml_mapping_scalar_node(mapping, key)&.value.to_s
9239
+ end
9240
+
9241
+ def yaml_mapping_scalar_node(mapping, key)
9177
9242
  mapping.children.each_slice(2) do |key_node, value_node|
9178
9243
  next unless key_node.is_a?(Psych::Nodes::Scalar) && key_node.value.to_s == key.to_s
9179
9244
  next unless value_node.is_a?(Psych::Nodes::Scalar)
9180
9245
 
9181
- return value_node.value.to_s
9246
+ return value_node
9182
9247
  end
9183
9248
  nil
9184
9249
  end
@@ -12235,6 +12300,7 @@ module Kettle
12235
12300
  relative_path = recipe.fetch(:target_path).to_s
12236
12301
  basename = File.basename(relative_path)
12237
12302
  extension = File.extname(relative_path).downcase
12303
+ return :gitignore if basename == ".gitignore"
12238
12304
  return :gemfile if basename == "Gemfile" || basename.end_with?(".gemfile")
12239
12305
  return :appraisals if basename.start_with?("Appraisals") || basename == "Appraisal.root.gemfile"
12240
12306
  return :gemspec if basename.end_with?(".gemspec")
@@ -12255,6 +12321,40 @@ module Kettle
12255
12321
  :text
12256
12322
  end
12257
12323
 
12324
+ def merge_gitignore_template_source(template_content, destination_content)
12325
+ # Git ignore files have no parser-backed AST. Treat each non-comment line
12326
+ # as a rule node, retain destination order and comments, and append only
12327
+ # template rules that the destination does not already declare.
12328
+ destination_rules = destination_content.lines.map(&:strip).reject { |line| line.empty? || line.start_with?("#") }.to_set
12329
+ additions = []
12330
+ pending_comments = []
12331
+
12332
+ template_content.lines.each do |line|
12333
+ stripped = line.strip
12334
+ if stripped.empty?
12335
+ pending_comments << line unless pending_comments.empty?
12336
+ next
12337
+ end
12338
+ if stripped.start_with?("#")
12339
+ pending_comments << line
12340
+ next
12341
+ end
12342
+ next if destination_rules.include?(stripped)
12343
+
12344
+ additions.concat(pending_comments)
12345
+ additions << line
12346
+ destination_rules << stripped
12347
+ pending_comments = []
12348
+ end
12349
+
12350
+ return destination_content if additions.empty?
12351
+
12352
+ output = destination_content.dup
12353
+ output << "\n" unless output.empty? || output.end_with?("\n\n")
12354
+ output << additions.join
12355
+ ensure_trailing_newline(output)
12356
+ end
12357
+
12258
12358
  def apply_kettle_config_bootstrap(project_root, recipe, env: ENV, template_contents: nil)
12259
12359
  content = recipe_template_content(project_root, recipe, template_contents: template_contents)
12260
12360
  tokens = stringify_template_tokens(recipe.fetch(:template_tokens, {}))
@@ -13796,7 +13896,9 @@ module Kettle
13796
13896
 
13797
13897
  def commit_file_work_units_thread(file_work_units, workers:)
13798
13898
  distribute_file_work_units(file_work_units, workers).map do |chunk|
13899
+ # rubocop:disable ThreadSafety/NewThread -- Independent file units are joined before this method returns.
13799
13900
  Thread.new { chunk.each { |file_work_unit| commit_file_work_unit(file_work_unit) } }
13901
+ # rubocop:enable ThreadSafety/NewThread
13800
13902
  end.each(&:join)
13801
13903
  end
13802
13904
 
@@ -14239,7 +14341,7 @@ module Kettle
14239
14341
  root: ["src", "my", "kettle-dev"]
14240
14342
  )
14241
14343
  elsif Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("4.0.0")
14242
- gem "kettle-changelog", "~> 1.0", ">= 1.0.6"
14344
+ gem "kettle-changelog", "~> 1.0", ">= 1.0.7"
14243
14345
  end
14244
14346
  end
14245
14347
  RUBY
@@ -14439,6 +14541,9 @@ module Kettle
14439
14541
  version = "0.0.1.pre" if version.empty?
14440
14542
  return {} if namespace.empty?
14441
14543
 
14544
+ namespace_kinds = version_namespace_kinds_from_facts(facts)
14545
+ outer_namespace_kind = namespace_kinds.fetch(namespace.split("::").length - 1, :module)
14546
+
14442
14547
  version_rb = if facts.dig(:shim, :version_strategy).to_s == "shim"
14443
14548
  shim_version_file_content(
14444
14549
  namespace: namespace,
@@ -14446,7 +14551,13 @@ module Kettle
14446
14551
  replacement_require: facts.dig(:shim, :replacement_require)
14447
14552
  )
14448
14553
  else
14449
- version_gem_version_file_content(existing_version: "", namespace: namespace, version: version)
14554
+ version_gem_version_file_content(
14555
+ existing_version: "",
14556
+ namespace: namespace,
14557
+ version: version,
14558
+ outer_namespace_kind: outer_namespace_kind,
14559
+ namespace_kinds: namespace_kinds
14560
+ )
14450
14561
  end
14451
14562
 
14452
14563
  {
@@ -14457,7 +14568,11 @@ module Kettle
14457
14568
  entrypoint_require: facts.dig(:rubygems, :entrypoint_require).to_s,
14458
14569
  dedicated: true
14459
14570
  ).chomp,
14460
- "KJ|VERSION_GEM:VERSION_RBS" => version_gem_signature_file_content(namespace: namespace).chomp
14571
+ "KJ|VERSION_GEM:VERSION_RBS" => version_gem_signature_file_content(
14572
+ namespace: namespace,
14573
+ outer_namespace_kind: outer_namespace_kind,
14574
+ namespace_kinds: namespace_kinds
14575
+ ).chomp
14461
14576
  }
14462
14577
  end
14463
14578
 
@@ -14951,18 +15066,30 @@ module Kettle
14951
15066
  return [] unless project_root && gemspec_metadata.is_a?(Hash)
14952
15067
 
14953
15068
  sibling_root = File.expand_path("..", project_root.to_s)
14954
- dependencies = Array(
14955
- gemspec_metadata[:runtime_dependencies] || gemspec_metadata["runtime_dependencies"]
14956
- )
14957
- dependencies.each_with_object([]) do |dependency, names|
14958
- name = dependency.respond_to?(:name) ? dependency.name.to_s : dependency.to_s
14959
- next if name.empty? || name == package_name.to_s
14960
- next unless direct_sibling_directory_defines_gem?(File.join(sibling_root, name), name)
14961
- next if Array(local_modular_eval_paths[name]).any?
14962
- next if names.include?(name)
15069
+ excluded = [package_name.to_s, *local_modular_eval_paths.keys.map(&:to_s)]
15070
+ pending = gemspec_runtime_dependency_names(gemspec_metadata)
15071
+ discovered = []
14963
15072
 
14964
- names << name
15073
+ until pending.empty?
15074
+ name = pending.shift.to_s
15075
+ next if name.empty? || discovered.include?(name)
15076
+
15077
+ sibling_path = File.join(sibling_root, name)
15078
+ next unless direct_sibling_directory_defines_gem?(sibling_path, name)
15079
+
15080
+ discovered << name
15081
+ sibling_metadata = sibling_gemspec_metadata(sibling_path, name)
15082
+ pending.concat(gemspec_runtime_dependency_names(sibling_metadata))
15083
+ end
15084
+
15085
+ discovered.reject { |name| excluded.include?(name) }
15086
+ end
15087
+
15088
+ def sibling_gemspec_metadata(sibling_path, gem_name)
15089
+ gemspec_path = Dir.glob(File.join(sibling_path, "*.gemspec")).find do |path|
15090
+ metadata_value(static_project_gemspec_metadata(path), :gem_name).to_s == gem_name.to_s
14965
15091
  end
15092
+ gemspec_path ? static_project_gemspec_metadata(gemspec_path) : {}
14966
15093
  end
14967
15094
 
14968
15095
  def local_modular_runtime_eval_paths(project_root, gemspec_metadata, package_name:)
@@ -15263,7 +15390,7 @@ module Kettle
15263
15390
  def main_gemfile_kettle_family_gem(package_name)
15264
15391
  return "" if package_name.to_s == "kettle-family"
15265
15392
 
15266
- %(gem "kettle-family", "~> 1.2", ">= 1.2.65"\n)
15393
+ %(gem "kettle-family", "~> 1.2", ">= 1.2.79"\n)
15267
15394
  end
15268
15395
 
15269
15396
  def main_gemfile_nomono_bootstrap(package_name)
@@ -15347,12 +15474,13 @@ module Kettle
15347
15474
  end
15348
15475
 
15349
15476
  def version_gem_bootstrap_step_for_paths(project_root, facts, manage_version_file: true, manage_signature_file: true,
15350
- package_entrypoint_preexisting: true, preserve_version_module_include: nil)
15477
+ package_entrypoint_preexisting: true, preserve_version_module_include: nil, namespace_kinds_override: {})
15351
15478
  package_name = facts.dig(:package, :name).to_s
15352
15479
  return {name: "version_gem_bootstrap", status: "unavailable", reason: "missing_package_facts"} if package_name.empty?
15353
15480
 
15354
15481
  entrypoint_require = facts.dig(:rubygems, :entrypoint_require).to_s
15355
15482
  entrypoint_require = package_name.tr("-", "/") if entrypoint_require.empty?
15483
+ namespace = facts.dig(:rubygems, :namespace).to_s
15356
15484
  version_path = File.join("lib", entrypoint_require, "version.rb")
15357
15485
  entrypoint_path = version_gem_bootstrap_entrypoint_path(
15358
15486
  project_root,
@@ -15365,7 +15493,6 @@ module Kettle
15365
15493
  version_spec_path = File.join("spec", entrypoint_require, "version_spec.rb")
15366
15494
  signature_path = File.join("sig", "#{entrypoint_require}.rbs")
15367
15495
  legacy_signature_paths = legacy_rbs_signature_paths(project_root, entrypoint_require)
15368
- namespace = facts.dig(:rubygems, :namespace).to_s
15369
15496
  if namespace.empty?
15370
15497
  namespace = existing_entrypoint_version_namespace(
15371
15498
  project_root,
@@ -15405,14 +15532,17 @@ module Kettle
15405
15532
  version = "0.0.1.pre" if version.empty?
15406
15533
  changes = []
15407
15534
  current_entrypoint = read_project_file(project_root, entrypoint_path)
15408
- outer_namespace_kind = ruby_entrypoint_outer_namespace_kind(current_entrypoint, namespace)
15409
- namespace_kinds = version_namespace_kinds_from_facts(facts).merge(
15410
- existing_version_namespace_kinds(
15411
- project_root,
15412
- version_path,
15413
- namespace,
15414
- entrypoint_path: entrypoint_path
15415
- )
15535
+ discovered_namespace_kinds = existing_version_namespace_kinds(
15536
+ project_root,
15537
+ version_path,
15538
+ namespace,
15539
+ entrypoint_path: entrypoint_path
15540
+ )
15541
+ namespace_kinds = version_namespace_kinds_from_facts(facts).merge(discovered_namespace_kinds)
15542
+ namespace_kinds = namespace_kinds.merge(namespace_kinds_override)
15543
+ outer_namespace_kind = namespace_kinds.fetch(
15544
+ namespace.split("::").length - 1,
15545
+ ruby_entrypoint_outer_namespace_kind(current_entrypoint, namespace)
15416
15546
  )
15417
15547
  preserve_version_module_include = existing_version_file_includes_version_module?(project_root, version_path) if preserve_version_module_include.nil?
15418
15548
 
@@ -15480,7 +15610,9 @@ module Kettle
15480
15610
  project_root,
15481
15611
  signature_path,
15482
15612
  legacy_signature_paths,
15483
- namespace: namespace
15613
+ namespace: namespace,
15614
+ outer_namespace_kind: outer_namespace_kind,
15615
+ namespace_kinds: namespace_kinds
15484
15616
  )
15485
15617
  )
15486
15618
  end
@@ -15771,8 +15903,13 @@ module Kettle
15771
15903
  end
15772
15904
  end
15773
15905
 
15774
- def write_consolidated_version_signature(project_root, signature_path, legacy_signature_paths, namespace:)
15775
- template = version_gem_signature_file_content(namespace: namespace)
15906
+ def write_consolidated_version_signature(project_root, signature_path, legacy_signature_paths, namespace:,
15907
+ outer_namespace_kind: :module, namespace_kinds: {})
15908
+ template = version_gem_signature_file_content(
15909
+ namespace: namespace,
15910
+ outer_namespace_kind: outer_namespace_kind,
15911
+ namespace_kinds: namespace_kinds
15912
+ )
15776
15913
  current = read_project_file(project_root, signature_path)
15777
15914
  merged = current
15778
15915
  legacy_signature_paths.each do |legacy_signature_path|
@@ -15862,7 +15999,7 @@ module Kettle
15862
15999
  "#{sections.reject(&:empty?).join("\n\n")}\n"
15863
16000
  end
15864
16001
 
15865
- def version_gem_signature_file_content(namespace:)
16002
+ def version_gem_signature_file_content(namespace:, outer_namespace_kind: :module, namespace_kinds: {})
15866
16003
  body = [
15867
16004
  "module Version",
15868
16005
  " VERSION: String",
@@ -15870,7 +16007,7 @@ module Kettle
15870
16007
  "VERSION: String"
15871
16008
  ]
15872
16009
 
15873
- "#{wrap_ruby_namespace(namespace, body).join("\n")}\n"
16010
+ "#{wrap_ruby_namespace(namespace, body, outer_namespace_kind: outer_namespace_kind, namespace_kinds: namespace_kinds).join("\n")}\n"
15874
16011
  end
15875
16012
 
15876
16013
  def version_gem_bootstrap_entrypoint_content(content, namespace:, entrypoint_require:, namespace_superclasses: {}, version_require_path: nil)
@@ -18276,6 +18413,7 @@ module Kettle
18276
18413
  def default_template_strategy_config(template_root, target_path)
18277
18414
  return unless template_root.fetch(:kind) == "packaged"
18278
18415
  return {strategy: :merge, preference: :destination, add_template_only_nodes: true} if target_path.to_s == KETTLE_CONFIG_PATH
18416
+ return {strategy: :merge, preference: :destination, add_template_only_nodes: true} if target_path.to_s == ".gitignore"
18279
18417
  return {strategy: :accept_template} if target_path.to_s == "CITATION.cff"
18280
18418
  return {strategy: :merge, preference: :destination, add_template_only_nodes: true} if target_path.to_s == "Rakefile"
18281
18419
  return {strategy: :accept_template} if version_gem_template_target_path?(target_path)
@@ -18987,6 +19125,23 @@ module Kettle
18987
19125
  )
18988
19126
  end
18989
19127
 
19128
+ # A generated workflow normally uses one command for every matrix entry.
19129
+ # Legacy engines occasionally need a narrower command while retaining the
19130
+ # rest of the generated workflow (setup, retries, cache keys, and pins).
19131
+ def github_actions_engine_exec_cmds(config)
19132
+ workflows = config["workflows"]
19133
+ return {} unless workflows.is_a?(Hash)
19134
+
19135
+ raw = workflows["engine_exec_cmds"]
19136
+ return {} unless raw.is_a?(Hash)
19137
+
19138
+ raw.each_with_object({}) do |(engine, command), overrides|
19139
+ engine_name = engine.to_s.strip
19140
+ command_text = command.to_s.strip
19141
+ overrides[engine_name] = command_text unless engine_name.empty? || command_text.empty?
19142
+ end
19143
+ end
19144
+
18990
19145
  def normalize_github_actions_exec_cmd(command)
18991
19146
  normalized = command.to_s.strip
18992
19147
  return "kettle-test" if OBSOLETE_APPRAISAL_SPEC_EXEC_CMDS.include?(normalized)
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.12
4
+ version: 7.1.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -66,7 +66,7 @@ dependencies:
66
66
  version: '7.1'
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 7.1.4
69
+ version: 7.1.6
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '7.1'
77
77
  - - ">="
78
78
  - !ruby/object:Gem::Version
79
- version: 7.1.4
79
+ version: 7.1.6
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: ast-crispr-ruby-prism
82
82
  requirement: !ruby/object:Gem::Requirement
@@ -86,7 +86,7 @@ dependencies:
86
86
  version: '7.1'
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 7.1.4
89
+ version: 7.1.6
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
@@ -96,7 +96,7 @@ dependencies:
96
96
  version: '7.1'
97
97
  - - ">="
98
98
  - !ruby/object:Gem::Version
99
- version: 7.1.4
99
+ version: 7.1.6
100
100
  - !ruby/object:Gem::Dependency
101
101
  name: ast-merge
102
102
  requirement: !ruby/object:Gem::Requirement
@@ -106,7 +106,7 @@ dependencies:
106
106
  version: '7.1'
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
- version: 7.1.4
109
+ version: 7.1.6
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
@@ -116,7 +116,7 @@ dependencies:
116
116
  version: '7.1'
117
117
  - - ">="
118
118
  - !ruby/object:Gem::Version
119
- version: 7.1.4
119
+ version: 7.1.6
120
120
  - !ruby/object:Gem::Dependency
121
121
  name: bash-merge
122
122
  requirement: !ruby/object:Gem::Requirement
@@ -126,7 +126,7 @@ dependencies:
126
126
  version: '7.1'
127
127
  - - ">="
128
128
  - !ruby/object:Gem::Version
129
- version: 7.1.4
129
+ version: 7.1.6
130
130
  type: :runtime
131
131
  prerelease: false
132
132
  version_requirements: !ruby/object:Gem::Requirement
@@ -136,7 +136,7 @@ dependencies:
136
136
  version: '7.1'
137
137
  - - ">="
138
138
  - !ruby/object:Gem::Version
139
- version: 7.1.4
139
+ version: 7.1.6
140
140
  - !ruby/object:Gem::Dependency
141
141
  name: citrus-toml-merge
142
142
  requirement: !ruby/object:Gem::Requirement
@@ -146,7 +146,7 @@ dependencies:
146
146
  version: '7.1'
147
147
  - - ">="
148
148
  - !ruby/object:Gem::Version
149
- version: 7.1.4
149
+ version: 7.1.6
150
150
  type: :runtime
151
151
  prerelease: false
152
152
  version_requirements: !ruby/object:Gem::Requirement
@@ -156,7 +156,7 @@ dependencies:
156
156
  version: '7.1'
157
157
  - - ">="
158
158
  - !ruby/object:Gem::Version
159
- version: 7.1.4
159
+ version: 7.1.6
160
160
  - !ruby/object:Gem::Dependency
161
161
  name: commonmarker-merge
162
162
  requirement: !ruby/object:Gem::Requirement
@@ -166,7 +166,7 @@ dependencies:
166
166
  version: '7.1'
167
167
  - - ">="
168
168
  - !ruby/object:Gem::Version
169
- version: 7.1.4
169
+ version: 7.1.6
170
170
  type: :runtime
171
171
  prerelease: false
172
172
  version_requirements: !ruby/object:Gem::Requirement
@@ -176,7 +176,7 @@ dependencies:
176
176
  version: '7.1'
177
177
  - - ">="
178
178
  - !ruby/object:Gem::Version
179
- version: 7.1.4
179
+ version: 7.1.6
180
180
  - !ruby/object:Gem::Dependency
181
181
  name: dotenv-merge
182
182
  requirement: !ruby/object:Gem::Requirement
@@ -186,7 +186,7 @@ dependencies:
186
186
  version: '7.1'
187
187
  - - ">="
188
188
  - !ruby/object:Gem::Version
189
- version: 7.1.4
189
+ version: 7.1.6
190
190
  type: :runtime
191
191
  prerelease: false
192
192
  version_requirements: !ruby/object:Gem::Requirement
@@ -196,7 +196,7 @@ dependencies:
196
196
  version: '7.1'
197
197
  - - ">="
198
198
  - !ruby/object:Gem::Version
199
- version: 7.1.4
199
+ version: 7.1.6
200
200
  - !ruby/object:Gem::Dependency
201
201
  name: json-merge
202
202
  requirement: !ruby/object:Gem::Requirement
@@ -206,7 +206,7 @@ dependencies:
206
206
  version: '7.1'
207
207
  - - ">="
208
208
  - !ruby/object:Gem::Version
209
- version: 7.1.4
209
+ version: 7.1.6
210
210
  type: :runtime
211
211
  prerelease: false
212
212
  version_requirements: !ruby/object:Gem::Requirement
@@ -216,7 +216,7 @@ dependencies:
216
216
  version: '7.1'
217
217
  - - ">="
218
218
  - !ruby/object:Gem::Version
219
- version: 7.1.4
219
+ version: 7.1.6
220
220
  - !ruby/object:Gem::Dependency
221
221
  name: kettle-changelog
222
222
  requirement: !ruby/object:Gem::Requirement
@@ -326,7 +326,7 @@ dependencies:
326
326
  version: '7.1'
327
327
  - - ">="
328
328
  - !ruby/object:Gem::Version
329
- version: 7.1.4
329
+ version: 7.1.6
330
330
  type: :runtime
331
331
  prerelease: false
332
332
  version_requirements: !ruby/object:Gem::Requirement
@@ -336,7 +336,7 @@ dependencies:
336
336
  version: '7.1'
337
337
  - - ">="
338
338
  - !ruby/object:Gem::Version
339
- version: 7.1.4
339
+ version: 7.1.6
340
340
  - !ruby/object:Gem::Dependency
341
341
  name: markdown-merge
342
342
  requirement: !ruby/object:Gem::Requirement
@@ -346,7 +346,7 @@ dependencies:
346
346
  version: '7.1'
347
347
  - - ">="
348
348
  - !ruby/object:Gem::Version
349
- version: 7.1.4
349
+ version: 7.1.6
350
350
  type: :runtime
351
351
  prerelease: false
352
352
  version_requirements: !ruby/object:Gem::Requirement
@@ -356,7 +356,7 @@ dependencies:
356
356
  version: '7.1'
357
357
  - - ">="
358
358
  - !ruby/object:Gem::Version
359
- version: 7.1.4
359
+ version: 7.1.6
360
360
  - !ruby/object:Gem::Dependency
361
361
  name: markly-merge
362
362
  requirement: !ruby/object:Gem::Requirement
@@ -366,7 +366,7 @@ dependencies:
366
366
  version: '7.1'
367
367
  - - ">="
368
368
  - !ruby/object:Gem::Version
369
- version: 7.1.4
369
+ version: 7.1.6
370
370
  type: :runtime
371
371
  prerelease: false
372
372
  version_requirements: !ruby/object:Gem::Requirement
@@ -376,7 +376,7 @@ dependencies:
376
376
  version: '7.1'
377
377
  - - ">="
378
378
  - !ruby/object:Gem::Version
379
- version: 7.1.4
379
+ version: 7.1.6
380
380
  - !ruby/object:Gem::Dependency
381
381
  name: parslet
382
382
  requirement: !ruby/object:Gem::Requirement
@@ -400,7 +400,7 @@ dependencies:
400
400
  version: '7.1'
401
401
  - - ">="
402
402
  - !ruby/object:Gem::Version
403
- version: 7.1.4
403
+ version: 7.1.6
404
404
  type: :runtime
405
405
  prerelease: false
406
406
  version_requirements: !ruby/object:Gem::Requirement
@@ -410,7 +410,7 @@ dependencies:
410
410
  version: '7.1'
411
411
  - - ">="
412
412
  - !ruby/object:Gem::Version
413
- version: 7.1.4
413
+ version: 7.1.6
414
414
  - !ruby/object:Gem::Dependency
415
415
  name: psych-merge
416
416
  requirement: !ruby/object:Gem::Requirement
@@ -420,7 +420,7 @@ dependencies:
420
420
  version: '7.1'
421
421
  - - ">="
422
422
  - !ruby/object:Gem::Version
423
- version: 7.1.4
423
+ version: 7.1.6
424
424
  type: :runtime
425
425
  prerelease: false
426
426
  version_requirements: !ruby/object:Gem::Requirement
@@ -430,7 +430,7 @@ dependencies:
430
430
  version: '7.1'
431
431
  - - ">="
432
432
  - !ruby/object:Gem::Version
433
- version: 7.1.4
433
+ version: 7.1.6
434
434
  - !ruby/object:Gem::Dependency
435
435
  name: rbs
436
436
  requirement: !ruby/object:Gem::Requirement
@@ -454,7 +454,7 @@ dependencies:
454
454
  version: '7.1'
455
455
  - - ">="
456
456
  - !ruby/object:Gem::Version
457
- version: 7.1.4
457
+ version: 7.1.6
458
458
  type: :runtime
459
459
  prerelease: false
460
460
  version_requirements: !ruby/object:Gem::Requirement
@@ -464,7 +464,7 @@ dependencies:
464
464
  version: '7.1'
465
465
  - - ">="
466
466
  - !ruby/object:Gem::Version
467
- version: 7.1.4
467
+ version: 7.1.6
468
468
  - !ruby/object:Gem::Dependency
469
469
  name: ruby-merge
470
470
  requirement: !ruby/object:Gem::Requirement
@@ -474,7 +474,7 @@ dependencies:
474
474
  version: '7.1'
475
475
  - - ">="
476
476
  - !ruby/object:Gem::Version
477
- version: 7.1.4
477
+ version: 7.1.6
478
478
  type: :runtime
479
479
  prerelease: false
480
480
  version_requirements: !ruby/object:Gem::Requirement
@@ -484,7 +484,7 @@ dependencies:
484
484
  version: '7.1'
485
485
  - - ">="
486
486
  - !ruby/object:Gem::Version
487
- version: 7.1.4
487
+ version: 7.1.6
488
488
  - !ruby/object:Gem::Dependency
489
489
  name: token-resolver
490
490
  requirement: !ruby/object:Gem::Requirement
@@ -514,7 +514,7 @@ dependencies:
514
514
  version: '7.1'
515
515
  - - ">="
516
516
  - !ruby/object:Gem::Version
517
- version: 7.1.4
517
+ version: 7.1.6
518
518
  type: :runtime
519
519
  prerelease: false
520
520
  version_requirements: !ruby/object:Gem::Requirement
@@ -524,7 +524,7 @@ dependencies:
524
524
  version: '7.1'
525
525
  - - ">="
526
526
  - !ruby/object:Gem::Version
527
- version: 7.1.4
527
+ version: 7.1.6
528
528
  - !ruby/object:Gem::Dependency
529
529
  name: toml-rb
530
530
  requirement: !ruby/object:Gem::Requirement
@@ -548,7 +548,7 @@ dependencies:
548
548
  version: '7.1'
549
549
  - - ">="
550
550
  - !ruby/object:Gem::Version
551
- version: 7.1.4
551
+ version: 7.1.6
552
552
  type: :runtime
553
553
  prerelease: false
554
554
  version_requirements: !ruby/object:Gem::Requirement
@@ -558,7 +558,7 @@ dependencies:
558
558
  version: '7.1'
559
559
  - - ">="
560
560
  - !ruby/object:Gem::Version
561
- version: 7.1.4
561
+ version: 7.1.6
562
562
  - !ruby/object:Gem::Dependency
563
563
  name: yaml-merge
564
564
  requirement: !ruby/object:Gem::Requirement
@@ -568,7 +568,7 @@ dependencies:
568
568
  version: '7.1'
569
569
  - - ">="
570
570
  - !ruby/object:Gem::Version
571
- version: 7.1.4
571
+ version: 7.1.6
572
572
  type: :runtime
573
573
  prerelease: false
574
574
  version_requirements: !ruby/object:Gem::Requirement
@@ -578,7 +578,7 @@ dependencies:
578
578
  version: '7.1'
579
579
  - - ">="
580
580
  - !ruby/object:Gem::Version
581
- version: 7.1.4
581
+ version: 7.1.6
582
582
  - !ruby/object:Gem::Dependency
583
583
  name: bundler-audit
584
584
  requirement: !ruby/object:Gem::Requirement
@@ -976,10 +976,10 @@ licenses:
976
976
  - PolyForm-Small-Business-1.0.0
977
977
  metadata:
978
978
  homepage_uri: https://structuredmerge.org
979
- source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.12
980
- changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.12/CHANGELOG.md
979
+ source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.14
980
+ changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.14/CHANGELOG.md
981
981
  bug_tracker_uri: https://github.com/structuredmerge/structuredmerge-ruby/issues
982
- documentation_uri: https://www.rubydoc.info/gems/kettle-jem/7.1.12
982
+ documentation_uri: https://www.rubydoc.info/gems/kettle-jem/7.1.14
983
983
  funding_uri: https://github.com/sponsors/pboling
984
984
  wiki_uri: https://github.com/structuredmerge/structuredmerge-ruby/wiki
985
985
  news_uri: https://www.railsbling.com/tags/kettle-jem
metadata.gz.sig CHANGED
Binary file