kettle-dev 1.1.21 → 1.1.23

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ancient.yml +0 -5
  4. data/.github/workflows/ancient.yml.example +0 -5
  5. data/.github/workflows/coverage.yml +0 -5
  6. data/.github/workflows/coverage.yml.example +0 -5
  7. data/.github/workflows/current.yml +8 -14
  8. data/.github/workflows/current.yml.example +89 -0
  9. data/.github/workflows/dep-heads.yml +0 -5
  10. data/.github/workflows/heads.yml +0 -5
  11. data/.github/workflows/heads.yml.example +0 -5
  12. data/.github/workflows/jruby.yml +0 -5
  13. data/.github/workflows/jruby.yml.example +0 -5
  14. data/.github/workflows/legacy.yml +0 -5
  15. data/.github/workflows/license-eye.yml +0 -5
  16. data/.github/workflows/locked_deps.yml +0 -5
  17. data/.github/workflows/style.yml +0 -5
  18. data/.github/workflows/supported.yml +0 -5
  19. data/.github/workflows/truffle.yml +0 -5
  20. data/.github/workflows/unlocked_deps.yml +0 -5
  21. data/.github/workflows/unsupported.yml +0 -5
  22. data/.junie/guidelines.md +4 -2
  23. data/CHANGELOG.md +35 -1
  24. data/README.md +1 -1
  25. data/README.md.example +2 -2
  26. data/Rakefile.example +1 -1
  27. data/kettle-dev.gemspec.example +3 -4
  28. data/lib/kettle/dev/gem_spec_reader.rb +22 -25
  29. data/lib/kettle/dev/open_collective_config.rb +60 -0
  30. data/lib/kettle/dev/readme_backers.rb +6 -12
  31. data/lib/kettle/dev/tasks/template_task.rb +5 -0
  32. data/lib/kettle/dev/template_helpers.rb +45 -1
  33. data/lib/kettle/dev/version.rb +1 -1
  34. data/lib/kettle/dev.rb +1 -0
  35. data/sig/kettle/dev/open_collective_config.rbs +8 -0
  36. data/sig/kettle/dev/template_helpers.rbs +3 -3
  37. data.tar.gz.sig +0 -0
  38. metadata +7 -4
  39. metadata.gz.sig +4 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bda29e9327b5714faa682451c88597ff3a96811155b2876d1db37fe374edc54f
4
- data.tar.gz: af0eb8bfe6afdcb896b993fb6fa59d50be21ce047b6fd2e1d34281ad6bcced17
3
+ metadata.gz: beaae4a405c9356c0b987d0e6c44bbfa914e41a222bf4c249b3dd69948bda155
4
+ data.tar.gz: 6d38fc925464a056dce98e605a3c6221405434815f0983dbcc72281a911a876c
5
5
  SHA512:
6
- metadata.gz: 9f76db200b74e6a1438ba735fe81268a674634e327ccb9b74e04645e0305d859c7be166eba1e60f2dec922a0c19697347f49df1a08d4c3e2f5f9d9346aa9f3bc
7
- data.tar.gz: 55e4f6763438a9389029843500e5fe5bf6f59954c609899c36673fdc9d9e142c3711b43deaafedd3bc672b0d36bf0e52f5b5f20339d114a557ecd355ae63edcf
6
+ metadata.gz: fd71a3030195bb3700d3bbb88a0b6ad654ad1c035b5e9307b13d1a267a83da0ef0ea2bd7ff03c86c5b6abeeddeb591b8e4248bded39663ab3799ce1457051fa3
7
+ data.tar.gz: 9471913ce78cdaae3d988ab526918938084a88381ea555406bf7274f54ee9c822a068a4ae1e5ccb638d29038e2134059933fcaff8eaa6b853a9beaf23b907218
checksums.yaml.gz.sig CHANGED
Binary file
@@ -13,11 +13,6 @@ on:
13
13
  pull_request:
14
14
  branches:
15
15
  - '*'
16
- # security - only use workflows from the canonical branches
17
- pull_request_target:
18
- branches:
19
- - 'main'
20
- - '*-stable'
21
16
  # Allow manually triggering the workflow.
22
17
  workflow_dispatch:
23
18
 
@@ -13,11 +13,6 @@ on:
13
13
  pull_request:
14
14
  branches:
15
15
  - '*'
16
- # security - only use workflows from the canonical branches
17
- pull_request_target:
18
- branches:
19
- - 'main'
20
- - '*-stable'
21
16
  # Allow manually triggering the workflow.
22
17
  workflow_dispatch:
23
18
 
@@ -25,11 +25,6 @@ on:
25
25
  pull_request:
26
26
  branches:
27
27
  - '*'
28
- # security - only use workflows from the canonical branches
29
- pull_request_target:
30
- branches:
31
- - 'main'
32
- - '*-stable'
33
28
  # Allow manually triggering the workflow.
34
29
  workflow_dispatch:
35
30
 
@@ -24,11 +24,6 @@ on:
24
24
  pull_request:
25
25
  branches:
26
26
  - '*'
27
- # security - only use workflows from the canonical branches
28
- pull_request_target:
29
- branches:
30
- - 'main'
31
- - '*-stable'
32
27
  # Allow manually triggering the workflow.
33
28
  workflow_dispatch:
34
29
 
