kettle-dev 1.1.45 → 1.1.47
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/.git-hooks/footer-template.erb.txt +1 -1
- data/.github/workflows/style.yml +2 -0
- data/CHANGELOG.md +36 -1
- data/FUNDING.md +2 -2
- data/FUNDING.md.no-osc.example +1 -1
- data/README.md +4 -4
- data/README.md.example +4 -4
- data/README.md.no-osc.example +3 -3
- data/Rakefile.example +1 -1
- data/lib/kettle/dev/template_helpers.rb +227 -0
- data/lib/kettle/dev/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +4 -4
- 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: ce61aa17df248a723743179807ea6da8b1c139dbd2555459a69035b4a33338bd
|
|
4
|
+
data.tar.gz: 7eb08bdf8772350131a62caa2ac893de26871ab093d671ee798b5a1edb7a97b0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7936fd630aab1b64ab97ae9b52a570524b5c20ddc576bddbb10df3ee6dd05e26a736e33c34cbe3ba7cebd903c112d68440d9863f5ade11ae7c18f84cc1d08b68
|
|
7
|
+
data.tar.gz: cec2cbdcab872105c822f07d0539ccd08c8ad66aa1a1e7ded93a1c8d3f790a1efc48449f0810dc4128e201d32aa517fde4c5054f4a7e604c1b4e0cda630d3155
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
⚡️ A message from a fellow meat-based-AI ⚡️
|
|
2
|
-
- [❤️] Finely-crafted open-source tools like <%= @gem_name %> (& many more)
|
|
2
|
+
- [❤️] Finely-crafted open-source tools like <%= @gem_name %> (& many more) require time and effort.
|
|
3
3
|
- [❤️] Though I adore my work, it lacks financial sustainability.
|
|
4
4
|
- [❤️] Please, help me continue enhancing your tools by becoming a sponsor:
|
|
5
5
|
- [💲] https://liberapay.com/pboling/donate
|
data/.github/workflows/style.yml
CHANGED
|
@@ -63,3 +63,5 @@ jobs:
|
|
|
63
63
|
run: bundle exec appraisal ${{ matrix.appraisal }} bundle
|
|
64
64
|
- name: Run ${{ matrix.appraisal }} checks via ${{ matrix.exec_cmd }}
|
|
65
65
|
run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}
|
|
66
|
+
- name: Validate RBS Types
|
|
67
|
+
run: bundle exec appraisal ${{ matrix.appraisal }} bin/rbs validate
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,37 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
30
30
|
|
|
31
31
|
### Security
|
|
32
32
|
|
|
33
|
+
## [1.1.47] - 2025-11-06
|
|
34
|
+
|
|
35
|
+
- TAG: [v1.1.47][1.1.47t]
|
|
36
|
+
- COVERAGE: 95.68% -- 4054/4237 lines in 26 files
|
|
37
|
+
- BRANCH COVERAGE: 80.45% -- 1675/2082 branches in 26 files
|
|
38
|
+
- 79.89% documented
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- Handle custom dependencies in Gemfiles gracefully
|
|
43
|
+
- Intelligent templating of Appraisals
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- Typos in funding links
|
|
48
|
+
|
|
49
|
+
## [1.1.46] - 2025-11-04
|
|
50
|
+
|
|
51
|
+
- TAG: [v1.1.46][1.1.46t]
|
|
52
|
+
- COVERAGE: 96.25% -- 3958/4112 lines in 26 files
|
|
53
|
+
- BRANCH COVERAGE: 80.95% -- 1636/2021 branches in 26 files
|
|
54
|
+
- 79.68% documented
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- Validate RBS Types within style workflow
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
|
|
62
|
+
- typos in README.md
|
|
63
|
+
|
|
33
64
|
## [1.1.45] - 2025-10-31
|
|
34
65
|
|
|
35
66
|
- TAG: [v1.1.45][1.1.45t]
|
|
@@ -1252,7 +1283,11 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
|
1252
1283
|
- Selecting will run the selected workflow via `act`
|
|
1253
1284
|
- This may move to its own gem in the future.
|
|
1254
1285
|
|
|
1255
|
-
[Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.
|
|
1286
|
+
[Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.47...HEAD
|
|
1287
|
+
[1.1.47]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.46...v1.1.47
|
|
1288
|
+
[1.1.47t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.47
|
|
1289
|
+
[1.1.46]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.45...v1.1.46
|
|
1290
|
+
[1.1.46t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.46
|
|
1256
1291
|
[1.1.45]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.44...v1.1.45
|
|
1257
1292
|
[1.1.45t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.45
|
|
1258
1293
|
[1.1.44]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.43...v1.1.44
|
data/FUNDING.md
CHANGED
|
@@ -6,7 +6,7 @@ Many paths lead to being a sponsor or a backer of this project. Are you on such
|
|
|
6
6
|
|
|
7
7
|
[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal]
|
|
8
8
|
|
|
9
|
-
[![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS
|
|
9
|
+
[![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon]
|
|
10
10
|
|
|
11
11
|
[⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat
|
|
12
12
|
[⛳liberapay]: https://liberapay.com/pboling/donate
|
|
@@ -46,7 +46,7 @@ To join the community or get help 👇️ Join the Discord.
|
|
|
46
46
|
|
|
47
47
|
To say "thanks for maintaining such a great tool" ☝️ Join the Discord or 👇️ send money.
|
|
48
48
|
|
|
49
|
-
[![Sponsor kettle-rb/kettle-dev on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay
|
|
49
|
+
[![Sponsor kettle-rb/kettle-dev on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
|
|
50
50
|
|
|
51
51
|
# Another Way to Support Open Source Software
|
|
52
52
|
|
data/FUNDING.md.no-osc.example
CHANGED
|
@@ -6,7 +6,7 @@ Many paths lead to being a sponsor or a backer of this project. Are you on such
|
|
|
6
6
|
|
|
7
7
|
[![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal]
|
|
8
8
|
|
|
9
|
-
[![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS
|
|
9
|
+
[![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon]
|
|
10
10
|
|
|
11
11
|
[⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat
|
|
12
12
|
[⛳liberapay]: https://liberapay.com/pboling/donate
|
data/README.md
CHANGED
|
@@ -652,7 +652,7 @@ I’m developing a new library, [floss_funding][🖇floss-funding-gem], designed
|
|
|
652
652
|
|
|
653
653
|
**[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
|
|
654
654
|
|
|
655
|
-
[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS
|
|
655
|
+
[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon]
|
|
656
656
|
|
|
657
657
|
## 🔐 Security
|
|
658
658
|
|
|
@@ -779,7 +779,7 @@ To join the community or get help 👇️ Join the Discord.
|
|
|
779
779
|
|
|
780
780
|
To say "thanks!" ☝️ Join the Discord or 👇️ send money.
|
|
781
781
|
|
|
782
|
-
[![Sponsor kettle-rb/kettle-dev on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay
|
|
782
|
+
[![Sponsor kettle-rb/kettle-dev on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
|
|
783
783
|
|
|
784
784
|
### Please give the project a star ⭐ ♥.
|
|
785
785
|
|
|
@@ -965,9 +965,9 @@ Thanks for RTFM. ☺️
|
|
|
965
965
|
[📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
|
|
966
966
|
[📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
|
|
967
967
|
[📌gitmoji]:https://gitmoji.dev
|
|
968
|
-
[📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
968
|
+
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
969
969
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
970
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.
|
|
970
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.237-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
971
971
|
[🔐security]: SECURITY.md
|
|
972
972
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
973
973
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
data/README.md.example
CHANGED
|
@@ -225,7 +225,7 @@ I’m developing a new library, [floss_funding][🖇floss-funding-gem], designed
|
|
|
225
225
|
|
|
226
226
|
**[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
|
|
227
227
|
|
|
228
|
-
[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS
|
|
228
|
+
[![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon]
|
|
229
229
|
|
|
230
230
|
## 🔐 Security
|
|
231
231
|
|
|
@@ -352,7 +352,7 @@ To join the community or get help 👇️ Join the Discord.
|
|
|
352
352
|
|
|
353
353
|
To say "thanks!" ☝️ Join the Discord or 👇️ send money.
|
|
354
354
|
|
|
355
|
-
[![Sponsor kettle-rb/kettle-dev on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay
|
|
355
|
+
[![Sponsor kettle-rb/kettle-dev on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
|
|
356
356
|
|
|
357
357
|
### Please give the project a star ⭐ ♥.
|
|
358
358
|
|
|
@@ -543,9 +543,9 @@ Thanks for RTFM. ☺️
|
|
|
543
543
|
[📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
|
|
544
544
|
[📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
|
|
545
545
|
[📌gitmoji]:https://gitmoji.dev
|
|
546
|
-
[📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
546
|
+
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
547
547
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
548
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.
|
|
548
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.237-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
549
549
|
[🔐security]: SECURITY.md
|
|
550
550
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
551
551
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
data/README.md.no-osc.example
CHANGED
|
@@ -202,7 +202,7 @@ I’m developing a new library, [floss_funding][🖇floss-funding-gem], designed
|
|
|
202
202
|
|
|
203
203
|
**[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
|
|
204
204
|
|
|
205
|
-
[![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS
|
|
205
|
+
[![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon]
|
|
206
206
|
|
|
207
207
|
## 🔐 Security
|
|
208
208
|
|
|
@@ -329,7 +329,7 @@ To join the community or get help 👇️ Join the Discord.
|
|
|
329
329
|
|
|
330
330
|
To say "thanks!" ☝️ Join the Discord or 👇️ send money.
|
|
331
331
|
|
|
332
|
-
[![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay
|
|
332
|
+
[![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
|
|
333
333
|
|
|
334
334
|
### Please give the project a star ⭐ ♥.
|
|
335
335
|
|
|
@@ -509,7 +509,7 @@ Thanks for RTFM. ☺️
|
|
|
509
509
|
[📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
|
|
510
510
|
[📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
|
|
511
511
|
[📌gitmoji]:https://gitmoji.dev
|
|
512
|
-
[📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
512
|
+
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
513
513
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
514
514
|
[🧮kloc-img]: https://img.shields.io/badge/KLOC-4.076-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
515
515
|
[🔐security]: SECURITY.md
|
data/Rakefile.example
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# External stdlibs
|
|
4
4
|
require "find"
|
|
5
|
+
require "set"
|
|
5
6
|
|
|
6
7
|
module Kettle
|
|
7
8
|
module Dev
|
|
@@ -277,6 +278,46 @@ module Kettle
|
|
|
277
278
|
Kettle::Dev.debug_error(e, __method__)
|
|
278
279
|
# If replacement fails unexpectedly, proceed with content as-is
|
|
279
280
|
end
|
|
281
|
+
|
|
282
|
+
# If updating the Appraisals file and a destination already exists,
|
|
283
|
+
# merge appraise blocks: augment matching blocks with missing gem/eval_gemfile lines,
|
|
284
|
+
# preserve destination-only blocks and comments/preamble.
|
|
285
|
+
begin
|
|
286
|
+
if dest_exists && File.basename(dest_path.to_s) == "Appraisals" && File.file?(dest_path.to_s)
|
|
287
|
+
existing = begin
|
|
288
|
+
File.read(dest_path)
|
|
289
|
+
rescue
|
|
290
|
+
""
|
|
291
|
+
end
|
|
292
|
+
content = merge_appraisals(content, existing)
|
|
293
|
+
end
|
|
294
|
+
rescue StandardError => e
|
|
295
|
+
Kettle::Dev.debug_error(e, __method__)
|
|
296
|
+
# On any error, fall back to generated content
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# If updating a Gemfile or modular .gemfile and the destination already exists,
|
|
300
|
+
# merge dependency lines from the source into the destination to preserve any
|
|
301
|
+
# user-defined gem entries. We append missing `gem "name"` lines; we never
|
|
302
|
+
# alter or remove existing gem lines in the destination.
|
|
303
|
+
begin
|
|
304
|
+
if dest_exists
|
|
305
|
+
dest_str = dest_path.to_s
|
|
306
|
+
is_gemfile_like = File.basename(dest_str) == "Gemfile" || dest_str.end_with?(".gemfile")
|
|
307
|
+
if is_gemfile_like && File.file?(dest_str)
|
|
308
|
+
begin
|
|
309
|
+
existing = File.read(dest_str)
|
|
310
|
+
content = merge_gemfile_dependencies(content, existing)
|
|
311
|
+
rescue StandardError => e
|
|
312
|
+
Kettle::Dev.debug_error(e, __method__)
|
|
313
|
+
# If merging fails, fall back to writing generated content
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
rescue StandardError => e
|
|
318
|
+
Kettle::Dev.debug_error(e, __method__)
|
|
319
|
+
end
|
|
320
|
+
|
|
280
321
|
write_file(dest_path, content)
|
|
281
322
|
begin
|
|
282
323
|
# Ensure executable bit for git hook scripts when writing under .git-hooks
|
|
@@ -291,6 +332,192 @@ module Kettle
|
|
|
291
332
|
puts "Wrote #{dest_path}"
|
|
292
333
|
end
|
|
293
334
|
|
|
335
|
+
# Merge gem dependency lines from a source Gemfile-like content into an existing
|
|
336
|
+
# destination Gemfile-like content. Existing gem lines in the destination win;
|
|
337
|
+
# we only append missing gem declarations from the source at the end of the file.
|
|
338
|
+
# This is deliberately conservative and avoids attempting to relocate gems inside
|
|
339
|
+
# group/platform blocks or reconcile version constraints.
|
|
340
|
+
# @param src_content [String]
|
|
341
|
+
# @param dest_content [String]
|
|
342
|
+
# @return [String] merged content
|
|
343
|
+
def merge_gemfile_dependencies(src_content, dest_content)
|
|
344
|
+
begin
|
|
345
|
+
gem_re = /^\s*gem\s+['"]([^'"\s]+)['"].*$/
|
|
346
|
+
# Collect first occurrence of each gem line in source
|
|
347
|
+
src_gems = {}
|
|
348
|
+
src_content.each_line do |ln|
|
|
349
|
+
next if ln.strip.start_with?("#")
|
|
350
|
+
if (m = ln.match(gem_re))
|
|
351
|
+
name = m[1]
|
|
352
|
+
src_gems[name] ||= ln.rstrip
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
# Index existing gems in destination
|
|
357
|
+
dest_gems = {}
|
|
358
|
+
dest_content.each_line do |ln|
|
|
359
|
+
next if ln.strip.start_with?("#")
|
|
360
|
+
if (m = ln.match(gem_re))
|
|
361
|
+
dest_gems[m[1]] = true
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
missing = src_gems.keys.reject { |n| dest_gems.key?(n) }
|
|
366
|
+
return dest_content if missing.empty?
|
|
367
|
+
|
|
368
|
+
out = dest_content.dup
|
|
369
|
+
out << "\n" unless out.end_with?("\n") || out.empty?
|
|
370
|
+
out << missing.map { |n| src_gems[n] }.join("\n")
|
|
371
|
+
out << "\n"
|
|
372
|
+
out
|
|
373
|
+
rescue StandardError => e
|
|
374
|
+
Kettle::Dev.debug_error(e, __method__)
|
|
375
|
+
dest_content
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# Merge Appraisals template into existing Appraisals file.
|
|
380
|
+
# Rules:
|
|
381
|
+
# - For each appraise "name" block in template:
|
|
382
|
+
# * If destination has same block, ensure all gem/ eval_gemfile lines from template
|
|
383
|
+
# exist in destination (append missing just before end), keep other dest lines.
|
|
384
|
+
# Use template's contiguous header comment lines (immediately preceding the appraise line)
|
|
385
|
+
# if any; otherwise retain destination's header comments.
|
|
386
|
+
# * If destination lacks the block, add the full template block (with its header).
|
|
387
|
+
# - Preserve destination-only blocks (not present in template) unchanged and after
|
|
388
|
+
# the merged template-ordered blocks.
|
|
389
|
+
# - Preamble (content before first appraise) comes from template when present, else destination.
|
|
390
|
+
def merge_appraisals(template_content, dest_content)
|
|
391
|
+
begin
|
|
392
|
+
parse_blocks = lambda do |text|
|
|
393
|
+
lines = text.lines
|
|
394
|
+
blocks = []
|
|
395
|
+
i = 0
|
|
396
|
+
while i < lines.length
|
|
397
|
+
line = lines[i]
|
|
398
|
+
if line =~ /^\s*appraise\s+["']([^"']+)["']\s+do\s*$/
|
|
399
|
+
name = $1
|
|
400
|
+
# collect header comment lines immediately preceding (contiguous, no blank between comment group and appraise line)
|
|
401
|
+
header_lines = []
|
|
402
|
+
j = i - 1
|
|
403
|
+
while j >= 0
|
|
404
|
+
prev = lines[j]
|
|
405
|
+
break if prev.strip.empty?
|
|
406
|
+
if prev.lstrip.start_with?("#")
|
|
407
|
+
header_lines.unshift(prev)
|
|
408
|
+
j -= 1
|
|
409
|
+
else
|
|
410
|
+
break
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
body_lines = []
|
|
414
|
+
i += 1
|
|
415
|
+
while i < lines.length
|
|
416
|
+
l2 = lines[i]
|
|
417
|
+
if l2 =~ /^\s*end\s*$/
|
|
418
|
+
end_line = l2
|
|
419
|
+
blocks << {
|
|
420
|
+
name: name,
|
|
421
|
+
header: header_lines.dup,
|
|
422
|
+
body: body_lines.dup,
|
|
423
|
+
end_line: end_line,
|
|
424
|
+
raw_order: blocks.length,
|
|
425
|
+
original_indices: (j ? (j + 1)..i : i),
|
|
426
|
+
}
|
|
427
|
+
break
|
|
428
|
+
else
|
|
429
|
+
body_lines << l2
|
|
430
|
+
end
|
|
431
|
+
i += 1
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
i += 1
|
|
435
|
+
end
|
|
436
|
+
preamble = if blocks.empty?
|
|
437
|
+
text
|
|
438
|
+
else
|
|
439
|
+
# preamble = lines from start up to first block start (exclusive)
|
|
440
|
+
first_block = blocks.first
|
|
441
|
+
# Take lines up to first occurrence of the appraise line (supports either quote type)
|
|
442
|
+
re = /^\s*appraise\s+["']#{Regexp.escape(first_block[:name])}["']\s+do\s*$/
|
|
443
|
+
idx = lines.index { |l| l =~ re } || 0
|
|
444
|
+
lines[0...idx].join
|
|
445
|
+
end
|
|
446
|
+
{blocks: blocks, preamble: preamble}
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
tmpl = parse_blocks.call(template_content)
|
|
450
|
+
dest = parse_blocks.call(dest_content)
|
|
451
|
+
tmpl_blocks = tmpl[:blocks]
|
|
452
|
+
dest_blocks = dest[:blocks]
|
|
453
|
+
dest_by_name = dest_blocks.map { |b| [b[:name], b] }.to_h
|
|
454
|
+
|
|
455
|
+
merged_blocks_strings = []
|
|
456
|
+
gem_or_eval_re = /^\s*(?:gem|eval_gemfile)\b/
|
|
457
|
+
|
|
458
|
+
tmpl_blocks.each do |tb|
|
|
459
|
+
if (db = dest_by_name[tb[:name]])
|
|
460
|
+
# Merge lines
|
|
461
|
+
existing_lines = db[:body].map(&:rstrip)
|
|
462
|
+
existing_set = existing_lines.to_set
|
|
463
|
+
# Collect template gem/eval lines
|
|
464
|
+
tmpl_needed = tb[:body].select { |l| gem_or_eval_re =~ l }
|
|
465
|
+
additions = []
|
|
466
|
+
tmpl_needed.each do |l|
|
|
467
|
+
line_key = l.rstrip
|
|
468
|
+
additions << l unless existing_set.include?(line_key)
|
|
469
|
+
end
|
|
470
|
+
merged_body = db[:body].dup
|
|
471
|
+
unless additions.empty?
|
|
472
|
+
# insert before end (just append; body excludes 'end')
|
|
473
|
+
merged_body += additions
|
|
474
|
+
end
|
|
475
|
+
header = tb[:header].any? ? tb[:header] : db[:header]
|
|
476
|
+
block_text = +""
|
|
477
|
+
block_text << "\n" unless merged_blocks_strings.empty?
|
|
478
|
+
header.each { |hl| block_text << hl } if header.any?
|
|
479
|
+
block_text << "appraise \"#{tb[:name]}\" do\n"
|
|
480
|
+
merged_body.each { |bl| block_text << bl }
|
|
481
|
+
block_text << db[:end_line]
|
|
482
|
+
merged_blocks_strings << block_text
|
|
483
|
+
dest_by_name.delete(tb[:name])
|
|
484
|
+
else
|
|
485
|
+
# New block from template
|
|
486
|
+
block_text = +""
|
|
487
|
+
block_text << "\n" unless merged_blocks_strings.empty?
|
|
488
|
+
tb[:header].each { |hl| block_text << hl } if tb[:header].any?
|
|
489
|
+
block_text << "appraise \"#{tb[:name]}\" do\n"
|
|
490
|
+
tb[:body].each { |bl| block_text << bl }
|
|
491
|
+
block_text << tb[:end_line]
|
|
492
|
+
merged_blocks_strings << block_text
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
# Append destination-only blocks preserving their original text
|
|
496
|
+
dest_remaining_order = dest_blocks.select { |b| dest_by_name.key?(b[:name]) }
|
|
497
|
+
dest_remaining_order.each do |b|
|
|
498
|
+
block_text = +""
|
|
499
|
+
block_text << "\n" unless merged_blocks_strings.empty?
|
|
500
|
+
b[:header].each { |hl| block_text << hl } if b[:header].any?
|
|
501
|
+
block_text << "appraise \"#{b[:name]}\" do\n"
|
|
502
|
+
b[:body].each { |bl| block_text << bl }
|
|
503
|
+
block_text << b[:end_line]
|
|
504
|
+
merged_blocks_strings << block_text
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
preamble = tmpl[:preamble].to_s.strip.empty? ? dest[:preamble] : tmpl[:preamble]
|
|
508
|
+
out = +""
|
|
509
|
+
out << preamble unless preamble.nil? || preamble.empty?
|
|
510
|
+
out << "\n" unless out.end_with?("\n")
|
|
511
|
+
out << merged_blocks_strings.join
|
|
512
|
+
out << "\n" unless out.end_with?("\n")
|
|
513
|
+
out
|
|
514
|
+
rescue StandardError => e
|
|
515
|
+
Kettle::Dev.debug_error(e, __method__)
|
|
516
|
+
# Fallback: prefer destination (user changes) and append template content to allow manual reconciliation
|
|
517
|
+
dest_content + "\n# --- TEMPLATE APPRAISALS (unmerged) ---\n" + template_content
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
|
|
294
521
|
# Copy a directory tree, prompting before creating or overwriting.
|
|
295
522
|
# @return [void]
|
|
296
523
|
def copy_dir_with_prompt(src_dir, dest_dir)
|
data/lib/kettle/dev/version.rb
CHANGED
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kettle-dev
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.47
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -396,10 +396,10 @@ licenses:
|
|
|
396
396
|
- MIT
|
|
397
397
|
metadata:
|
|
398
398
|
homepage_uri: https://kettle-dev.galtzo.com/
|
|
399
|
-
source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.1.
|
|
400
|
-
changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.1.
|
|
399
|
+
source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.1.47
|
|
400
|
+
changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.1.47/CHANGELOG.md
|
|
401
401
|
bug_tracker_uri: https://github.com/kettle-rb/kettle-dev/issues
|
|
402
|
-
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.1.
|
|
402
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.1.47
|
|
403
403
|
funding_uri: https://github.com/sponsors/pboling
|
|
404
404
|
wiki_uri: https://github.com/kettle-rb/kettle-dev/wiki
|
|
405
405
|
news_uri: https://www.railsbling.com/tags/kettle-dev
|
metadata.gz.sig
CHANGED
|
Binary file
|