kettle-dev 1.0.17 → 1.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a1bd1c247de10bf953f58bfabaeb578ef5500c76f7a75a39def5f8b8303befb
4
- data.tar.gz: 4ecbfe623cbaf2402e9955746d25f2b2f3a186c874c0be4d252d500814aaae9f
3
+ metadata.gz: 0de7363176923ea5edec18008593906059935cdc8ba3a2ac8095ad05c5a88279
4
+ data.tar.gz: 03cb017debc73c2b28fe08093bf361b954e51677780a4327dff3a7fdefc6d4e6
5
5
  SHA512:
6
- metadata.gz: b9143cb40e9ef0ba4b806e784a8c84fa1520767d452c629c41ba92959c4b49f34c0d636cb28321ab914681801b408ea3f0220ada1aeeba47b46ecd34817dcd4f
7
- data.tar.gz: b4e649547fea4d918c6ce1689c9d6b3848568b4bd85ad406773c34e55a18b21bccd674fe27b2ccc0254b2048565bf8af6862bd2c1508301519a7913dfa28ff53
6
+ metadata.gz: ff70841f58c267c0ddb6388569de8b9370477712aeffba194d7e111f5a6d528336563d827ea3d1bbd53dd01c6fbebbf46954b7368e1786f9d4faf80ff19b7d12
7
+ data.tar.gz: 5dcd05cb14b0a75aff205ed4ff6582e1cd41b8febdcd42485776b360a72c0d4d00e0a4ae561cee0a293ccb68fcdcc2edca80ee7a301c4eed471ed03e056b39f8
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -24,6 +24,31 @@ Please file a bug if you notice a violation of semantic versioning.
24
24
  ### Fixed
25
25
  ### Security
26
26
 
27
+ ## [1.0.19] - 2025-08-29
28
+ - TAG: [v1.0.19][1.0.19t]
29
+ - COVERAGE: 97.84% -- 2350/2402 lines in 20 files
30
+ - BRANCH COVERAGE: 81.46% -- 962/1181 branches in 20 files
31
+ - 76.23% documented
32
+ ### Fixed
33
+ - replacement logic handles a dashed gem-name which maps onto a nested path structure
34
+
35
+ ## [Unreleased]
36
+ ### Added
37
+ - kettle:dev:install and kettle:dev:template support `only=` option: comma-separated glob patterns matched against destination paths relative to project root; non-matching files are excluded from templating.
38
+
39
+ ## [1.0.18] - 2025-08-29
40
+ - TAG: [v1.0.18][1.0.18t]
41
+ - COVERAGE: 71.70% -- 456/636 lines in 9 files
42
+ - BRANCH COVERAGE: 51.17% -- 153/299 branches in 9 files
43
+ - 76.23% documented
44
+ ### Added
45
+ - kettle:dev:install can overwrite gemspec with example gemspec
46
+ - documentation for the start_step CLI option for kettle-release
47
+ - kettle:dev:install add `only=` option for glob filtering.
48
+ ### Fixed
49
+ - kettle:dev:install remove "Works with MRI Ruby*" lines with no badges left
50
+ - kettle:dev:install prefix badge cell replacement with a single space
51
+
27
52
  ## [1.0.17] - 2025-08-29
28
53
  - TAG: [v1.0.17][1.0.17t]
29
54
  - COVERAGE: 98.14% -- 2271/2314 lines in 20 files
@@ -273,7 +298,7 @@ Please file a bug if you notice a violation of semantic versioning.
273
298
  - Selecting will run the selected workflow via `act`
274
299
  - This may move to its own gem in the future.
275
300
 
