kettle-jem 7.1.7 → 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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +77 -1
- data/README.md +23 -1
- data/lib/kettle/jem/cli.rb +2 -0
- data/lib/kettle/jem/maintenance_changelog.rb +4 -0
- data/lib/kettle/jem/tasks/install_task.rb +21 -1
- data/lib/kettle/jem/templates/.github/workflows/license-eye.yml.example +1 -1
- data/lib/kettle/jem/templates/.structuredmerge/kettle-jem.yml.example +25 -7
- data/lib/kettle/jem/templates/gem.gemspec.example +2 -2
- data/lib/kettle/jem/templates/gemfiles/modular/coverage.gemfile.example +1 -1
- data/lib/kettle/jem/templates/gemfiles/modular/templating.gemfile.example +1 -1
- data/lib/kettle/jem/templates/shim/Gemfile.example +1 -1
- data/lib/kettle/jem/templates/shim/gem.gemspec.example +2 -2
- data/lib/kettle/jem/version.rb +1 -1
- data/lib/kettle/jem.rb +350 -90
- data.tar.gz.sig +0 -0
- metadata +6 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cc954a9b2e13ecec8a5dbf0858c76b7a7157f92fabd6f07092024690ab163048
|
|
4
|
+
data.tar.gz: '0628e48c05357df4f752ef7e252cb3992d380ab578faaeee44801d7e818ed39f'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1c549dd026691dbfc28854df99784f1b3c8904237d19f23eaab450de64983c5f9116102811e385f997a661c443e4efe01b6832613dbef6da5c1d9b30eeaad451
|
|
7
|
+
data.tar.gz: 54991a0795b8d7da63318264a5dcefec11cbe78e0ba151a9a53ab56ff8c39b4b6375070b80007d0c446b59c4bc7ad2ee8756c63c25a209f3cf0edfd79b6e900e
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,78 @@ 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
|
+
|
|
86
|
+
## [7.1.8] - 2026-08-26
|
|
87
|
+
|
|
88
|
+
- TAG: [v7.1.8][7.1.8t]
|
|
89
|
+
- COVERAGE: 93.68% -- 10873/11606 lines in 16 files
|
|
90
|
+
- BRANCH COVERAGE: 77.22% -- 4640/6009 branches in 16 files
|
|
91
|
+
- 17.93% documented
|
|
92
|
+
|
|
93
|
+
### Added
|
|
94
|
+
|
|
95
|
+
- Gemspec author metadata now expands existing authors with Git-derived copyright holders and consolidates configured author aliases, while applying the documented default machine-account filter.
|
|
96
|
+
|
|
97
|
+
### Changed
|
|
98
|
+
|
|
99
|
+
- Copyright filtering now excludes bot-marker identities and the packaged template seeds shared author aliases and machine-account defaults.
|
|
100
|
+
|
|
101
|
+
- [kc] kettle-jem-deps-floor: Update kettle-jem template dependency floors:
|
|
102
|
+
- kettle-family (>= 1.2.61 -> >= 1.2.62)
|
|
103
|
+
- kettle-jem (>= 7.1.6 -> >= 7.1.7)
|
|
104
|
+
|
|
33
105
|
## [7.1.7] - 2026-08-26
|
|
34
106
|
|
|
35
107
|
- TAG: [v7.1.7][7.1.7t]
|
|
@@ -1602,7 +1674,11 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
1602
1674
|
- Released kettle-jem as part of the initial StructuredMerge Ruby 7.0.0 gem set.
|
|
1603
1675
|
- Included packaged templates and parser-backed merge support for Ruby gem templating.
|
|
1604
1676
|
|
|
1605
|
-
[Unreleased]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.
|
|
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
|
|
1680
|
+
[7.1.8]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.7...v7.1.8
|
|
1681
|
+
[7.1.8t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.8
|
|
1606
1682
|
[7.1.7]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.6...v7.1.7
|
|
1607
1683
|
[7.1.7t]: https://github.com/structuredmerge/structuredmerge-ruby/releases/tag/v7.1.7
|
|
1608
1684
|
[7.1.6]: https://github.com/structuredmerge/structuredmerge-ruby/compare/v7.1.5...v7.1.6
|
data/README.md
CHANGED
|
@@ -202,6 +202,15 @@ readme:
|
|
|
202
202
|
machine_users:
|
|
203
203
|
- dependabot
|
|
204
204
|
|
|
205
|
+
# Map alternate Git author names or email addresses to one canonical name.
|
|
206
|
+
# The canonical names are used in generated LICENSE.md and gemspec metadata.
|
|
207
|
+
author_aliases:
|
|
208
|
+
pboling: "Peter H. Boling"
|
|
209
|
+
"|7eter l-|. l3oling": "Peter H. Boling"
|
|
210
|
+
"Peter Boling": "Peter H. Boling"
|
|
211
|
+
galtzo: "Peter H. Boling"
|
|
212
|
+
Aboling0: "Annibelle Boling"
|
|
213
|
+
|
|
205
214
|
# Maximum allowed divergence (%) for selftest CI check
|
|
206
215
|
min_divergence_threshold: 5 # ENV override: KJ_MIN_DIVERGENCE_THRESHOLD
|
|
207
216
|
|
|
@@ -290,12 +299,25 @@ Common tokens:
|
|
|
290
299
|
| `{KJ\|GEM_NAME}` | Gem name from gemspec |
|
|
291
300
|
| `{KJ\|NAMESPACE}` | Ruby module namespace |
|
|
292
301
|
| `{KJ\|AUTHOR:NAME}` | Author full name |
|
|
302
|
+
| `{KJ\|AUTHOR:NAMES}` | Existing gemspec authors plus Git-derived copyright holders |
|
|
293
303
|
| `{KJ\|AUTHOR:EMAIL}` | Author email |
|
|
294
304
|
| `{KJ\|GH:USER}` | GitHub username |
|
|
295
305
|
| `{KJ\|PROJECT_EMOJI}` | Project emoji from config |
|
|
296
306
|
| `{KJ\|MIN_RUBY}` | Minimum Ruby version |
|
|
297
307
|
| `{KJ\|FREEZE_TOKEN}` | Freeze marker name |
|
|
298
308
|
|
|
309
|
+
`machine_users` excludes configured Git author names or email addresses from
|
|
310
|
+
Git-derived copyright output. Any identity containing `[bot]` is filtered
|
|
311
|
+
automatically. The built-in machine-account set includes `autobolt`,
|
|
312
|
+
`StepSecurity Bot`, `dependabot[bot]`, and `depfu[bot]`; configured entries
|
|
313
|
+
extend this set rather than replacing it.
|
|
314
|
+
|
|
315
|
+
`author_aliases` consolidates alternate Git author names or email addresses to
|
|
316
|
+
canonical display names. The mapping is case-insensitive and applies to Git
|
|
317
|
+
copyright facts and existing gemspec author names; it does not rewrite Git
|
|
318
|
+
history. `AUTHOR:NAMES` preserves existing gemspec authors and appends any
|
|
319
|
+
copyright holders not already present.
|
|
320
|
+
|
|
299
321
|
### Freeze Blocks
|
|
300
322
|
|
|
301
323
|
Protect sections in any file from template overwrites:
|
|
@@ -772,7 +794,7 @@ Thanks for RTFM. ☺️
|
|
|
772
794
|
[📌gitmoji]: https://gitmoji.dev
|
|
773
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
|
|
774
796
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
775
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-11.
|
|
797
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-11.690-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
776
798
|
[🔐security]: https://github.com/structuredmerge/structuredmerge-ruby/blob/main/SECURITY.md
|
|
777
799
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
778
800
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
data/lib/kettle/jem/cli.rb
CHANGED
|
@@ -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@
|
|
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}"
|
|
@@ -63,7 +63,8 @@
|
|
|
63
63
|
#
|
|
64
64
|
# Safe automatic derivations currently implemented:
|
|
65
65
|
# AUTHOR:NAME <- first author from the gemspec
|
|
66
|
-
# AUTHOR:NAMES <-
|
|
66
|
+
# AUTHOR:NAMES <- existing gemspec authors plus Git-derived copyright holders
|
|
67
|
+
# (after author_aliases consolidation)
|
|
67
68
|
# AUTHOR:EMAIL <- first email from the gemspec
|
|
68
69
|
# AUTHOR:DOMAIN <- domain part of AUTHOR:EMAIL
|
|
69
70
|
# AUTHOR:GIVEN_NAMES <- AUTHOR:NAME minus the last word
|
|
@@ -71,6 +72,19 @@
|
|
|
71
72
|
#
|
|
72
73
|
# Everything else should be set explicitly here or via ENV.
|
|
73
74
|
|
|
75
|
+
# Author identity aliases used when rendering copyright notices and gemspec
|
|
76
|
+
# author metadata. Keys are matched case-insensitively against Git commit
|
|
77
|
+
# author names, Git commit author emails, and existing gemspec author names.
|
|
78
|
+
# Values are the canonical display names written to generated files. This is
|
|
79
|
+
# useful when one person has committed under multiple names or email addresses.
|
|
80
|
+
# These aliases do not rewrite Git history.
|
|
81
|
+
author_aliases:
|
|
82
|
+
pboling: "Peter H. Boling"
|
|
83
|
+
"|7eter l-|. l3oling": "Peter H. Boling"
|
|
84
|
+
"Peter Boling": "Peter H. Boling"
|
|
85
|
+
galtzo: "Peter H. Boling"
|
|
86
|
+
Aboling0: "Annibelle Boling"
|
|
87
|
+
|
|
74
88
|
# Direct dependency ownership decisions.
|
|
75
89
|
# On first templating, kettle-jem discovers dependencies declared directly by
|
|
76
90
|
# Gemfile/gemspec and also by modular Gemfiles, and writes them here for review.
|
|
@@ -360,16 +374,20 @@ license_eye:
|
|
|
360
374
|
# Machine / automation accounts to exclude from generated copyright output.
|
|
361
375
|
#
|
|
362
376
|
# When kettle-jem collects copyright information via `git blame`, it filters
|
|
363
|
-
# out
|
|
364
|
-
# exclude internal automation accounts that
|
|
365
|
-
# (i.e. they do not follow the "[bot]" naming convention).
|
|
377
|
+
# out identities containing "[bot]" automatically. Use this list to also
|
|
378
|
+
# exclude internal automation accounts that do not use that naming convention.
|
|
366
379
|
#
|
|
367
380
|
# Each entry is matched case-insensitively against the commit author name AND
|
|
368
|
-
# the commit author email, so you can list either form.
|
|
381
|
+
# the commit author email, so you can list either form. Project entries extend
|
|
382
|
+
# the built-in defaults below; they do not remove those defaults.
|
|
369
383
|
#
|
|
370
|
-
#
|
|
384
|
+
# Built-in defaults always include: ["autobolt", "StepSecurity Bot",
|
|
385
|
+
# "dependabot[bot]", "depfu[bot]"]
|
|
371
386
|
machine_users:
|
|
372
387
|
- autobolt
|
|
388
|
+
- StepSecurity Bot
|
|
389
|
+
- dependabot[bot]
|
|
390
|
+
- depfu[bot]
|
|
373
391
|
|
|
374
392
|
# Self-test / templating CI threshold.
|
|
375
393
|
# Set to a number from 0 to 100 to fail `rake kettle:jem:selftest` once
|
|
@@ -468,7 +486,7 @@ tokens:
|
|
|
468
486
|
sh_user: "galtzo" # SourceHut username only, no leading ~, no URL. Used as https://sr.ht/~<value>/. ENV: KJ_SH_USER
|
|
469
487
|
|
|
470
488
|
author:
|
|
471
|
-
name: "Peter H. Boling" # Full display name. Example: Ada Lovelace. ENV: KJ_AUTHOR_NAME. Auto-seeded from gemspec authors.first;
|
|
489
|
+
name: "Peter H. Boling" # Full display name. Example: Ada Lovelace. ENV: KJ_AUTHOR_NAME. Auto-seeded from gemspec authors.first; AUTHOR:NAMES preserves existing gemspec authors and appends Git-derived copyright holders.
|
|
472
490
|
given_names: "Peter H." # Given/personal names only. Example: Ada. ENV: KJ_AUTHOR_GIVEN_NAMES. Auto-seeded when AUTHOR:NAME can be split
|
|
473
491
|
family_names: "Boling" # Family/surname only. Example: Lovelace. ENV: KJ_AUTHOR_FAMILY_NAMES. Auto-seeded when AUTHOR:NAME can be split
|
|
474
492
|
email: "floss@galtzo.com" # Primary public email address. Example: floss@galtzo.com. ENV: KJ_AUTHOR_EMAIL. Auto-seeded from gemspec email.first
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
data/lib/kettle/jem/version.rb
CHANGED
|
@@ -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
|
+
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
|
@@ -474,8 +474,8 @@ module Kettle
|
|
|
474
474
|
KJ|SOCIAL:MASTODON
|
|
475
475
|
].freeze
|
|
476
476
|
COPYRIGHT_NAME_RE = /\ACopyright \(c\) [\d,\s-]+ (.+)\z/
|
|
477
|
-
|
|
478
|
-
|
|
477
|
+
BOT_IDENTITY_PATTERN = /\[bot\]/i
|
|
478
|
+
DEFAULT_MACHINE_USERS = ["autobolt", "StepSecurity Bot", "dependabot[bot]", "depfu[bot]"].freeze
|
|
479
479
|
NOT_COMMITTED_EMAIL = "not.committed.yet"
|
|
480
480
|
LOGOS_GALTZO_BASE_URL = "https://logos.galtzo.com/assets/images"
|
|
481
481
|
README_TOP_LOGO_DEFAULTS = %w[org project].freeze
|
|
@@ -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
|
-
|
|
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
|
-
|
|
3347
|
-
entrypoint_path: entrypoint_path
|
|
3361
|
+
namespace
|
|
3348
3362
|
)
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
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.
|
|
5387
|
-
{name: "kettle-drift", source: %(gem "kettle-drift", "~> 1.0", ">= 1.0.
|
|
5388
|
-
{name: "kettle-family", source: %(gem "kettle-family", "~> 1.2", ">= 1.2.
|
|
5389
|
-
{name: "kettle-jem", source: %(gem "kettle-jem", "~> 7.1", ">= 7.1.
|
|
5390
|
-
{name: "kettle-test", source: %(gem "kettle-test", "~> 2.0", ">= 2.0.
|
|
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
|
-
|
|
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
|
-
|
|
5571
|
+
cleanup = version_gem_cleanup_step(
|
|
5533
5572
|
project_root,
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
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
|
|
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
|
|
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
|
|
|
@@ -12322,7 +12422,28 @@ module Kettle
|
|
|
12322
12422
|
def sync_kettle_config_documentation_comments(content)
|
|
12323
12423
|
synced = sync_readme_top_logos_documentation_comment(content)
|
|
12324
12424
|
synced = remove_duplicate_framework_matrix_documentation(synced)
|
|
12325
|
-
remove_duplicate_readme_preservation_documentation(synced)
|
|
12425
|
+
synced = remove_duplicate_readme_preservation_documentation(synced)
|
|
12426
|
+
sync_author_names_documentation_comment(synced)
|
|
12427
|
+
end
|
|
12428
|
+
|
|
12429
|
+
def sync_author_names_documentation_comment(content)
|
|
12430
|
+
legacy = "# AUTHOR:NAMES <- all authors from the gemspec, or copyright holders if no gemspec authors exist"
|
|
12431
|
+
current = [
|
|
12432
|
+
"# AUTHOR:NAMES <- existing gemspec authors plus Git-derived copyright holders\n",
|
|
12433
|
+
"# (after author_aliases consolidation)\n"
|
|
12434
|
+
]
|
|
12435
|
+
lines = content.to_s.lines
|
|
12436
|
+
index = lines.index { |line| line.chomp == legacy }
|
|
12437
|
+
updated = if index
|
|
12438
|
+
lines[index, 1] = current
|
|
12439
|
+
lines.join
|
|
12440
|
+
else
|
|
12441
|
+
content
|
|
12442
|
+
end
|
|
12443
|
+
|
|
12444
|
+
legacy_token_comment = "generated gemspec authors preserve the full existing authors array via AUTHOR:NAMES."
|
|
12445
|
+
current_token_comment = "AUTHOR:NAMES preserves existing gemspec authors and appends Git-derived copyright holders."
|
|
12446
|
+
updated.lines.map { |line| line.sub(legacy_token_comment, current_token_comment) }.join
|
|
12326
12447
|
end
|
|
12327
12448
|
|
|
12328
12449
|
# YAML parsers do not retain comments. These migrations therefore operate
|
|
@@ -14077,7 +14198,7 @@ module Kettle
|
|
|
14077
14198
|
root: ["src", "my", "kettle-dev"]
|
|
14078
14199
|
)
|
|
14079
14200
|
elsif Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("4.0.0")
|
|
14080
|
-
gem "kettle-changelog", "~> 1.0", ">= 1.0.
|
|
14201
|
+
gem "kettle-changelog", "~> 1.0", ">= 1.0.5"
|
|
14081
14202
|
end
|
|
14082
14203
|
end
|
|
14083
14204
|
RUBY
|
|
@@ -14391,7 +14512,10 @@ module Kettle
|
|
|
14391
14512
|
def author_facts(config, env, gemspec_metadata: {}, copyright: {})
|
|
14392
14513
|
token_config = token_config_values(config)
|
|
14393
14514
|
author_config = token_config["author"].is_a?(Hash) ? token_config["author"] : {}
|
|
14394
|
-
|
|
14515
|
+
aliases = author_aliases(config)
|
|
14516
|
+
derived_name = Array(gemspec_metadata[:authors]).map { |value| canonical_author_name(value, aliases) }.find do |value|
|
|
14517
|
+
present_template_token_value?(value)
|
|
14518
|
+
end
|
|
14395
14519
|
derived_email = Array(gemspec_metadata[:email]).map(&:to_s).find { |value| present_template_token_value?(value) }
|
|
14396
14520
|
name = preferred_template_token_value(derived_name, author_config["name"], env, "KJ_AUTHOR_NAME").to_s
|
|
14397
14521
|
email = preferred_template_token_value(derived_email, author_config["email"], env, "KJ_AUTHOR_EMAIL").to_s
|
|
@@ -14401,7 +14525,7 @@ module Kettle
|
|
|
14401
14525
|
orcid = preferred_template_token_value(nil, author_config["orcid"], env, "KJ_AUTHOR_ORCID")
|
|
14402
14526
|
compact_hash(
|
|
14403
14527
|
name: name,
|
|
14404
|
-
names: author_names(gemspec_metadata, copyright, name),
|
|
14528
|
+
names: author_names(gemspec_metadata, copyright, name, author_aliases: aliases),
|
|
14405
14529
|
given_names: given_names.to_s,
|
|
14406
14530
|
family_names: family_names.to_s,
|
|
14407
14531
|
email: email,
|
|
@@ -14435,6 +14559,46 @@ module Kettle
|
|
|
14435
14559
|
value.to_s.strip.match?(%r{\A\{KJ\|[A-Z][A-Z0-9_:]*\}\z})
|
|
14436
14560
|
end
|
|
14437
14561
|
|
|
14562
|
+
def author_aliases(config)
|
|
14563
|
+
return {} unless config.is_a?(Hash)
|
|
14564
|
+
|
|
14565
|
+
configured = config["author_aliases"]
|
|
14566
|
+
configured = config.dig("copyright", "author_aliases") if configured.nil? && config["copyright"].is_a?(Hash)
|
|
14567
|
+
return {} unless configured.is_a?(Hash)
|
|
14568
|
+
|
|
14569
|
+
configured.each_with_object({}) do |(alias_name, canonical_name), aliases|
|
|
14570
|
+
alias_key = alias_name.to_s.strip.downcase
|
|
14571
|
+
canonical = canonical_name.to_s.strip
|
|
14572
|
+
next if alias_key.empty? || canonical.empty?
|
|
14573
|
+
|
|
14574
|
+
aliases[alias_key] = canonical
|
|
14575
|
+
end
|
|
14576
|
+
end
|
|
14577
|
+
|
|
14578
|
+
def canonical_author_name(value, aliases)
|
|
14579
|
+
current = value.to_s.strip
|
|
14580
|
+
seen = {}
|
|
14581
|
+
loop do
|
|
14582
|
+
key = current.downcase
|
|
14583
|
+
break if current.empty? || seen[key]
|
|
14584
|
+
|
|
14585
|
+
seen[key] = true
|
|
14586
|
+
replacement = aliases[key]
|
|
14587
|
+
break if replacement.nil? || replacement.to_s.strip.empty?
|
|
14588
|
+
|
|
14589
|
+
current = replacement.to_s.strip
|
|
14590
|
+
end
|
|
14591
|
+
current
|
|
14592
|
+
end
|
|
14593
|
+
|
|
14594
|
+
def canonical_author_name_for_entry(entry, aliases)
|
|
14595
|
+
name = entry[:name].to_s.strip
|
|
14596
|
+
email = entry[:email].to_s.strip
|
|
14597
|
+
configured_name = aliases[name.downcase]
|
|
14598
|
+
configured_email = aliases[email.downcase]
|
|
14599
|
+
canonical_author_name(configured_name || configured_email || name, aliases)
|
|
14600
|
+
end
|
|
14601
|
+
|
|
14438
14602
|
def author_template_tokens(author)
|
|
14439
14603
|
names = Array(author[:names]).map(&:to_s).reject(&:empty?)
|
|
14440
14604
|
names = [author[:name].to_s] if names.empty?
|
|
@@ -14449,11 +14613,13 @@ module Kettle
|
|
|
14449
14613
|
}
|
|
14450
14614
|
end
|
|
14451
14615
|
|
|
14452
|
-
def author_names(gemspec_metadata, copyright, primary_name)
|
|
14616
|
+
def author_names(gemspec_metadata, copyright, primary_name, author_aliases: {})
|
|
14453
14617
|
names = Array(gemspec_metadata[:authors]).map(&:to_s)
|
|
14454
|
-
names
|
|
14455
|
-
names =
|
|
14456
|
-
|
|
14618
|
+
names += copyright_author_names(copyright)
|
|
14619
|
+
names = names
|
|
14620
|
+
.map { |name| canonical_author_name(name, author_aliases) }
|
|
14621
|
+
.select { |name| present_template_token_value?(name) }
|
|
14622
|
+
names = [canonical_author_name(primary_name, author_aliases)] if names.empty?
|
|
14457
14623
|
names.map(&:strip).reject(&:empty?).uniq
|
|
14458
14624
|
end
|
|
14459
14625
|
|
|
@@ -14481,16 +14647,21 @@ module Kettle
|
|
|
14481
14647
|
end
|
|
14482
14648
|
|
|
14483
14649
|
def copyright_facts(project_root, config)
|
|
14484
|
-
lines = git_copyright_lines(
|
|
14650
|
+
lines = git_copyright_lines(
|
|
14651
|
+
project_root,
|
|
14652
|
+
copyright_machine_users(config),
|
|
14653
|
+
author_aliases: author_aliases(config)
|
|
14654
|
+
)
|
|
14485
14655
|
compact_hash(lines: lines)
|
|
14486
14656
|
end
|
|
14487
14657
|
|
|
14488
14658
|
def copyright_machine_users(config)
|
|
14489
14659
|
copyright = config["copyright"].is_a?(Hash) ? config["copyright"] : {}
|
|
14490
|
-
|
|
14660
|
+
configured = DEFAULT_MACHINE_USERS + Array(config["machine_users"]) + Array(copyright["machine_users"])
|
|
14661
|
+
configured.map { |user| user.to_s.downcase.strip }.reject(&:empty?).uniq
|
|
14491
14662
|
end
|
|
14492
14663
|
|
|
14493
|
-
def git_copyright_lines(project_root, machine_users)
|
|
14664
|
+
def git_copyright_lines(project_root, machine_users, author_aliases: {})
|
|
14494
14665
|
files = git_capture(project_root, "ls-files", "-z")
|
|
14495
14666
|
return [] if files.to_s.empty?
|
|
14496
14667
|
|
|
@@ -14503,10 +14674,20 @@ module Kettle
|
|
|
14503
14674
|
next
|
|
14504
14675
|
end
|
|
14505
14676
|
resolve_uncommitted_author!(project_root, author_map)
|
|
14506
|
-
author_map.values
|
|
14677
|
+
consolidated = author_map.values
|
|
14507
14678
|
.reject { |entry| copyright_bot_entry?(entry) }
|
|
14508
|
-
.reject { |entry| copyright_machine_user_entry?(entry, machine_users) }
|
|
14509
|
-
.
|
|
14679
|
+
.reject { |entry| copyright_machine_user_entry?(entry, machine_users, author_aliases: author_aliases) }
|
|
14680
|
+
.each_with_object({}) do |entry, authors|
|
|
14681
|
+
next if entry[:name].to_s.strip.empty? || entry[:years].empty?
|
|
14682
|
+
|
|
14683
|
+
name = canonical_author_name_for_entry(entry, author_aliases)
|
|
14684
|
+
next if name.empty?
|
|
14685
|
+
|
|
14686
|
+
author = authors[name.downcase] ||= {name: name, years: []}
|
|
14687
|
+
author[:years].concat(entry[:years])
|
|
14688
|
+
end
|
|
14689
|
+
.values
|
|
14690
|
+
consolidated
|
|
14510
14691
|
.sort_by { |entry| [entry[:years].map(&:to_i).min, entry[:name].to_s.downcase] }
|
|
14511
14692
|
.map { |entry| "Copyright (c) #{format_copyright_years(entry[:years])} #{entry[:name]}" }
|
|
14512
14693
|
rescue ArgumentError
|
|
@@ -14566,14 +14747,18 @@ module Kettle
|
|
|
14566
14747
|
end
|
|
14567
14748
|
|
|
14568
14749
|
def copyright_bot_entry?(entry)
|
|
14569
|
-
entry[:name].to_s.match?(
|
|
14750
|
+
entry[:name].to_s.match?(BOT_IDENTITY_PATTERN) || entry[:email].to_s.match?(BOT_IDENTITY_PATTERN)
|
|
14570
14751
|
end
|
|
14571
14752
|
|
|
14572
|
-
def copyright_machine_user_entry?(entry, machine_users)
|
|
14753
|
+
def copyright_machine_user_entry?(entry, machine_users, author_aliases: {})
|
|
14573
14754
|
return false if machine_users.empty?
|
|
14574
14755
|
|
|
14575
|
-
|
|
14576
|
-
|
|
14756
|
+
identities = [
|
|
14757
|
+
entry[:name],
|
|
14758
|
+
entry[:email],
|
|
14759
|
+
canonical_author_name_for_entry(entry, author_aliases)
|
|
14760
|
+
].map { |identity| identity.to_s.downcase.strip }
|
|
14761
|
+
identities.any? { |identity| machine_users.include?(identity) }
|
|
14577
14762
|
end
|
|
14578
14763
|
|
|
14579
14764
|
def format_copyright_years(years)
|
|
@@ -15037,7 +15222,7 @@ module Kettle
|
|
|
15037
15222
|
def main_gemfile_kettle_family_gem(package_name)
|
|
15038
15223
|
return "" if package_name.to_s == "kettle-family"
|
|
15039
15224
|
|
|
15040
|
-
%(gem "kettle-family", "~> 1.2", ">= 1.2.
|
|
15225
|
+
%(gem "kettle-family", "~> 1.2", ">= 1.2.64"\n)
|
|
15041
15226
|
end
|
|
15042
15227
|
|
|
15043
15228
|
def main_gemfile_nomono_bootstrap(package_name)
|
|
@@ -15050,7 +15235,7 @@ module Kettle
|
|
|
15050
15235
|
end
|
|
15051
15236
|
|
|
15052
15237
|
def nomono_gemfile_declaration
|
|
15053
|
-
%(gem "nomono", "~> 1.1", ">= 1.1.
|
|
15238
|
+
%(gem "nomono", "~> 1.1", ">= 1.1.5", require: false # ruby >= 3.2.0)
|
|
15054
15239
|
end
|
|
15055
15240
|
|
|
15056
15241
|
def local_gemfile_nomono_bootstrap(_package_name)
|
|
@@ -15058,7 +15243,7 @@ module Kettle
|
|
|
15058
15243
|
# Bootstrapping nomono here cannot rely on a plain `gem "nomono", ...` line.
|
|
15059
15244
|
# Bundler records that dependency during Gemfile evaluation, but it does not
|
|
15060
15245
|
# activate that exact version before the immediate `require "nomono/bundler"`.
|
|
15061
|
-
nomono_activation_requirements = ["~> 1.1", ">= 1.1.
|
|
15246
|
+
nomono_activation_requirements = ["~> 1.1", ">= 1.1.5"]
|
|
15062
15247
|
nomono_requirement = Gem::Requirement.new(nomono_activation_requirements)
|
|
15063
15248
|
nomono_already_activated = Gem.loaded_specs["nomono"]
|
|
15064
15249
|
nomono_lockfile = File.expand_path("../../Gemfile.lock", __dir__)
|
|
@@ -15136,6 +15321,36 @@ module Kettle
|
|
|
15136
15321
|
)
|
|
15137
15322
|
default_entrypoint_path = File.join("lib", "#{entrypoint_require}.rb")
|
|
15138
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
|
|
15139
15354
|
default_entrypoint_loads_version = entrypoint_path != default_entrypoint_path &&
|
|
15140
15355
|
entrypoint_loads_version_file?(
|
|
15141
15356
|
default_entrypoint,
|
|
@@ -15143,25 +15358,20 @@ module Kettle
|
|
|
15143
15358
|
entrypoint_path: default_entrypoint_path,
|
|
15144
15359
|
version_path: version_path
|
|
15145
15360
|
)
|
|
15146
|
-
version_spec_path = File.join("spec", entrypoint_require, "version_spec.rb")
|
|
15147
|
-
signature_path = File.join("sig", "#{entrypoint_require}.rbs")
|
|
15148
|
-
legacy_signature_paths = legacy_rbs_signature_paths(project_root, entrypoint_require)
|
|
15149
|
-
namespace = existing_version_namespace(project_root, version_path).to_s
|
|
15150
|
-
namespace = facts.dig(:rubygems, :namespace).to_s if namespace.empty?
|
|
15151
|
-
namespace = classify_namespace(package_name) if namespace.empty?
|
|
15152
|
-
namespace = existing_entrypoint_version_namespace(project_root, entrypoint_path).to_s if namespace.empty?
|
|
15153
|
-
return {name: "version_gem_bootstrap", status: "unavailable", reason: "missing_package_facts"} if namespace.empty?
|
|
15154
|
-
|
|
15155
15361
|
version = facts.dig(:project_runtime, :version).to_s
|
|
15156
15362
|
version = project_gemspec_version(project_root) if version.empty?
|
|
15157
15363
|
version = "0.0.1.pre" if version.empty?
|
|
15158
15364
|
changes = []
|
|
15159
15365
|
current_entrypoint = read_project_file(project_root, entrypoint_path)
|
|
15160
15366
|
outer_namespace_kind = ruby_entrypoint_outer_namespace_kind(current_entrypoint, namespace)
|
|
15161
|
-
namespace_kinds =
|
|
15162
|
-
|
|
15163
|
-
|
|
15164
|
-
|
|
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
|
+
)
|
|
15165
15375
|
preserve_version_module_include = existing_version_file_includes_version_module?(project_root, version_path) if preserve_version_module_include.nil?
|
|
15166
15376
|
|
|
15167
15377
|
if manage_version_file
|
|
@@ -15174,7 +15384,6 @@ module Kettle
|
|
|
15174
15384
|
version: version,
|
|
15175
15385
|
outer_namespace_kind: outer_namespace_kind,
|
|
15176
15386
|
namespace_kinds: namespace_kinds,
|
|
15177
|
-
namespace_superclasses: namespace_superclasses,
|
|
15178
15387
|
preserve_version_module_include: preserve_version_module_include
|
|
15179
15388
|
)
|
|
15180
15389
|
)
|
|
@@ -15186,6 +15395,7 @@ module Kettle
|
|
|
15186
15395
|
current_entrypoint,
|
|
15187
15396
|
entrypoint_require: entrypoint_require,
|
|
15188
15397
|
ensure_version_require: !default_entrypoint_loads_version,
|
|
15398
|
+
after_declarations: !entrypoint_namespace_superclasses.empty?,
|
|
15189
15399
|
version_require_path: version_require_path_for_entrypoint(entrypoint_path, version_path)
|
|
15190
15400
|
)
|
|
15191
15401
|
elsif current_entrypoint.empty?
|
|
@@ -15195,6 +15405,7 @@ module Kettle
|
|
|
15195
15405
|
current_entrypoint,
|
|
15196
15406
|
namespace: namespace,
|
|
15197
15407
|
entrypoint_require: entrypoint_require,
|
|
15408
|
+
namespace_superclasses: entrypoint_namespace_superclasses,
|
|
15198
15409
|
version_require_path: version_require_path_for_entrypoint(entrypoint_path, version_path)
|
|
15199
15410
|
)
|
|
15200
15411
|
end
|
|
@@ -15577,7 +15788,7 @@ module Kettle
|
|
|
15577
15788
|
version_gem_require_insertion_index(content)
|
|
15578
15789
|
end
|
|
15579
15790
|
|
|
15580
|
-
def version_gem_version_file_content(existing_version:, namespace:, version:, outer_namespace_kind: :module, namespace_kinds: {},
|
|
15791
|
+
def version_gem_version_file_content(existing_version:, namespace:, version:, outer_namespace_kind: :module, namespace_kinds: {}, preserve_version_module_include: false)
|
|
15581
15792
|
resolved_version = existing_version.to_s.empty? ? version.to_s : existing_version.to_s
|
|
15582
15793
|
body = [
|
|
15583
15794
|
"# Version namespace for this gem.",
|
|
@@ -15593,7 +15804,7 @@ module Kettle
|
|
|
15593
15804
|
<<~RUBY
|
|
15594
15805
|
# frozen_string_literal: true
|
|
15595
15806
|
|
|
15596
|
-
#{wrap_ruby_namespace(namespace, body, outer_namespace_kind: outer_namespace_kind, namespace_kinds: namespace_kinds
|
|
15807
|
+
#{wrap_ruby_namespace(namespace, body, outer_namespace_kind: outer_namespace_kind, namespace_kinds: namespace_kinds).join("\n")}
|
|
15597
15808
|
RUBY
|
|
15598
15809
|
end
|
|
15599
15810
|
|
|
@@ -15620,11 +15831,12 @@ module Kettle
|
|
|
15620
15831
|
"#{wrap_ruby_namespace(namespace, body).join("\n")}\n"
|
|
15621
15832
|
end
|
|
15622
15833
|
|
|
15623
|
-
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)
|
|
15624
15835
|
current = normalize_entrypoint_version_require(
|
|
15625
15836
|
content,
|
|
15626
15837
|
entrypoint_require: entrypoint_require,
|
|
15627
|
-
version_require_path: version_require_path
|
|
15838
|
+
version_require_path: version_require_path,
|
|
15839
|
+
after_declarations: !namespace_superclasses.empty?
|
|
15628
15840
|
)
|
|
15629
15841
|
current = remove_version_gem_class_eval_references(current) unless ruby_version_class_eval_namespaces(current).include?(namespace.to_s)
|
|
15630
15842
|
lines = current.lines
|
|
@@ -15645,7 +15857,7 @@ module Kettle
|
|
|
15645
15857
|
collapse_excess_blank_lines(updated)
|
|
15646
15858
|
end
|
|
15647
15859
|
|
|
15648
|
-
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)
|
|
15649
15861
|
current = remove_version_gem_entrypoint_references(content)
|
|
15650
15862
|
unless ensure_version_require
|
|
15651
15863
|
relative_path = version_require_path.to_s.empty? ? File.join(File.basename(entrypoint_require), "version") : version_require_path.to_s
|
|
@@ -15660,17 +15872,23 @@ module Kettle
|
|
|
15660
15872
|
normalize_entrypoint_version_require(
|
|
15661
15873
|
current,
|
|
15662
15874
|
entrypoint_require: entrypoint_require,
|
|
15663
|
-
version_require_path: version_require_path
|
|
15875
|
+
version_require_path: version_require_path,
|
|
15876
|
+
after_declarations: after_declarations
|
|
15664
15877
|
)
|
|
15665
15878
|
end
|
|
15666
15879
|
|
|
15667
|
-
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)
|
|
15668
15881
|
relative_path = version_require_path.to_s.empty? ? File.join(File.basename(entrypoint_require), "version") : version_require_path.to_s
|
|
15669
15882
|
absolute_path = File.join(entrypoint_require, "version")
|
|
15670
15883
|
legacy_relative_path = File.join(File.basename(entrypoint_require), "version")
|
|
15671
15884
|
current = [relative_path, legacy_relative_path].uniq.reduce(content) do |value, path|
|
|
15672
15885
|
remove_entrypoint_version_requires(value, relative_path: path, absolute_path: absolute_path)
|
|
15673
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
|
+
|
|
15674
15892
|
lines = current.lines
|
|
15675
15893
|
lines.insert(version_gem_require_insertion_index(current), %(require_relative "#{relative_path}"\n), "\n")
|
|
15676
15894
|
trim_trailing_blank_lines(collapse_excess_blank_lines(lines.join))
|
|
@@ -15838,6 +16056,9 @@ module Kettle
|
|
|
15838
16056
|
kind = version_namespace_outer_kind(project_root, entrypoint_path, namespace)
|
|
15839
16057
|
return kind if kind == :class
|
|
15840
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
|
+
|
|
15841
16062
|
configured_kinds = version_namespace_kinds_from_facts(facts)
|
|
15842
16063
|
target_index = namespace.to_s.split("::").count { |element| !element.empty? } - 1
|
|
15843
16064
|
configured_kind = configured_kinds[target_index]
|
|
@@ -15866,6 +16087,16 @@ module Kettle
|
|
|
15866
16087
|
end
|
|
15867
16088
|
end
|
|
15868
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
|
+
|
|
15869
16100
|
def ruby_entrypoint_outer_namespace_kind(content, namespace)
|
|
15870
16101
|
first_segment = namespace.to_s.split("::").reject(&:empty?).first
|
|
15871
16102
|
return :module if first_segment.to_s.empty?
|
|
@@ -15979,6 +16210,27 @@ module Kettle
|
|
|
15979
16210
|
end
|
|
15980
16211
|
end
|
|
15981
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
|
+
|
|
15982
16234
|
def ruby_namespace_declaration_kind(content, namespace)
|
|
15983
16235
|
target = namespace.to_s.split("::").reject(&:empty?)
|
|
15984
16236
|
body = prism_parse_success(content)&.value&.statements&.body || []
|
|
@@ -16069,8 +16321,13 @@ module Kettle
|
|
|
16069
16321
|
node&.slice.to_s.split("::").reject(&:empty?)
|
|
16070
16322
|
end
|
|
16071
16323
|
|
|
16072
|
-
def existing_entrypoint_version_namespace(project_root, relative_path)
|
|
16324
|
+
def existing_entrypoint_version_namespace(project_root, relative_path, expected_depth: nil)
|
|
16073
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
|
+
|
|
16074
16331
|
ruby_version_class_eval_namespaces(content).first || ruby_entrypoint_module_namespace(content)
|
|
16075
16332
|
end
|
|
16076
16333
|
|
|
@@ -16084,24 +16341,27 @@ module Kettle
|
|
|
16084
16341
|
end
|
|
16085
16342
|
end
|
|
16086
16343
|
|
|
16087
|
-
def ruby_entrypoint_module_namespace(content)
|
|
16344
|
+
def ruby_entrypoint_module_namespace(content, expected_depth: nil)
|
|
16088
16345
|
body = prism_parse_success(content)&.value&.statements&.body || []
|
|
16089
16346
|
body.each do |node|
|
|
16090
|
-
namespace = ruby_entrypoint_module_namespace_for(node, [])
|
|
16347
|
+
namespace = ruby_entrypoint_module_namespace_for(node, [], expected_depth: expected_depth)
|
|
16091
16348
|
return namespace if namespace
|
|
16092
16349
|
end
|
|
16093
16350
|
nil
|
|
16094
16351
|
end
|
|
16095
16352
|
|
|
16096
|
-
def ruby_entrypoint_module_namespace_for(node, namespace)
|
|
16353
|
+
def ruby_entrypoint_module_namespace_for(node, namespace, expected_depth: nil)
|
|
16097
16354
|
return unless node.is_a?(::Prism::ModuleNode) || node.is_a?(::Prism::ClassNode)
|
|
16098
16355
|
|
|
16099
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
|
+
|
|
16100
16360
|
node.body&.body&.each do |child|
|
|
16101
|
-
child_namespace = ruby_entrypoint_module_namespace_for(child, current)
|
|
16361
|
+
child_namespace = ruby_entrypoint_module_namespace_for(child, current, expected_depth: expected_depth)
|
|
16102
16362
|
return child_namespace if child_namespace
|
|
16103
16363
|
end
|
|
16104
|
-
current.join("::") unless current.empty?
|
|
16364
|
+
current.join("::") unless expected_depth || current.empty?
|
|
16105
16365
|
end
|
|
16106
16366
|
|
|
16107
16367
|
def read_project_file(project_root, relative_path)
|
|
@@ -19554,11 +19814,11 @@ module Kettle
|
|
|
19554
19814
|
"actions/upload-artifact" => "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1",
|
|
19555
19815
|
"amancevice/setup-code-climate" => "amancevice/setup-code-climate@0daf2985a225e8ac15975b4d233010e94d65b76a # v2",
|
|
19556
19816
|
"actions/dependency-review-action" => "actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0",
|
|
19557
|
-
"github/codeql-action/init" => "github/codeql-action/init@
|
|
19558
|
-
"github/codeql-action/autobuild" => "github/codeql-action/autobuild@
|
|
19559
|
-
"github/codeql-action/analyze" => "github/codeql-action/analyze@
|
|
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",
|
|
19560
19820
|
"pozil/auto-assign-issue" => "pozil/auto-assign-issue@af6beea6bdf1e8eb373f061c5bc168681fc6d011 # v4.0.1",
|
|
19561
|
-
"apache/skywalking-eyes/dependency" => "apache/skywalking-eyes/dependency@
|
|
19821
|
+
"apache/skywalking-eyes/dependency" => "apache/skywalking-eyes/dependency@a196742f472feaffafea537ce5a2a4c3c53a8de4 # v0.9.0",
|
|
19562
19822
|
"sarisia/actions-status-discord" => "sarisia/actions-status-discord@eb045afee445dc055c18d3d90bd0f244fd062708 # v1.16.0"
|
|
19563
19823
|
}
|
|
19564
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.
|
|
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.
|
|
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.
|
|
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.
|
|
980
|
-
changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.
|
|
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.
|
|
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
|