@@ -17,11 +17,6 @@ on:
17
17
  pull_request:
18
18
  branches:
19
19
  - '*'
20
- # security - only use workflows from the canonical branches
21
- pull_request_target:
22
- branches:
23
- - 'main'
24
- - '*-stable'
25
20
  # Allow manually triggering the workflow.
26
21
  workflow_dispatch:
27
22
 
@@ -50,15 +45,14 @@ jobs:
50
45
  rubygems: latest
51
46
  bundler: latest
52
47
 
53
- # truffleruby-24.1
54
- # (according to documentation: targets Ruby 3.3 compatibility)
55
- # (according to runtime: targets Ruby 3.2 compatibility)
56
- - ruby: "truffleruby"
57
- appraisal: "current"
58
- exec_cmd: "rake test"
59
- gemfile: "Appraisal.root"
60
- rubygems: default
61
- bundler: default
48
+ # Turn back on once allow-failures is a feature of GHA.
49
+ # # truffleruby-24.1 (targets Ruby 3.3 compatibility)
50
+ # - ruby: "truffleruby"
51
+ # appraisal: "current"
52
+ # exec_cmd: "rake test"
53
+ # gemfile: "Appraisal.root"
54
+ # rubygems: default
55
+ # bundler: default
62
56
 
63
57
  # jruby-10.0 (targets Ruby 3.4 compatibility)
64
58
  - ruby: "jruby"
@@ -0,0 +1,89 @@
1
+ # Targets the evergreen latest release of ruby, truffleruby, and jruby
2
+ name: Current
3
+
4
+ permissions:
5
+ contents: read
6
+
7
+ env:
8
+ K_SOUP_COV_DO: false
9
+
10
+ on:
11
+ push:
12
+ branches:
13
+ - 'main'
14
+ - '*-stable'
15
+ tags:
16
+ - '!*' # Do not execute on tags
17
+ pull_request:
18
+ branches:
19
+ - '*'
20
+ # Allow manually triggering the workflow.
21
+ workflow_dispatch:
22
+
23
+ # Cancels all previous workflow runs for the same branch that have not yet completed.
24
+ concurrency:
25
+ # The concurrency group contains the workflow name and the branch name.
26
+ group: "${{ github.workflow }}-${{ github.ref }}"
27
+ cancel-in-progress: true
28
+
29
+ jobs:
30
+ test:
31
+ if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
32
+ name: Specs ${{ matrix.ruby }}@${{ matrix.appraisal }}
33
+ runs-on: ubuntu-latest
34
+ continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
35
+ env: # $BUNDLE_GEMFILE must be set at job level, so it is set for all steps
36
+ BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile
37
+ strategy:
38
+ matrix:
39
+ include:
40
+ # Ruby 3.4
41
+ - ruby: "ruby"
42
+ appraisal: "current"
43
+ exec_cmd: "rake test"
44
+ gemfile: "Appraisal.root"
45
+ rubygems: latest
46
+ bundler: latest
47
+
48
+ # truffleruby-24.1 (targets Ruby 3.3 compatibility)
49
+ - ruby: "truffleruby"
50
+ appraisal: "current"
51
+ exec_cmd: "rake test"
52
+ gemfile: "Appraisal.root"
53
+ rubygems: default
54
+ bundler: default
55
+
56
+ # jruby-10.0 (targets Ruby 3.4 compatibility)
57
+ - ruby: "jruby"
58
+ appraisal: "current"
59
+ exec_cmd: "rake test"
60
+ gemfile: "Appraisal.root"
61
+ rubygems: default
62
+ bundler: default
63
+
64
+ steps:
65
+ - name: Checkout
66
+ if: ${{ !(env.ACT && startsWith(matrix.ruby, 'jruby')) }}
67
+ uses: actions/checkout@v5
68
+
69
+ - name: Setup Ruby & RubyGems
70
+ if: ${{ !(env.ACT && startsWith(matrix.ruby, 'jruby')) }}
71
+ uses: ruby/setup-ruby@v1
72
+ with:
73
+ ruby-version: ${{ matrix.ruby }}
74
+ rubygems: ${{ matrix.rubygems }}
75
+ bundler: ${{ matrix.bundler }}
76
+ bundler-cache: false
77
+
78
+ # Raw `bundle` will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root)
79
+ # We need to do this first to get appraisal installed.
80
+ # NOTE: This does not use the primary Gemfile at all.
81
+ - name: Install Root Appraisal
82
+ if: ${{ !(env.ACT && startsWith(matrix.ruby, 'jruby')) }}
83
+ run: bundle
84
+ - name: Appraisal for ${{ matrix.ruby }}@${{ matrix.appraisal }}
85
+ if: ${{ !(env.ACT && startsWith(matrix.ruby, 'jruby')) }}
86
+ run: bundle exec appraisal ${{ matrix.appraisal }} bundle
87
+ - name: Tests for ${{ matrix.ruby }}@${{ matrix.appraisal }} via ${{ matrix.exec_cmd }}
88
+ if: ${{ !(env.ACT && startsWith(matrix.ruby, 'jruby')) }}
89
+ run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec ${{ matrix.exec_cmd }}
@@ -18,11 +18,6 @@ on:
18
18
  pull_request:
19
19
  branches:
20
20
  - '*'