276
- [Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.0.17...HEAD
301
+ [Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.0.19...HEAD
277
302
  [1.0.0]: https://github.com/kettle-rb/kettle-dev/compare/a427c302df09cfe4253a7c8d400333f9a4c1a208...v1.0.0
278
303
  [1.0.0t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.0.0
279
304
  [1.0.1]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.0...v1.0.1
@@ -310,3 +335,7 @@ Please file a bug if you notice a violation of semantic versioning.
310
335
  [1.0.16t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.0.16
311
336
  [1.0.17]: https://github.com/kettle-rb/kettle-dev/compare/v1.0.16...v1.0.17
312
337
  [1.0.17t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.0.17
338
+ [1.0.18]: https://github.com/kettle-rb/kettle-dev/compare/v1.0.17...v1.0.18
339
+ [1.0.18t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.0.18
340
+ [1.0.19]: https://github.com/kettle-rb/kettle-dev/compare/v1.0.18...v1.0.19
341
+ [1.0.19t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.0.19
data/README.md CHANGED
@@ -9,15 +9,15 @@
9
9
 
10
10
  # 🍲 Kettle::Dev
11
11
 
12
- [![Version][👽versioni]][👽version] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![CodeCov Test Coverage][🔑codecovi]][🔑codecov] [![Coveralls Test Coverage][🔑coveralls-img]][🔑coveralls] [![QLTY Test Coverage][🔑qlty-covi]][🔑qlty-cov] [![QLTY Maintainability][🔑qlty-mnti]][🔑qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf]
12
+ [![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![CodeCov Test Coverage][🔑codecovi]][🔑codecov] [![Coveralls Test Coverage][🔑coveralls-img]][🔑coveralls] [![QLTY Test Coverage][🔑qlty-covi]][🔑qlty-cov] [![QLTY Maintainability][🔑qlty-mnti]][🔑qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf]
13
13
 
14
14
  If ☝️ `ci_badges.map(&:color).detect { it != "green"}` [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
15
15
 
16
16
  ---
17
17
 
18
- OTOH, if `ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS is now my full-time job.
18
+ OTOH, if `ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS maintenance is now my full-time job.
19
19
 
20
- [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
20
+ [![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 or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
21
21
 
22
22
  ## 🌻 Synopsis
23
23
 
@@ -55,7 +55,7 @@ and concordant releases of JRuby, and TruffleRuby.
55
55
  | Works with JRuby | ![JRuby 9.1 Compat][💎jruby-9.1i] ![JRuby 9.2 Compat][💎jruby-9.2i] ![JRuby 9.3 Compat][💎jruby-9.3i] <br/> [![JRuby 9.4 Compat][💎jruby-9.4i]][🚎10-j-wf] [![JRuby 10.0 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] |
56
56
  | Works with Truffle Ruby | ![Truffle Ruby 22.3 Compat][💎truby-22.3i] ![Truffle Ruby 23.0 Compat][💎truby-23.0i] <br/> [![Truffle Ruby 23.1 Compat][💎truby-23.1i]][🚎9-t-wf] [![Truffle Ruby 24.1 Compat][💎truby-c-i]][🚎11-c-wf] |
57
57
  | Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎4-lg-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎6-s-wf] [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎6-s-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎6-s-wf] [![Ruby 3.4 Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf] |
58
- | Works with MRI Ruby 2 | <br/> [![Ruby 2.3 Compat][💎ruby-2.3i]][🚎1-an-wf] [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎1-an-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎1-an-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎7-us-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎7-us-wf] |
58
+ | Works with MRI Ruby 2 | [![Ruby 2.3 Compat][💎ruby-2.3i]][🚎1-an-wf] [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎1-an-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎1-an-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎7-us-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎7-us-wf] |
59
59
  | Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on CodeBerg.org][📜src-cb-img]][📜src-cb] [![Source on Github.com][📜src-gh-img]][📜src-gh] [![The best SHA: dQw4w9WgXcQ!][🧮kloc-img]][🧮kloc] |
60
60
  | Documentation | [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![YARD on Galtzo.com][📜docs-head-rd-img]][🚎yard-head] [![Maintainer Blog][🚂maint-blog-img]][🚂maint-blog] [![Wiki][📜wiki-img]][📜wiki] |
61
61
  | Compliance | [![License: MIT][📄license-img]][📄license-ref] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
@@ -207,9 +207,11 @@ That’s it. Once installed, kettle-dev:
207
207
  - Grapheme syncing: detects the grapheme (e.g., emoji) immediately following the first `#` H1 in README.md and ensures the same grapheme, followed by a single space, prefixes both `spec.summary` and `spec.description` in your gemspec. If the H1 has none, you’ll be prompted to enter one; tests use an input adapter, so runs never hang in CI.
208
208
  - option: force: When truthy (1, true, y, yes), treat all y/N prompts as Yes. Useful for non-interactive runs or to accept defaults quickly. Example: `bundle exec rake kettle:dev:template force=true`
209
209
  - option: allowed: When truthy (1, true, y, yes), resume task after you have reviewed `.envrc`/`.env.local` and run `direnv allow`. If either file is created or updated, the task will abort with instructions unless `allowed=true` is present. Example: `bundle exec rake kettle:dev:install allowed=true`
210
+ - option: only: A comma-separated list of glob patterns to include in templating. Any destination file whose path+filename does not match one of the patterns is excluded. Patterns are matched relative to your project root. Examples: `only="README.md,.github/**"`, `only="docs/**,lib/**/*.rb"`.
210
211
  - `kettle:dev:template` — templates files from this gem into your project (e.g., .github workflows, .devcontainer, .qlty, modular Gemfiles, README/CONTRIBUTING stubs). You can run this independently to refresh templates without the extra install prompts.
211
212
  - option: force: When truthy (1, true, y, yes), treat all y/N prompts as Yes. Useful for non-interactive runs or to accept defaults quickly. Example: `bundle exec rake kettle:dev:template force=true`
212
213
  - option: allowed: When truthy (1, true, y, yes), resume task after you have reviewed `.envrc`/`.env.local` and run `direnv allow`. If either file is created or updated, the task will abort with instructions unless `allowed=true` is present. Example: `bundle exec rake kettle:dev:template allowed=true`
214
+ - option: only: Same as for install; limits which destination files are written based on glob patterns relative to the project root.
213
215
 
214
216
  Recommended one-time setup in your project:
215
217
  - Install binstubs so kettle-dev executables are available under `./bin`:
@@ -320,6 +322,29 @@ Releasing (maintainers)
320
322
  - Ensures trunk sync and rebases feature as needed, pushes, monitors GitHub Actions with a progress bar, and merges feature to trunk on success.
321
323
  - Exports `SOURCE_DATE_EPOCH`, builds (optionally signed), creates gem checksums, and runs `bundle exec rake release` (prompts for signing key + RubyGems MFA OTP as needed).
322
324
 
325
+ - start_step map (skip directly to a phase):
326
+ - 1: Ensure Bundler >= 2.7.0 and begin full flow
327
+ - 2: Version detection + sanity checks + prompt to confirm version.rb and CHANGELOG.md
328
+ - 3: Run bin/setup
329
+ - 4: Run bin/rake (default task)
330
+ - 5: Run appraisal:update when Appraisals exists (skip otherwise)
331
+ - 6: Verify git user.name/email and commit release prep "🔖 Prepare release vX.Y.Z"
332
+ - 7: Optionally run local CI with nektos/act before pushing (see K_RELEASE_LOCAL_CI, K_RELEASE_LOCAL_CI_WORKFLOW)
333
+ - 8: Ensure trunk is up-to-date and reconcile with GitHub remote if needed
334
+ - 9: Push current branch to configured remotes (or default), force-pushing on retry when needed
335
+ - 10: Monitor CI after push (GitHub Actions and/or GitLab pipelines); progress bar; aborts on failure
336
+ - 11: Merge feature branch into trunk and push
337
+ - 12: Checkout trunk and pull latest
338
+ - 13: Signing checks and guidance (abort when signing enabled but cert missing); respect SKIP_GEM_SIGNING
339
+ - 14: Build gem (honors SKIP_GEM_SIGNING via env prefix)
340
+ - 15: Generate and validate gem checksums (bin/gem_checksums)
341
+ - 16: Release via `bundle exec rake release` and validate checksums again
342
+ - 17: Create GitHub release from CHANGELOG when GITHUB_TOKEN present
343
+ - 18: Push git tags to remotes (to "all" remote only when present; otherwise to each remote)
344
+
345
+ Examples:
346
+ - After intermittent CI failure, restart from monitoring: `bundle exec kettle-release start_step=10`
347
+
323
348
  Tip: The commit message helper `exe/kettle-commit-msg` prefers project-local `.git-hooks` (then falls back to `~/.git-hooks`). The goalie file `commit-subjects-goalie.txt` controls when a footer is appended; customize `footer-template.erb.txt` as you like.
324
349
 
325
350
  ### Open Collective README updater
@@ -403,7 +428,7 @@ I’m developing a new library, [floss_funding][🖇floss-funding-gem], designed
403
428
 
404
429
  **[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
405
430
 
406
- [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
431
+ [![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 or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
407
432
 
408
433
  ## 🔐 Security
409
434
 
@@ -542,6 +567,10 @@ Thanks for RTFM. ☺️
542
567
  [🖇osc-all-img]: https://img.shields.io/opencollective/all/kettle-rb
543
568
  [🖇osc-sponsors-img]: https://img.shields.io/opencollective/sponsors/kettle-rb
544
569
  [🖇osc-backers-img]: https://img.shields.io/opencollective/backers/kettle-rb
570
+ [🖇osc-backers]: https://opencollective.com/kettle-rb#backer
571
+ [🖇osc-backers-i]: https://opencollective.com/kettle-rb/backers/badge.svg
572
+ [🖇osc-sponsors]: https://opencollective.com/kettle-rb#sponsor
573
+ [🖇osc-sponsors-i]: https://opencollective.com/kettle-rb/sponsors/badge.svg
545
574
  [🖇osc-all-bottom-img]: https://img.shields.io/opencollective/all/kettle-rb?style=for-the-badge
546
575
  [🖇osc-sponsors-bottom-img]: https://img.shields.io/opencollective/sponsors/kettle-rb?style=for-the-badge
547
576
  [🖇osc-backers-bottom-img]: https://img.shields.io/opencollective/backers/kettle-rb?style=for-the-badge
@@ -571,6 +600,8 @@ Thanks for RTFM. ☺️
571
600
  [⛳️namespace-img]: https://img.shields.io/badge/namespace-Kettle%3A%3ADev-3C2D2D.svg?style=square&logo=ruby&logoColor=white
572
601
  [⛳️gem-name]: https://rubygems.org/gems/kettle-dev
573
602
  [⛳️name-img]: https://img.shields.io/badge/name-kettle--dev-3C2D2D.svg?style=square&logo=rubygems&logoColor=red
603
+ [⛳️tag-img]: https://img.shields.io/github/tag/kettle-rb/kettle-dev.svg
604
+ [⛳️tag]: http://github.com/kettle-rb/kettle-dev/releases
574
605
  [🚂maint-blog]: http://www.railsbling.com/tags/kettle-dev
575
606
  [🚂maint-blog-img]: https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange
576
607
  [🚂maint-contact]: http://www.railsbling.com/contact
@@ -704,7 +735,7 @@ Thanks for RTFM. ☺️
704
735
  [📌gitmoji]:https://gitmoji.dev
705
736
  [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20😜%20😍-34495e.svg?style=flat-square
706
737
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
707
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-2.314-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
738
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-2.402-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
708
739
  [🔐security]: SECURITY.md
709
740
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
710
741
  [📄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
@@ -9,15 +9,15 @@
9
9
 
10
10
  # 🍲 Kettle::Dev
11
11
 
12
- [![Version][👽versioni]][👽version] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![CodeCov Test Coverage][🔑codecovi]][🔑codecov] [![Coveralls Test Coverage][🔑coveralls-img]][🔑coveralls] [![QLTY Test Coverage][🔑qlty-covi]][🔑qlty-cov] [![QLTY Maintainability][🔑qlty-mnti]][🔑qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf]
12
+ [![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![CodeCov Test Coverage][🔑codecovi]][🔑codecov] [![Coveralls Test Coverage][🔑coveralls-img]][🔑coveralls] [![QLTY Test Coverage][🔑qlty-covi]][🔑qlty-cov] [![QLTY Maintainability][🔑qlty-mnti]][🔑qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf]
13
13
 
14
14
  If ☝️ `ci_badges.map(&:color).detect { it != "green"}` [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
15
15
 
16
16
  ---
17
17
 
18
- OTOH, if `ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS is now my full-time job.
18
+ OTOH, if `ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS maintenance is now my full-time job.
19
19
 
20
- [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
20
+ [![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 or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
21
21
 
22
22
  ## 🌻 Synopsis
23
23
 
@@ -189,7 +189,7 @@ I’m developing a new library, [floss_funding][🖇floss-funding-gem], designed
189
189
 
190
190
  **[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
191
191
 
192
- [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
192
+ [![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 or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
193
193
 
194
194
  ## 🔐 Security
195
195
 
@@ -328,6 +328,10 @@ Thanks for RTFM. ☺️
328
328
  [🖇osc-all-img]: https://img.shields.io/opencollective/all/kettle-rb
329
329
  [🖇osc-sponsors-img]: https://img.shields.io/opencollective/sponsors/kettle-rb
330
330
  [🖇osc-backers-img]: https://img.shields.io/opencollective/backers/kettle-rb
331
+ [🖇osc-backers]: https://opencollective.com/kettle-rb#backer
332
+ [🖇osc-backers-i]: https://opencollective.com/kettle-rb/backers/badge.svg
333
+ [🖇osc-sponsors]: https://opencollective.com/kettle-rb#sponsor
334
+ [🖇osc-sponsors-i]: https://opencollective.com/kettle-rb/sponsors/badge.svg
331
335
  [🖇osc-all-bottom-img]: https://img.shields.io/opencollective/all/kettle-rb?style=for-the-badge
332
336
  [🖇osc-sponsors-bottom-img]: https://img.shields.io/opencollective/sponsors/kettle-rb?style=for-the-badge
333
337
  [🖇osc-backers-bottom-img]: https://img.shields.io/opencollective/backers/kettle-rb?style=for-the-badge
@@ -357,6 +361,8 @@ Thanks for RTFM. ☺️
357
361
  [⛳️namespace-img]: https://img.shields.io/badge/namespace-Kettle%3A%3ADev-3C2D2D.svg?style=square&logo=ruby&logoColor=white
358
362
  [⛳️gem-name]: https://rubygems.org/gems/kettle-dev
359
363
  [⛳️name-img]: https://img.shields.io/badge/name-kettle--dev-3C2D2D.svg?style=square&logo=rubygems&logoColor=red
364
+ [⛳️tag-img]: https://img.shields.io/github/tag/kettle-rb/kettle-dev.svg
365
+ [⛳️tag]: http://github.com/kettle-rb/kettle-dev/releases
360
366
  [🚂maint-blog]: http://www.railsbling.com/tags/kettle-dev
361
367
  [🚂maint-blog-img]: https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange
362
368
  [🚂maint-contact]: http://www.railsbling.com/contact
@@ -495,7 +501,7 @@ Thanks for RTFM. ☺️
495
501
  [📌gitmoji]:https://gitmoji.dev
496
502
  [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20😜%20😍-34495e.svg?style=flat-square
497
503
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
498
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-2.314-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
504
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-2.402-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
499
505
  [🔐security]: SECURITY.md
500
506
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
501
507
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
data/Rakefile.example CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # kettle-dev Rakefile v1.0.17 - 2025-08-29
3
+ # kettle-dev Rakefile v1.0.19 - 2025-08-29
4
4
  # Ruby 2.3 (Safe Navigation) or higher required
5
5
  #
6
6
  # MIT License (see License.txt)
@@ -0,0 +1,119 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ gem_version =
5
+ if RUBY_VERSION >= "3.1" # rubocop:disable Gemspec/RubyVersionGlobalsUsage
6
+ # Loading Version into an anonymous module allows version.rb to get code coverage from SimpleCov!
7
+ # See: https://github.com/simplecov-ruby/simplecov/issues/557#issuecomment-2630782358
8
+ # See: https://github.com/panorama-ed/memo_wise/pull/397
9
+ Module.new.tap { |mod| Kernel.load("#{__dir__}/lib/kettle/dev/version.rb", mod) }::Kettle::Dev::Version::VERSION
10
+ else
11
+ # NOTE: Use __FILE__ or __dir__ until removal of Ruby 1.x support
12
+ # __dir__ introduced in Ruby 1.9.1
13
+ # lib = File.expand_path("../lib", __FILE__)
14
+ lib = File.expand_path("lib", __dir__)
15
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
16
+ require "kettle/dev/version"
17
+ Kettle::Dev::Version::VERSION
18
+ end
19
+
20
+ Gem::Specification.new do |spec|
21
+ spec.name = "kettle-dev"
22
+ spec.version = gem_version
23
+ spec.authors = ["Peter H. Boling"]
24
+ spec.email = ["floss@galtzo.com"]
25
+
26
+ spec.summary = "🍲 "
27
+ spec.description = "🍲 "
28
+ spec.homepage = "https://github.com/kettle-rb/kettle-dev"
29
+ spec.license = "MIT"
30
+ spec.required_ruby_version = ">= 2.3.0"
31
+
32
+ # Linux distros often package gems and securely certify them independent
33
+ # of the official RubyGem certification process. Allowed via ENV["SKIP_GEM_SIGNING"]
34
+ # Ref: https://gitlab.com/oauth-xx/version_gem/-/issues/3
35
+ # Hence, only enable signing if `SKIP_GEM_SIGNING` is not set in ENV.
36
+ # See CONTRIBUTING.md
37
+ unless ENV.include?("SKIP_GEM_SIGNING")
38
+ user_cert = "certs/#{ENV.fetch("GEM_CERT_USER", ENV["USER"])}.pem"
39
+ cert_file_path = File.join(__dir__, user_cert)
40
+ cert_chain = cert_file_path.split(",")
41
+ cert_chain.select! { |fp| File.exist?(fp) }
42
+ if cert_file_path && cert_chain.any?
43
+ spec.cert_chain = cert_chain
44
+ if $PROGRAM_NAME.end_with?("gem") && ARGV[0] == "build"
45
+ spec.signing_key = File.join(Gem.user_home, ".ssh", "gem-private_key.pem")
46
+ end
47
+ end
48
+ end
49
+
50
+ spec.metadata["homepage_uri"] = "https://#{spec.name.tr("_", "-")}.galtzo.com/"
51
+ spec.metadata["source_code_uri"] = "#{spec.homepage}/tree/v#{spec.version}"
52
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/v#{spec.version}/CHANGELOG.md"
53
+ spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
54
+ spec.metadata["documentation_uri"] = "https://www.rubydoc.info/gems/#{spec.name}/#{spec.version}"
55
+ spec.metadata["funding_uri"] = "https://github.com/sponsors/pboling"
56
+ spec.metadata["wiki_uri"] = "#{spec.homepage}/wiki"
57
+ spec.metadata["news_uri"] = "https://www.railsbling.com/tags/#{spec.name}"
58
+ spec.metadata["discord_uri"] = "https://discord.gg/3qme4XHNKN"
59
+ spec.metadata["rubygems_mfa_required"] = "true"
60
+
61
+ # Specify which files are part of the released package.
62
+ spec.files = Dir[
63
+ # Executables and tasks
64
+ "exe/*",
65
+ "lib/**/*.rb",
66
+ "lib/**/*.rake",
67
+ # Signatures
68
+ "sig/**/*.rbs",
69
+ ]
70
+ # Automatically included with gem package, normally no need to list again in files.
71
+ # But this gem acts as a pseudo-template, so we include some in both places.
72
+ spec.extra_rdoc_files = Dir[
73
+ # Files (alphabetical)
74
+ "CHANGELOG.md",
75
+ "CITATION.cff",
76
+ "CODE_OF_CONDUCT.md",
77
+ "CONTRIBUTING.md",
78
+ "LICENSE.txt",
79
+ "README.md",
80
+ "REEK",
81
+ "RUBOCOP.md",
82
+ "SECURITY.md",
83
+ ]
84
+ spec.rdoc_options += [
85
+ "--title",
86
+ "#{spec.name} - #{spec.summary}",
87
+ "--main",
88
+ "README.md",
89
+ "--exclude",
90
+ "^sig/",
91
+ "--line-numbers",
92
+ "--inline-source",
93
+ "--quiet",
94
+ ]
95
+ spec.require_paths = ["lib"]
96
+ spec.bindir = "exe"
97
+ # files listed are relative paths from bindir above.
98
+ spec.executables = []
99
+
100
+ # Utilities
101
+ spec.add_dependency("version_gem", "~> 1.1", ">= 1.1.8") # ruby >= 2.2.0
102
+
103
+ # NOTE: It is preferable to list development dependencies in the gemspec due to increased
104
+ # visibility and discoverability on RubyGems.org.
105
+ # However, development dependencies in gemspec will install on
106
+ # all versions of Ruby that will run in CI.
107
+ # This gem, and its gemspec runtime dependencies, will install on Ruby down to 2.3.x.
108
+ # This gem, and its gemspec development dependencies, will install on Ruby down to 2.3.x.
109
+ # This is because in CI easy installation of Ruby, via setup-ruby, is for >= 2.3.
110
+ # Thus, dev dependencies in gemspec must have
111
+ #
112
+ # required_ruby_version ">= 2.3" (or lower)
113
+ #
114
+ # Development dependencies that require strictly newer Ruby versions should be in a "gemfile",
115
+ # and preferably a modular one (see gemfiles/modular/*.gemfile).
116
+
117
+ # Dev, Test, & Release Tasks
118
+ spec.add_development_dependency("kettle-dev", "~> 1.0.17") # ruby >= 2.3.0
119
+ end
@@ -77,12 +77,32 @@ module Kettle
77
77
  end
78
78
  end
79
79
 
80
- # Remove any MRI Ruby rows that are left with no badges/links after trimming
81
- content = content.lines.reject { |ln|
80
+ # Fix leading <br/> in MRI rows and remove rows that end up empty
81
+ content = content.lines.map { |ln|
82
82
  if ln.start_with?("| Works with MRI Ruby")
83
83
  cells = ln.split("|", -1)
84
84
  # cells[0] is empty (leading |), cells[1] = label cell, cells[2] = badges cell
85
85
  badge_cell = cells[2] || ""
86
+ # If badge cell is only a <br/> (possibly with whitespace), treat as empty (row will be removed later)
87
+ if badge_cell.strip == "<br/>"
88
+ cells[2] = " "
89
+ cells.join("|")
90
+ elsif badge_cell =~ /\A\s*<br\/>/i
91
+ # If badge cell starts with <br/> and there are no badges before it, strip the leading <br/>
92
+ # We consider "no badges before" as any leading whitespace followed immediately by <br/>
93
+ cleaned = badge_cell.sub(/\A\s*<br\/>\s*/i, "")
94
+ cells[2] = " #{cleaned}" # prefix with a single space
95
+ cells.join("|")
96
+ else
97
+ ln
98
+ end
99
+ else
100
+ ln
101
+ end
102
+ }.reject { |ln|
103
+ if ln.start_with?("| Works with MRI Ruby")
104
+ cells = ln.split("|", -1)
105
+ badge_cell = cells[2] || ""
86
106
  badge_cell.strip.empty?
87
107
  else
88
108
  false
@@ -177,6 +177,40 @@ module Kettle
177
177
  end
178
178
 
179
179
  # 7) Root and other files
180
+ # 7a) Special-case: gemspec example must be renamed to destination gem's name
181
+ begin
182
+ # Prefer the .example variant when present
183
+ gemspec_template_src = helpers.prefer_example(File.join(gem_checkout_root, "kettle-dev.gemspec"))
184
+ if File.exist?(gemspec_template_src)
185
+ dest_gemspec = if gem_name && !gem_name.to_s.empty?
186
+ File.join(project_root, "#{gem_name}.gemspec")
187
+ else
188
+ # Fallback rules:
189
+ # 1) Prefer any existing gemspec in the destination project
190
+ existing = Dir.glob(File.join(project_root, "*.gemspec")).sort.first
191
+ if existing
192
+ existing
193
+ else
194
+ # 2) If none, use the example file's name with ".example" removed
195
+ fallback_name = File.basename(gemspec_template_src).sub(/\.example\z/, "")
196
+ File.join(project_root, fallback_name)
197
+ end
198
+ end
199
+ helpers.copy_file_with_prompt(gemspec_template_src, dest_gemspec, allow_create: true, allow_replace: true) do |content|
200
+ helpers.apply_common_replacements(
201
+ content,
202
+ org: forge_org,
203
+ gem_name: gem_name,
204
+ namespace: namespace,
205
+ namespace_shield: namespace_shield,
206
+ gem_shield: gem_shield,
207
+ )
208
+ end
209
+ end
210
+ rescue StandardError
211
+ # Do not fail the entire template task if gemspec copy has issues
212
+ end
213
+
180
214
  files_to_copy = %w[
181
215
  .envrc
182
216
  .gitignore
@@ -486,6 +520,35 @@ module Kettle
486
520
  # Handle .git-hooks files (see original rake task for details)
487
521
  source_hooks_dir = File.join(gem_checkout_root, ".git-hooks")
488
522
  if Dir.exist?(source_hooks_dir)
523
+ # Honor ENV["only"]: skip entire .git-hooks handling unless patterns include .git-hooks
524
+ begin
525
+ only_raw = ENV["only"].to_s
526
+ if !only_raw.empty?
527
+ patterns = only_raw.split(",").map { |s| s.strip }.reject(&:empty?)
528
+ if !patterns.empty?
529
+ proj = helpers.project_root.to_s
530
+ target_dir = File.join(proj, ".git-hooks")
531
+ # Determine if any pattern would match either the directory itself (with /** semantics) or files within it
532
+ matches = patterns.any? do |pat|
533
+ if pat.end_with?("/**")
534
+ base = pat[0..-4]
535
+ base == ".git-hooks" || base == target_dir.sub(/^#{Regexp.escape(proj)}\/?/, "")
536
+ else
537
+ # Check for explicit .git-hooks or subpaths
538
+ File.fnmatch?(pat, ".git-hooks", File::FNM_PATHNAME | File::FNM_EXTGLOB | File::FNM_DOTMATCH) ||
539
+ File.fnmatch?(pat, ".git-hooks/*", File::FNM_PATHNAME | File::FNM_EXTGLOB | File::FNM_DOTMATCH)
540
+ end
541
+ end
542
+ unless matches
543
+ # No interest in .git-hooks => skip prompts and copies for hooks entirely
544
+ # Note: we intentionally do not record template_results for hooks
545
+ return
546
+ end
547
+ end
548
+ end
549
+ rescue StandardError
550
+ # If filter parsing fails, proceed as before
551
+ end
489
552
  goalie_src = File.join(source_hooks_dir, "commit-subjects-goalie.txt")
490
553
  footer_src = File.join(source_hooks_dir, "footer-template.erb.txt")
491
554
  hook_ruby_src = File.join(source_hooks_dir, "commit-msg")
@@ -135,6 +135,39 @@ module Kettle
135
135
  # @return [void]
136
136
  def copy_file_with_prompt(src_path, dest_path, allow_create: true, allow_replace: true)
137
137
  return unless File.exist?(src_path)
138
+
139
+ # Apply optional inclusion filter via ENV["only"] (comma-separated glob patterns relative to project root)
140
+ begin
141
+ only_raw = ENV["only"].to_s
142
+ if !only_raw.empty?
143
+ patterns = only_raw.split(",").map { |s| s.strip }.reject(&:empty?)
144
+ if !patterns.empty?
145
+ proj = project_root.to_s
146
+ rel_dest = dest_path.to_s
147
+ if rel_dest.start_with?(proj + "/")
148
+ rel_dest = rel_dest[(proj.length + 1)..-1]
149
+ elsif rel_dest == proj
150
+ rel_dest = ""
151
+ end
152
+ matched = patterns.any? do |pat|
153
+ if pat.end_with?("/**")
154
+ base = pat[0..-4]
155
+ rel_dest == base || rel_dest.start_with?(base + "/")
156
+ else
157
+ File.fnmatch?(pat, rel_dest, File::FNM_PATHNAME | File::FNM_EXTGLOB | File::FNM_DOTMATCH)
158
+ end
159
+ end
160
+ unless matched
161
+ record_template_result(dest_path, :skip)
162
+ puts "Skipping #{dest_path} (excluded by only filter)"
163
+ return
164
+ end
165
+ end
166
+ end
167
+ rescue StandardError
168
+ # If anything goes wrong parsing/matching, ignore the filter and proceed.
169
+ end
170
+
138
171
  dest_exists = File.exist?(dest_path)
139
172
  action = nil
140
173
  if dest_exists
@@ -166,6 +199,59 @@ module Kettle
166
199
  # @return [void]
167
200
  def copy_dir_with_prompt(src_dir, dest_dir)
168
201
  return unless Dir.exist?(src_dir)
202
+
203
+ # Build a matcher for ENV["only"], relative to project root, that can be reused within this method
204
+ only_raw = ENV["only"].to_s
205
+ patterns = only_raw.split(",").map { |s| s.strip }.reject(&:empty?) unless only_raw.nil?
206
+ patterns ||= []
207
+ proj_root = project_root.to_s
208
+ matches_only = lambda do |abs_dest|
209
+ return true if patterns.empty?
210
+ begin
211
+ rel_dest = abs_dest.to_s
212
+ if rel_dest.start_with?(proj_root + "/")
213
+ rel_dest = rel_dest[(proj_root.length + 1)..-1]
214
+ elsif rel_dest == proj_root
215
+ rel_dest = ""
216
+ end
217
+ patterns.any? do |pat|
218
+ if pat.end_with?("/**")
219
+ base = pat[0..-4]
220
+ rel_dest == base || rel_dest.start_with?(base + "/")
221
+ else
222
+ File.fnmatch?(pat, rel_dest, File::FNM_PATHNAME | File::FNM_EXTGLOB | File::FNM_DOTMATCH)
223
+ end
224
+ end
225
+ rescue StandardError
226
+ # On any error, do not filter out (act as matched)
227
+ true
228
+ end
229
+ end
230
+
231
+ # Early exit: if an only filter is present and no files inside this directory would match,
232
+ # do not prompt to create/replace this directory at all.
233
+ begin
234
+ if !patterns.empty?
235
+ any_match = false
236
+ Find.find(src_dir) do |path|
237
+ rel = path.sub(/^#{Regexp.escape(src_dir)}\/?/, "")
238
+ next if rel.empty?
239
+ next if File.directory?(path)
240
+ target = File.join(dest_dir, rel)
241
+ if matches_only.call(target)
242
+ any_match = true
243
+ break
244
+ end
245
+ end
246
+ unless any_match
247
+ record_template_result(dest_dir, :skip)
248
+ return
249
+ end
250
+ end
251
+ rescue StandardError
252
+ # If determining matches fails, fall through to prompting logic
253
+ end
254
+
169
255
  dest_exists = Dir.exist?(dest_dir)
170
256
  if dest_exists
171
257
  if ask("Replace directory #{dest_dir} (will overwrite files)?", true)
@@ -176,8 +262,12 @@ module Kettle
176
262
  if File.directory?(path)
177
263
  FileUtils.mkdir_p(target)
178
264
  else
265
+ # Per-file inclusion filter
266
+ next unless matches_only.call(target)
267
+
179
268
  FileUtils.mkdir_p(File.dirname(target))
180
269
  if File.exist?(target)
270
+
181
271
  # Skip only if contents are identical. If source and target paths are the same,
182
272
  # avoid FileUtils.cp (which raises) and do an in-place rewrite to satisfy "copy".
183
273
  begin
@@ -210,6 +300,9 @@ module Kettle
210
300
  if File.directory?(path)
211
301
  FileUtils.mkdir_p(target)
212
302
  else
303
+ # Per-file inclusion filter
304
+ next unless matches_only.call(target)
305
+
213
306
  FileUtils.mkdir_p(File.dirname(target))
214
307
  if File.exist?(target)
215
308
  # Skip only if contents are identical. If source and target paths are the same,
@@ -252,6 +345,8 @@ module Kettle
252
345
  c = c.gsub(/\bKettle::Dev\b/u, namespace) unless namespace.empty?
253
346
  c = c.gsub("Kettle%3A%3ADev", namespace_shield) unless namespace_shield.empty?
254
347
  c = c.gsub("kettle--dev", gem_shield)
348
+ # Replace require and path structures with gem_name, modifying - to / if needed
349
+ c = c.gsub("kettle/dev", gem_name.tr("-", "/"))
255
350
  end
256
351
  c
257
352
  end
@@ -6,7 +6,7 @@ module Kettle
6
6
  module Version
7
7
  # The gem version.
8
8
  # @return [String]
9
- VERSION = "1.0.17"
9
+ VERSION = "1.0.19"
10
10
  end
11
11
  end
12
12
  end
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.0.17
4
+ version: 1.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -288,6 +288,7 @@ files:
288
288
  - gemfiles/modular/optional.gemfile
289
289
  - gemfiles/modular/optional.gemfile.example
290
290
  - gemfiles/modular/style.gemfile
291
+ - kettle-dev.gemspec.example
291
292
  - lib/kettle-dev.rb
292
293
  - lib/kettle/dev.rb
293
294
  - lib/kettle/dev/ci_helpers.rb
@@ -341,10 +342,10 @@ licenses:
341
342
  - MIT
342
343
  metadata:
343
344
  homepage_uri: https://kettle-dev.galtzo.com/
344
- source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.0.17
345
- changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.0.17/CHANGELOG.md
345
+ source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.0.19
346
+ changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.0.19/CHANGELOG.md
346
347
  bug_tracker_uri: https://github.com/kettle-rb/kettle-dev/issues
347
- documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.0.17
348
+ documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.0.19
348
349
  funding_uri: https://github.com/sponsors/pboling
349
350
  wiki_uri: https://github.com/kettle-rb/kettle-dev/wiki
350
351
  news_uri: https://www.railsbling.com/tags/kettle-dev
metadata.gz.sig CHANGED
Binary file