kettle-jem 7.0.0 → 7.1.3

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 (202) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +1505 -0
  4. data/LICENSE.md +13 -0
  5. data/README.md +794 -0
  6. data/exe/kettle-jem +20 -0
  7. data/lib/kettle/jem/cli.rb +334 -0
  8. data/lib/kettle/jem/license_txt_migrator.rb +33 -0
  9. data/lib/kettle/jem/rakelib/install.rake +10 -0
  10. data/lib/kettle/jem/rakelib/prepare.rake +10 -0
  11. data/lib/kettle/jem/rakelib/selftest.rake +10 -0
  12. data/lib/kettle/jem/rakelib/template.rake +10 -0
  13. data/lib/kettle/jem/tasks/install_task.rb +2178 -0
  14. data/lib/kettle/jem/tasks/prepare_task.rb +274 -0
  15. data/lib/kettle/jem/tasks/self_test_task.rb +256 -0
  16. data/lib/kettle/jem/tasks/template_task.rb +124 -0
  17. data/lib/kettle/jem/tasks.rb +6 -0
  18. data/lib/kettle/jem/templates/.aiignore.example +19 -0
  19. data/lib/kettle/jem/templates/.config/mise/env.sh +26 -0
  20. data/lib/kettle/jem/templates/.devcontainer/apt-install/devcontainer-feature.json.example +9 -0
  21. data/lib/kettle/jem/templates/.devcontainer/apt-install/install.sh.example +19 -0
  22. data/lib/kettle/jem/templates/.devcontainer/devcontainer.json.example +27 -0
  23. data/lib/kettle/jem/templates/.devcontainer/scripts/setup-tree-sitter.sh.example +210 -0
  24. data/lib/kettle/jem/templates/.env.local.example +67 -0
  25. data/lib/kettle/jem/templates/.envrc.example +4 -0
  26. data/lib/kettle/jem/templates/.envrc.no-osc.example +4 -0
  27. data/lib/kettle/jem/templates/.gemrc.example +1 -0
  28. data/lib/kettle/jem/templates/.git-hooks/commit-msg.example +60 -0
  29. data/lib/kettle/jem/templates/.git-hooks/commit-subjects-goalie.txt.example +8 -0
  30. data/lib/kettle/jem/templates/.git-hooks/footer-template.erb.txt.example +16 -0
  31. data/lib/kettle/jem/templates/.git-hooks/prepare-commit-msg.example +9 -0
  32. data/lib/kettle/jem/templates/.github/.codecov.yml.example +14 -0
  33. data/lib/kettle/jem/templates/.github/FUNDING.yml.example +10 -0
  34. data/lib/kettle/jem/templates/.github/FUNDING.yml.no-osc.example +10 -0
  35. data/lib/kettle/jem/templates/.github/copilot_instructions.md.example +1 -0
  36. data/lib/kettle/jem/templates/.github/dependabot.yml.example +13 -0
  37. data/lib/kettle/jem/templates/.github/workflows/auto-assign.yml.example +21 -0
  38. data/lib/kettle/jem/templates/.github/workflows/coverage.yml.example +102 -0
  39. data/lib/kettle/jem/templates/.github/workflows/current.yml.example +86 -0
  40. data/lib/kettle/jem/templates/.github/workflows/dep-heads.yml.example +249 -0
  41. data/lib/kettle/jem/templates/.github/workflows/dependency-review.yml.example +22 -0
  42. data/lib/kettle/jem/templates/.github/workflows/discord-notifier.yml.example +39 -0
  43. data/lib/kettle/jem/templates/.github/workflows/framework-ci.yml.example +81 -0
  44. data/lib/kettle/jem/templates/.github/workflows/heads.yml.example +212 -0
  45. data/lib/kettle/jem/templates/.github/workflows/jruby-10.0.yml.example +91 -0
  46. data/lib/kettle/jem/templates/.github/workflows/jruby-9.1.yml.example +90 -0
  47. data/lib/kettle/jem/templates/.github/workflows/jruby-9.2.yml.example +95 -0
  48. data/lib/kettle/jem/templates/.github/workflows/jruby-9.3.yml.example +95 -0
  49. data/lib/kettle/jem/templates/.github/workflows/jruby-9.4.yml.example +95 -0
  50. data/lib/kettle/jem/templates/.github/workflows/jruby.yml.example +91 -0
  51. data/lib/kettle/jem/templates/.github/workflows/license-eye.yml.example +43 -0
  52. data/lib/kettle/jem/templates/.github/workflows/locked_deps.yml.example +89 -0
  53. data/lib/kettle/jem/templates/.github/workflows/opencollective.yml.example +44 -0
  54. data/lib/kettle/jem/templates/.github/workflows/ruby-2.3.yml.example +80 -0
  55. data/lib/kettle/jem/templates/.github/workflows/ruby-2.4.yml.example +84 -0
  56. data/lib/kettle/jem/templates/.github/workflows/ruby-2.5.yml.example +84 -0
  57. data/lib/kettle/jem/templates/.github/workflows/ruby-2.6.yml.example +84 -0
  58. data/lib/kettle/jem/templates/.github/workflows/ruby-2.7.yml.example +84 -0
  59. data/lib/kettle/jem/templates/.github/workflows/ruby-3.0.yml.example +85 -0
  60. data/lib/kettle/jem/templates/.github/workflows/ruby-3.1.yml.example +83 -0
  61. data/lib/kettle/jem/templates/.github/workflows/ruby-3.2.yml.example +80 -0
  62. data/lib/kettle/jem/templates/.github/workflows/ruby-3.3.yml.example +80 -0
  63. data/lib/kettle/jem/templates/.github/workflows/ruby-3.4.yml.example +80 -0
  64. data/lib/kettle/jem/templates/.github/workflows/style.yml.example +78 -0
  65. data/lib/kettle/jem/templates/.github/workflows/templating.yml.example +86 -0
  66. data/lib/kettle/jem/templates/.github/workflows/truffle.yml.example +91 -0
  67. data/lib/kettle/jem/templates/.github/workflows/truffleruby-22.3.yml.example +92 -0
  68. data/lib/kettle/jem/templates/.github/workflows/truffleruby-23.0.yml.example +92 -0
  69. data/lib/kettle/jem/templates/.github/workflows/truffleruby-23.1.yml.example +78 -0
  70. data/lib/kettle/jem/templates/.github/workflows/truffleruby-24.2.yml.example +91 -0
  71. data/lib/kettle/jem/templates/.github/workflows/truffleruby-25.0.yml.example +96 -0
  72. data/lib/kettle/jem/templates/.github/workflows/truffleruby-33.0.yml.example +91 -0
  73. data/lib/kettle/jem/templates/.github/workflows/unlocked_deps.yml.example +93 -0
  74. data/lib/kettle/jem/templates/.gitignore.example +53 -0
  75. data/lib/kettle/jem/templates/.gitlab-ci.yml.example +134 -0
  76. data/lib/kettle/jem/templates/.idea/.gitignore.example +44 -0
  77. data/lib/kettle/jem/templates/.licenserc.yaml.example +8 -0
  78. data/lib/kettle/jem/templates/.opencollective.yml.example +3 -0
  79. data/lib/kettle/jem/templates/.qlty/qlty.toml.example +79 -0
  80. data/lib/kettle/jem/templates/.rspec.example +10 -0
  81. data/lib/kettle/jem/templates/.rubocop.example +1 -0
  82. data/lib/kettle/jem/templates/.rubocop.yml.example +47 -0
  83. data/lib/kettle/jem/templates/.rubocop_rspec.yml.example +55 -0
  84. data/lib/kettle/jem/templates/.simplecov.example +18 -0
  85. data/lib/kettle/jem/templates/.structuredmerge/git-drivers.toml.example +86 -0
  86. data/lib/kettle/jem/templates/.structuredmerge/kettle-jem.yml.example +519 -0
  87. data/lib/kettle/jem/templates/.yard-lint.yml.example +54 -0
  88. data/lib/kettle/jem/templates/.yardignore.example +13 -0
  89. data/lib/kettle/jem/templates/.yardopts.example +14 -0
  90. data/lib/kettle/jem/templates/AGENTS.md.example +283 -0
  91. data/lib/kettle/jem/templates/AGPL-3.0-only.md.example +235 -0
  92. data/lib/kettle/jem/templates/Appraisal.root.gemfile.example +26 -0
  93. data/lib/kettle/jem/templates/Appraisals.example +150 -0
  94. data/lib/kettle/jem/templates/Big-Time-Public-License.md.example +99 -0
  95. data/lib/kettle/jem/templates/CHANGELOG.md.example +33 -0
  96. data/lib/kettle/jem/templates/CHANGELOG.transfer.md +109 -0
  97. data/lib/kettle/jem/templates/CITATION.cff.example +20 -0
  98. data/lib/kettle/jem/templates/CODE_OF_CONDUCT.md.example +134 -0
  99. data/lib/kettle/jem/templates/CONTRIBUTING.md.example +292 -0
  100. data/lib/kettle/jem/templates/FUNDING.md.example +74 -0
  101. data/lib/kettle/jem/templates/FUNDING.md.no-osc.example +63 -0
  102. data/lib/kettle/jem/templates/Gemfile.example +52 -0
  103. data/lib/kettle/jem/templates/IRP.md.example +34 -0
  104. data/lib/kettle/jem/templates/LICENSE.md.example +3 -0
  105. data/lib/kettle/jem/templates/MIT.md.example +21 -0
  106. data/lib/kettle/jem/templates/PolyForm-Noncommercial-1.0.0.md.example +131 -0
  107. data/lib/kettle/jem/templates/PolyForm-Small-Business-1.0.0.md.example +121 -0
  108. data/lib/kettle/jem/templates/README.md.example +544 -0
  109. data/lib/kettle/jem/templates/REEK +0 -0
  110. data/lib/kettle/jem/templates/RUBOCOP.md.example +78 -0
  111. data/lib/kettle/jem/templates/Rakefile.example +163 -0
  112. data/lib/kettle/jem/templates/SECURITY.md.example +21 -0
  113. data/lib/kettle/jem/templates/bin/setup.example +36 -0
  114. data/lib/kettle/jem/templates/certs/pboling.pem.example +27 -0
  115. data/lib/kettle/jem/templates/gem.gemspec.example +161 -0
  116. data/lib/kettle/jem/templates/gemfiles/modular/benchmark/r4/v0.5.gemfile.example +2 -0
  117. data/lib/kettle/jem/templates/gemfiles/modular/benchmark/vHEAD.gemfile.example +2 -0
  118. data/lib/kettle/jem/templates/gemfiles/modular/cgi/r4/v0.5.gemfile.example +1 -0
  119. data/lib/kettle/jem/templates/gemfiles/modular/cgi/vHEAD.gemfile.example +1 -0
  120. data/lib/kettle/jem/templates/gemfiles/modular/changelog.gemfile.example +6 -0
  121. data/lib/kettle/jem/templates/gemfiles/modular/coverage.gemfile.example +14 -0
  122. data/lib/kettle/jem/templates/gemfiles/modular/coverage_local.gemfile.example +34 -0
  123. data/lib/kettle/jem/templates/gemfiles/modular/debug.gemfile.example +22 -0
  124. data/lib/kettle/jem/templates/gemfiles/modular/documentation.gemfile.example +24 -0
  125. data/lib/kettle/jem/templates/gemfiles/modular/documentation_local.gemfile.example +20 -0
  126. data/lib/kettle/jem/templates/gemfiles/modular/erb/r2/v3.0.gemfile.example +1 -0
  127. data/lib/kettle/jem/templates/gemfiles/modular/erb/r2.3/default.gemfile.example +6 -0
  128. data/lib/kettle/jem/templates/gemfiles/modular/erb/r2.6/v2.2.gemfile.example +3 -0
  129. data/lib/kettle/jem/templates/gemfiles/modular/erb/r3/v5.0.gemfile.example +1 -0
  130. data/lib/kettle/jem/templates/gemfiles/modular/erb/r3.1/v4.0.gemfile.example +2 -0
  131. data/lib/kettle/jem/templates/gemfiles/modular/erb/r4/v5.0.gemfile.example +1 -0
  132. data/lib/kettle/jem/templates/gemfiles/modular/erb/vHEAD.gemfile.example +2 -0
  133. data/lib/kettle/jem/templates/gemfiles/modular/json/truffleruby_22_3.gemfile.example +6 -0
  134. data/lib/kettle/jem/templates/gemfiles/modular/json/truffleruby_23_0.gemfile.example +6 -0
  135. data/lib/kettle/jem/templates/gemfiles/modular/json/truffleruby_23_1.gemfile.example +6 -0
  136. data/lib/kettle/jem/templates/gemfiles/modular/mutex_m/r2/v0.3.gemfile.example +2 -0
  137. data/lib/kettle/jem/templates/gemfiles/modular/mutex_m/r2.4/v0.1.gemfile.example +3 -0
  138. data/lib/kettle/jem/templates/gemfiles/modular/mutex_m/r3/v0.3.gemfile.example +2 -0
  139. data/lib/kettle/jem/templates/gemfiles/modular/mutex_m/r4/v0.3.gemfile.example +2 -0
  140. data/lib/kettle/jem/templates/gemfiles/modular/mutex_m/vHEAD.gemfile.example +2 -0
  141. data/lib/kettle/jem/templates/gemfiles/modular/optional.gemfile.example +16 -0
  142. data/lib/kettle/jem/templates/gemfiles/modular/recording/r2.3/recording.gemfile.example +16 -0
  143. data/lib/kettle/jem/templates/gemfiles/modular/recording/r2.4/recording.gemfile.example +18 -0
  144. data/lib/kettle/jem/templates/gemfiles/modular/recording/r2.5/recording.gemfile.example +16 -0
  145. data/lib/kettle/jem/templates/gemfiles/modular/recording/r3/recording.gemfile.example +16 -0
  146. data/lib/kettle/jem/templates/gemfiles/modular/recording/r4/recording.gemfile.example +16 -0
  147. data/lib/kettle/jem/templates/gemfiles/modular/recording/vHEAD.gemfile.example +2 -0
  148. data/lib/kettle/jem/templates/gemfiles/modular/rspec.gemfile.example +4 -0
  149. data/lib/kettle/jem/templates/gemfiles/modular/runtime_heads.gemfile.example +14 -0
  150. data/lib/kettle/jem/templates/gemfiles/modular/shunted.gemfile.example +21 -0
  151. data/lib/kettle/jem/templates/gemfiles/modular/stringio/r2/v3.0.gemfile.example +5 -0
  152. data/lib/kettle/jem/templates/gemfiles/modular/stringio/r2.4/v0.0.2.gemfile.example +4 -0
  153. data/lib/kettle/jem/templates/gemfiles/modular/stringio/r3/v3.0.gemfile.example +5 -0
  154. data/lib/kettle/jem/templates/gemfiles/modular/stringio/r4/v3.0.gemfile.example +5 -0
  155. data/lib/kettle/jem/templates/gemfiles/modular/stringio/vHEAD.gemfile.example +2 -0
  156. data/lib/kettle/jem/templates/gemfiles/modular/style.gemfile.example +33 -0
  157. data/lib/kettle/jem/templates/gemfiles/modular/style_local.gemfile.example +26 -0
  158. data/lib/kettle/jem/templates/gemfiles/modular/templating.gemfile.example +34 -0
  159. data/lib/kettle/jem/templates/gemfiles/modular/templating_local.gemfile.example +73 -0
  160. data/lib/kettle/jem/templates/gemfiles/modular/webrick/r4/v1.9.gemfile.example +1 -0
  161. data/lib/kettle/jem/templates/gemfiles/modular/webrick/vHEAD.gemfile.example +1 -0
  162. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r2/libs.gemfile.example +3 -0
  163. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r2.3/libs.gemfile.example +3 -0
  164. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r2.4/libs.gemfile.example +3 -0
  165. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r2.6/libs.gemfile.example +3 -0
  166. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r3/libs.gemfile.example +3 -0
  167. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r3.1/libs.gemfile.example +5 -0
  168. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/r4/libs.gemfile.example +6 -0
  169. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs/vHEAD.gemfile.example +6 -0
  170. data/lib/kettle/jem/templates/gemfiles/modular/x_std_libs.gemfile.example +12 -0
  171. data/lib/kettle/jem/templates/lib/gem/version.rb.example +1 -0
  172. data/lib/kettle/jem/templates/lib/gem/version_gem.rb.example +1 -0
  173. data/lib/kettle/jem/templates/mise.toml.example +25 -0
  174. data/lib/kettle/jem/templates/mise.toml.no-osc.example +25 -0
  175. data/lib/kettle/jem/templates/parsers.toml.example +19 -0
  176. data/lib/kettle/jem/templates/readme/partials/basic_usage.md.example +28 -0
  177. data/lib/kettle/jem/templates/readme/partials/configuration.md.example +112 -0
  178. data/lib/kettle/jem/templates/readme/partials/synopsis.md.example +3 -0
  179. data/lib/kettle/jem/templates/shim/.github/workflows/current.yml.example +40 -0
  180. data/lib/kettle/jem/templates/shim/.rspec.example +5 -0
  181. data/lib/kettle/jem/templates/shim/.structuredmerge/kettle-jem.yml.example +28 -0
  182. data/lib/kettle/jem/templates/shim/CHANGELOG.md.example +9 -0
  183. data/lib/kettle/jem/templates/shim/Gemfile.example +14 -0
  184. data/lib/kettle/jem/templates/shim/README.md.example +25 -0
  185. data/lib/kettle/jem/templates/shim/Rakefile.example +8 -0
  186. data/lib/kettle/jem/templates/shim/gem.gemspec.example +45 -0
  187. data/lib/kettle/jem/templates/shim/lib/compat_require.rb.example +3 -0
  188. data/lib/kettle/jem/templates/shim/lib/entrypoint.rb.example +3 -0
  189. data/lib/kettle/jem/templates/shim/lib/version.rb.example +1 -0
  190. data/lib/kettle/jem/templates/shim/spec/shim_spec.rb.example +15 -0
  191. data/lib/kettle/jem/templates/shim/spec/spec_helper.rb.example +23 -0
  192. data/lib/kettle/jem/templates/sig/gem.rbs.example +1 -0
  193. data/lib/kettle/jem/templates/spec/README.md.example +28 -0
  194. data/lib/kettle/jem/templates/spec/spec_helper.rb.example +39 -0
  195. data/lib/kettle/jem/version.rb +5 -3
  196. data/lib/kettle/jem/version_gem.rb +8 -0
  197. data/lib/kettle/jem.rb +18540 -1517
  198. data/lib/kettle-jem.rb +2 -1
  199. data/sig/kettle/jem.rbs +8 -0
  200. data.tar.gz.sig +0 -0
  201. metadata +870 -32
  202. metadata.gz.sig +0 -0