21
- # security - only use workflows from the canonical branches
22
- pull_request_target:
23
- branches:
24
- - 'main'
25
- - '*-stable'
26
21
  # Allow manually triggering the workflow.
27
22
  workflow_dispatch:
28
23
 
@@ -16,11 +16,6 @@ on:
16
16
  pull_request:
17
17
  branches:
18
18
  - '*'
19
- # security - only use workflows from the canonical branches
20
- pull_request_target:
21
- branches:
22
- - 'main'
23
- - '*-stable'
24
19
  # Allow manually triggering the workflow.
25
20
  workflow_dispatch:
26
21
 
@@ -16,11 +16,6 @@ on:
16
16
  pull_request:
17
17
  branches:
18
18
  - '*'
19
- # security - only use workflows from the canonical branches
20
- pull_request_target:
21
- branches:
22
- - 'main'
23
- - '*-stable'
24
19
  # Allow manually triggering the workflow.
25
20
  workflow_dispatch:
26
21
 
@@ -16,11 +16,6 @@ on:
16
16
  pull_request:
17
17
  branches:
18
18
  - '*'
19
- # security - only use workflows from the canonical branches
20
- pull_request_target:
21
- branches:
22
- - 'main'
23
- - '*-stable'
24
19
  # Allow manually triggering the workflow.
25
20
  workflow_dispatch:
26
21
 
@@ -16,11 +16,6 @@ on:
16
16
  pull_request:
17
17
  branches:
18
18
  - '*'
19
- # security - only use workflows from the canonical branches
20
- pull_request_target:
21
- branches:
22
- - 'main'
23
- - '*-stable'
24
19
  # Allow manually triggering the workflow.
25
20
  workflow_dispatch:
26
21
 
@@ -16,11 +16,6 @@ on:
16
16
  pull_request:
17
17
  branches:
18
18
  - '*'
19
- # security - only use workflows from the canonical branches
20
- pull_request_target:
21
- branches:
22
- - 'main'
23
- - '*-stable'
24
19
  # Allow manually triggering the workflow.
25
20
  workflow_dispatch:
26
21
 
@@ -13,11 +13,6 @@ on:
13
13
  pull_request:
14
14
  branches:
15
15
  - '*'
16
- # security - only use workflows from the canonical branches
17
- pull_request_target:
18
- branches:
19
- - 'main'
20
- - '*-stable'
21
16
  # Allow manually triggering the workflow.
22
17
  workflow_dispatch:
23
18
 
@@ -43,11 +43,6 @@ on:
43
43
  pull_request:
44
44
  branches:
45
45
  - '*'
46
- # security - only use workflows from the canonical branches
47
- pull_request_target:
48
- branches:
49
- - 'main'
50
- - '*-stable'
51
46
  # Allow manually triggering the workflow.
52
47
  workflow_dispatch:
53
48
 
@@ -13,11 +13,6 @@ on:
13
13
  pull_request:
14
14
  branches:
15
15
  - '*'
16
- # security - only use workflows from the canonical branches
17
- pull_request_target:
18
- branches:
19
- - 'main'
20
- - '*-stable'
21
16
  # Allow manually triggering the workflow.
22
17
  workflow_dispatch:
23
18
 
@@ -16,11 +16,6 @@ on:
16
16
  pull_request:
17
17
  branches:
18
18
  - '*'
19
- # security - only use workflows from the canonical branches
20
- pull_request_target:
21
- branches:
22
- - 'main'
23
- - '*-stable'
24
19
  # Allow manually triggering the workflow.
25
20
  workflow_dispatch:
26
21
 
@@ -16,11 +16,6 @@ on:
16
16
  pull_request:
17
17
  branches:
18
18
  - '*'
19
- # security - only use workflows from the canonical branches
20
- pull_request_target:
21
- branches:
22
- - 'main'
23
- - '*-stable'
24
19
  # Allow manually triggering the workflow.
25
20
  workflow_dispatch:
26
21
 
@@ -33,11 +33,6 @@ on:
33
33
  pull_request:
34
34
  branches:
35
35
  - '*'
36
- # security - only use workflows from the canonical branches
37
- pull_request_target:
38
- branches:
39
- - 'main'
40
- - '*-stable'
41
36
  # Allow manually triggering the workflow.
42
37
  workflow_dispatch:
43
38
 
@@ -16,11 +16,6 @@ on:
16
16
  pull_request:
17
17
  branches:
18
18
  - '*'
19
- # security - only use workflows from the canonical branches
20
- pull_request_target:
21
- branches:
22
- - 'main'
23
- - '*-stable'
24
19
  # Allow manually triggering the workflow.
25
20
  workflow_dispatch:
26
21
 
data/.junie/guidelines.md CHANGED
@@ -12,7 +12,8 @@ This document captures project-specific knowledge to streamline setup, testing,
12
12
  - See .env.local.example for an example of what to put in .env.local.
13
13
  - See CONTRIBUTING.md for details on how to set up your local environment.
14
14
  - Ruby and Bundler
15
- - Runtime supports very old Rubies (>= 1.9.2) but development tooling targets >= 2.3 because of CI/setup-ruby and dev dependencies.
15
+ - Runtime supports Ruby >= 1.9.2.
16
+ - Development tooling targets Ruby >= 2.3 (minimum supported by setup-ruby GHA).
16
17
  - Use a recent Ruby (>= 3.4 recommended) for fastest setup and to exercise modern coverage behavior.
