kettle-jem 7.1.8 → 7.1.10

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: f6c5f5fc9bc53f2126159023d8c5648b14d48bf686a3db540d79468848fb3d30
4
- data.tar.gz: f44a05f17df8cb139e53b1bae7be96c439eada3e4f958387175e161ba08bf93b
3
+ metadata.gz: cc954a9b2e13ecec8a5dbf0858c76b7a7157f92fabd6f07092024690ab163048
4
+ data.tar.gz: '0628e48c05357df4f752ef7e252cb3992d380ab578faaeee44801d7e818ed39f'
5
5
  SHA512:
6
- metadata.gz: fdafbae49efd6f2858c718ee4b7df6a14502c561e8d98b9bf11c96d5b1795b4710f2eb0aeddb3951392d9ec164afb533aa7db4d56ea6ea7cb44da21bc9398efa
7
- data.tar.gz: 186e8070d0d5aed6c18d6db8937e3d267ac38bef6703f2e5445b6bdfffc6cf2da9a097f63b580084c7eabce82fe7631eaa6da18c45ddfe09da1fe2133bb7a55f
6
+ metadata.gz: 1c549dd026691dbfc28854df99784f1b3c8904237d19f23eaab450de64983c5f9116102811e385f997a661c443e4efe01b6832613dbef6da5c1d9b30eeaad451
7
+ data.tar.gz: 54991a0795b8d7da63318264a5dcefec11cbe78e0ba151a9a53ab56ff8c39b4b6375070b80007d0c446b59c4bc7ad2ee8756c63c25a209f3cf0edfd79b6e900e
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,59 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [7.1.10] - 2026-08-29
34
+
35
+ - TAG: [v7.1.10][7.1.10t]
36
+ - COVERAGE: 93.56% -- 10937/11690 lines in 16 files
37
+ - BRANCH COVERAGE: 76.95% -- 4658/6053 branches in 16 files
38
+ - 17.92% documented
39
+
40
+ ### Changed
41
+
42
+ - Record template-run changelog updates before the bootstrap commit so generated changes and their maintenance summary are committed together.
43
+
44
+ - [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
45
+ - kettle-changelog (>= 1.0.3 -> >= 1.0.5)
46
+ - kettle-dev (>= 3.0.13 -> >= 3.0.16)
47
+ - kettle-drift (>= 1.0.12 -> >= 1.0.13)
48
+ - kettle-family (>= 1.2.62 -> >= 1.2.63)
49
+ - kettle-jem (>= 7.1.7 -> >= 7.1.8)
50
+ - kettle-soup-cover (>= 3.0.9 -> >= 3.0.10)
51
+ - kettle-test (>= 2.0.20 -> >= 2.0.21)
52
+ - nomono (>= 1.1.4 -> >= 1.1.5)
53
+
54
+ - [kc] kettle-jem-workflow-pins: Update pinned GitHub Actions in kettle-jem templates:
55
+ - apache/skywalking-eyes/dependency v0.8.0 (61275cc80d0798a405cb070f7d3a8aaf7cf2c2c1) -> v0.9.0 (a196742f472feaffafea537ce5a2a4c3c53a8de4)
56
+ - github/codeql-action/analyze v4.37.8 (db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28) -> v4.37.9 (cdf488f595d80d6e07e03d4674febd5ab45fa938)
57
+ - github/codeql-action/autobuild v4.37.8 (db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28) -> v4.37.9 (cdf488f595d80d6e07e03d4674febd5ab45fa938)
58
+ - github/codeql-action/init v4.37.8 (db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28) -> v4.37.9 (cdf488f595d80d6e07e03d4674febd5ab45fa938)
59
+
60
+ - [kc] kettle-jem/template: updated 1194 project files:
61
+ - code and tests (60)
62
+ - configuration (36)
63
+ - dependencies (441)
64
+ - documentation (27)
65
+ - other (369)
66
+ - workflows (261)
67
+
68
+ - [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
69
+ - kettle-dev (>= 3.0.16 -> >= 3.0.17)
70
+ - kettle-family (>= 1.2.63 -> >= 1.2.64)
71
+
72
+ - [kc] kettle-jem/prepare: updated 13 project files:
73
+ - dependencies (13)
74
+
75
+ - [kc] kettle-jem/template: updated 3 project files:
76
+ - code and tests (1)
77
+ - dependencies (1)
78
+ - other (1)
79
+
80
+ ### Fixed
81
+
82
+ - Keep external superclass expressions out of generated standalone version files.
83
+
84
+ - Skip template changelog recording for partial destination projects that do not contain a changelog.
85
+
33
86
  ## [7.1.8] - 2026-08-26
34
87
 
35
88
  - TAG: [v7.1.8][7.1.8t]
@@ -1621,7 +1674,9 @@ Please file a bug if you notice a violation of semantic versioning.
1621
1674
  - Released kettle-jem as part of the initial StructuredMerge Ruby 7.0.0 gem set.
1622
1675
  - Included packaged templates and parser-backed merge support for Ruby gem templating.
1623
1676
 
1624
- [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.8...HEAD
1677
+ [Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.10...HEAD
1678
+ [7.1.10]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.8...v7.1.10
1679
+ [7.1.10t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.10
1625
1680
  [7.1.8]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.7...v7.1.8
1626
1681
  [7.1.8t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.8
1627
1682
  [7.1.7]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.6...v7.1.7
data/README.md CHANGED
@@ -794,7 +794,7 @@ Thanks for RTFM. ☺️
794
794
  [📌gitmoji]: https://gitmoji.dev
795
795
  [📌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
796
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
797
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.606-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
797
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-11.690-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
798
798
  [🔐security]: https://github.com/structuredmerge/structuredmerge-ruby/blob/main/SECURITY.md
799
799
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
800
800
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -234,6 +234,8 @@ module Kettle
234
234
  end
235
235
  return result unless %w[setup prepare apply template install].include?(command)
236
236
 
237
+ return result if result.is_a?(Hash) && result.key?(:changelog)
238
+
237
239
  Kettle::Jem::MaintenanceChangelog.record_template_run(
238
240
  project_root: project_root,
239
241
  report: result,
@@ -95,6 +95,10 @@ module Kettle
95
95
  return report.merge(changelog: {status: "skipped", reason: "no_template_changes", changed_files: []})
96
96
  end
97
97
 
98
+ unless File.file?(File.join(project_root, "CHANGELOG.md"))
99
+ return report.merge(changelog: {status: "skipped", reason: "missing_changelog"})
100
+ end
101
+
98
102
  key = TEMPLATE_CHANGELOG_KEYS.fetch(label, "kettle-jem/template")
99
103
  entry = ->(matches) { template_run_entry(changed_files, matches) }
100
104
  result = upsert_unreleased_entry(project_root: project_root, section: "Changed", key: key, entry: entry)
@@ -8,6 +8,7 @@ require "toml-rb"
8
8
  require "uri"
9
9
  require "yaml"
10
10
  require "kettle/rb/compat_matrix"
11
+ require "kettle/jem/maintenance_changelog"
11
12
 
12
13
  module Kettle
13
14
  module Jem
@@ -48,7 +49,6 @@ module Kettle
48
49
  install_steps << rubocop_gradual_autocorrect_step(project_root, env: setup_env, run_options: effective_run_options)
49
50
  install_steps << normalize_lockfile_step(project_root, env: setup_env, run_options: effective_run_options)
50
51
  install_steps << bundled_handoff_step(project_root: project_root, env: env, run_options: effective_run_options)
51
- install_steps << bootstrap_commit_step(project_root, run_options: effective_run_options)
52
52
  install_steps = execute_orchestration_steps(install_steps, project_root: project_root, env: setup_env, run_options: effective_run_options, command_runner: command_runner)
53
53
 
54
54
  final_report = report.merge(
@@ -62,6 +62,26 @@ module Kettle
62
62
  message: "kettle:jem:install applied templates, completed local post-template checks, and executed available orchestration steps."
63
63
  }]
64
64
  )
65
+ final_report = Kettle::Jem::MaintenanceChangelog.record_template_run(
66
+ project_root: project_root,
67
+ report: final_report,
68
+ run_options: effective_run_options
69
+ )
70
+ bootstrap_commit = bootstrap_commit_step(project_root, run_options: effective_run_options)
71
+ install_steps.concat(
72
+ execute_orchestration_steps(
73
+ [bootstrap_commit],
74
+ project_root: project_root,
75
+ env: setup_env,
76
+ run_options: effective_run_options,
77
+ command_runner: command_runner
78
+ )
79
+ )
80
+ final_report = final_report.merge(
81
+ install_steps: install_steps,
82
+ install_phase_reports: install_phase_reports(install_steps),
83
+ install_summary: install_step_summary(install_steps)
84
+ )
65
85
  Kettle::Jem.emit_summary_event(Kettle::Jem.event_stream_from_options(effective_run_options), final_report)
66
86
  final_report
67
87
  end
@@ -33,7 +33,7 @@ jobs:
33
33
  persist-credentials: false
34
34
 
35
35
  - name: Check Dependencies' License
36
- uses: apache/skywalking-eyes/dependency@61275cc80d0798a405cb070f7d3a8aaf7cf2c2c1 # v0.8.0
36
+ uses: apache/skywalking-eyes/dependency@a196742f472feaffafea537ce5a2a4c3c53a8de4 # v0.9.0
37
37
  with:
38
38
  config: .licenserc.yaml
39
39
  mode: "{KJ|LICENSE_EYE:MODE}"
@@ -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.13") # ruby >= {KJ|MIN_TEST_RUBY}
121
+ spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.17") # 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
@@ -133,7 +133,7 @@ Gem::Specification.new do |spec|
133
133
  # Loads version files in anonymous namespaces for coverage without constant redefinition warnings.
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
- spec.add_development_dependency("kettle-test", "~> 2.0", ">= 2.0.20") # ruby >= {KJ|MIN_TEST_RUBY}
136
+ spec.add_development_dependency("kettle-test", "~> 2.0", ">= 2.0.21") # ruby >= {KJ|MIN_TEST_RUBY}
137
137
  spec.add_development_dependency("turbo_tests2", "~> 3.2", ">= 3.2.6") # ruby >= 2.4.0, default kettle-test runner
138
138
 
139
139
  # Releasing
@@ -7,7 +7,7 @@
7
7
  if ENV.fetch("KETTLE_DEV_DEV", "false").casecmp("false").zero?
8
8
  # Coverage (remote/released)
9
9
  platform :mri do
10
- gem "kettle-soup-cover", "~> 3.0", ">= 3.0.9", require: false
10
+ gem "kettle-soup-cover", "~> 3.0", ">= 3.0.10", require: false
11
11
  end
12
12
  else
13
13
  eval_gemfile "coverage_local.gemfile"
@@ -23,7 +23,7 @@ end
23
23
 
24
24
  if kettle_remote
25
25
  # Template/plugin checks for released installs.
26
- gem "kettle-drift", "~> 1.0", ">= 1.0.12", require: false
26
+ gem "kettle-drift", "~> 1.0", ">= 1.0.13", require: false
27
27
  end
28
28
 
29
29
  # Set STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local development with path-based dependencies.
@@ -6,7 +6,7 @@ shimmed_gem_path = ENV["KETTLE_JEM_SHIMMED_GEM_PATH"].to_s
6
6
  gem "{KJ|SHIMMED_GEM_NAME}", path: shimmed_gem_path unless shimmed_gem_path.empty?
7
7
 
8
8
  # Local workspace dependency wiring for templating_local.gemfile overrides.
9
- gem "nomono", "~> 1.1", ">= 1.1.4", require: false # ruby >= 3.2.0
9
+ gem "nomono", "~> 1.1", ">= 1.1.5", require: false # ruby >= 3.2.0
10
10
 
11
11
  # Templating (env-switched: STRUCTUREDMERGE_DEV=/path/to/structuredmerge/ruby/gems for local paths)
12
12
  eval_gemfile "gemfiles/modular/templating.gemfile" if ENV.fetch("K_JEM_TEMPLATING", "false").casecmp("true").zero?
@@ -30,13 +30,13 @@ 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.13") # ruby >= {KJ|MIN_TEST_RUBY}
33
+ spec.add_development_dependency("kettle-dev", "~> 3.0", ">= 3.0.17") # ruby >= {KJ|MIN_TEST_RUBY}
34
34
 
35
35
  # Tasks
36
36
  spec.add_development_dependency "rake", "~> 13.0"
37
37
 
38
38
  # Testing
39
- spec.add_development_dependency("kettle-test", "~> 2.0", ">= 2.0.20") # ruby >= {KJ|MIN_TEST_RUBY}
39
+ spec.add_development_dependency("kettle-test", "~> 2.0", ">= 2.0.21") # ruby >= {KJ|MIN_TEST_RUBY}
40
40
  spec.add_development_dependency "rspec", "~> 3.12"
41
41
 
42
42
  # Releasing
@@ -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.8"
8
+ VERSION = "7.1.10"
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
@@ -525,6 +525,7 @@ module Kettle
525
525
  APPRAISAL_VERSION_SELECTION_MODES = %w[major minor patch minor-minmax semver].freeze
526
526
  DEFAULT_TEST_MINIMUM_RUBY = Gem::Version.new("2.4")
527
527
  REQUIRE_RELATIVE_MIN_RUBY = Gem::Version.new("2.2").freeze
528
+ ANONYMOUS_VERSION_LOADER_MIN_RUBY = Gem::Version.new("2.2").freeze
528
529
  MODERN_GEMSPEC_VERSION_LOADER_MIN_RUBY = Gem::Version.new("3.1").freeze
529
530
  APPRAISAL_DEFAULT_FRESHNESS_TTL = 604_800
530
531
  DECISION_ACTIONS = %w[create merge replace keep delete skip].freeze
@@ -3326,7 +3327,6 @@ module Kettle
3326
3327
  version_path = File.join("lib", entrypoint_require, "version.rb")
3327
3328
  entrypoint_path = File.join("lib", "#{entrypoint_require}.rb")
3328
3329
  configured_namespace = rubygems_config["namespace"].to_s.strip
3329
- entrypoint_namespace = existing_entrypoint_version_namespace(project_root, entrypoint_path)
3330
3330
  version_namespace = existing_version_namespace(project_root, version_path)
3331
3331
  version_namespace = reconcile_existing_version_namespace(
3332
3332
  project_root,
@@ -3334,27 +3334,38 @@ module Kettle
3334
3334
  version_path,
3335
3335
  version_namespace
3336
3336
  )
3337
+ metadata_namespace = metadata_value(gemspec_metadata, :namespace)
3338
+ default_namespace = classify_namespace(name)
3339
+ namespace_hint = configured_namespace.empty? ? default_namespace : configured_namespace
3340
+ entrypoint_namespace = existing_entrypoint_version_namespace(
3341
+ project_root,
3342
+ entrypoint_path,
3343
+ expected_depth: namespace_hint.split("::").count { |segment| !segment.empty? }
3344
+ )
3345
+ namespace = configured_namespace.empty? ? nil : configured_namespace
3346
+ namespace ||= project_namespace(
3347
+ entrypoint_namespace: entrypoint_namespace,
3348
+ version_namespace: version_namespace,
3349
+ metadata_namespace: metadata_namespace,
3350
+ default_namespace: default_namespace
3351
+ )
3337
3352
  version_namespace_kinds = existing_version_namespace_kinds(
3338
3353
  project_root,
3339
3354
  version_path,
3340
- version_namespace,
3355
+ namespace,
3341
3356
  entrypoint_path: entrypoint_path
3342
3357
  )
3343
3358
  version_namespace_superclasses = existing_version_namespace_superclasses(
3344
3359
  project_root,
3345
3360
  version_path,
3346
- version_namespace,
3347
- entrypoint_path: entrypoint_path
3361
+ namespace
3348
3362
  )
3349
- metadata_namespace = metadata_value(gemspec_metadata, :namespace)
3350
- default_namespace = classify_namespace(name)
3351
- namespace = configured_namespace.empty? ? nil : configured_namespace
3352
- namespace ||= project_namespace(
3353
- entrypoint_namespace: entrypoint_namespace,
3354
- version_namespace: version_namespace,
3355
- metadata_namespace: metadata_namespace,
3356
- default_namespace: default_namespace
3363
+ namespace_superclass_details = existing_namespace_superclass_details(
3364
+ project_root,
3365
+ namespace,
3366
+ preferred_path: entrypoint_path
3357
3367
  )
3368
+ entrypoint_namespace_superclasses = namespace_superclass_details.fetch(:superclasses)
3358
3369
  project_version = metadata_value(gemspec_metadata, :version)
3359
3370
  project_version = existing_version_file_value(project_root, version_path) unless valid_gem_version?(project_version)
3360
3371
  project_version = git_version_file_value(project_root, version_path) unless valid_gem_version?(project_version)
@@ -3428,6 +3439,8 @@ module Kettle
3428
3439
  min_ruby: min_ruby,
3429
3440
  version_namespace_kinds: version_namespace_kinds,
3430
3441
  version_namespace_superclasses: version_namespace_superclasses,
3442
+ entrypoint_namespace_superclasses: entrypoint_namespace_superclasses,
3443
+ entrypoint_namespace_superclass_path: namespace_superclass_details[:path],
3431
3444
  version_gem_default_enabled: version_gem_default_enabled_for_project?(rubygems_config, gemspec_metadata),
3432
3445
  engines: ruby_engines_config(kettle_config)
3433
3446
  )
@@ -5383,11 +5396,11 @@ module Kettle
5383
5396
  [
5384
5397
  {name: "appraisal2", source: %(gem "appraisal2", "~> 3.2", ">= 3.2.2"\n)},
5385
5398
  {name: "bundler-audit", source: %(gem "bundler-audit", "~> 0.9.3"\n)},
5386
- {name: "kettle-dev", source: %(gem "kettle-dev", "~> 3.0", ">= 3.0.13"\n)},
5387
- {name: "kettle-drift", source: %(gem "kettle-drift", "~> 1.0", ">= 1.0.12"\n)},
5388
- {name: "kettle-family", source: %(gem "kettle-family", "~> 1.2", ">= 1.2.62"\n)},
5389
- {name: "kettle-jem", source: %(gem "kettle-jem", "~> 7.1", ">= 7.1.7"\n)},
5390
- {name: "kettle-test", source: %(gem "kettle-test", "~> 2.0", ">= 2.0.20"\n)},
5399
+ {name: "kettle-dev", source: %(gem "kettle-dev", "~> 3.0", ">= 3.0.17"\n)},
5400
+ {name: "kettle-drift", source: %(gem "kettle-drift", "~> 1.0", ">= 1.0.13"\n)},
5401
+ {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)},
5403
+ {name: "kettle-test", source: %(gem "kettle-test", "~> 2.0", ">= 2.0.21"\n)},
5391
5404
  {name: "rake", source: %(gem "rake", "~> 13.0"\n)},
5392
5405
  {name: "rspec", source: %(gem "rspec", "~> 3.0"\n)},
5393
5406
  {name: "stone_checksums", source: %(gem "stone_checksums", "~> 1.0", ">= 1.0.8"\n)},
@@ -5469,8 +5482,15 @@ module Kettle
5469
5482
  templated_paths = report.fetch(:recipe_reports, []).map { |recipe_report| recipe_report.fetch(:relative_path, "") }
5470
5483
  version_path = File.join("lib", entrypoint_require, "version.rb")
5471
5484
  signature_path = File.join("sig", "#{entrypoint_require}.rbs")
5472
- entrypoint_path = File.join("lib", "#{entrypoint_require}.rb")
5473
5485
  namespace = facts.dig(:rubygems, :namespace).to_s
5486
+ entrypoint_path = facts.dig(:rubygems, :entrypoint_namespace_superclass_path).to_s
5487
+ entrypoint_path = File.join("lib", "#{entrypoint_require}.rb") unless File.file?(File.join(project_root, entrypoint_path))
5488
+ namespace_superclass_details = existing_namespace_superclass_details(
5489
+ project_root,
5490
+ namespace,
5491
+ preferred_path: entrypoint_path
5492
+ )
5493
+ entrypoint_path = namespace_superclass_details[:path] if namespace_superclass_details[:path]
5474
5494
  version_gem_bootstrap_step_for_paths(
5475
5495
  project_root,
5476
5496
  facts,
@@ -5511,17 +5531,36 @@ module Kettle
5511
5531
 
5512
5532
  entrypoint_require = package_name.tr("-", "/") if entrypoint_require.to_s.empty?
5513
5533
  namespace = facts.dig(:rubygems, :namespace).to_s
5514
- namespace = classify_namespace(package_name) if namespace.empty?
5515
5534
  version_path = File.join("lib", entrypoint_require, "version.rb")
5516
5535
  entrypoint_path = File.join("lib", "#{entrypoint_require}.rb")
5517
- namespace = existing_entrypoint_version_namespace(project_root, entrypoint_path).to_s if namespace.empty?
5536
+ if namespace.empty?
5537
+ namespace = existing_entrypoint_version_namespace(
5538
+ project_root,
5539
+ entrypoint_path,
5540
+ expected_depth: classify_namespace(package_name).split("::").count { |segment| !segment.empty? }
5541
+ ).to_s
5542
+ end
5518
5543
  namespace = existing_version_namespace(project_root, version_path).to_s if namespace.empty?
5544
+ namespace = classify_namespace(package_name) if namespace.empty?
5519
5545
  return {name: "version_bootstrap", status: "unavailable", reason: "missing_package_facts"} if namespace.empty?
5520
5546
 
5547
+ namespace_superclass_details = existing_namespace_superclass_details(
5548
+ project_root,
5549
+ namespace,
5550
+ preferred_path: entrypoint_path
5551
+ )
5552
+ entrypoint_namespace_superclasses = namespace_superclass_details.fetch(:superclasses)
5553
+ entrypoint_namespace_superclasses = entrypoint_namespace_superclasses.merge(
5554
+ entrypoint_namespace_superclasses_from_facts(facts)
5555
+ )
5556
+ fact_superclass_path = facts.dig(:rubygems, :entrypoint_namespace_superclass_path).to_s
5557
+ if entrypoint_namespace_superclasses.any? && File.file?(File.join(project_root, fact_superclass_path))
5558
+ entrypoint_path = fact_superclass_path
5559
+ elsif namespace_superclass_details[:path]
5560
+ entrypoint_path = namespace_superclass_details[:path]
5561
+ end
5521
5562
  templated_paths = report.fetch(:recipe_reports, []).map { |recipe_report| recipe_report.fetch(:relative_path, "") }
5522
5563
  changes = []
5523
- cleanup = version_gem_cleanup_step(project_root, facts)
5524
- changes.concat(Array(cleanup[:changed_files]))
5525
5564
  outer_namespace_kind = version_namespace_outer_kind(project_root, entrypoint_path, namespace)
5526
5565
  namespace_kinds = existing_version_namespace_kinds(
5527
5566
  project_root,
@@ -5529,12 +5568,13 @@ module Kettle
5529
5568
  namespace,
5530
5569
  entrypoint_path: entrypoint_path
5531
5570
  )
5532
- namespace_superclasses = existing_version_namespace_superclasses(
5571
+ cleanup = version_gem_cleanup_step(
5533
5572
  project_root,
5534
- version_path,
5535
- namespace,
5536
- entrypoint_path: entrypoint_path
5573
+ facts,
5574
+ entrypoint_path: entrypoint_path,
5575
+ after_declarations: !entrypoint_namespace_superclasses.empty?
5537
5576
  )
5577
+ changes.concat(Array(cleanup[:changed_files]))
5538
5578
  preserve_version_module_include = existing_version_file_includes_version_module?(project_root, version_path) if preserve_version_module_include.nil?
5539
5579
  unless templated_paths.include?(version_path) && outer_namespace_kind != :class
5540
5580
  version = facts.dig(:project_runtime, :version).to_s
@@ -5549,7 +5589,6 @@ module Kettle
5549
5589
  version: version,
5550
5590
  outer_namespace_kind: outer_namespace_kind,
5551
5591
  namespace_kinds: namespace_kinds,
5552
- namespace_superclasses: namespace_superclasses,
5553
5592
  preserve_version_module_include: preserve_version_module_include
5554
5593
  )
5555
5594
  )
@@ -5593,13 +5632,13 @@ module Kettle
5593
5632
  }
5594
5633
  end
5595
5634
 
5596
- def version_gem_cleanup_step(project_root, facts, cleanup_entrypoint: true)
5635
+ def version_gem_cleanup_step(project_root, facts, cleanup_entrypoint: true, after_declarations: false, entrypoint_path: nil)
5597
5636
  package_name = facts.dig(:package, :name).to_s
5598
5637
  return {name: "version_gem_cleanup", status: "unavailable", reason: "missing_package_facts"} if package_name.empty?
5599
5638
 
5600
5639
  entrypoint_require = facts.dig(:rubygems, :entrypoint_require).to_s
5601
5640
  entrypoint_require = package_name.tr("-", "/") if entrypoint_require.empty?
5602
- entrypoint_path = File.join("lib", "#{entrypoint_require}.rb")
5641
+ entrypoint_path ||= File.join("lib", "#{entrypoint_require}.rb")
5603
5642
  dedicated_entrypoint_path = File.join("lib", entrypoint_require, "version_gem.rb")
5604
5643
  version_spec_path = File.join("spec", entrypoint_require, "version_spec.rb")
5605
5644
  changed_files = []
@@ -5609,7 +5648,8 @@ module Kettle
5609
5648
  cleaned = version_gem_free_entrypoint_content(
5610
5649
  current,
5611
5650
  entrypoint_require: entrypoint_require,
5612
- ensure_version_require: File.file?(version_path)
5651
+ ensure_version_require: File.file?(version_path),
5652
+ after_declarations: after_declarations
5613
5653
  )
5614
5654
  changed_files << write_if_changed(project_root, entrypoint_path, cleaned)
5615
5655
  end
@@ -6894,10 +6934,12 @@ module Kettle
6894
6934
  modern = Gem::Version.new(min_ruby) >= MODERN_GEMSPEC_VERSION_LOADER_MIN_RUBY
6895
6935
  before_legacy = !gemspec_top_level_gem_version_node(original).nil?
6896
6936
  after_legacy = !gemspec_top_level_gem_version_node(final).nil?
6937
+ superclass_sensitive = gemspec_version_loader_superclass_sensitive?(request[:runtime_context] || request["runtime_context"] || {})
6897
6938
  {
6898
6939
  operation: "rewrite_version_loader",
6899
6940
  min_ruby: min_ruby,
6900
6941
  mode: modern ? "modern" : "legacy",
6942
+ superclass_sensitive: superclass_sensitive,
6901
6943
  legacy_preamble_removed: before_legacy && !after_legacy,
6902
6944
  legacy_preamble_present: after_legacy
6903
6945
  }
@@ -8208,8 +8250,6 @@ module Kettle
8208
8250
  )
8209
8251
  end
8210
8252
  main_gemfile_nomono_requirement_records(output).fetch(:calls).sort_by { |record| -record.fetch(:start_line) }.reduce(output) do |memo, record|
8211
- next memo unless record.fetch(:source).include?("*nomono_requirements")
8212
-
8213
8253
  replace_source_range_lines(memo, record.fetch(:start_line), record.fetch(:end_line), "#{nomono_gemfile_declaration}\n")
8214
8254
  end
8215
8255
  end
@@ -10526,7 +10566,18 @@ module Kettle
10526
10566
  modern = min_ruby_version >= MODERN_GEMSPEC_VERSION_LOADER_MIN_RUBY
10527
10567
  rhs = modern ? gemspec_modern_version_loader_expression(entrypoint_require: entrypoint_require, namespace: namespace) : "gem_version"
10528
10568
  rewritten = replace_gemspec_version_assignment(content, receiver: receiver, rhs: rhs)
10529
- modern ? remove_gemspec_legacy_version_loader_preamble(rewritten) : ensure_gemspec_legacy_version_loader_preamble(rewritten, entrypoint_require: entrypoint_require, namespace: namespace, min_ruby: min_ruby_version)
10569
+ if modern
10570
+ remove_gemspec_legacy_version_loader_preamble(rewritten)
10571
+ else
10572
+ ensure_gemspec_legacy_version_loader_preamble(
10573
+ rewritten,
10574
+ entrypoint_require: entrypoint_require,
10575
+ namespace: namespace,
10576
+ min_ruby: min_ruby_version,
10577
+ superclass_sensitive: gemspec_version_loader_superclass_sensitive?(facts),
10578
+ fallback_version: facts.to_h.dig(:project_runtime, :version)
10579
+ )
10580
+ end
10530
10581
  rescue ArgumentError, Ast::Crispr::Error
10531
10582
  content
10532
10583
  end
@@ -10546,7 +10597,48 @@ module Kettle
10546
10597
  %(Module.new.tap { |mod| Kernel.load("\#{__dir__}/lib/#{entrypoint_require}/version.rb", mod) }::#{namespace}::Version::VERSION)
10547
10598
  end
10548
10599
 
10549
- def gemspec_legacy_version_loader_block(entrypoint_require:, namespace:, min_ruby:)
10600
+ def gemspec_legacy_version_loader_block(entrypoint_require:, namespace:, min_ruby:, superclass_sensitive: false, fallback_version: nil)
10601
+ unless superclass_sensitive
10602
+ return gemspec_standard_legacy_version_loader_block(
10603
+ entrypoint_require: entrypoint_require,
10604
+ namespace: namespace,
10605
+ min_ruby: min_ruby
10606
+ )
10607
+ end
10608
+
10609
+ anonymous_loader = <<~RUBY.chomp
10610
+ require "anonymous_loader"
10611
+ path = File.expand_path("lib/#{entrypoint_require}/version.rb", __dir__)
10612
+ anonymous_namespace = AnonymousLoader.load(files: path)
10613
+ anonymous_namespace::#{namespace}::Version::VERSION
10614
+ RUBY
10615
+ anonymous_loader_lines = anonymous_loader.lines.map { |line| " #{line.chomp}" }
10616
+ fallback = fallback_version.to_s
10617
+ fallback = "0.0.0" if fallback.empty?
10618
+ lines = [
10619
+ "gem_version =",
10620
+ " if Gem.ruby_version >= Gem::Version.new(\"3.1\")",
10621
+ " # Loading Version into an anonymous module allows version.rb to get code coverage from SimpleCov!",
10622
+ " # See: https://github.com/simplecov-ruby/simplecov/issues/557#issuecomment-2630782358",
10623
+ " # See: https://github.com/panorama-ed/memo_wise/pull/397",
10624
+ " #{gemspec_modern_version_loader_expression(entrypoint_require: entrypoint_require, namespace: namespace)}"
10625
+ ]
10626
+ lines << " # The namesake namespace has a superclass. Directly requiring version.rb"
10627
+ lines << " # on legacy Ruby could define that namespace with the wrong superclass."
10628
+ if min_ruby < ANONYMOUS_VERSION_LOADER_MIN_RUBY
10629
+ lines << " elsif Gem.ruby_version >= Gem::Version.new(\"2.2\")"
10630
+ lines.concat(anonymous_loader_lines)
10631
+ lines << " else"
10632
+ lines << " #{fallback.dump}"
10633
+ else
10634
+ lines << " else"
10635
+ lines.concat(anonymous_loader_lines)
10636
+ end
10637
+ lines << " end"
10638
+ "#{lines.join("\n")}\n"
10639
+ end
10640
+
10641
+ def gemspec_standard_legacy_version_loader_block(entrypoint_require:, namespace:, min_ruby:)
10550
10642
  legacy_require =
10551
10643
  if min_ruby >= REQUIRE_RELATIVE_MIN_RUBY
10552
10644
  %(require_relative "lib/#{entrypoint_require}/version")
@@ -10574,6 +10666,14 @@ module Kettle
10574
10666
  RUBY
10575
10667
  end
10576
10668
 
10669
+ def gemspec_version_loader_superclass_sensitive?(facts)
10670
+ rubygems = facts.to_h[:rubygems]
10671
+ return false unless rubygems.is_a?(Hash)
10672
+
10673
+ value = rubygems[:entrypoint_namespace_superclasses]
10674
+ value.is_a?(Hash) && !value.empty?
10675
+ end
10676
+
10577
10677
  def remove_gemspec_legacy_version_loader_preamble(content)
10578
10678
  node = gemspec_top_level_gem_version_node(content)
10579
10679
  unless node
@@ -10606,8 +10706,8 @@ module Kettle
10606
10706
  {start_line: start_index + 1, end_line: end_line}
10607
10707
  end
10608
10708
 
10609
- def ensure_gemspec_legacy_version_loader_preamble(content, entrypoint_require:, namespace:, min_ruby:)
10610
- block = "#{gemspec_legacy_version_loader_block(entrypoint_require: entrypoint_require, namespace: namespace, min_ruby: min_ruby)}\n"
10709
+ def ensure_gemspec_legacy_version_loader_preamble(content, entrypoint_require:, namespace:, min_ruby:, superclass_sensitive: false, fallback_version: nil)
10710
+ block = "#{gemspec_legacy_version_loader_block(entrypoint_require: entrypoint_require, namespace: namespace, min_ruby: min_ruby, superclass_sensitive: superclass_sensitive, fallback_version: fallback_version)}\n"
10611
10711
  node = gemspec_top_level_gem_version_node(content)
10612
10712
  return replace_source_range_lines(content, node.location.start_line, expand_line_range_through_following_blanks(content, node.location.end_line), block) if node
10613
10713
 
@@ -14098,7 +14198,7 @@ module Kettle
14098
14198
  root: ["src", "my", "kettle-dev"]
14099
14199
  )
14100
14200
  elsif Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("4.0.0")
14101
- gem "kettle-changelog", "~> 1.0", ">= 1.0.3"
14201
+ gem "kettle-changelog", "~> 1.0", ">= 1.0.5"
14102
14202
  end
14103
14203
  end
14104
14204
  RUBY
@@ -15122,7 +15222,7 @@ module Kettle
15122
15222
  def main_gemfile_kettle_family_gem(package_name)
15123
15223
  return "" if package_name.to_s == "kettle-family"
15124
15224
 
15125
- %(gem "kettle-family", "~> 1.2", ">= 1.2.62"\n)
15225
+ %(gem "kettle-family", "~> 1.2", ">= 1.2.64"\n)
15126
15226
  end
15127
15227
 
15128
15228
  def main_gemfile_nomono_bootstrap(package_name)
@@ -15135,7 +15235,7 @@ module Kettle
15135
15235
  end
15136
15236
 
15137
15237
  def nomono_gemfile_declaration
15138
- %(gem "nomono", "~> 1.1", ">= 1.1.4", require: false # ruby >= 3.2.0)
15238
+ %(gem "nomono", "~> 1.1", ">= 1.1.5", require: false # ruby >= 3.2.0)
15139
15239
  end
15140
15240
 
15141
15241
  def local_gemfile_nomono_bootstrap(_package_name)
@@ -15143,7 +15243,7 @@ module Kettle
15143
15243
  # Bootstrapping nomono here cannot rely on a plain `gem "nomono", ...` line.
15144
15244
  # Bundler records that dependency during Gemfile evaluation, but it does not
15145
15245
  # activate that exact version before the immediate `require "nomono/bundler"`.
15146
- nomono_activation_requirements = ["~> 1.1", ">= 1.1.4"]
15246
+ nomono_activation_requirements = ["~> 1.1", ">= 1.1.5"]
15147
15247
  nomono_requirement = Gem::Requirement.new(nomono_activation_requirements)
15148
15248
  nomono_already_activated = Gem.loaded_specs["nomono"]
15149
15249
  nomono_lockfile = File.expand_path("../../Gemfile.lock", __dir__)
@@ -15221,6 +15321,36 @@ module Kettle
15221
15321
  )
15222
15322
  default_entrypoint_path = File.join("lib", "#{entrypoint_require}.rb")
15223
15323
  default_entrypoint = read_project_file(project_root, default_entrypoint_path)
15324
+ version_spec_path = File.join("spec", entrypoint_require, "version_spec.rb")
15325
+ signature_path = File.join("sig", "#{entrypoint_require}.rbs")
15326
+ legacy_signature_paths = legacy_rbs_signature_paths(project_root, entrypoint_require)
15327
+ namespace = facts.dig(:rubygems, :namespace).to_s
15328
+ if namespace.empty?
15329
+ namespace = existing_entrypoint_version_namespace(
15330
+ project_root,
15331
+ entrypoint_path,
15332
+ expected_depth: classify_namespace(package_name).split("::").count { |segment| !segment.empty? }
15333
+ ).to_s
15334
+ end
15335
+ namespace = existing_version_namespace(project_root, version_path).to_s if namespace.empty?
15336
+ namespace = classify_namespace(package_name) if namespace.empty?
15337
+ return {name: "version_gem_bootstrap", status: "unavailable", reason: "missing_package_facts"} if namespace.empty?
15338
+
15339
+ namespace_superclass_details = existing_namespace_superclass_details(
15340
+ project_root,
15341
+ namespace,
15342
+ preferred_path: entrypoint_path
15343
+ )
15344
+ entrypoint_namespace_superclasses = namespace_superclass_details.fetch(:superclasses)
15345
+ entrypoint_namespace_superclasses = entrypoint_namespace_superclasses.merge(
15346
+ entrypoint_namespace_superclasses_from_facts(facts)
15347
+ )
15348
+ fact_superclass_path = facts.dig(:rubygems, :entrypoint_namespace_superclass_path).to_s
15349
+ if entrypoint_namespace_superclasses.any? && File.file?(File.join(project_root, fact_superclass_path))
15350
+ entrypoint_path = fact_superclass_path
15351
+ elsif namespace_superclass_details[:path]
15352
+ entrypoint_path = namespace_superclass_details[:path]
15353
+ end
15224
15354
  default_entrypoint_loads_version = entrypoint_path != default_entrypoint_path &&
15225
15355
  entrypoint_loads_version_file?(
15226
15356
  default_entrypoint,
@@ -15228,25 +15358,20 @@ module Kettle
15228
15358
  entrypoint_path: default_entrypoint_path,
15229
15359
  version_path: version_path
15230
15360
  )
15231
- version_spec_path = File.join("spec", entrypoint_require, "version_spec.rb")
15232
- signature_path = File.join("sig", "#{entrypoint_require}.rbs")
15233
- legacy_signature_paths = legacy_rbs_signature_paths(project_root, entrypoint_require)
15234
- namespace = existing_version_namespace(project_root, version_path).to_s
15235
- namespace = facts.dig(:rubygems, :namespace).to_s if namespace.empty?
15236
- namespace = classify_namespace(package_name) if namespace.empty?
15237
- namespace = existing_entrypoint_version_namespace(project_root, entrypoint_path).to_s if namespace.empty?
15238
- return {name: "version_gem_bootstrap", status: "unavailable", reason: "missing_package_facts"} if namespace.empty?
15239
-
15240
15361
  version = facts.dig(:project_runtime, :version).to_s
15241
15362
  version = project_gemspec_version(project_root) if version.empty?
15242
15363
  version = "0.0.1.pre" if version.empty?
15243
15364
  changes = []
15244
15365
  current_entrypoint = read_project_file(project_root, entrypoint_path)
15245
15366
  outer_namespace_kind = ruby_entrypoint_outer_namespace_kind(current_entrypoint, namespace)
15246
- namespace_kinds = existing_version_namespace_kinds(project_root, version_path, namespace)
15247
- namespace_kinds = namespace_kinds.merge(version_namespace_kinds_from_facts(facts))
15248
- namespace_superclasses = existing_version_namespace_superclasses(project_root, version_path, namespace)
15249
- namespace_superclasses = namespace_superclasses.merge(version_namespace_superclasses_from_facts(facts))
15367
+ namespace_kinds = version_namespace_kinds_from_facts(facts).merge(
15368
+ existing_version_namespace_kinds(
15369
+ project_root,
15370
+ version_path,
15371
+ namespace,
15372
+ entrypoint_path: entrypoint_path
15373
+ )
15374
+ )
15250
15375
  preserve_version_module_include = existing_version_file_includes_version_module?(project_root, version_path) if preserve_version_module_include.nil?
15251
15376
 
15252
15377
  if manage_version_file
@@ -15259,7 +15384,6 @@ module Kettle
15259
15384
  version: version,
15260
15385
  outer_namespace_kind: outer_namespace_kind,
15261
15386
  namespace_kinds: namespace_kinds,
15262
- namespace_superclasses: namespace_superclasses,
15263
15387
  preserve_version_module_include: preserve_version_module_include
15264
15388
  )
15265
15389
  )
@@ -15271,6 +15395,7 @@ module Kettle
15271
15395
  current_entrypoint,
15272
15396
  entrypoint_require: entrypoint_require,
15273
15397
  ensure_version_require: !default_entrypoint_loads_version,
15398
+ after_declarations: !entrypoint_namespace_superclasses.empty?,
15274
15399
  version_require_path: version_require_path_for_entrypoint(entrypoint_path, version_path)
15275
15400
  )
15276
15401
  elsif current_entrypoint.empty?
@@ -15280,6 +15405,7 @@ module Kettle
15280
15405
  current_entrypoint,
15281
15406
  namespace: namespace,
15282
15407
  entrypoint_require: entrypoint_require,
15408
+ namespace_superclasses: entrypoint_namespace_superclasses,
15283
15409
  version_require_path: version_require_path_for_entrypoint(entrypoint_path, version_path)
15284
15410
  )
15285
15411
  end
@@ -15662,7 +15788,7 @@ module Kettle
15662
15788
  version_gem_require_insertion_index(content)
15663
15789
  end
15664
15790
 
15665
- def version_gem_version_file_content(existing_version:, namespace:, version:, outer_namespace_kind: :module, namespace_kinds: {}, namespace_superclasses: {}, preserve_version_module_include: false)
15791
+ def version_gem_version_file_content(existing_version:, namespace:, version:, outer_namespace_kind: :module, namespace_kinds: {}, preserve_version_module_include: false)
15666
15792
  resolved_version = existing_version.to_s.empty? ? version.to_s : existing_version.to_s
15667
15793
  body = [
15668
15794
  "# Version namespace for this gem.",
@@ -15678,7 +15804,7 @@ module Kettle
15678
15804
  <<~RUBY
15679
15805
  # frozen_string_literal: true
15680
15806
 
15681
- #{wrap_ruby_namespace(namespace, body, outer_namespace_kind: outer_namespace_kind, namespace_kinds: namespace_kinds, namespace_superclasses: namespace_superclasses).join("\n")}
15807
+ #{wrap_ruby_namespace(namespace, body, outer_namespace_kind: outer_namespace_kind, namespace_kinds: namespace_kinds).join("\n")}
15682
15808
  RUBY
15683
15809
  end
15684
15810
 
@@ -15705,11 +15831,12 @@ module Kettle
15705
15831
  "#{wrap_ruby_namespace(namespace, body).join("\n")}\n"
15706
15832
  end
15707
15833
 
15708
- def version_gem_bootstrap_entrypoint_content(content, namespace:, entrypoint_require:, version_require_path: nil)
15834
+ def version_gem_bootstrap_entrypoint_content(content, namespace:, entrypoint_require:, namespace_superclasses: {}, version_require_path: nil)
15709
15835
  current = normalize_entrypoint_version_require(
15710
15836
  content,
15711
15837
  entrypoint_require: entrypoint_require,
15712
- version_require_path: version_require_path
15838
+ version_require_path: version_require_path,
15839
+ after_declarations: !namespace_superclasses.empty?
15713
15840
  )
15714
15841
  current = remove_version_gem_class_eval_references(current) unless ruby_version_class_eval_namespaces(current).include?(namespace.to_s)
15715
15842
  lines = current.lines
@@ -15730,7 +15857,7 @@ module Kettle
15730
15857
  collapse_excess_blank_lines(updated)
15731
15858
  end
15732
15859
 
15733
- def version_gem_free_entrypoint_content(content, entrypoint_require:, ensure_version_require: true, version_require_path: nil)
15860
+ def version_gem_free_entrypoint_content(content, entrypoint_require:, ensure_version_require: true, after_declarations: false, version_require_path: nil)
15734
15861
  current = remove_version_gem_entrypoint_references(content)
15735
15862
  unless ensure_version_require
15736
15863
  relative_path = version_require_path.to_s.empty? ? File.join(File.basename(entrypoint_require), "version") : version_require_path.to_s
@@ -15745,17 +15872,23 @@ module Kettle
15745
15872
  normalize_entrypoint_version_require(
15746
15873
  current,
15747
15874
  entrypoint_require: entrypoint_require,
15748
- version_require_path: version_require_path
15875
+ version_require_path: version_require_path,
15876
+ after_declarations: after_declarations
15749
15877
  )
15750
15878
  end
15751
15879
 
15752
- def normalize_entrypoint_version_require(content, entrypoint_require:, version_require_path: nil)
15880
+ def normalize_entrypoint_version_require(content, entrypoint_require:, version_require_path: nil, after_declarations: false)
15753
15881
  relative_path = version_require_path.to_s.empty? ? File.join(File.basename(entrypoint_require), "version") : version_require_path.to_s
15754
15882
  absolute_path = File.join(entrypoint_require, "version")
15755
15883
  legacy_relative_path = File.join(File.basename(entrypoint_require), "version")
15756
15884
  current = [relative_path, legacy_relative_path].uniq.reduce(content) do |value, path|
15757
15885
  remove_entrypoint_version_requires(value, relative_path: path, absolute_path: absolute_path)
15758
15886
  end
15887
+ if after_declarations
15888
+ current = trim_trailing_blank_lines(collapse_excess_blank_lines(current))
15889
+ return "#{current}\n\nrequire_relative \"#{relative_path}\"\n" unless current.empty?
15890
+ end
15891
+
15759
15892
  lines = current.lines
15760
15893
  lines.insert(version_gem_require_insertion_index(current), %(require_relative "#{relative_path}"\n), "\n")
15761
15894
  trim_trailing_blank_lines(collapse_excess_blank_lines(lines.join))
@@ -15923,6 +16056,9 @@ module Kettle
15923
16056
  kind = version_namespace_outer_kind(project_root, entrypoint_path, namespace)
15924
16057
  return kind if kind == :class
15925
16058
 
16059
+ entrypoint_kind = ruby_namespace_declaration_kind(read_project_file(project_root, entrypoint_path), namespace)
16060
+ return entrypoint_kind if entrypoint_kind == :class
16061
+
15926
16062
  configured_kinds = version_namespace_kinds_from_facts(facts)
15927
16063
  target_index = namespace.to_s.split("::").count { |element| !element.empty? } - 1
15928
16064
  configured_kind = configured_kinds[target_index]
@@ -15951,6 +16087,16 @@ module Kettle
15951
16087
  end
15952
16088
  end
15953
16089
 
16090
+ def entrypoint_namespace_superclasses_from_facts(facts)
16091
+ raw = facts.dig(:rubygems, :entrypoint_namespace_superclasses)
16092
+ return {} unless raw.is_a?(Hash)
16093
+
16094
+ raw.each_with_object({}) do |(index, superclass), superclasses|
16095
+ value = superclass.to_s.strip
16096
+ superclasses[index.to_i] = value unless value.empty?
16097
+ end
16098
+ end
16099
+
15954
16100
  def ruby_entrypoint_outer_namespace_kind(content, namespace)
15955
16101
  first_segment = namespace.to_s.split("::").reject(&:empty?).first
15956
16102
  return :module if first_segment.to_s.empty?
@@ -16064,6 +16210,27 @@ module Kettle
16064
16210
  end
16065
16211
  end
16066
16212
 
16213
+ def existing_namespace_superclass_details(project_root, namespace, preferred_path: nil)
16214
+ library_paths = [preferred_path, *ruby_library_source_paths(project_root)].compact.uniq
16215
+ library_paths.each do |relative_path|
16216
+ superclasses = existing_version_namespace_superclasses(project_root, relative_path, namespace)
16217
+ next if superclasses.empty?
16218
+
16219
+ return {path: relative_path, superclasses: superclasses}
16220
+ end
16221
+
16222
+ {path: nil, superclasses: {}}
16223
+ end
16224
+
16225
+ def ruby_library_source_paths(project_root)
16226
+ Dir.glob(File.join(project_root, "lib", "**", "*.rb")).sort.filter_map do |path|
16227
+ relative_path = Pathname(path).relative_path_from(Pathname(project_root)).to_s
16228
+ next if relative_path.end_with?("/version.rb", "/version_gem.rb")
16229
+
16230
+ relative_path
16231
+ end
16232
+ end
16233
+
16067
16234
  def ruby_namespace_declaration_kind(content, namespace)
16068
16235
  target = namespace.to_s.split("::").reject(&:empty?)
16069
16236
  body = prism_parse_success(content)&.value&.statements&.body || []
@@ -16154,8 +16321,13 @@ module Kettle
16154
16321
  node&.slice.to_s.split("::").reject(&:empty?)
16155
16322
  end
16156
16323
 
16157
- def existing_entrypoint_version_namespace(project_root, relative_path)
16324
+ def existing_entrypoint_version_namespace(project_root, relative_path, expected_depth: nil)
16158
16325
  content = read_project_file(project_root, relative_path)
16326
+ if expected_depth
16327
+ return ruby_entrypoint_module_namespace(content, expected_depth: expected_depth) ||
16328
+ ruby_version_class_eval_namespaces(content).first
16329
+ end
16330
+
16159
16331
  ruby_version_class_eval_namespaces(content).first || ruby_entrypoint_module_namespace(content)
16160
16332
  end
16161
16333
 
@@ -16169,24 +16341,27 @@ module Kettle
16169
16341
  end
16170
16342
  end
16171
16343
 
16172
- def ruby_entrypoint_module_namespace(content)
16344
+ def ruby_entrypoint_module_namespace(content, expected_depth: nil)
16173
16345
  body = prism_parse_success(content)&.value&.statements&.body || []
16174
16346
  body.each do |node|
16175
- namespace = ruby_entrypoint_module_namespace_for(node, [])
16347
+ namespace = ruby_entrypoint_module_namespace_for(node, [], expected_depth: expected_depth)
16176
16348
  return namespace if namespace
16177
16349
  end
16178
16350
  nil
16179
16351
  end
16180
16352
 
16181
- def ruby_entrypoint_module_namespace_for(node, namespace)
16353
+ def ruby_entrypoint_module_namespace_for(node, namespace, expected_depth: nil)
16182
16354
  return unless node.is_a?(::Prism::ModuleNode) || node.is_a?(::Prism::ClassNode)
16183
16355
 
16184
16356
  current = namespace + ruby_constant_path_segments(node.constant_path)
16357
+ return current.join("::") if expected_depth && current.length == expected_depth
16358
+ return if expected_depth && current.length > expected_depth
16359
+
16185
16360
  node.body&.body&.each do |child|
16186
- child_namespace = ruby_entrypoint_module_namespace_for(child, current)
16361
+ child_namespace = ruby_entrypoint_module_namespace_for(child, current, expected_depth: expected_depth)
16187
16362
  return child_namespace if child_namespace
16188
16363
  end
16189
- current.join("::") unless current.empty?
16364
+ current.join("::") unless expected_depth || current.empty?
16190
16365
  end
16191
16366
 
16192
16367
  def read_project_file(project_root, relative_path)
@@ -19639,11 +19814,11 @@ module Kettle
19639
19814
  "actions/upload-artifact" => "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1",
19640
19815
  "amancevice/setup-code-climate" => "amancevice/setup-code-climate@0daf2985a225e8ac15975b4d233010e94d65b76a # v2",
19641
19816
  "actions/dependency-review-action" => "actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0",
19642
- "github/codeql-action/init" => "github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8",
19643
- "github/codeql-action/autobuild" => "github/codeql-action/autobuild@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8",
19644
- "github/codeql-action/analyze" => "github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8",
19817
+ "github/codeql-action/init" => "github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9",
19818
+ "github/codeql-action/autobuild" => "github/codeql-action/autobuild@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9",
19819
+ "github/codeql-action/analyze" => "github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9",
19645
19820
  "pozil/auto-assign-issue" => "pozil/auto-assign-issue@af6beea6bdf1e8eb373f061c5bc168681fc6d011 # v4.0.1",
19646
- "apache/skywalking-eyes/dependency" => "apache/skywalking-eyes/dependency@61275cc80d0798a405cb070f7d3a8aaf7cf2c2c1 # v0.8.0",
19821
+ "apache/skywalking-eyes/dependency" => "apache/skywalking-eyes/dependency@a196742f472feaffafea537ce5a2a4c3c53a8de4 # v0.9.0",
19647
19822
  "sarisia/actions-status-discord" => "sarisia/actions-status-discord@eb045afee445dc055c18d3d90bd0f244fd062708 # v1.16.0"
19648
19823
  }
19649
19824
  end
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.8
4
+ version: 7.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -676,7 +676,7 @@ dependencies:
676
676
  version: '2.0'
677
677
  - - ">="
678
678
  - !ruby/object:Gem::Version
679
- version: 2.0.20
679
+ version: 2.0.21
680
680
  type: :development
681
681
  prerelease: false
682
682
  version_requirements: !ruby/object:Gem::Requirement
@@ -686,7 +686,7 @@ dependencies:
686
686
  version: '2.0'
687
687
  - - ">="
688
688
  - !ruby/object:Gem::Version
689
- version: 2.0.20
689
+ version: 2.0.21
690
690
  - !ruby/object:Gem::Dependency
691
691
  name: turbo_tests2
692
692
  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.8
980
- changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.8/CHANGELOG.md
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
981
981
  bug_tracker_uri: https://github.com/structuredmerge/structuredmerge-ruby/issues
982
- documentation_uri: https://www.rubydoc.info/gems/kettle-jem/7.1.8
982
+ documentation_uri: https://www.rubydoc.info/gems/kettle-jem/7.1.10
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