@@ -0,0 +1,544 @@
1
+ {KJ|README:TOP_LOGO_ROW}
2
+
3
+ {KJ|README:TOP_LOGO_REFS}
4
+
5
+ # {KJ|PROJECT_EMOJI} {KJ|README:TITLE}
6
+
7
+ [![Version][👽versioni]][👽version] [![Ruby Users Forum][✉️ruby-forum-top-img]][✉️ruby-forum] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] {KJ|README:LICENSE_BADGE} [![Total downloads][👽dl-ranki]][👽dl-rank] [![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 Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-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 Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] {KJ|README:LICENSE_EYE_WORKFLOW_BADGE} {KJ|README:FOSSA_BADGE}
8
+
9
+ `if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know on Discord][✉️discord-invite] or [RubyForum][✉️ruby-forum], as I may have missed the notification.
10
+
11
+ ---
12
+
13
+ `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.
14
+
15
+ <!-- KJ:OPEN_COLLECTIVE:START -->
16
+ [![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 at ko-fi.com][🖇kofi-img]][🖇kofi]
17
+ <!-- KJ:OPEN_COLLECTIVE:END -->
18
+ <!-- KJ:NO_OPEN_COLLECTIVE:START -->
19
+ [![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 at ko-fi.com][🖇kofi-img]][🖇kofi]
20
+ <!-- KJ:NO_OPEN_COLLECTIVE:END -->
21
+ {KJ|README:CORPORATE_SPONSORS}
22
+
23
+ <details markdown="1">
24
+ <summary>👣 How will this project approach the September 2025 hostile takeover of RubyGems? 🚑️</summary>
25
+
26
+ I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-takeover-of-rubygems-my-thoughts-5hlo).
27
+
28
+ </details>
29
+
30
+ ## 🌻 Synopsis {KJ|README:H2_SYNOPSIS_LOGO_ROW}
31
+
32
+
33
+ ## 💡 Info you can shake a stick at
34
+
35
+ | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
36
+ |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
37
+ | Works with JRuby | [![JRuby 9.1 Compat][💎jruby-9.1i]][🚎jruby-9.1-wf] [![JRuby 9.2 Compat][💎jruby-9.2i]][🚎jruby-9.2-wf] [![JRuby 9.3 Compat][💎jruby-9.3i]][🚎jruby-9.3-wf] <br/> [![JRuby 9.4 Compat][💎jruby-9.4i]][🚎jruby-9.4-wf] [![JRuby 10.0 Compat][💎jruby-10.0i]][🚎jruby-10.0-wf] [![JRuby current Compat][💎jruby-c-i]][🚎10-j-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] |
38
+ | Works with Truffle Ruby | [![Truffle Ruby 22.3 Compat][💎truby-22.3i]][🚎truby-22.3-wf] [![Truffle Ruby 23.0 Compat][💎truby-23.0i]][🚎truby-23.0-wf] [![Truffle Ruby 23.1 Compat][💎truby-23.1i]][🚎truby-23.1-wf] <br/> [![Truffle Ruby 24.2 Compat][💎truby-24.2i]][🚎truby-24.2-wf] [![Truffle Ruby 25.0 Compat][💎truby-25.0i]][🚎truby-25.0-wf] [![Truffle Ruby 33.0 Compat][💎truby-33.0i]][🚎truby-33.0-wf] [![Truffle Ruby current Compat][💎truby-c-i]][🚎9-t-wf] [![Truffle Ruby HEAD Compat][💎truby-headi]][🚎3-hd-wf] |
39
+ | Works with MRI Ruby 4 | [![Ruby current Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf] |
40
+ | Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎ruby-3.0-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎ruby-3.1-wf] [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎ruby-3.2-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎ruby-3.3-wf] [![Ruby 3.4 Compat][💎ruby-3.4i]][🚎ruby-3.4-wf] |
41
+ | Works with MRI Ruby 2 | ![Ruby 2.0 Compat][💎ruby-2.0i] ![Ruby 2.1 Compat][💎ruby-2.1i] ![Ruby 2.2 Compat][💎ruby-2.2i] ![Ruby 2.3 Compat][💎ruby-2.3i] <br/> [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎ruby-2.4-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎ruby-2.5-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎ruby-2.6-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎ruby-2.7-wf] |
42
+ | Works with MRI Ruby 1 | ![Ruby 1.8 Compat][💎ruby-1.8i] ![Ruby 1.9 Compat][💎ruby-1.9i] |
43
+ | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Get help from RubyForum][✉️ruby-forum-img]][✉️ruby-forum] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
44
+ | 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] |
45
+ | 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] [![GitLab Wiki][📜gl-wiki-img]][📜gl-wiki] [![GitHub Wiki][📜gh-wiki-img]][📜gh-wiki] |
46
+ | Compliance | {KJ|README:LICENSE_BADGE} {KJ|README:LICENSE_COMPAT_BADGE} [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
47
+ | Style | [![Enforced Code Style Linter][💎rlts-img]][💎rlts] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] [![Gitmoji Commits][📌gitmoji-img]][📌gitmoji] [![Compatibility appraised by: appraisal2][💎appraisal2-img]][💎appraisal2] |
48
+ | Maintainer 🎖️ | [![Follow Me on LinkedIn][💖🖇linkedin-img]][💖🖇linkedin] [![Follow Me on Ruby.Social][💖🐘ruby-mast-img]][💖🐘ruby-mast] [![Follow Me on Bluesky][💖🦋bluesky-img]][💖🦋bluesky] [![Contact Maintainer][🚂maint-contact-img]][🚂maint-contact] [![My technical writing][💖💁🏼‍♂️devto-img]][💖💁🏼‍♂️devto] |
49
+ | `...` 💖 | [![Find Me on WellFound:][💖✌️wellfound-img]][💖✌️wellfound] [![Find Me on CrunchBase][💖💲crunchbase-img]][💖💲crunchbase] [![My LinkTree][💖🌳linktree-img]][💖🌳linktree] [![More About Me][💖💁🏼‍♂️aboutme-img]][💖💁🏼‍♂️aboutme] [🧊][💖🧊berg] [🐙][💖🐙hub] [🛖][💖🛖hut] [🧪][💖🧪lab] |
50
+
51
+ ### Compatibility
52
+
53
+ Compatible with MRI Ruby {KJ|MIN_RUBY}+, and concordant releases of JRuby, and TruffleRuby.
54
+ CI workflows and Appraisals are generated for MRI Ruby {KJ|MIN_TEST_RUBY}+.
55
+ This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and
56
+ may be higher than the gem's runtime compatibility floor when legacy Rubies are
57
+ not practical for the current toolchain.
58
+
59
+ <a href="https://github.com/kettle-dev"><img alt="kettle-dev Logo by Aboling0, CC BY-SA 4.0" src="https://logos.galtzo.com/assets/images/kettle-dev/avatar-128px.svg" width="14%" align="right"/></a>
60
+
61
+ The _amazing_ test matrix is powered by the kettle-dev stack.
62
+
63
+ {KJ|README:DEV_TEST_STACK_TABLE}
64
+
65
+ {KJ|README:FAMILY_INTRO_BACKEND_MATRIX}
66
+
67
+ ### Federated DVCS
68
+
69
+ <details markdown="1">
70
+ <summary>Find this repo on federated forges (Coming soon!)</summary>
71
+
72
+ | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI |
73
+ |-------------------------------------------------|-------------------------------------------|-------------------|------------------|-----------------|----------------|
74
+ | 🧪 [{KJ|README:REPO_SLUG} on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜gl-wiki] | 🐭 Tiny Matrix |
75
+ | 🧊 [{KJ|README:REPO_SLUG} on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix |
76
+ | 🐙 [{KJ|README:REPO_SLUG} on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | [💚][📜gh-wiki] | 💯 Full Matrix |
77
+
78
+ </details>
79
+
80
+ ### Enterprise Support [![Tidelift](https://tidelift.com/badges/package/rubygems/{KJ|GEM_NAME})](https://tidelift.com/subscription/pkg/rubygems-{KJ|GEM_NAME}?utm_source=rubygems-{KJ|GEM_NAME}&utm_medium=referral&utm_campaign=readme)
81
+
82
+ Available as part of the Tidelift Subscription.
83
+
84
+ <details markdown="1">
85
+ <summary>Need enterprise-level guarantees?</summary>
86
+
87
+ The maintainers of this and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.
88
+
89
+ [![Get help from me on Tidelift][🏙️entsup-tidelift-img]][🏙️entsup-tidelift]
90
+
91
+ - 💡Subscribe for support guarantees covering _all_ your FLOSS dependencies
92
+ - 💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar]
93
+ - 💡Tidelift pays maintainers to maintain the software you depend on!<br/>📊`@`Pointy Haired Boss: An [enterprise support][🏙️entsup-tidelift] subscription is "[never gonna let you down][🧮kloc]", and *supports* open source maintainers
94
+
95
+ Alternatively:
96
+
97
+ - [![Ruby Users Forum][✉️ruby-forum-img]][✉️ruby-forum]
98
+ - [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite]
99
+ - [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork]
100
+ - [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor]
101
+
102
+ </details>
103
+
104
+ ## ✨ Installation
105
+
106
+ Install the gem and add to the application's Gemfile by executing:
107
+
108
+ ```console
109
+ bundle add {KJ|GEM_NAME}
110
+ ```
111
+
112
+ If bundler is not being used to manage dependencies, install the gem by executing:
113
+
114
+ ```console
115
+ gem install {KJ|GEM_NAME}
116
+ ```
117
+
118
+ ## ⚙️ Configuration
119
+
120
+
121
+ ## 🔧 Basic Usage
122
+
123
+
124
+ ## 🦷 FLOSS Funding
125
+
126
+ While {KJ|GH_ORG} tools are free software and will always be, the project would benefit immensely from some funding.
127
+ Raising a monthly budget of... "dollars" would make the project more sustainable.
128
+
129
+ We welcome both individual and corporate sponsors! We also offer a
130
+ wide array of funding channels to account for your preferences.
131
+ <!-- KJ:OPEN_COLLECTIVE:START -->
132
+ Currently, [Open Collective][🖇osc] is our preferred funding platform.
133
+ <!-- KJ:OPEN_COLLECTIVE:END -->
134
+ <!-- KJ:NO_OPEN_COLLECTIVE:START -->
135
+ Currently, [GitHub Sponsors][🖇sponsor], and [Liberapay][⛳liberapay] are our preferred funding platforms.
136
+ <!-- KJ:NO_OPEN_COLLECTIVE:END -->
137
+
138
+ **If you're working in a company that's making significant use of {KJ|GH_ORG} tools we'd
139
+ appreciate it if you suggest to your company to become a {KJ|GH_ORG} sponsor.**
140
+
141
+ You can support the development of {KJ|GH_ORG} tools via
142
+ [GitHub Sponsors][🖇sponsor],
143
+ [Liberapay][⛳liberapay],
144
+ [PayPal][🖇paypal],
145
+ <!-- KJ:OPEN_COLLECTIVE:START -->
146
+ [Open Collective][🖇osc]
147
+ <!-- KJ:OPEN_COLLECTIVE:END -->
148
+ and [Tidelift][🏙️entsup-tidelift].
149
+
150
+ | 📍 NOTE |
151
+ |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
152
+ | If doing a sponsorship in the form of donation is problematic for your company <br/> from an accounting standpoint, we'd recommend the use of Tidelift, <br/> where you can get a support-like subscription instead. |
153
+
154
+ <!-- KJ:OPEN_COLLECTIVE:START -->
155
+ ### Open Collective for Individuals
156
+
157
+ Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/{KJ|OPENCOLLECTIVE_ORG}#backer)]
158
+
159
+ NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
160
+
161
+ <!-- OPENCOLLECTIVE-INDIVIDUALS:START -->
162
+ No backers yet. Be the first!
163
+ <!-- OPENCOLLECTIVE-INDIVIDUALS:END -->
164
+
165
+ ### Open Collective for Organizations
166
+
167
+ Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor](https://opencollective.com/{KJ|OPENCOLLECTIVE_ORG}#sponsor)]
168
+
169
+ NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
170
+
171
+ <!-- OPENCOLLECTIVE-ORGANIZATIONS:START -->
172
+ No sponsors yet. Be the first!
173
+ <!-- OPENCOLLECTIVE-ORGANIZATIONS:END -->
174
+
175
+ [kettle-readme-backers]: {KJ|README:GH_REPOSITORY_URL}/blob/main/bin/kettle-readme-backers
176
+ <!-- KJ:OPEN_COLLECTIVE:END -->
177
+
178
+ ### Another way to support open-source
179
+
180
+ I’m driven by a passion to foster a thriving open-source community – a space where people can tackle complex problems, no matter how small. Revitalizing libraries that have fallen into disrepair, and building new libraries focused on solving real-world challenges, are my passions. I was recently affected by layoffs, and the tech jobs market is unwelcoming. I’m reaching out here because your support would significantly aid my efforts to provide for my family, and my farm (11 🐔 chickens, 2 🐶 dogs, 3 🐰 rabbits, 8 🐈‍ cats).
181
+
182
+ If you work at a company that uses my work, please encourage them to support me as a corporate sponsor. My work on gems you use might show up in `bundle fund`.
183
+
184
+ I’m developing a new library, [floss_funding][🖇floss-funding-gem], designed to empower open-source developers like myself to get paid for the work we do, in a sustainable way. Please give it a look.
185
+
186
+ **[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
187
+
188
+ [![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 to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi]
189
+
190
+ ## 🔐 Security
191
+
192
+ See [SECURITY.md][🔐security].
193
+
194
+ ## 🤝 Contributing
195
+
196
+ If you need some ideas of where to help, you could work on adding more code coverage,
197
+ check [issues][🤝gh-issues] or [PRs][🤝gh-pulls], or use the gem and think about how it could be better.
198
+
199
+ We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
200
+
201
+ See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
202
+
203
+ ### 🚀 Release Instructions
204
+
205
+ See [CONTRIBUTING.md][🤝contributing].
206
+
207
+ ### Code Coverage
208
+
209
+ <details markdown="1">
210
+ <summary>Coverage service badges</summary>
211
+
212
+ [![Coverage Graph][🏀codecov-g]][🏀codecov]
213
+
214
+ [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls]
215
+
216
+ [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov]
217
+
218
+ </details>
219
+
220
+ ### 🪇 Code of Conduct
221
+
222
+ Everyone interacting with this project's codebases, issue trackers,
223
+ chat rooms and mailing lists agrees to follow the [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct].
224
+
225
+ ## 🌈 Contributors
226
+
227
+ [![Contributors][🖐contributors-img]][🖐contributors]
228
+
229
+ Made with [contributors-img][🖐contrib-rocks].
230
+
231
+ Also see GitLab Contributors: [{KJ|README:GL_CONTRIBUTORS_URL}][🚎contributors-gl]
232
+
233
+ <details markdown="1">
234
+ <summary>⭐️ Star History</summary>
235
+
236
+ <a href="https://star-history.dera.page/#{KJ|README:STAR_HISTORY_REPO}&type=date&legend=top-left">
237
+ <picture>
238
+ <source media="(prefers-color-scheme: dark)" srcset="https://star-history.dera.page/svg?repos={KJ|README:STAR_HISTORY_REPO}&type=date&theme=dark&legend=top-left" />
239
+ <source media="(prefers-color-scheme: light)" srcset="https://star-history.dera.page/svg?repos={KJ|README:STAR_HISTORY_REPO}&type=date&legend=top-left" />
240
+ <img alt="Star History Chart" src="https://star-history.dera.page/svg?repos={KJ|README:STAR_HISTORY_REPO}&type=date&legend=top-left" />
241
+ </picture>
242
+ </a>
243
+
244
+ </details>
245
+
246
+ ## 📌 Versioning
247
+
248
+ This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical.
249
+ For most applications, prefer the [Pessimistic Version Constraint][📌pvc] with two digits of precision.
250
+
251
+ For example:
252
+
253
+ ```ruby
254
+ spec.add_dependency("{KJ|GEM_NAME}", "~> {KJ|GEM_MAJOR}.0")
255
+ ```
256
+
257
+ <details markdown="1">
258
+ <summary>📌 Is "Platform Support" part of the public API? More details inside.</summary>
259
+
260
+ Dropping support for a platform can be a breaking change for affected users.
261
+ If a release changes supported platforms, it should be called out clearly in the changelog and versioned with that impact in mind.
262
+
263
+ To get a better understanding of how SemVer is intended to work over a project's lifetime,
264
+ read this article from the creator of SemVer:
265
+
266
+ - ["Major Version Numbers are Not Sacred"][📌major-versions-not-sacred]
267
+
268
+ </details>
269
+
270
+ See [CHANGELOG.md][📌changelog] for a list of releases.
271
+
272
+ ## 📄 License
273
+
274
+ {KJ|README:LICENSE_INTRO}
275
+
276
+ ### © Copyright
277
+
278
+ {KJ|README:COPYRIGHT_NOTICE}
279
+
280
+ ## 🤑 A request for help
281
+
282
+ Maintainers have teeth and need to pay their dentists.
283
+ After getting laid off in an RIF in March, and encountering difficulty finding a new one,
284
+ I began spending most of my time building open source tools.
285
+ I'm hoping to be able to pay for my kids' health insurance this month,
286
+ so if you value the work I am doing, I need your support.
287
+ Please consider sponsoring me or the project.
288
+
289
+ To join the community or get help, use the RubyForum or Discord.
290
+
291
+ [![Ruby Users Forum][✉️ruby-forum-img]][✉️ruby-forum]
292
+ [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite]
293
+
294
+ To say "thanks!" ☝️ Join the community or 👇️ send money.
295
+
296
+ <!-- KJ:OPEN_COLLECTIVE:START -->
297
+ [![Sponsor {KJ|OPENCOLLECTIVE_ORG}/{KJ|GEM_NAME} on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
298
+ <!-- KJ:OPEN_COLLECTIVE:END -->
299
+ <!-- KJ:NO_OPEN_COLLECTIVE:START -->
300
+ [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
301
+ <!-- KJ:NO_OPEN_COLLECTIVE:END -->
302
+
303
+ ### Please give the project a star ⭐ ♥.
304
+
305
+ Many parts of this project are actively managed by a [kettle-jem](https://github.com/structuredmerge/structuredmerge-ruby/tree/main/gems/kettle-jem) smart template utilizing [StructuredMerge.org](https://structuredmerge.org) merge contracts.
306
+
307
+ Thanks for RTFM. ☺️
308
+
309
+ [⛳liberapay-img]: https://img.shields.io/liberapay/goal/{KJ|FUNDING:LIBERAPAY}.svg?logo=liberapay&color=a51611&style=flat
310
+ [⛳liberapay-bottom-img]: https://img.shields.io/liberapay/goal/{KJ|FUNDING:LIBERAPAY}.svg?style=for-the-badge&logo=liberapay&color=a51611
311
+ [⛳liberapay]: https://liberapay.com/{KJ|FUNDING:LIBERAPAY}/donate
312
+ <!-- KJ:OPEN_COLLECTIVE:START -->
313
+ [🖇osc-all-img]: https://img.shields.io/opencollective/all/{KJ|OPENCOLLECTIVE_ORG}
314
+ [🖇osc-sponsors-img]: https://img.shields.io/opencollective/sponsors/{KJ|OPENCOLLECTIVE_ORG}
315
+ [🖇osc-backers-img]: https://img.shields.io/opencollective/backers/{KJ|OPENCOLLECTIVE_ORG}
316
+ [🖇osc-backers]: https://opencollective.com/{KJ|OPENCOLLECTIVE_ORG}#backer
317
+ [🖇osc-backers-i]: https://opencollective.com/{KJ|OPENCOLLECTIVE_ORG}/backers/badge.svg?style=flat
318
+ [🖇osc-sponsors]: https://opencollective.com/{KJ|OPENCOLLECTIVE_ORG}#sponsor
319
+ [🖇osc-sponsors-i]: https://opencollective.com/{KJ|OPENCOLLECTIVE_ORG}/sponsors/badge.svg?style=flat
320
+ [🖇osc-all-bottom-img]: https://img.shields.io/opencollective/all/{KJ|OPENCOLLECTIVE_ORG}?style=for-the-badge
321
+ [🖇osc-sponsors-bottom-img]: https://img.shields.io/opencollective/sponsors/{KJ|OPENCOLLECTIVE_ORG}?style=for-the-badge
322
+ [🖇osc-backers-bottom-img]: https://img.shields.io/opencollective/backers/{KJ|OPENCOLLECTIVE_ORG}?style=for-the-badge
323
+ [🖇osc]: https://opencollective.com/{KJ|OPENCOLLECTIVE_ORG}
324
+ <!-- KJ:OPEN_COLLECTIVE:END -->
325
+ [🖇sponsor-img]: https://img.shields.io/badge/Sponsor_Me!-{KJ|GH:USER}.svg?style=social&logo=github
326
+ [🖇sponsor-bottom-img]: https://img.shields.io/badge/Sponsor_Me!-{KJ|GH:USER}-blue?style=for-the-badge&logo=github
327
+ [🖇sponsor]: https://github.com/sponsors/{KJ|GH:USER}
328
+ [🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat
329
+ [🖇kofi]: https://ko-fi.com/{KJ|FUNDING:KOFI}
330
+ [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat
331
+ [🖇buyme-img]: https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20latte&emoji=&slug={KJ|FUNDING:BUYMEACOFFEE}&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff
332
+ [🖇buyme]: https://www.buymeacoffee.com/{KJ|FUNDING:BUYMEACOFFEE}
333
+ [🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal
334
+ [🖇paypal-bottom-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=for-the-badge&logo=paypal&color=0A0A0A
335
+ [🖇paypal]: https://www.paypal.com/paypalme/{KJ|FUNDING:PAYPAL}
336
+ [🖇floss-funding.dev]: https://floss-funding.dev
337
+ [🖇floss-funding-gem]: https://github.com/galtzo-floss/floss_funding
338
+ [✉️discord-invite]: https://discord.gg/3qme4XHNKN
339
+ [✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord
340
+ [✉️ruby-friends-img]: https://img.shields.io/badge/daily.dev-%F0%9F%92%8E_Ruby_Friends-0A0A0A?style=for-the-badge&logo=dailydotdev&logoColor=white
341
+ [✉️ruby-friends]: https://app.daily.dev/squads/rubyfriends
342
+ [✉️ruby-forum-top-img]: {KJ|RUBYFORUM:BADGE_IMG}
343
+ [✉️ruby-forum-img]: {KJ|RUBYFORUM:BADGE_IMG_FTB}
344
+ [✉️ruby-forum]: {KJ|RUBYFORUM:URL}
345
+
346
+ [✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
347
+ [⛳️gem-namespace]: {KJ|README:GH_PACKAGE_SOURCE_URL}
348
+ [⛳️namespace-img]: https://img.shields.io/badge/namespace-{KJ|NAMESPACE_SHIELD}-3C2D2D.svg?style=square&logo=ruby&logoColor=white
349
+ [⛳️gem-name]: https://clickgems.clickhouse.com/dashboard/{KJ|GEM_NAME}
350
+ [⛳️name-img]: https://img.shields.io/badge/name-{KJ|GEM_SHIELD}-3C2D2D.svg?style=square&logo=rubygems&logoColor=red
351
+ [⛳️tag-img]: https://img.shields.io/github/tag/{KJ|README:GH_TAG_BADGE_REPO}.svg
352
+ [⛳️tag]: {KJ|README:GH_RELEASES_URL}
353
+ [🚂maint-blog]: http://www.railsbling.com/tags/{KJ|GEM_NAME}
354
+ [🚂maint-blog-img]: https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange
355
+ [🚂maint-contact]: http://www.railsbling.com/contact
356
+ [🚂maint-contact-img]: https://img.shields.io/badge/Contact-Maintainer-0093D0.svg?style=flat&logo=rubyonrails&logoColor=red
357
+ [💖🖇linkedin]: http://www.linkedin.com/in/peterboling
358
+ [💖🖇linkedin-img]: https://img.shields.io/badge/LinkedIn-Profile-0B66C2?style=flat&logo=newjapanprowrestling
359
+ [💖✌️wellfound]: https://wellfound.com/u/peter-boling
360
+ [💖✌️wellfound-img]: https://img.shields.io/badge/peter--boling-orange?style=flat&logo=wellfound
361
+ [💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling
362
+ [💖💲crunchbase-img]: https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase
363
+ [💖🐘ruby-mast]: https://ruby.social/@{KJ|SOCIAL:MASTODON}
364
+ [💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https://ruby.social&style=flat&logo=mastodon&label=Ruby%20@{KJ|SOCIAL:MASTODON}
365
+ [💖🦋bluesky]: https://bsky.app/profile/{KJ|SOCIAL:BLUESKY}
366
+ [💖🦋bluesky-img]: https://img.shields.io/badge/@{KJ|SOCIAL:BLUESKY}-0285FF?style=flat&logo=bluesky&logoColor=white
367
+ [💖🌳linktree]: https://linktr.ee/{KJ|SOCIAL:LINKTREE}
368
+ [💖🌳linktree-img]: https://img.shields.io/badge/{KJ|SOCIAL:LINKTREE}-purple?style=flat&logo=linktree
369
+ [💖💁🏼‍♂️devto]: https://dev.to/{KJ|SOCIAL:DEVTO}
370
+ [💖💁🏼‍♂️devto-img]: https://img.shields.io/badge/dev.to-0A0A0A?style=flat&logo=devdotto&logoColor=white
371
+ [💖💁🏼‍♂️aboutme]: https://about.me/peter.boling
372
+ [💖💁🏼‍♂️aboutme-img]: https://img.shields.io/badge/about.me-0A0A0A?style=flat&logo=aboutme&logoColor=white
373
+ [💖🧊berg]: https://codeberg.org/{KJ|CB:USER}
374
+ [💖🐙hub]: https://github.org/{KJ|GH:USER}
375
+ [💖🛖hut]: https://sr.ht/~{KJ|SH:USER}/
376
+ [💖🧪lab]: https://gitlab.com/{KJ|GL:USER}
377
+ [👨🏼‍🏫expsup-upwork]: https://www.upwork.com/freelancers/~014942e9b056abdf86?mp_source=share
378
+ [👨🏼‍🏫expsup-upwork-img]: https://img.shields.io/badge/UpWork-13544E?style=for-the-badge&logo=Upwork&logoColor=white
379
+ [👨🏼‍🏫expsup-codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
380
+ [👨🏼‍🏫expsup-codementor-img]: https://img.shields.io/badge/CodeMentor-Get_Help-1abc9c?style=for-the-badge&logo=CodeMentor&logoColor=white
381
+ [🏙️entsup-tidelift]: https://tidelift.com/subscription/pkg/rubygems-{KJ|GEM_NAME}?utm_source=rubygems-{KJ|GEM_NAME}&utm_medium=referral&utm_campaign=readme
382
+ [🏙️entsup-tidelift-img]: https://img.shields.io/badge/Tidelift_and_Sonar-Enterprise_Support-FD3456?style=for-the-badge&logo=sonar&logoColor=white
383
+ [🏙️entsup-tidelift-sonar]: https://blog.tidelift.com/tidelift-joins-sonar
384
+ [💁🏼‍♂️peterboling]: http://www.peterboling.com
385
+ [🚂railsbling]: http://www.railsbling.com
386
+ [📜src-gl-img]: https://img.shields.io/badge/GitLab-FBA326?style=for-the-badge&logo=Gitlab&logoColor=orange
387
+ [📜src-gl]: {KJ|README:GL_PACKAGE_SOURCE_URL}
388
+ [📜src-cb-img]: https://img.shields.io/badge/CodeBerg-4893CC?style=for-the-badge&logo=CodeBerg&logoColor=blue
389
+ [📜src-cb]: {KJ|README:CB_PACKAGE_SOURCE_URL}
390
+ [📜src-gh-img]: https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=GitHub&logoColor=green
391
+ [📜src-gh]: {KJ|README:GH_PACKAGE_SOURCE_URL}
392
+ [📜docs-cr-rd-img]: https://img.shields.io/badge/RubyDoc-Current_Release-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
393
+ [📜docs-head-rd-img]: https://img.shields.io/badge/YARD_on_Galtzo.com-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
394
+ [📜gl-wiki]: {KJ|README:GL_WIKI_URL}
395
+ [📜gh-wiki]: {KJ|README:GH_WIKI_URL}
396
+ [📜gl-wiki-img]: https://img.shields.io/badge/wiki-gitlab-943CD2.svg?style=for-the-badge&logo=gitlab&logoColor=white
397
+ [📜gh-wiki-img]: https://img.shields.io/badge/wiki-github-943CD2.svg?style=for-the-badge&logo=github&logoColor=white
398
+ [👽dl-rank]: https://clickgems.clickhouse.com/dashboard/{KJ|GEM_NAME}
399
+ [👽dl-ranki]: https://img.shields.io/gem/dt/{KJ|GEM_NAME}.svg
400
+ [👽version]: https://clickgems.clickhouse.com/dashboard/{KJ|GEM_NAME}
401
+ [👽versioni]: https://img.shields.io/gem/v/{KJ|GEM_NAME}.svg
402
+ [🏀qlty-mnt]: {KJ|README:QLTY_PROJECT_URL}
403
+ [🏀qlty-mnti]: {KJ|README:QLTY_MAINTAINABILITY_URL}
404
+ [🏀qlty-cov]: {KJ|README:QLTY_COVERAGE_URL}
405
+ [🏀qlty-covi]: {KJ|README:QLTY_COVERAGE_BADGE_URL}
406
+ [🏀codecov]: {KJ|README:CODECOV_URL}
407
+ [🏀codecovi]: {KJ|README:CODECOV_BADGE_URL}
408
+ [🏀coveralls]: {KJ|README:COVERALLS_URL}
409
+ [🏀coveralls-img]: {KJ|README:COVERALLS_BADGE_URL}
410
+ [🚎ruby-2.4-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-2.4.yml
411
+ [🚎ruby-2.4-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-2.4.yml/badge.svg
412
+ [🚎ruby-2.5-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-2.5.yml
413
+ [🚎ruby-2.5-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-2.5.yml/badge.svg
414
+ [🚎ruby-2.6-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-2.6.yml
415
+ [🚎ruby-2.6-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-2.6.yml/badge.svg
416
+ [🚎ruby-2.7-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-2.7.yml
417
+ [🚎ruby-2.7-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-2.7.yml/badge.svg
418
+ [🚎ruby-3.0-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-3.0.yml
419
+ [🚎ruby-3.0-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-3.0.yml/badge.svg
420
+ [🚎ruby-3.1-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-3.1.yml
421
+ [🚎ruby-3.1-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-3.1.yml/badge.svg
422
+ [🚎ruby-3.2-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-3.2.yml
423
+ [🚎ruby-3.2-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-3.2.yml/badge.svg
424
+ [🚎ruby-3.3-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-3.3.yml
425
+ [🚎ruby-3.3-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-3.3.yml/badge.svg
426
+ [🚎ruby-3.4-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-3.4.yml
427
+ [🚎ruby-3.4-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/ruby-3.4.yml/badge.svg
428
+ [🚎jruby-9.1-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby-9.1.yml
429
+ [🚎jruby-9.1-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby-9.1.yml/badge.svg
430
+ [🚎jruby-9.2-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby-9.2.yml
431
+ [🚎jruby-9.2-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby-9.2.yml/badge.svg
432
+ [🚎jruby-9.3-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby-9.3.yml
433
+ [🚎jruby-9.3-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby-9.3.yml/badge.svg
434
+ [🚎jruby-9.4-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby-9.4.yml
435
+ [🚎jruby-9.4-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby-9.4.yml/badge.svg
436
+ [🚎jruby-10.0-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby-10.0.yml
437
+ [🚎jruby-10.0-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby-10.0.yml/badge.svg
438
+ [🚎truby-22.3-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-22.3.yml
439
+ [🚎truby-22.3-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-22.3.yml/badge.svg
440
+ [🚎truby-23.0-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-23.0.yml
441
+ [🚎truby-23.0-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-23.0.yml/badge.svg
442
+ [🚎truby-23.1-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-23.1.yml
443
+ [🚎truby-23.1-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-23.1.yml/badge.svg
444
+ [🚎truby-24.2-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-24.2.yml
445
+ [🚎truby-24.2-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-24.2.yml/badge.svg
446
+ [🚎truby-25.0-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-25.0.yml
447
+ [🚎truby-25.0-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-25.0.yml/badge.svg
448
+ [🚎truby-33.0-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-33.0.yml
449
+ [🚎truby-33.0-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffleruby-33.0.yml/badge.svg
450
+ [🚎2-cov-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/coverage.yml
451
+ [🚎2-cov-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/coverage.yml/badge.svg
452
+ [🚎3-hd-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/heads.yml
453
+ [🚎3-hd-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/heads.yml/badge.svg
454
+ [🚎5-st-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/style.yml
455
+ [🚎5-st-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/style.yml/badge.svg
456
+ [🚎9-t-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffle.yml
457
+ [🚎9-t-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/truffle.yml/badge.svg
458
+ [🚎10-j-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby.yml
459
+ [🚎10-j-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/jruby.yml/badge.svg
460
+ [🚎11-c-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/current.yml
461
+ [🚎11-c-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/current.yml/badge.svg
462
+ [🚎12-crh-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/dep-heads.yml
463
+ [🚎12-crh-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/dep-heads.yml/badge.svg
464
+ [🚎13-🔒️-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/locked_deps.yml
465
+ [🚎13-🔒️-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/locked_deps.yml/badge.svg
466
+ [🚎14-🔓️-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/unlocked_deps.yml
467
+ [🚎14-🔓️-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/unlocked_deps.yml/badge.svg
468
+ [🚎15-🪪-wf]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/license-eye.yml
469
+ [🚎15-🪪-wfi]: {KJ|README:GH_REPOSITORY_URL}/actions/workflows/license-eye.yml/badge.svg
470
+ [💎ruby-1.8i]: https://img.shields.io/badge/Ruby-1.8_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=white
471
+ [💎ruby-1.9i]: https://img.shields.io/badge/Ruby-1.9_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=white
472
+ [💎ruby-2.0i]: https://img.shields.io/badge/Ruby-2.0_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=white
473
+ [💎ruby-2.1i]: https://img.shields.io/badge/Ruby-2.1_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=white
474
+ [💎ruby-2.2i]: https://img.shields.io/badge/Ruby-2.2_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=white
475
+ [💎ruby-2.3i]: https://img.shields.io/badge/Ruby-2.3_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=white
476
+ [💎ruby-2.4i]: https://img.shields.io/badge/Ruby-2.4-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
477
+ [💎ruby-2.5i]: https://img.shields.io/badge/Ruby-2.5-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
478
+ [💎ruby-2.6i]: https://img.shields.io/badge/Ruby-2.6-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
479
+ [💎ruby-2.7i]: https://img.shields.io/badge/Ruby-2.7-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
480
+ [💎ruby-3.0i]: https://img.shields.io/badge/Ruby-3.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white
481
+ [💎ruby-3.1i]: https://img.shields.io/badge/Ruby-3.1-CC342D?style=for-the-badge&logo=ruby&logoColor=white
482
+ [💎ruby-3.2i]: https://img.shields.io/badge/Ruby-3.2-CC342D?style=for-the-badge&logo=ruby&logoColor=white
483
+ [💎ruby-3.3i]: https://img.shields.io/badge/Ruby-3.3-CC342D?style=for-the-badge&logo=ruby&logoColor=white
484
+ [💎ruby-3.4i]: https://img.shields.io/badge/Ruby-3.4-CC342D?style=for-the-badge&logo=ruby&logoColor=white
485
+ [💎ruby-4.0i]: https://img.shields.io/badge/Ruby-4.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white
486
+ [💎ruby-c-i]: https://img.shields.io/badge/Ruby-current-CC342D?style=for-the-badge&logo=ruby&logoColor=green
487
+ [💎ruby-headi]: https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue
488
+ [💎truby-22.3i]: https://img.shields.io/badge/Truffle_Ruby-22.3-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
489
+ [💎truby-23.0i]: https://img.shields.io/badge/Truffle_Ruby-23.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
490
+ [💎truby-23.1i]: https://img.shields.io/badge/Truffle_Ruby-23.1-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
491
+ [💎truby-24.2i]: https://img.shields.io/badge/Truffle_Ruby-24.2-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
492
+ [💎truby-25.0i]: https://img.shields.io/badge/Truffle_Ruby-25.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
493
+ [💎truby-33.0i]: https://img.shields.io/badge/Truffle_Ruby-33.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
494
+ [💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green
495
+ [💎truby-headi]: https://img.shields.io/badge/Truffle_Ruby-HEAD-34BCB1?style=for-the-badge&logo=ruby&logoColor=blue
496
+ [💎jruby-9.1i]: https://img.shields.io/badge/JRuby-9.1-FBE742?style=for-the-badge&logo=ruby&logoColor=red
497
+ [💎jruby-9.2i]: https://img.shields.io/badge/JRuby-9.2-FBE742?style=for-the-badge&logo=ruby&logoColor=red
498
+ [💎jruby-9.3i]: https://img.shields.io/badge/JRuby-9.3-FBE742?style=for-the-badge&logo=ruby&logoColor=red
499
+ [💎jruby-9.4i]: https://img.shields.io/badge/JRuby-9.4-FBE742?style=for-the-badge&logo=ruby&logoColor=red
500
+ [💎jruby-10.0i]: https://img.shields.io/badge/JRuby-10.0-FBE742?style=for-the-badge&logo=ruby&logoColor=red
501
+ [💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green
502
+ [💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue
503
+ [🤝gh-issues]: {KJ|README:GH_ISSUES_URL}
504
+ [🤝gh-pulls]: {KJ|README:GH_PULLS_URL}
505
+ [🤝gl-issues]: {KJ|README:GL_ISSUES_URL}
506
+ [🤝gl-pulls]: {KJ|README:GL_PULLS_URL}
507
+ [🤝cb-issues]: {KJ|README:CB_ISSUES_URL}
508
+ [🤝cb-pulls]: {KJ|README:CB_PULLS_URL}
509
+ [🤝cb-donate]: https://donate.codeberg.org/
510
+ [🤝contributing]: {KJ|README:GH_CONTRIBUTING_URL}
511
+ [🏀codecov-g]: {KJ|README:CODECOV_GRAPH_URL}
512
+ [🖐contrib-rocks]: https://contrib.rocks
513
+ [🖐contributors]: {KJ|README:GH_CONTRIBUTORS_URL}
514
+ [🖐contributors-img]: https://contrib.rocks/image?repo={KJ|README:CONTRIBUTORS_IMAGE_REPO}
515
+ [🚎contributors-gl]: {KJ|README:GL_CONTRIBUTORS_URL}
516
+ [🪇conduct]: {KJ|README:GH_CODE_OF_CONDUCT_URL}
517
+ [🪇conduct-img]: https://img.shields.io/badge/Contributor_Covenant-2.1-259D6C.svg
518
+ [📌pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint
519
+ [📌semver]: https://semver.org/spec/v2.0.0.html
520
+ [📌semver-img]: https://img.shields.io/badge/semver-2.0.0-259D6C.svg?style=flat
521
+ [📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139
522
+ [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html
523
+ [📌changelog]: {KJ|README:GH_CHANGELOG_URL}
524
+ [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
525
+ [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
526
+ [📌gitmoji]: https://gitmoji.dev
527
+ [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
528
+ [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
529
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-5.053-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
530
+ [🔐security]: {KJ|README:GH_SECURITY_URL}
531
+ [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
532
+ {KJ|README:LICENSE_REFS}
533
+ {KJ|README:FOSSA_REFS}
534
+ [📄ilo-declaration]: https://www.ilo.org/declaration/lang--en/index.htm
535
+ [📄ilo-declaration-img]: https://img.shields.io/badge/ILO_Fundamental_Principles-✓-259D6C.svg?style=flat
536
+ [🚎yard-current]: http://rubydoc.info/gems/{KJ|GEM_NAME}
537
+ [🚎yard-head]: https://{KJ|YARD_HOST}
538
+ [💎stone_checksums]: https://github.com/galtzo-floss/stone_checksums
539
+ [💎SHA_checksums]: {KJ|README:SHA_CHECKSUMS_URL}
540
+ [💎rlts]: https://github.com/rubocop-lts/rubocop-lts
541
+ [💎rlts-img]: https://img.shields.io/badge/code_style_&_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white
542
+ [💎appraisal2]: https://github.com/appraisal-rb/appraisal2
543
+ [💎appraisal2-img]: https://img.shields.io/badge/appraised_by-appraisal2-34495e.svg?plastic&logo=ruby&logoColor=white
544
+ [💎d-in-dvcs]: https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/
File without changes
@@ -0,0 +1,78 @@
1
+ # RuboCop Usage Guide
2
+
3
+ ## Overview
4
+
5
+ A tale of two RuboCop plugin gems.
6
+
7
+ ### RuboCop Gradual
8
+
9
+ This project uses `rubocop_gradual` instead of vanilla RuboCop for code style checking. The `rubocop_gradual` tool allows for gradual adoption of RuboCop rules by tracking violations in a lock file.
10
+
11
+ ### RuboCop LTS
12
+
13
+ This project uses `rubocop-lts` to ensure, on a best-effort basis, compatibility with Ruby >= 1.9.2.
14
+ RuboCop rules are meticulously configured by the `rubocop-lts` family of gems to ensure that a project is compatible with a specific version of Ruby. See: https://rubocop-lts.gitlab.io for more.
15
+
16
+ ## Checking RuboCop Violations
17
+
18
+ To check for RuboCop violations in this project, always use:
19
+
20
+ ```bash
21
+ bundle exec rake rubocop_gradual:check
22
+ ```
23
+
24
+ **Do not use** the standard RuboCop commands like:
25
+ - `bundle exec rubocop`
26
+ - `rubocop`
27
+
28
+ ## Understanding the Lock File
29
+
30
+ The `.rubocop_gradual.lock` file is a work list, not a permanent baseline. Every entry represents a style issue that should be resolved by either fixing the code or making an intentional exception explicit.
31
+
32
+ This allows the team to:
33
+
34
+ 1. Prevent new violations while existing issues are handled deliberately
35
+ 2. Track progress on code style improvements
36
+ 3. Distinguish temporary work items from intentional project style exceptions
37
+
38
+ ## Common Commands
39
+
40
+ - **Check violations**
41
+ - `bundle exec rake rubocop_gradual`
42
+ - `bundle exec rake rubocop_gradual:check`
43
+ - **(Safe) Autocorrect violations, and update lockfile if no new violations**
44
+ - `bundle exec rake rubocop_gradual:autocorrect`
45
+ - **Force update the lock file (w/o autocorrect) to match violations present in code**
46
+ - `bundle exec rake rubocop_gradual:force_update`
47
+
48
+ ## Workflow
49
+
50
+ 1. Before submitting a PR, run `bundle exec rake rubocop_gradual:autocorrect`
51
+ a. or just the default `bundle exec rake`, as autocorrection is a pre-requisite of the default task.
52
+ 2. If there are violations, either:
53
+ - Fix them in your code
54
+ - Normalize intentional deviations with an explicit config or inline exception
55
+ - Run `bundle exec rake rubocop_gradual:force_update` only for temporary work items you cannot fix immediately
56
+ 3. Commit the updated `.rubocop_gradual.lock` file along with your changes
57
+
58
+ ## Explicit Style Exceptions
59
+
60
+ Do not treat `.rubocop_gradual.lock` as a baseline. Treat it as a list of work that must be fixed or normalized into the styleguide.
61
+
62
+ Prefer this order:
63
+
64
+ 1. Fix the code so it follows the configured styleguide.
65
+ 2. For intentional project conventions, add the narrowest useful override in `.rubocop.yml` or `.rubocop_rspec.yml`.
66
+ 3. For local intentional deviations, add a tightly scoped inline `rubocop:disable` / `rubocop:enable` around the exact line or block.
67
+ 4. Keep an entry in `.rubocop_gradual.lock` only as temporary work to be resolved later.
68
+
69
+ Use configuration overrides when a deviation is structural, generated, path-specific, or applies consistently to a small set of files. Use inline disables when the exception is local and the reason is clearer at the code site than in global config.
70
+
71
+ In general, treat the rules as guidance to follow; fix violations rather than ignore them. For example, RSpec conventions in this project expect `described_class` to be used in specs that target a specific class under test.
72
+
73
+ ## Benefits of rubocop_gradual
74
+
75
+ - Allows incremental adoption of code style rules
76
+ - Prevents CI failures due to temporary pre-existing violations
77
+ - Provides a clear work list of code style debt
78
+ - Enables focused efforts on improving code quality over time