17
18
  - Install dependencies via Bundler in project root:
18
19
  - bundle install
@@ -89,7 +90,7 @@ This document captures project-specific knowledge to streamline setup, testing,
89
90
  - Place new specs under spec/ mirroring lib/ structure where possible. Do not require "spec_helper" at the top of spec files, as it is automatically loaded by .rspec.
90
91
  - If your code relies on environment variables that drive activation (see "Activation env vars" below), prefer using rspec-stubbed_env:
91
92
  - it does not support stubbing with blocks, but it does automatically clean up after itself.
92
- - outside the example:
93
+ - the below config is included in all spec scenarios by the kettle-test gem, so no need to do it again; it is here for reference:
93
94
  include_context 'with stubbed env'
94
95
  - in a before hook, or in an example:
95
96
  stub_env("FLOSS_FUNDING_MY_NS" => "Free-as-in-beer")
@@ -133,6 +134,7 @@ Notes
133
134
  - Coverage reports: NEVER review the HTML report. Use JSON (preferred), XML, LCOV, or RCOV. For this project, always run tests with K_SOUP_COV_FORMATTERS set to "json".
134
135
  - Do NOT modify .envrc in tasks; when running tests locally or in scripts, manually prefix each run, e.g.: K_SOUP_COV_FORMATTERS="json" bin/rspec
135
136
  - For all the kettle-soup-cover options, see .envrc and find the K_SOUP_COV_* env vars.
137
+ - NEVER modify ENV variables in tests directly. Always use the stub_env macro from the rspec-stubbed_env gem (more details in the testing section above).
136
138
 
137
139
  Important documentation rules
138
140
  - Do NOT edit files under docs/ manually; they are generated by `bundle exec rake yard` as part of the default rake task.
data/CHANGELOG.md CHANGED
@@ -20,16 +20,46 @@ Please file a bug if you notice a violation of semantic versioning.
20
20
 
21
21
  ### Added
22
22
 
23
+ - Replace template tokens with real minimum ruby versions for runtime and development
24
+
23
25
  ### Changed
24
26
 
27
+ - consolidated specs
28
+
25
29
  ### Deprecated
26
30
 
27
31
  ### Removed
28
32
 
29
33
  ### Fixed
30
34
 
35
+ - Leaky state in specs
36
+
31
37
  ### Security
32
38
 
39
+ ## [1.1.23] - 2025-09-16
40
+
41
+ - TAG: [v1.1.23][1.1.23t]
42
+ - COVERAGE: 96.71% -- 3673/3798 lines in 26 files
43
+ - BRANCH COVERAGE: 81.57% -- 1509/1850 branches in 26 files
44
+ - 77.97% documented
45
+
46
+ ### Fixed
47
+
48
+ - GemSpecReader, ReadmeBackers now use shared OpenCollectiveConfig
49
+ - fixes broken opencollective config handling in GemSPecReader
50
+
51
+ ## [1.1.22] - 2025-09-16
52
+
53
+ - TAG: [v1.1.22][1.1.22t]
54
+ - COVERAGE: 96.83% -- 3661/3781 lines in 25 files
55
+ - BRANCH COVERAGE: 81.70% -- 1505/1842 branches in 25 files
56
+ - 77.01% documented
57
+
58
+ ### Changed
59
+
60
+ - Revert "🔒️ Use pull_request_target in workflows"
61
+ - It's not relevant to my projects (either this gem or the ones templated)
62
+
33
63
  ## [1.1.21] - 2025-09-16
34
64
 
35
65
  - TAG: [v1.1.21][1.1.21t]
@@ -925,7 +955,11 @@ Please file a bug if you notice a violation of semantic versioning.
925
955
  - Selecting will run the selected workflow via `act`
926
956
  - This may move to its own gem in the future.
927
957
 
