kettle-dev 1.0.17 → 1.0.18
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 +20 -1
- data/README.md +37 -6
- data/README.md.example +11 -5
- data/Rakefile.example +1 -1
- data/kettle-dev.gemspec.example +119 -0
- data/lib/kettle/dev/tasks/install_task.rb +22 -2
- data/lib/kettle/dev/tasks/template_task.rb +63 -0
- data/lib/kettle/dev/template_helpers.rb +93 -0
- data/lib/kettle/dev/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +5 -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: 37a31b1ef8fcd5ec07cddb7b0f96f1eaf3f6670f30a2f8bdfd36a2a35454784d
|
4
|
+
data.tar.gz: 39a1e1ada0fb1034c543d4bd7b3295dfc3f8cced4aee717220f841104d8587fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e53a5bdc7b9121b89524fc0df53d7d4c2955f7248b3db751ba3f45bb60ef0b7738b1380d4c5c8a5295ac2084a225e67e62379fd2bc5d0ddcb8ec28b9f8687c9
|
7
|
+
data.tar.gz: 800681daf457912fff0639273f101ac2393fae15146837803c10662dbd60b6555f3c65665155bef8ffe0fe883fcdad789b682cb052c7a7f83379cd659b75f80c
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -24,6 +24,23 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
24
24
|
### Fixed
|
25
25
|
### Security
|
26
26
|
|
27
|
+
## [Unreleased]
|
28
|
+
### Added
|
29
|
+
- 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.
|
30
|
+
|
31
|
+
## [1.0.18] - 2025-08-29
|
32
|
+
- TAG: [v1.0.18][1.0.18t]
|
33
|
+
- COVERAGE: 71.70% -- 456/636 lines in 9 files
|
34
|
+
- BRANCH COVERAGE: 51.17% -- 153/299 branches in 9 files
|
35
|
+
- 76.23% documented
|
36
|
+
### Added
|
37
|
+
- kettle:dev:install can overwrite gemspec with example gemspec
|
38
|
+
- documentation for the start_step CLI option for kettle-release
|
39
|
+
- kettle:dev:install add `only=` option for glob filtering.
|
40
|
+
### Fixed
|
41
|
+
- kettle:dev:install remove "Works with MRI Ruby*" lines with no badges left
|
42
|
+
- kettle:dev:install prefix badge cell replacement with a single space
|
43
|
+
|
27
44
|
## [1.0.17] - 2025-08-29
|
28
45
|
- TAG: [v1.0.17][1.0.17t]
|
29
46
|
- COVERAGE: 98.14% -- 2271/2314 lines in 20 files
|
@@ -273,7 +290,7 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
273
290
|
- Selecting will run the selected workflow via `act`
|
274
291
|
- This may move to its own gem in the future.
|
275
292
|
|
276
|
-
[Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.0.
|
293
|
+
[Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.0.18...HEAD
|
277
294
|
[1.0.0]: https://github.com/kettle-rb/kettle-dev/compare/a427c302df09cfe4253a7c8d400333f9a4c1a208...v1.0.0
|
278
295
|
[1.0.0t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.0.0
|
279
296
|
[1.0.1]: https://gitlab.com/kettle-rb/kettle-dev/-/compare/v1.0.0...v1.0.1
|
@@ -310,3 +327,5 @@ Please file a bug if you notice a violation of semantic versioning.
|
|
310
327
|
[1.0.16t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.0.16
|
311
328
|
[1.0.17]: https://github.com/kettle-rb/kettle-dev/compare/v1.0.16...v1.0.17
|
312
329
|
[1.0.17t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.0.17
|
330
|
+
[1.0.18]: https://github.com/kettle-rb/kettle-dev/compare/v1.0.17...v1.0.18
|
331
|
+
[1.0.18t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.0.18
|
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] [![
|
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 |
|
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
|
-
[![
|
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-
|
738
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.636-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] [![
|
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
|
-
[![
|
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-
|
504
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.636-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
@@ -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
|
-
#
|
81
|
-
content = content.lines.
|
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,
|
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.0.
|
4
|
+
version: 1.0.18
|
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.
|
345
|
-
changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.0.
|
345
|
+
source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.0.18
|
346
|
+
changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.0.18/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.
|
348
|
+
documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.0.18
|
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
|