kettle-jem 7.1.10 → 7.1.11

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: cc954a9b2e13ecec8a5dbf0858c76b7a7157f92fabd6f07092024690ab163048
4
- data.tar.gz: '0628e48c05357df4f752ef7e252cb3992d380ab578faaeee44801d7e818ed39f'
3
+ metadata.gz: 4557a45c40575cf35c6a6630ca4f15694407df55cae707f4187c282111a5fe6e
4
+ data.tar.gz: df10a122743e47d9236115a4e7d44fbc0342a70de1da7643b863da983f9d800e
5
5
  SHA512:
6
- metadata.gz: 1c549dd026691dbfc28854df99784f1b3c8904237d19f23eaab450de64983c5f9116102811e385f997a661c443e4efe01b6832613dbef6da5c1d9b30eeaad451
7
- data.tar.gz: 54991a0795b8d7da63318264a5dcefec11cbe78e0ba151a9a53ab56ff8c39b4b6375070b80007d0c446b59c4bc7ad2ee8756c63c25a209f3cf0edfd79b6e900e
6
+ metadata.gz: 77dfdae1740bbe776afb7d9f181a34244c6bd594cc0b9d6d274e9183c8d1be60894c7c112243c9f5d064f9cf4a57b2ec043e0bb84d55eb4dfe86b48008f535c7
7
+ data.tar.gz: 17fac3e17f62555dc40598d641007ce21c05c7968cb9745409b3eeaf153c86648b47dde2abaee0b2ed1a82cab268e267eeeac1ce31fbf2d69d493119de03d9bc
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,36 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [7.1.11] - 2026-08-29
34
+
35
+ - TAG: [v7.1.11][7.1.11t]
36
+ - COVERAGE: 93.64% -- 11027/11776 lines in 16 files
37
+ - BRANCH COVERAGE: 76.95% -- 4698/6105 branches in 16 files
38
+ - 17.95% documented
39
+
40
+ ### Changed
41
+
42
+ - [kc] kettle-jem/template: updated 398 project files:
43
+ - code and tests (20)
44
+ - configuration (12)
45
+ - dependencies (147)
46
+ - documentation (9)
47
+ - other (123)
48
+ - workflows (87)
49
+
50
+ - [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
51
+ - kettle-changelog (>= 1.0.5 -> >= 1.0.6)
52
+ - kettle-jem (>= 7.1.8 -> >= 7.1.10)
53
+ - turbo_tests2 (>= 3.2.6 -> >= 3.2.7)
54
+
55
+ - Raise first-party dependency minimums to their latest released versions.
56
+
57
+ ### Fixed
58
+
59
+ - Preserve inherited version namespaces by declaring their superclass before loading version.rb.
60
+
61
+ - Template-manage default local test bundles independently from appraisal and framework CI matrices.
62
+
33
63
  ## [7.1.10] - 2026-08-29
34
64
 
35
65
  - TAG: [v7.1.10][7.1.10t]
@@ -1674,7 +1704,9 @@ Please file a bug if you notice a violation of semantic versioning.
1674
1704
  - Released kettle-jem as part of the initial StructuredMerge Ruby 7.0.0 gem set.
1675
1705
  - Included packaged templates and parser-backed merge support for Ruby gem templating.
1676
1706
 
1677
- [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.10...HEAD
1707
+ [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.11...HEAD
1708
+ [7.1.11]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.10...v7.1.11
1709
+ [7.1.11t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.11
1678
1710
  [7.1.10]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.8...v7.1.10
1679
1711
  [7.1.10t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.10
1680
1712
  [7.1.8]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.7...v7.1.8
data/README.md CHANGED
@@ -268,7 +268,77 @@ good fit when you want kettle-jem to generate framework-version modular gemfiles
268
268
 
269
269
  If you need a deeper or more complex matrix, prefer
270
270
  **`kettle-jem-appraisals`**, which generates `Appraisals` entries and is the
271
- better fit for Appraisals-style combinations.
271
+ better fit for Appraisals-style combinations. Its `appraisal_matrix` config is
272
+ the source of truth for the generated matrix: use `mode` (or per-gem `mode`),
273
+ `freshness_ttl`, `exec_cmd`, `appraisal_gemfiles`, `standard_appraisal_role`,
274
+ and `gems.tier1` / `gems.tier2` as documented in the
275
+ [`kettle-jem-appraisals` configuration reference](https://github.com/appraisal-rb/kettle-jem-appraisals#%EF%B8%8F-configuration).
276
+
277
+ Neither `appraisal_matrix` nor `framework_matrix` implicitly changes the root
278
+ local development bundle. Pair either policy with `test_bundle` when the
279
+ default local test command needs a specific framework or harness.
280
+
281
+ ### Default Local Test Bundle
282
+
283
+ The root `Gemfile` is the default bundle for local commands such as
284
+ `bundle exec kettle-test`. It is intentionally separate from Appraisals and
285
+ CI, which run with their own generated Gemfiles. Declare its project-specific
286
+ test dependencies with `test_bundle`; kettle-jem will add them to the root
287
+ `Gemfile` on every template run.
288
+
289
+ Use `test_bundle.gemfiles` for a modular fragment. A mapping may name direct
290
+ dependencies that the fragment replaces, so kettle-jem removes stale root
291
+ declarations before adding the `eval_gemfile` call:
292
+
293
+ ```yaml
294
+ test_bundle:
295
+ gemfiles:
296
+ - path: gemfiles/rails_7_2.gemfile
297
+ replaces:
298
+ - combustion
299
+ - actionmailer
300
+ - railties
301
+ ```
302
+
303
+ Use `test_bundle.gems` for a small, explicit local test dependency that does
304
+ not warrant a modular fragment. Use either `requirement` or `requirements`; set
305
+ `require: false` only when the dependency must be available to Bundler but
306
+ should not be automatically required:
307
+
308
+ ```yaml
309
+ test_bundle:
310
+ gems:
311
+ - name: activerecord
312
+ requirement: "~> 7.2"
313
+ - name: debug
314
+ requirement: "~> 1.11"
315
+ require: false
316
+ ```
317
+
318
+ For a simple `workflows.framework_matrix`, mark exactly one version as
319
+ `default: true` to load that generated framework gemfile into the root
320
+ `Gemfile` as the local default. The matrix still controls Appraisals and CI;
321
+ the flag only selects the root local bundle. `appraisal_matrix` deliberately
322
+ has no implicit default selector: use `test_bundle` to name the stable local
323
+ Gemfile fragment or direct dependencies while the plugin continues to generate
324
+ the full appraisal matrix.
325
+
326
+ ```yaml
327
+ workflows:
328
+ preset: framework
329
+ framework_matrix:
330
+ dimension: rails
331
+ gem: rails
332
+ gemfile_pattern: "rails_{version}.gemfile"
333
+ versions:
334
+ - label: "7.2"
335
+ slug: "7_2"
336
+ requirement: "~> 7.2.2"
337
+ default: true
338
+ ```
339
+
340
+ Do not use freeze markers for any of these declarations. The configuration is
341
+ the source of truth, and templating keeps the root bundle synchronized with it.
272
342
 
273
343
  ### Strategies
274
344
 
@@ -794,7 +864,7 @@ Thanks for RTFM. ☺️
794
864
  [📌gitmoji]: https://gitmoji.dev
795
865
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
796
866
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
797
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.690-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
867
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.776-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
798
868
  [🔐security]: https://github.com/structuredmerge/structuredmerge-ruby/blob/main/SECURITY.md
799
869
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
800
870
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -215,6 +215,11 @@ rubyforum:
215
215
  # label - display value used in CI
216
216
  # slug - path-safe value used in gemfile_pattern
217
217
  # requirement - Bundler requirement written to the gemfile
218
+ # default - true for the one generated framework
219
+ # gemfile loaded by the root Gemfile for local
220
+ # `bundle exec kettle-test` commands
221
+ # replaces - direct root Gemfile dependencies replaced by
222
+ # the default framework gemfile
218
223
  # gemfile_pattern — pattern for gemfile paths; {version} is replaced
219
224
  # with each version slug (dots replaced by underscores
220
225
  # when the pattern contains an underscore placeholder).
@@ -225,7 +230,9 @@ rubyforum:
225
230
  # "rails_{version}" → gemfiles/rails_7_0.gemfile
226
231
  # Use this when you need a simple 2D matrix: Ruby × one framework gem/version axis.
227
232
  # For deeper or more complex matrices that are better modeled as Appraisals entries,
228
- # prefer kettle-jem-appraisals instead.
233
+ # prefer the kettle-jem-appraisals plugin instead. Its appraisal_matrix config
234
+ # controls generated Appraisals and CI strategy; pair it with test_bundle below
235
+ # when the root local Gemfile needs a stable framework or harness.
229
236
  #
230
237
  workflows:
231
238
  # Default command used by generated test workflows.
@@ -247,6 +254,35 @@ workflows:
247
254
  # requirement: ">= 8.0"
248
255
  # gemfile_pattern: "ar-{version}.x"
249
256
 
257
+ # Appraisal matrices are owned by the kettle-jem-appraisals plugin. It uses
258
+ # appraisal_matrix.mode, freshness_ttl, exec_cmd, appraisal_gemfiles,
259
+ # standard_appraisal_role, and gems.tier1 / gems.tier2 to generate the full
260
+ # Appraisals and CI matrix. It does not implicitly select the root local bundle;
261
+ # configure test_bundle below for that purpose.
262
+
263
+ # Default local test bundle.
264
+ # The root Gemfile is used by local bundle commands and is separate from
265
+ # Appraisals and CI, which use their own generated Gemfiles. Declare the
266
+ # project-specific test stack here instead of preserving it with freeze markers.
267
+ #
268
+ # gemfiles accepts either a path string or a mapping. `replaces` removes direct
269
+ # root Gemfile declarations that are supplied by the modular fragment.
270
+ # gems adds a direct declaration when a modular fragment is not warranted.
271
+ #
272
+ # test_bundle:
273
+ # gemfiles:
274
+ # - path: gemfiles/rails_7_2.gemfile
275
+ # replaces:
276
+ # - combustion
277
+ # - actionmailer
278
+ # - railties
279
+ # gems:
280
+ # - name: activerecord
281
+ # requirement: "~> 7.2"
282
+ # - name: debug
283
+ # requirement: "~> 1.11"
284
+ # require: false
285
+
250
286
  # Project-level third-party integrations.
251
287
  # Disabling an integration removes its upload/check action, suppresses its
252
288
  # README badges, skips templating its packaged config/workflow, and cleans up
@@ -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.21") # ruby >= {KJ|MIN_TEST_RUBY}
137
- spec.add_development_dependency("turbo_tests2", "~> 3.2", ">= 3.2.6") # ruby >= 2.4.0, default kettle-test runner
137
+ spec.add_development_dependency("turbo_tests2", "~> 3.2", ">= 3.2.7") # 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
@@ -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.10"
8
+ VERSION = "7.1.11"
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
@@ -3539,6 +3539,8 @@ module Kettle
3539
3539
  facts[:ci][:coverage] = coverage_config unless coverage_config.empty?
3540
3540
  framework_matrix = github_actions_framework_matrix(kettle_config)
3541
3541
  facts[:ci][:framework_matrix] = framework_matrix unless framework_matrix.empty?
3542
+ default_test_bundle = default_test_bundle_config(kettle_config, framework_matrix)
3543
+ facts[:ci][:default_test_bundle] = default_test_bundle unless default_test_bundle.empty?
3542
3544
  template_facts = {}
3543
3545
  template_preferences = template_source_preferences(
3544
3546
  project_root,
@@ -5399,12 +5401,12 @@ module Kettle
5399
5401
  {name: "kettle-dev", source: %(gem "kettle-dev", "~> 3.0", ">= 3.0.17"\n)},
5400
5402
  {name: "kettle-drift", source: %(gem "kettle-drift", "~> 1.0", ">= 1.0.13"\n)},
5401
5403
  {name: "kettle-family", source: %(gem "kettle-family", "~> 1.2", ">= 1.2.64"\n)},
5402
- {name: "kettle-jem", source: %(gem "kettle-jem", "~> 7.1", ">= 7.1.8"\n)},
5404
+ {name: "kettle-jem", source: %(gem "kettle-jem", "~> 7.1", ">= 7.1.10"\n)},
5403
5405
  {name: "kettle-test", source: %(gem "kettle-test", "~> 2.0", ">= 2.0.21"\n)},
5404
5406
  {name: "rake", source: %(gem "rake", "~> 13.0"\n)},
5405
5407
  {name: "rspec", source: %(gem "rspec", "~> 3.0"\n)},
5406
5408
  {name: "stone_checksums", source: %(gem "stone_checksums", "~> 1.0", ">= 1.0.8"\n)},
5407
- {name: "turbo_tests2", source: %(gem "turbo_tests2", "~> 3.2", ">= 3.2.6"\n)}
5409
+ {name: "turbo_tests2", source: %(gem "turbo_tests2", "~> 3.2", ">= 3.2.7"\n)}
5408
5410
  ].freeze
5409
5411
  end
5410
5412
 
@@ -5549,8 +5551,9 @@ module Kettle
5549
5551
  namespace,
5550
5552
  preferred_path: entrypoint_path
5551
5553
  )
5552
- entrypoint_namespace_superclasses = namespace_superclass_details.fetch(:superclasses)
5553
- entrypoint_namespace_superclasses = entrypoint_namespace_superclasses.merge(
5554
+ entrypoint_namespace_superclasses = version_namespace_superclasses_from_facts(facts).merge(
5555
+ namespace_superclass_details.fetch(:superclasses)
5556
+ ).merge(
5554
5557
  entrypoint_namespace_superclasses_from_facts(facts)
5555
5558
  )
5556
5559
  fact_superclass_path = facts.dig(:rubygems, :entrypoint_namespace_superclass_path).to_s
@@ -7976,6 +7979,7 @@ module Kettle
7976
7979
  output = preserve_destination_gemfile_source(output, destination_content)
7977
7980
  end
7978
7981
  output = inject_main_gemfile_recording_eval(output, facts)
7982
+ output = inject_main_gemfile_default_test_bundle(output, facts)
7979
7983
  output = remove_stale_main_gemfile_tree_sitter_language_pack(output, template_content)
7980
7984
  output = remove_stale_main_gemfile_direct_sibling_block(output, template_content)
7981
7985
  output = deduplicate_main_gemfile_direct_sibling_blocks(output)
@@ -9310,6 +9314,43 @@ module Kettle
9310
9314
  ensure_trailing_newline(lines.join.gsub(/\n{3,}/, "\n\n"))
9311
9315
  end
9312
9316
 
9317
+ # The root Gemfile is the local-development bundle. Appraisals and CI use
9318
+ # their own Gemfiles, so a project that needs a framework or application
9319
+ # harness locally must declare that dependency separately in test_bundle.
9320
+ def inject_main_gemfile_default_test_bundle(content, facts)
9321
+ bundle = facts.to_h.dig(:ci, :default_test_bundle).to_h
9322
+ return content if bundle.empty?
9323
+
9324
+ managed_gems = bundle.fetch(:managed_gems, [])
9325
+ output = remove_gemfile_dependency_blocks(content, managed_gems)
9326
+ existing_paths = gemfile_eval_paths(output).to_set
9327
+ additions = bundle.fetch(:gemfiles, []).filter_map do |path|
9328
+ next if existing_paths.include?(path)
9329
+
9330
+ %(eval_gemfile "#{path}")
9331
+ end
9332
+ additions.concat(bundle.fetch(:gems, []).map { |gem| default_test_bundle_gem_source(gem) })
9333
+ return output if additions.empty?
9334
+
9335
+ lines = output.to_s.lines
9336
+ insert_at = main_gemfile_default_test_bundle_insertion_index(output) || lines.length
9337
+ block = ["# Default local test bundle", *additions].join("\n")
9338
+ lines.insert(insert_at, "#{block}\n\n")
9339
+ ensure_trailing_newline(lines.join.gsub(/\n{3,}/, "\n\n"))
9340
+ end
9341
+
9342
+ def default_test_bundle_gem_source(gem)
9343
+ arguments = [gem.fetch(:name).inspect, *gem.fetch(:requirements, []).map(&:inspect)]
9344
+ arguments << "require: false" if gem[:require] == false
9345
+ "gem #{arguments.join(", ")}"
9346
+ end
9347
+
9348
+ def main_gemfile_default_test_bundle_insertion_index(content)
9349
+ main_gemfile_templating_eval_line(content) ||
9350
+ main_gemfile_first_eval_gemfile_line(content) ||
9351
+ main_gemfile_after_gemspec_line(content)
9352
+ end
9353
+
9313
9354
  def main_gemfile_recording_insertion_index(content)
9314
9355
  lines = content.to_s.lines
9315
9356
  call = ruby_call_records(content, :eval_gemfile).find do |candidate|
@@ -14198,7 +14239,7 @@ module Kettle
14198
14239
  root: ["src", "my", "kettle-dev"]
14199
14240
  )
14200
14241
  elsif Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("4.0.0")
14201
- gem "kettle-changelog", "~> 1.0", ">= 1.0.5"
14242
+ gem "kettle-changelog", "~> 1.0", ">= 1.0.6"
14202
14243
  end
14203
14244
  end
14204
14245
  RUBY
@@ -15341,8 +15382,9 @@ module Kettle
15341
15382
  namespace,
15342
15383
  preferred_path: entrypoint_path
15343
15384
  )
15344
- entrypoint_namespace_superclasses = namespace_superclass_details.fetch(:superclasses)
15345
- entrypoint_namespace_superclasses = entrypoint_namespace_superclasses.merge(
15385
+ entrypoint_namespace_superclasses = version_namespace_superclasses_from_facts(facts).merge(
15386
+ namespace_superclass_details.fetch(:superclasses)
15387
+ ).merge(
15346
15388
  entrypoint_namespace_superclasses_from_facts(facts)
15347
15389
  )
15348
15390
  fact_superclass_path = facts.dig(:rubygems, :entrypoint_namespace_superclass_path).to_s
@@ -15832,13 +15874,31 @@ module Kettle
15832
15874
  end
15833
15875
 
15834
15876
  def version_gem_bootstrap_entrypoint_content(content, namespace:, entrypoint_require:, namespace_superclasses: {}, version_require_path: nil)
15835
- current = normalize_entrypoint_version_require(
15836
- content,
15837
- entrypoint_require: entrypoint_require,
15838
- version_require_path: version_require_path,
15839
- after_declarations: !namespace_superclasses.empty?
15840
- )
15841
- current = remove_version_gem_class_eval_references(current) unless ruby_version_class_eval_namespaces(current).include?(namespace.to_s)
15877
+ current = if namespace_superclasses.empty?
15878
+ # Preserve the existing relative-require position when there is no
15879
+ # declaration ordering constraint.
15880
+ normalize_entrypoint_version_require(
15881
+ content,
15882
+ entrypoint_require: entrypoint_require,
15883
+ version_require_path: version_require_path
15884
+ )
15885
+ else
15886
+ # A namesake superclass is a declaration-order constraint: establish
15887
+ # the class, load version.rb, then extend its Version module.
15888
+ source = remove_version_gem_class_eval_references(content)
15889
+ source = ensure_entrypoint_namespace_superclass_declarations(
15890
+ source,
15891
+ namespace: namespace,
15892
+ namespace_superclasses: namespace_superclasses
15893
+ )
15894
+ normalize_entrypoint_version_require(
15895
+ source,
15896
+ entrypoint_require: entrypoint_require,
15897
+ version_require_path: version_require_path,
15898
+ after_declarations: true
15899
+ )
15900
+ end
15901
+ current = remove_version_gem_class_eval_references(current)
15842
15902
  lines = current.lines
15843
15903
  insert_lines = []
15844
15904
  if File.basename(entrypoint_require) != "version_gem" && !ruby_top_level_require?(current, "require", "version_gem")
@@ -15857,6 +15917,34 @@ module Kettle
15857
15917
  collapse_excess_blank_lines(updated)
15858
15918
  end
15859
15919
 
15920
+ def ensure_entrypoint_namespace_superclass_declarations(content, namespace:, namespace_superclasses: {})
15921
+ # A version file must only reopen a namesake class. When legacy source
15922
+ # declared that class and its superclass in version.rb, establish the
15923
+ # class in the entrypoint before requiring version.rb, then render the
15924
+ # version file without a superclass.
15925
+ segments = namespace.to_s.split("::").reject(&:empty?)
15926
+ return content.to_s if segments.empty? || namespace_superclasses.empty?
15927
+
15928
+ missing_superclass_declaration = namespace_superclasses.any? do |index, _superclass|
15929
+ ruby_namespace_declaration_node(content, segments.first(index + 1).join("::")).nil?
15930
+ end
15931
+ return content.to_s unless missing_superclass_declaration
15932
+
15933
+ namespace_kinds = segments.each_index.each_with_object({}) do |index, kinds|
15934
+ prefix = segments.first(index + 1).join("::")
15935
+ kinds[index] = ruby_namespace_declaration_kind(content, prefix) || :module
15936
+ kinds[index] = :class if namespace_superclasses.key?(index)
15937
+ end
15938
+ declaration = wrap_ruby_namespace(
15939
+ namespace,
15940
+ [],
15941
+ namespace_kinds: namespace_kinds,
15942
+ namespace_superclasses: namespace_superclasses
15943
+ ).join("\n")
15944
+ current = trim_trailing_blank_lines(content)
15945
+ current.empty? ? "#{declaration}\n" : "#{current}\n\n#{declaration}\n"
15946
+ end
15947
+
15860
15948
  def version_gem_free_entrypoint_content(content, entrypoint_require:, ensure_version_require: true, after_declarations: false, version_require_path: nil)
15861
15949
  current = remove_version_gem_entrypoint_references(content)
15862
15950
  unless ensure_version_require
@@ -18681,13 +18769,17 @@ module Kettle
18681
18769
  appraisal_gemfiles = framework_matrix_appraisal_gemfiles(raw)
18682
18770
  gemfiles = version_entries.map do |entry|
18683
18771
  gemfile = expand_framework_gemfile_pattern(pattern, entry.fetch(:slug))
18684
- {
18772
+ gemfile_entry = {
18685
18773
  path: framework_gemfile_path(gemfile),
18686
18774
  gem: framework_gem,
18687
18775
  requirement: entry.fetch(:requirement),
18688
18776
  env: entry.fetch(:env, {})
18689
18777
  }
18778
+ gemfile_entry[:default] = true if entry[:default]
18779
+ gemfile_entry[:replaces] = entry[:replaces] unless entry.fetch(:replaces, []).empty?
18780
+ gemfile_entry
18690
18781
  end.uniq { |entry| entry.fetch(:path) }
18782
+ default_gemfiles = gemfiles.select { |entry| entry[:default] }
18691
18783
  gemfiles.reject! { |entry| template_keep_destination_path?(config, entry.fetch(:path)) }
18692
18784
  {
18693
18785
  dimension: dimension,
@@ -18715,7 +18807,9 @@ module Kettle
18715
18807
  replaces: framework_matrix_replaced_appraisal_names(dimension, entry, name)
18716
18808
  }
18717
18809
  end
18718
- }
18810
+ }.tap do |matrix|
18811
+ matrix[:default_gemfiles] = default_gemfiles unless default_gemfiles.empty?
18812
+ end
18719
18813
  end
18720
18814
 
18721
18815
  def framework_matrix_replaced_appraisal_names(dimension, entry, name)
@@ -18756,12 +18850,16 @@ module Kettle
18756
18850
  requirement = raw.fetch("requirement", default_framework_matrix_requirement(label)).to_s.strip
18757
18851
  appraisal_name = (raw["appraisal"] || raw["appraisal_name"] || raw["standard_appraisal"]).to_s.strip
18758
18852
  env = framework_matrix_env(raw["env"])
18853
+ default = DecisionPolicy.value_to_boolean(raw["default"]) == true
18854
+ replaces = Array(raw["replaces"]).filter_map { |name| nonempty_string(name) }
18759
18855
  else
18760
18856
  label = raw.to_s.strip
18761
18857
  slug = label
18762
18858
  requirement = default_framework_matrix_requirement(label)
18763
18859
  appraisal_name = ""
18764
18860
  env = {}
18861
+ default = false
18862
+ replaces = []
18765
18863
  end
18766
18864
  return if label.empty? || slug.empty? || requirement.empty?
18767
18865
 
@@ -18773,9 +18871,75 @@ module Kettle
18773
18871
  entry[:appraisal_name] = appraisal_name unless appraisal_name.empty?
18774
18872
  entry[:standard_appraisal] = true if raw.is_a?(Hash) && raw["standard_appraisal"]
18775
18873
  entry[:env] = env unless env.empty?
18874
+ entry[:default] = true if default
18875
+ entry[:replaces] = replaces unless replaces.empty?
18776
18876
  entry
18777
18877
  end
18778
18878
 
18879
+ # Configures the dependencies used by `bundle exec kettle-test` without a
18880
+ # BUNDLE_GEMFILE override. This intentionally does not alter Appraisals or
18881
+ # CI matrices: those are owned by appraisal_matrix/framework_matrix.
18882
+ def default_test_bundle_config(config, framework_matrix)
18883
+ raw = config["test_bundle"]
18884
+ raw = {} unless raw.is_a?(Hash)
18885
+
18886
+ gemfiles = Array(raw["gemfiles"]).filter_map { |entry| default_test_bundle_gemfile_entry(entry) }
18887
+ gems = Array(raw["gems"]).filter_map { |entry| default_test_bundle_gem_entry(entry) }
18888
+ framework_defaults = framework_matrix.to_h.fetch(:default_gemfiles, []).select { |entry| entry[:default] }
18889
+ if framework_defaults.length > 1
18890
+ paths = framework_defaults.map { |entry| entry.fetch(:path) }.join(", ")
18891
+ raise ArgumentError, "workflows.framework_matrix has multiple default versions: #{paths}"
18892
+ end
18893
+ if (framework_default = framework_defaults.first)
18894
+ gemfiles << {
18895
+ path: framework_default.fetch(:path),
18896
+ replaces: framework_default.fetch(:replaces, [])
18897
+ }
18898
+ end
18899
+
18900
+ return {} if gemfiles.empty? && gems.empty?
18901
+
18902
+ {
18903
+ gemfiles: gemfiles.map { |entry| entry.fetch(:path) }.uniq,
18904
+ gems: gems,
18905
+ managed_gems: (gems.map { |entry| entry.fetch(:name) } + gemfiles.flat_map { |entry| entry.fetch(:replaces, []) }).uniq
18906
+ }
18907
+ end
18908
+
18909
+ def default_test_bundle_gemfile_entry(raw)
18910
+ if raw.is_a?(Hash)
18911
+ path = raw["path"].to_s.strip
18912
+ replaces = Array(raw["replaces"]).filter_map { |name| nonempty_string(name) }
18913
+ else
18914
+ path = raw.to_s.strip
18915
+ replaces = []
18916
+ end
18917
+ return if path.empty?
18918
+
18919
+ {path: path.start_with?("gemfiles/") ? path : "gemfiles/#{path}", replaces: replaces}
18920
+ end
18921
+
18922
+ def default_test_bundle_gem_entry(raw)
18923
+ return unless raw.is_a?(Hash)
18924
+
18925
+ name = (raw["name"] || raw["gem"]).to_s.strip
18926
+ return if name.empty?
18927
+
18928
+ requirements = raw.key?("requirements") ? Array(raw["requirements"]) : [raw["requirement"]]
18929
+ entry = {
18930
+ name: name,
18931
+ requirements: requirements.filter_map { |requirement| nonempty_string(requirement) }
18932
+ }
18933
+ require_value = DecisionPolicy.value_to_boolean(raw["require"])
18934
+ entry[:require] = false if require_value == false
18935
+ entry
18936
+ end
18937
+
18938
+ def nonempty_string(value)
18939
+ normalized = value.to_s.strip
18940
+ normalized unless normalized.empty?
18941
+ end
18942
+
18779
18943
  def framework_matrix_env(raw)
18780
18944
  return {} unless raw.is_a?(Hash)
18781
18945
 
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.10
4
+ version: 7.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -226,7 +226,7 @@ dependencies:
226
226
  version: '1.0'
227
227
  - - ">="
228
228
  - !ruby/object:Gem::Version
229
- version: 1.0.2
229
+ version: 1.0.6
230
230
  type: :runtime
231
231
  prerelease: false
232
232
  version_requirements: !ruby/object:Gem::Requirement
@@ -236,14 +236,14 @@ dependencies:
236
236
  version: '1.0'
237
237
  - - ">="
238
238
  - !ruby/object:Gem::Version
239
- version: 1.0.2
239
+ version: 1.0.6
240
240
  - !ruby/object:Gem::Dependency
241
241
  name: kettle-dev
242
242
  requirement: !ruby/object:Gem::Requirement
243
243
  requirements:
244
244
  - - ">="
245
245
  - !ruby/object:Gem::Version
246
- version: 2.3.5
246
+ version: 3.0.17
247
247
  - - "<"
248
248
  - !ruby/object:Gem::Version
249
249
  version: 4.0.0
@@ -253,7 +253,7 @@ dependencies:
253
253
  requirements:
254
254
  - - ">="
255
255
  - !ruby/object:Gem::Version
256
- version: 2.3.5
256
+ version: 3.0.17
257
257
  - - "<"
258
258
  - !ruby/object:Gem::Version
259
259
  version: 4.0.0
@@ -266,7 +266,7 @@ dependencies:
266
266
  version: '0.3'
267
267
  - - ">="
268
268
  - !ruby/object:Gem::Version
269
- version: 0.3.3
269
+ version: 0.3.14
270
270
  type: :runtime
271
271
  prerelease: false
272
272
  version_requirements: !ruby/object:Gem::Requirement
@@ -276,7 +276,7 @@ dependencies:
276
276
  version: '0.3'
277
277
  - - ">="
278
278
  - !ruby/object:Gem::Version
279
- version: 0.3.3
279
+ version: 0.3.14
280
280
  - !ruby/object:Gem::Dependency
281
281
  name: kettle-ndjson
282
282
  requirement: !ruby/object:Gem::Requirement
@@ -286,7 +286,7 @@ dependencies:
286
286
  version: '0.1'
287
287
  - - ">="
288
288
  - !ruby/object:Gem::Version
289
- version: 0.1.3
289
+ version: 0.1.13
290
290
  type: :runtime
291
291
  prerelease: false
292
292
  version_requirements: !ruby/object:Gem::Requirement
@@ -296,7 +296,7 @@ dependencies:
296
296
  version: '0.1'
297
297
  - - ">="
298
298
  - !ruby/object:Gem::Version
299
- version: 0.1.3
299
+ version: 0.1.13
300
300
  - !ruby/object:Gem::Dependency
301
301
  name: kettle-rb
302
302
  requirement: !ruby/object:Gem::Requirement
@@ -306,7 +306,7 @@ dependencies:
306
306
  version: '0.1'
307
307
  - - ">="
308
308
  - !ruby/object:Gem::Version
309
- version: 0.1.7
309
+ version: 0.1.11
310
310
  type: :runtime
311
311
  prerelease: false
312
312
  version_requirements: !ruby/object:Gem::Requirement
@@ -316,7 +316,7 @@ dependencies:
316
316
  version: '0.1'
317
317
  - - ">="
318
318
  - !ruby/object:Gem::Version
319
- version: 0.1.7
319
+ version: 0.1.11
320
320
  - !ruby/object:Gem::Dependency
321
321
  name: kramdown-merge
322
322
  requirement: !ruby/object:Gem::Requirement
@@ -494,7 +494,7 @@ dependencies:
494
494
  version: '2.0'
495
495
  - - ">="
496
496
  - !ruby/object:Gem::Version
497
- version: 2.0.4
497
+ version: 2.0.10
498
498
  type: :runtime
499
499
  prerelease: false
500
500
  version_requirements: !ruby/object:Gem::Requirement
@@ -504,7 +504,7 @@ dependencies:
504
504
  version: '2.0'
505
505
  - - ">="
506
506
  - !ruby/object:Gem::Version
507
- version: 2.0.4
507
+ version: 2.0.10
508
508
  - !ruby/object:Gem::Dependency
509
509
  name: toml-merge
510
510
  requirement: !ruby/object:Gem::Requirement
@@ -696,7 +696,7 @@ dependencies:
696
696
  version: '3.2'
697
697
  - - ">="
698
698
  - !ruby/object:Gem::Version
699
- version: 3.2.6
699
+ version: 3.2.7
700
700
  type: :development
701
701
  prerelease: false
702
702
  version_requirements: !ruby/object:Gem::Requirement
@@ -706,7 +706,7 @@ dependencies:
706
706
  version: '3.2'
707
707
  - - ">="
708
708
  - !ruby/object:Gem::Version
709
- version: 3.2.6
709
+ version: 3.2.7
710
710
  - !ruby/object:Gem::Dependency
711
711
  name: ruby-progressbar
712
712
  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.10
980
- changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.10/CHANGELOG.md
979
+ source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.11
980
+ changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.11/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.10
982
+ documentation_uri: https://www.rubydoc.info/gems/kettle-jem/7.1.11
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