928
- [Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.21...HEAD
958
+ [Unreleased]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.23...HEAD
959
+ [1.1.23]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.22...v1.1.23
960
+ [1.1.23t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.23
961
+ [1.1.22]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.21...v1.1.22
962
+ [1.1.22t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.22
929
963
  [1.1.21]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.20...v1.1.21
930
964
  [1.1.21t]: https://github.com/kettle-rb/kettle-dev/releases/tag/v1.1.21
931
965
  [1.1.20]: https://github.com/kettle-rb/kettle-dev/compare/v1.1.19...v1.1.20
data/README.md CHANGED
@@ -916,7 +916,7 @@ Thanks for RTFM. ☺️
916
916
  [📌gitmoji]:https://gitmoji.dev
917
917
  [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
918
918
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
919
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-3.781-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
919
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-3.798-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
920
920
  [🔐security]: SECURITY.md
921
921
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
922
922
  [📄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
@@ -41,7 +41,7 @@
41
41
 
42
42
  ### Compatibility
43
43
 
44
- Compatible with MRI Ruby 2.3+, and concordant releases of JRuby, and TruffleRuby.
44
+ Compatible with MRI Ruby {K_D_MIN_RUBY}+, and concordant releases of JRuby, and TruffleRuby.
45
45
 
46
46
  | 🚚 _Amazing_ test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 |
47
47
  |------------------------------------------------|--------------------------------------------------------|
@@ -513,7 +513,7 @@ Thanks for RTFM. ☺️
513
513
  [📌gitmoji]:https://gitmoji.dev
514
514
  [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
515
515
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
516
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-3.781-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
516
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-3.798-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
517
517
  [🔐security]: SECURITY.md
518
518
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
519
519
  [📄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.1.21 - 2025-09-16
3
+ # kettle-dev Rakefile v1.1.23 - 2025-09-16
4
4
  # Ruby 2.3 (Safe Navigation) or higher required
5
5
  #
6
6
  # MIT License (see License.txt)
@@ -105,12 +105,11 @@ Gem::Specification.new do |spec|
105
105
  # visibility and discoverability on RubyGems.org.
106
106
  # However, development dependencies in gemspec will install on
107
107
  # all versions of Ruby that will run in CI.
108
- # This gem, and its gemspec runtime dependencies, will install on Ruby down to 2.3.x.
109
- # This gem, and its gemspec development dependencies, will install on Ruby down to 2.3.x.
110
- # This is because in CI easy installation of Ruby, via setup-ruby, is for >= 2.3.
108
+ # This gem, and its gemspec runtime dependencies, will install on Ruby down to {K_D_MIN_RUBY}.x.
109
+ # This gem, and its gemspec development dependencies, will install on Ruby down to {K_D_MIN_DEV_RUBY}.x.
111
110
  # Thus, dev dependencies in gemspec must have
112
111
  #
113
- # required_ruby_version ">= 2.3" (or lower)
112
+ # required_ruby_version ">= {K_D_MIN_DEV_RUBY}" (or lower)
114
113
  #
115
114
  # Development dependencies that require strictly newer Ruby versions should be in a "gemfile",
116
115
  # and preferably a modular one (see gemfiles/modular/*.gemfile).
@@ -97,40 +97,37 @@ module Kettle
97
97
  entrypoint_require = gem_name.to_s.tr("-", "/")
98
98
  gem_shield = gem_name.to_s.gsub("-", "--").gsub("_", "__")
99
99
 
100
- # Funding org detection with bypass support.
101
- # By default a funding org must be discoverable, unless explicitly disabled by ENV['FUNDING_ORG'] == 'false'.
102
- funding_org_env = ENV["FUNDING_ORG"]
103
- funding_org = funding_org_env.to_s.strip
100
+ # Funding org (Open Collective handle) detection.
101
+ # Precedence:
102
+ # 1) ENV["FUNDING_ORG"] when set:
103
+ # - value "false" (any case) disables funding (nil)
104
+ # - otherwise use the value verbatim
105
+ # 2) OpenCollectiveConfig.handle(required: false)
106
+ # Be lenient: allow nil when not discoverable, with a concise warning.
104
107
  begin
105
- # Handle bypass: allow explicit string 'false' (any case) to disable funding org requirement.
106
- if funding_org_env && funding_org_env.to_s.strip.casecmp("false").zero?
107
- funding_org = nil
108
- else
109
- # Prefer .opencollective.yml when present so that specs forcing the file path are stable
110
- oc_path = File.join(root.to_s, ".opencollective.yml")
111
- if File.file?(oc_path)
112
- txt = File.read(oc_path)
113
- funding_org = if (m = txt.match(/\borg:\s*([\w\-]+)/i))
114
- m[1].to_s
115
- else
116
- ""
117
- end
108
+ env_funding = ENV["FUNDING_ORG"]
109
+ if env_funding && !env_funding.to_s.strip.empty?
110
+ funding_org = if env_funding.to_s.strip.casecmp("false").zero?
111
+ nil
112
+ else
113
+ env_funding.to_s
118
114
  end
115
+ else
116
+ # Preflight: if a YAML exists under the provided root, attempt to read it here so
117
+ # unexpected file IO errors surface within this rescue block (see specs).
118
+ oc_path = OpenCollectiveConfig.yaml_path(root)
119
+ File.read(oc_path) if File.file?(oc_path)
119
120
 
120
- # Fallback to ENV when file not present or did not contain an org
121
+ funding_org = OpenCollectiveConfig.handle(required: false, root: root)
121
122
  if funding_org.to_s.strip.empty?
122
- funding_org = ENV["OPENCOLLECTIVE_HANDLE"].to_s.strip if funding_org.empty?
123
- end
124
-
125
- # Be lenient: if funding_org cannot be determined, do not raise — leave it nil and warn.
126
- if funding_org.to_s.empty?
127
- Kernel.warn("kettle-dev: Could not determine funding org.\n - Options:\n * Set ENV['FUNDING_ORG'] to your funding handle (e.g., 'opencollective-handle').\n * Or set ENV['OPENCOLLECTIVE_HANDLE'].\n * Or add .opencollective.yml with: org: <handle>\n * Or bypass by setting ENV['FUNDING_ORG']=false for gems without funding.")
123
+ Kernel.warn("kettle-dev: Could not determine funding org.\n - Options:\n * Set ENV['FUNDING_ORG'] to your funding handle, or 'false' to disable.\n * Or set ENV['OPENCOLLECTIVE_HANDLE'].\n * Or add .opencollective.yml with: collective: <handle> (or org: <handle>).\n * Or proceed without funding if not applicable.")
128
124
  funding_org = nil
129
125
  end
130
126
  end
131
127
  rescue StandardError => error
132
128
  Kettle::Dev.debug_error(error, __method__)
133
- raise Error, "Unable to determine funding org from env or .opencollective.yml.\n\tError was: #{error.class}: #{error.message}"
129
+ # In an unexpected exception path, escalate to a domain error to aid callers/specs
130
+ raise Kettle::Dev::Error, "Unable to determine funding org: #{error.message}"
134
131
  end
135
132
 
136
133
  {
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module Kettle
6
+ module Dev
7
+ # Shared utility for resolving Open Collective configuration for this repository.
8
+ # Centralizes the logic for locating and reading .opencollective.yml and
9
+ # for deriving the handle from environment or the YAML file.
10
+ module OpenCollectiveConfig
11
+ module_function
12
+
13
+ # Absolute path to a .opencollective.yml
14
+ # @param root [String, nil] optional project root to resolve against; when nil, uses this repo root
15
+ # @return [String]
16
+ def yaml_path(root = nil)
17
+ return File.expand_path(".opencollective.yml", root) if root
18
+ File.expand_path("../../../.opencollective.yml", __dir__)
19
+ end
20
+
21
+ # Determine the Open Collective handle.
22
+ # Precedence:
23
+ # 1) ENV["OPENCOLLECTIVE_HANDLE"] when set and non-empty
24
+ # 2) .opencollective.yml key "collective" (or :collective)
25
+ #
26
+ # @param required [Boolean] when true, aborts the process if not found; when false, returns nil
27
+ # @param root [String, nil] optional project root to look for .opencollective.yml
28
+ # @return [String, nil] the handle, or nil when not required and not discoverable
29
+ def handle(required: false, root: nil, strict: false)
30
+ env = ENV["OPENCOLLECTIVE_HANDLE"]
31
+ return env unless env.nil? || env.to_s.strip.empty?
32
+
33
+ ypath = yaml_path(root)
34
+ if strict
35
+ yml = YAML.safe_load(File.read(ypath))
36
+ if yml.is_a?(Hash)
37
+ handle = yml["collective"] || yml[:collective] || yml["org"] || yml[:org]
38
+ return handle.to_s unless handle.nil? || handle.to_s.strip.empty?
39
+ end
40
+ elsif File.file?(ypath)
41
+ begin
42
+ yml = YAML.safe_load(File.read(ypath))
43
+ if yml.is_a?(Hash)
44
+ handle = yml["collective"] || yml[:collective] || yml["org"] || yml[:org]
45
+ return handle.to_s unless handle.nil? || handle.to_s.strip.empty?
46
+ end
47
+ rescue StandardError => e
48
+ Kettle::Dev.debug_error(e, __method__) if Kettle::Dev.respond_to?(:debug_error)
49
+ # fall through to required check
50
+ end
51
+ end
52
+
53
+ if required
54
+ Kettle::Dev::ExitAdapter.abort("ERROR: Open Collective handle not provided. Set OPENCOLLECTIVE_HANDLE or add 'collective: <handle>' to .opencollective.yml.")
55
+ end
56
+ nil
57
+ end
58
+ end
59
+ end
60
+ end
@@ -20,9 +20,11 @@ module Kettle
20
20
 
21
21
  DEFAULT_AVATAR = "https://opencollective.com/static/images/default-avatar.png"
22
22
  README_PATH = File.expand_path("../../../README.md", __dir__)
23
- OC_YML_PATH = File.expand_path("../../../.opencollective.yml", __dir__)
24
23
  README_OSC_TAG_DEFAULT = "OPENCOLLECTIVE"
25
24
  COMMIT_SUBJECT_DEFAULT = "💸 Thanks 🙏 to our new backers 🎒 and subscribers 📜"
25
+ # Deprecated constant maintained for backwards compatibility in tests/specs.
26
+ # Prefer OpenCollectiveConfig.yaml_path going forward.
27
+ OC_YML_PATH = OpenCollectiveConfig.yaml_path
26
28
 
27
29
  # Ruby 2.3 compatibility: Struct keyword_init added in Ruby 2.5
28
30
  # Switch to struct when dropping ruby < 2.5
@@ -120,9 +122,9 @@ module Kettle
120
122
  env = ENV["KETTLE_DEV_BACKER_README_OSC_TAG"].to_s
121
123
  return env unless env.strip.empty?
122
124
 
123
- if File.file?(OC_YML_PATH)
125
+ if File.file?(OpenCollectiveConfig.yaml_path)
124
126
  begin
125
- yml = YAML.safe_load(File.read(OC_YML_PATH))
127
+ yml = YAML.safe_load(File.read(OpenCollectiveConfig.yaml_path))
126
128
  if yml.is_a?(Hash)
127
129
  from_yml = yml["readme-osc-tag"] || yml[:"readme-osc-tag"]
128
130
  from_yml = from_yml.to_s if from_yml
@@ -148,15 +150,7 @@ module Kettle
148
150
  end
149
151
 
150
152
  def resolve_handle
151
- env = ENV["OPENCOLLECTIVE_HANDLE"]
152
- return env unless env.nil? || env.strip.empty?
153
-
154
- if File.file?(OC_YML_PATH)
155
- yml = YAML.safe_load(File.read(OC_YML_PATH))
156
- handle = yml.is_a?(Hash) ? yml["collective"] || yml[:collective] : nil
157
- return handle.to_s unless handle.nil? || handle.to_s.strip.empty?
158
- end
159
- abort("ERROR: Open Collective handle not provided. Set OPENCOLLECTIVE_HANDLE or add 'collective: <handle>' to .opencollective.yml.")
153
+ OpenCollectiveConfig.handle(required: true)
160
154
  end
161
155
 
162
156
  def fetch_members(path)
@@ -150,6 +150,7 @@ module Kettle
150
150
  namespace: namespace,
151
151
  namespace_shield: namespace_shield,
152
152
  gem_shield: gem_shield,
153
+ min_ruby: min_ruby,
153
154
  )
154
155
  end
155
156
  else
@@ -162,6 +163,7 @@ module Kettle
162
163
  namespace: namespace,
163
164
  namespace_shield: namespace_shield,
164
165
  gem_shield: gem_shield,
166
+ min_ruby: min_ruby,
165
167
  )
166
168
  end
167
169
  end
@@ -259,6 +261,7 @@ module Kettle
259
261
  namespace: namespace,
260
262
  namespace_shield: namespace_shield,
261
263
  gem_shield: gem_shield,
264
+ min_ruby: min_ruby,
262
265
  )
263
266
  else
264
267
  content.dup
@@ -469,6 +472,7 @@ module Kettle
469
472
  namespace: namespace,
470
473
  namespace_shield: namespace_shield,
471
474
  gem_shield: gem_shield,
475
+ min_ruby: min_ruby,
472
476
  )
473
477
 
474
478
  # 2) Merge specific sections from destination README, if present
@@ -618,6 +622,7 @@ module Kettle
618
622
  namespace: namespace,
619
623
  namespace_shield: namespace_shield,
620
624
  gem_shield: gem_shield,
625
+ min_ruby: min_ruby,
621
626
  )
622
627
  if File.basename(rel) == "CHANGELOG.md"
623
628
  begin
@@ -13,6 +13,8 @@ module Kettle
13
13
  @@template_results = {}
14
14
 
15
15
  EXECUTABLE_GIT_HOOKS_RE = %r{[\\/]\.git-hooks[\\/](commit-msg|prepare-commit-msg)\z}
16
+ # The minimum Ruby supported by setup-ruby GHA
17
+ MIN_SETUP_RUBY = Gem::Version.create("2.3")
16
18
 
17
19
  module_function
18
20
 
@@ -409,14 +411,56 @@ module Kettle
409
411
  # @param gem_shield [String]
410
412
  # @param funding_org [String, nil]
411
413
  # @return [String]
412
- def apply_common_replacements(content, org:, gem_name:, namespace:, namespace_shield:, gem_shield:, funding_org: nil)
414
+ def apply_common_replacements(content, org:, gem_name:, namespace:, namespace_shield:, gem_shield:, funding_org: nil, min_ruby: nil)
413
415
  raise Error, "Org could not be derived" unless org && !org.empty?
414
416
  raise Error, "Gem name could not be derived" unless gem_name && !gem_name.empty?
415
417
 
416
418
  funding_org ||= org
419
+ # Derive min_ruby if not provided
420
+ mr = begin
421
+ meta = gemspec_metadata
422
+ meta[:min_ruby]
423
+ rescue StandardError => e
424
+ Kettle::Dev.debug_error(e, __method__)
425
+ # leave min_ruby as-is (possibly nil)
426
+ end
427
+ if min_ruby.nil? || min_ruby.to_s.strip.empty?
428
+ min_ruby = mr.respond_to?(:to_s) ? mr.to_s : mr
429
+ end
430
+
431
+ # Derive min_dev_ruby from min_ruby
432
+ # min_dev_ruby is the greater of min_dev_ruby and ruby 2.3,
433
+ # because ruby 2.3 is the minimum ruby supported by setup-ruby GHA
434
+ min_dev_ruby = begin
435
+ [mr, MIN_SETUP_RUBY].max
436
+ rescue StandardError => e
437
+ Kettle::Dev.debug_error(e, __method__)
438
+ MIN_SETUP_RUBY
439
+ end
440
+
417
441
  c = content.dup
418
442
  c = c.gsub("kettle-rb", org.to_s)
419
443
  c = c.gsub("{OPENCOLLECTIVE|ORG_NAME}", funding_org)
444
+ # Replace min ruby token if present
445
+ begin
446
+ if min_ruby && !min_ruby.to_s.empty? && c.include?("{K_D_MIN_RUBY}")
447
+ c = c.gsub("{K_D_MIN_RUBY}", min_ruby.to_s)
448
+ end
449
+ rescue StandardError => e
450
+ Kettle::Dev.debug_error(e, __method__)
451
+ # ignore
452
+ end
453
+
454
+ # Replace min ruby dev token if present
455
+ begin
456
+ if min_dev_ruby && !min_dev_ruby.to_s.empty? && c.include?("{K_D_MIN_DEV_RUBY}")
457
+ c = c.gsub("{K_D_MIN_DEV_RUBY}", min_dev_ruby.to_s)
458
+ end
459
+ rescue StandardError => e
460
+ Kettle::Dev.debug_error(e, __method__)
461
+ # ignore
462
+ end
463
+
420
464
  # Special-case: yard-head link uses the gem name as a subdomain and must be dashes-only.
421
465
  # Apply this BEFORE other generic replacements so it isn't altered incorrectly.
422
466
  begin
@@ -6,7 +6,7 @@ module Kettle
6
6
  module Version
7
7
  # The gem version.
8
8
  # @return [String]
9
- VERSION = "1.1.21"
9
+ VERSION = "1.1.23"
10
10
 
11
11
  module_function
12
12
 
data/lib/kettle/dev.rb CHANGED
@@ -22,6 +22,7 @@ module Kettle
22
22
  autoload :GitCommitFooter, "kettle/dev/git_commit_footer"
23
23
  autoload :InputAdapter, "kettle/dev/input_adapter"
24
24
  autoload :ReadmeBackers, "kettle/dev/readme_backers"
25
+ autoload :OpenCollectiveConfig, "kettle/dev/open_collective_config"
25
26
  autoload :ReleaseCLI, "kettle/dev/release_cli"
26
27
  autoload :PreReleaseCLI, "kettle/dev/pre_release_cli"
27
28
  autoload :SetupCLI, "kettle/dev/setup_cli"
@@ -0,0 +1,8 @@
1
+ module Kettle
2
+ module Dev
3
+ module OpenCollectiveConfig
4
+ def self.yaml_path: (?String) -> String
5
+ def self.handle: (?required: bool, ?root: String, ?strict: bool) -> String?
6
+ end
7
+ end
8
+ end
@@ -48,7 +48,9 @@ module Kettle
48
48
  gem_name: String,
49
49
  namespace: String,
50
50
  namespace_shield: String,
51
- gem_shield: String
51
+ gem_shield: String,
52
+ ?funding_org: String?,
53
+ ?min_ruby: String?
52
54
  ) -> String
53
55
 
54
56
  # Parse gemspec metadata and derive useful strings
@@ -77,8 +79,6 @@ module Kettle
77
79
  bindir: String,
78
80
  executables: Array[String],
79
81
  }
80
-
81
- def apply_common_replacements: () -> untyped
82
82
  end
83
83
  end
84
84
  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.1.21
4
+ version: 1.1.23
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -233,6 +233,7 @@ files:
233
233
  - ".github/workflows/coverage.yml"
234
234
  - ".github/workflows/coverage.yml.example"
235
235
  - ".github/workflows/current.yml"
236
+ - ".github/workflows/current.yml.example"
236
237
  - ".github/workflows/dep-heads.yml"
237
238
  - ".github/workflows/dependency-review.yml"
238
239
  - ".github/workflows/discord-notifier.yml.example"
@@ -337,6 +338,7 @@ files:
337
338
  - lib/kettle/dev/git_commit_footer.rb
338
339
  - lib/kettle/dev/input_adapter.rb
339
340
  - lib/kettle/dev/modular_gemfiles.rb
341
+ - lib/kettle/dev/open_collective_config.rb
340
342
  - lib/kettle/dev/pre_release_cli.rb
341
343
  - lib/kettle/dev/rakelib/appraisal.rake
342
344
  - lib/kettle/dev/rakelib/bench.rake
@@ -372,6 +374,7 @@ files:
372
374
  - sig/kettle/dev/git_commit_footer.rbs
373
375
  - sig/kettle/dev/input_adapter.rbs
374
376
  - sig/kettle/dev/modular_gemfiles.rbs
377
+ - sig/kettle/dev/open_collective_config.rbs
375
378
  - sig/kettle/dev/pre_release_cli.rbs
376
379
  - sig/kettle/dev/readme_backers.rbs
377
380
  - sig/kettle/dev/release_cli.rbs
@@ -388,10 +391,10 @@ licenses:
388
391
  - MIT
389
392
  metadata:
390
393
  homepage_uri: https://kettle-dev.galtzo.com/
391
- source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.1.21
392
- changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.1.21/CHANGELOG.md
394
+ source_code_uri: https://github.com/kettle-rb/kettle-dev/tree/v1.1.23
395
+ changelog_uri: https://github.com/kettle-rb/kettle-dev/blob/v1.1.23/CHANGELOG.md
393
396
  bug_tracker_uri: https://github.com/kettle-rb/kettle-dev/issues
394
- documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.1.21
397
+ documentation_uri: https://www.rubydoc.info/gems/kettle-dev/1.1.23
395
398
  funding_uri: https://github.com/sponsors/pboling
396
399
  wiki_uri: https://github.com/kettle-rb/kettle-dev/wiki
397
400
  news_uri: https://www.railsbling.com/tags/kettle-dev
metadata.gz.sig CHANGED
@@ -1 +1,3 @@
1
- IYc����9Q����:� 'tOp,QtG{�Dm�mYH�
1
+ @�=�F|y_
2
+ <�_�b�l4�&�@9S��7�����n�1�V�ZP »�(�����'`=hV�K@D��sV2Ħe��v(ۄ�j5����[�{��3�K�(c������7d���}�\�<.1ʘDLj���4����⅋�fh~�S��vT��9�X{̼ē"Mp�$�;@* �?��J�d�ń��Y�e���g�fF0�h��U
3
+ �KNL�*CM�Q���!& 
4
+ �v�J+on[��X�M�9]�/_�n�9�T=xK�\@Q���`iV��v��=�� i��yuӦ��1����I�vj����R�|��_q�!>����=b�btL���87