version_gem 1.1.0 → 1.1.8

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.
data/README.md CHANGED
@@ -1,6 +1,55 @@
1
- # VersionGem
2
-
3
- Give your next library an introspectable `Version` module.
1
+ # 🔖 VersionGem
2
+
3
+ [![Version][👽versioni]][👽version]
4
+ [![License: MIT][📄license-img]][📄license-ref]
5
+ [![Downloads Rank][👽dl-ranki]][👽dl-rank]
6
+ [![Open Source Helpers][👽oss-helpi]][👽oss-help]
7
+ [![Depfu][🔑depfui♻️]][🔑depfu]
8
+ [![CodeCov Test Coverage][🔑codecovi♻️]][🔑codecov]
9
+ [![Coveralls Test Coverage][🔑coveralls-img]][🔑coveralls]
10
+ [![CodeClimate Test Coverage][🔑cc-covi♻️]][🔑cc-cov]
11
+ [![Maintainability][🔑cc-mnti♻️]][🔑cc-mnt]
12
+ [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf]
13
+ [![CI Current][🚎11-c-wfi]][🚎11-c-wf]
14
+ [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf]
15
+ [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf]
16
+ [![CI Supported][🚎6-s-wfi]][🚎6-s-wf]
17
+ [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf]
18
+ [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf]
19
+ [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf]
20
+ [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf]
21
+ [![CI Style][🚎5-st-wfi]][🚎5-st-wf]
22
+
23
+ ---
24
+
25
+ [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay]
26
+ [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor]
27
+ [![Buy me a coffee][🖇buyme-small-img]][🖇buyme]
28
+ [![Donate on Polar][🖇polar-img]][🖇polar]
29
+ [![Donate to my FLOSS or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi]
30
+ [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
31
+
32
+ ## 🧐 Alternatives
33
+
34
+ This gem has a very niche purpose, which is:
35
+
36
+ 1. providing introspection of a `Version` module based on a `VERSION` constant string within it,
37
+ 2. while not interfering with `gemspec` parsing where the `VERSION` string is traditionally used,
38
+ 3. allowing 100% test coverage of Ruby code, including the `Version` module.
39
+
40
+ As proof in the pudding, this gem achieves 100% test coverage for lines and branches,
41
+ all 117 and 4 of them, respectively; coverage enabled in part by patterns from this library.
42
+ You can make it happen for your library too!
43
+
44
+ If this isn't **precisely** your use case you may be better off looking at
45
+ _[versionaire](https://www.alchemists.io/projects/versionaire)_, a wonderful, performant, well-maintained,
46
+ gem from the Alchemists, or _[version_sorter](https://rubygems.org/gems/version_sorter)_ from GitHub.
47
+
48
+ For more discussion about this [see issue #2](https://gitlab.com/oauth-xx/version_gem/-/issues/2)
49
+
50
+ ## 🚀 Still here?
51
+
52
+ Give your next library an introspectable `Version` module without breaking your Gemspec.
4
53
 
5
54
  ```ruby
6
55
  MyLib::Version.to_s # => "1.2.3.rc3"
@@ -12,147 +61,27 @@ MyLib::Version.to_a # => [1, 2, 3, "rc3"]
12
61
  MyLib::Version.to_h # => { major: 1, minor: 2, patch: 3, pre: "rc3" }
13
62
  ```
14
63
 
15
- This library was extracted from the gem [`oauth2`](https://github.com/oauth-xx/oauth2).
64
+ This library was extracted from the gem _[oauth2](https://gitlab.com/oauth-xx/oauth2)_.
16
65
 
17
66
  This gem has no runtime dependencies.
18
67
 
19
- <!--
20
- Numbering rows and badges in each row as a visual "database" lookup,
21
- as the table is extremely dense, and it can be very difficult to find anything
22
- Putting one on each row here, to document the emoji that should be used, and for ease of copy/paste.
23
-
24
- row #s:
25
- 1️⃣
26
- 2️⃣
27
- 3️⃣
28
- 4️⃣
29
- 5️⃣
30
- 6️⃣
31
- 7️⃣
32
-
33
- badge #s:
34
- ⛳️
35
- 🖇
36
- 🏘
37
- 🚎
38
- 🖐
39
- 🧮
40
- 📗
41
-
42
- appended indicators:
43
- ♻️ - URL needs to be updated from SASS integration. Find / Replace is insufficient.
44
- -->
45
-
46
- | | Project | bundle add version_gem |
47
- |:----|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
48
- | 1️⃣ | name, license, docs, standards | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![RubyDoc.info][🚎yard-img]][🚎yard] [![SemVer 2.0.0][🧮semver-img]][semver] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] |
49
- | 2️⃣ | version & activity | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-o-img]][🖐prs-o] [![Closed PRs][🧮prs-c-img]][🧮prs-c] <!--[![Next Version][📗next-img]][📗next]--> |
50
- | 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img♻️]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img♻️]][🏘depfu♻️] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc] |
51
- | 4️⃣ | testing | [![Open Issues][⛳iss-o-img]][⛳iss-o] [![Closed Issues][🖇iss-c-img]][🖇iss-c] [![Supported][🏘sup-wf-img]][🏘sup-wf] [![Heads][🚎heads-wf-img]][🚎heads-wf] [![Unofficial Support][🖐uns-wf-img]][🖐uns-wf] <!--[![MacOS][🧮mac-wf-img]][🧮mac-wf] [![Windows][📗win-wf-img]][📗win-wf]--> |
52
- | 5️⃣ | coverage & security | [![CodeClimate][⛳cclim-cov-img♻️]][⛳cclim-cov] [![CodeCov][🖇codecov-img♻️]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🧮cov-wf-img]][🧮cov-wf] |
53
- | 6️⃣ | resources | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Wiki][🖐wiki-img]][🖐wiki] |
54
- | 7️⃣ | spread 💖 | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] |
55
-
56
- <!--
57
- The link tokens in the following sections should be kept ordered by the row and badge numbering scheme
58
- -->
59
-
60
- <!-- 1️⃣ name, license, docs -->
61
- [⛳️gem]: https://rubygems.org/gems/version_gem
62
- [⛳️name-img]: https://img.shields.io/badge/name-version_gem-brightgreen.svg?style=flat
63
- [🖇src-license]: https://opensource.org/licenses/MIT
64
- [🖇src-license-img]: https://img.shields.io/badge/License-MIT-green.svg
65
- [🚎yard]: https://www.rubydoc.info/github/pboling/version_gem
66
- [🚎yard-img]: https://img.shields.io/badge/documentation-rubydoc-brightgreen.svg?style=flat
67
- [🧮semver-img]: https://img.shields.io/badge/semver-2.0.0-FFDD67.svg?style=flat
68
- [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
69
- [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-FFDD67.svg?style=flat
70
-
71
- <!-- 2️⃣ version & activity -->
72
- [⛳️version-img]: http://img.shields.io/gem/v/version_gem.svg
73
- [🖇DL-total-img]: https://img.shields.io/gem/dt/version_gem.svg
74
- [🏘DL-rank-img]: https://img.shields.io/gem/rt/version_gem.svg
75
- [🚎src-home]: https://github.com/pboling/version_gem
76
- [🚎src-home-img]: https://img.shields.io/badge/source-github-brightgreen.svg?style=flat
77
- [🖐prs-o]: https://github.com/pboling/version_gem/pulls
78
- [🖐prs-o-img]: https://img.shields.io/github/issues-pr/pboling/version_gem
79
- [🧮prs-c]: https://github.com/pboling/version_gem/pulls?q=is%3Apr+is%3Aclosed
80
- [🧮prs-c-img]: https://img.shields.io/github/issues-pr-closed/pboling/version_gem
81
- [📗next]: https://github.com/pboling/version_gem/milestone/1
82
- [📗next-img]: https://img.shields.io/github/milestones/progress/pboling/version_gem/1?label=Next%20Version
83
-
84
- <!-- 3️⃣ maintanence & linting -->
85
- [⛳cclim-maint]: https://codeclimate.com/github/pboling/version_gem/maintainability
86
- [⛳cclim-maint-img♻️]: https://api.codeclimate.com/v1/badges/b504d61c4ed1d46aec02/maintainability
87
- [🖇triage-help]: https://www.codetriage.com/pboling/version_gem
88
- [🖇triage-help-img]: https://www.codetriage.com/pboling/version_gem/badges/users.svg
89
- [🏘depfu♻️]: https://depfu.com/github/pboling/version_gem?project_id=35803
90
- [🏘depfu-img♻️]: https://badges.depfu.com/badges/5d8943de6cfdf1ee048ad6d907f3e35b/count.svg
91
- [🚎contributors]: https://github.com/pboling/version_gem/graphs/contributors
92
- [🚎contributors-img]: https://img.shields.io/github/contributors-anon/pboling/version_gem
93
- [🖐style-wf]: https://github.com/pboling/version_gem/actions/workflows/style.yml
94
- [🖐style-wf-img]: https://github.com/pboling/version_gem/actions/workflows/style.yml/badge.svg
95
- [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
96
- [🧮kloc-img]: https://img.shields.io/tokei/lines/github.com/pboling/version_gem
97
-
98
- <!-- 4️⃣ testing -->
99
- [⛳iss-o]: https://github.com/pboling/version_gem/issues
100
- [⛳iss-o-img]: https://img.shields.io/github/issues-raw/pboling/version_gem
101
- [🖇iss-c]: https://github.com/pboling/version_gem/issues?q=is%3Aissue+is%3Aclosed
102
- [🖇iss-c-img]: https://img.shields.io/github/issues-closed-raw/pboling/version_gem
103
- [🏘sup-wf]: https://github.com/pboling/version_gem/actions/workflows/supported.yml
104
- [🏘sup-wf-img]: https://github.com/pboling/version_gem/actions/workflows/supported.yml/badge.svg
105
- [🚎heads-wf]: https://github.com/pboling/version_gem/actions/workflows/heads.yml
106
- [🚎heads-wf-img]: https://github.com/pboling/version_gem/actions/workflows/heads.yml/badge.svg
107
- [🖐uns-wf]: https://github.com/pboling/version_gem/actions/workflows/unsupported.yml
108
- [🖐uns-wf-img]: https://github.com/pboling/version_gem/actions/workflows/unsupported.yml/badge.svg
109
- [🧮mac-wf]: https://github.com/pboling/version_gem/actions/workflows/macos.yml
110
- [🧮mac-wf-img]: https://github.com/pboling/version_gem/actions/workflows/macos.yml/badge.svg
111
- [📗win-wf]: https://github.com/pboling/version_gem/actions/workflows/windows.yml
112
- [📗win-wf-img]: https://github.com/pboling/version_gem/actions/workflows/windows.yml/badge.svg
113
-
114
- <!-- 5️⃣ coverage & security -->
115
- [⛳cclim-cov]: https://codeclimate.com/github/pboling/version_gem/test_coverage
116
- [⛳cclim-cov-img♻️]: https://api.codeclimate.com/v1/badges/b504d61c4ed1d46aec02/test_coverage
117
- [🖇codecov-img♻️]: https://codecov.io/gh/pboling/version_gem/branch/main/graph/badge.svg?token=79c3X4vtfO
118
- [🖇codecov]: https://codecov.io/gh/pboling/version_gem
119
- [🏘coveralls]: https://coveralls.io/github/pboling/version_gem?branch=main
120
- [🏘coveralls-img]: https://coveralls.io/repos/github/pboling/version_gem/badge.svg?branch=main
121
- [🚎sec-pol]: https://github.com/pboling/version_gem/blob/main/SECURITY.md
122
- [🚎sec-pol-img]: https://img.shields.io/badge/security-policy-brightgreen.svg?style=flat
123
- [🖐codeQL]: https://github.com/pboling/version_gem/security/code-scanning
124
- [🖐codeQL-img]: https://github.com/pboling/version_gem/actions/workflows/codeql-analysis.yml/badge.svg
125
- [🧮cov-wf]: https://github.com/pboling/version_gem/actions/workflows/coverage.yml
126
- [🧮cov-wf-img]: https://github.com/pboling/version_gem/actions/workflows/coverage.yml/badge.svg
127
-
128
- <!-- 6️⃣ resources -->
129
- [⛳gh-discussions]: https://github.com/pboling/version_gem/discussions
130
- [⛳gh-discussions-img]: https://img.shields.io/github/discussions/pboling/version_gem
131
- [🖇codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
132
- [🖇codementor-img]: https://cdn.codementor.io/badges/get_help_github.svg
133
- [🏘chat]: https://gitter.im/pboling/version_gem
134
- [🏘chat-img]: https://img.shields.io/gitter/room/pboling/version_gem.svg
135
- [🚎blog]: http://www.railsbling.com/tags/version_gem/
136
- [🚎blog-img]: https://img.shields.io/badge/blog-railsbling-brightgreen.svg?style=flat
137
- [🖐wiki]: https://github.com/pboling/version_gem/wiki
138
- [🖐wiki-img]: https://img.shields.io/badge/wiki-examples-brightgreen.svg?style=flat
139
-
140
- <!-- 7️⃣ spread 💖 -->
141
- [⛳liberapay-img]: https://img.shields.io/liberapay/patrons/pboling.svg?logo=liberapay
142
- [⛳liberapay]: https://liberapay.com/pboling/donate
143
- [🖇sponsor-img]: https://img.shields.io/badge/sponsor-pboling.svg?style=social&logo=github
144
- [🖇sponsor]: https://github.com/sponsors/pboling
145
- [🏘tweet-img]: https://img.shields.io/twitter/follow/galtzo.svg?style=social&label=Follow
146
- [🏘tweet]: http://twitter.com/galtzo
68
+ ## 💡 Info you can shake a stick at
147
69
 
148
- <!-- Maintainer Contact Links -->
149
- [railsbling]: http://www.railsbling.com
150
- [peterboling]: http://www.peterboling.com
151
- [aboutme]: https://about.me/peter.boling
152
- [angelme]: https://angel.co/peter-boling
153
- [coderme]:http://coderwall.com/pboling
70
+ | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
71
+ |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
72
+ | Works with JRuby | [![JRuby 9.1 Compat][💎jruby-9.1i]][🚎10-j-wf] [![JRuby 9.2 Compat][💎jruby-9.2i]][🚎10-j-wf] [![JRuby 9.3 Compat][💎jruby-9.3i]][🚎10-j-wf] [![JRuby 9.4 Compat][💎jruby-9.4i]][🚎10-j-wf] [![JRuby 10.0 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] |
73
+ | Works with Truffle Ruby | [![Truffle Ruby 22.3 Compat][💎truby-22.3i]][🚎9-t-wf] [![Truffle Ruby 23.0 Compat][💎truby-23.0i]][🚎9-t-wf] [![Truffle Ruby 23.1 Compat][💎truby-23.1i]][🚎9-t-wf] [![Truffle Ruby 24.1 Compat][💎truby-c-i]][🚎11-c-wf] [![Truffle Ruby HEAD Compat][💎truby-headi]][🚎3-hd-wf] |
74
+ | Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎4-lg-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎6-s-wf] [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎6-s-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎6-s-wf] [![Ruby 3.4 Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf] |
75
+ | Works with MRI Ruby 2 | [![Ruby 2.3 Compat][💎ruby-2.3i]][🚎1-an-wf] [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎1-an-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎1-an-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎7-us-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎7-us-wf] |
76
+ | Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on Github.com][📜src-gh-img]][📜src-gh] [![The best SHA: dQw4w9WgXcQ!][🧮kloc-img]][🧮kloc] |
77
+ | Documentation | [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![HEAD on RubyDoc.info][📜docs-head-rd-img]][🚎yard-head] [![BDFL Blog][🚂bdfl-blog-img]][🚂bdfl-blog] [![Wiki][📜wiki-img]][📜wiki] |
78
+ | Compliance | [![License: MIT][📄license-img]][📄license-ref] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] [![Gitmoji Commits][📌gitmoji-img]][📌gitmoji] |
79
+ | Expert 1:1 Support | [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] `or` [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
80
+ | Enterprise Support | [![Get help from me on Tidelift][🏙️entsup-tidelift-img]][🏙️entsup-tidelift]<br/>💡Subscribe for support guarantees covering _all_ FLOSS dependencies!<br/>💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar]!<br/>💡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! |
81
+ | Comrade BDFL 🎖️ | [![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 BDFL][🚂bdfl-contact-img]][🚂bdfl-contact] [![My technical writing][💖💁🏼‍♂️devto-img]][💖💁🏼‍♂️devto] |
82
+ | `...` 💖 | [![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] |
154
83
 
155
- ## Installation
84
+ ## Installation
156
85
 
157
86
  Install the gem and add to the application's Gemfile by executing:
158
87
 
@@ -162,7 +91,37 @@ If bundler is not being used to manage dependencies, install the gem by executin
162
91
 
163
92
  $ gem install version_gem
164
93
 
165
- ## Usage
94
+ ### 🔒 Secure Installation
95
+
96
+ `version_gem` is cryptographically signed, and with verifiable [SHA-256 and SHA-512][💎SHA_checksums] checksums by
97
+ [stone_checksums][💎stone_checksums]. Be sure the gem you install hasn’t been tampered with
98
+ by following the instructions below.
99
+
100
+ Add my public key (if you haven’t already, expires 2045-04-29) as a trusted certificate:
101
+
102
+ ```shell
103
+ gem cert --add <(curl -Ls https://raw.github.com/oauth-xx/version_gem/main/certs/pboling.pem)
104
+ ```
105
+
106
+ You only need to do that once. Then proceed to install with:
107
+
108
+ ```shell
109
+ gem install version_gem -P HighSecurity
110
+ ```
111
+
112
+ The `HighSecurity` trust profile will verify signed gems, and not allow the installation of unsigned dependencies.
113
+
114
+ If you want to up your security game full-time:
115
+
116
+ ```shell
117
+ bundle config set --global trust-policy MediumSecurity
118
+ ```
119
+
120
+ `MediumSecurity` instead of `HighSecurity` is necessary if not all the gems you use are signed.
121
+
122
+ NOTE: Be prepared to track down certs for signed gems and add them the same way you added mine.
123
+
124
+ ## 🔧 Basic Usage
166
125
 
167
126
  In the standard `bundle gem my_lib` code you get the following in `lib/my_lib/version.rb`:
168
127
 
@@ -209,153 +168,488 @@ MyLib::Version.to_a # => [0, 1, 0]
209
168
  MyLib::Version.to_h # => { major: 0, minor: 1, patch: 0, pre: "" }
210
169
  ```
211
170
 
212
- ### Side benefit
171
+ ### Side benefit #1
213
172
 
214
- Your `version.rb` file now abides the Ruby convention of directory / path matching the namespace / class!
173
+ You can reference the version from your gemspec, keeping the version string DRY,
174
+ *and* still get accurate code coverage!
215
175
 
216
- ### Caveat
176
+ ```ruby
177
+ # Get the GEMFILE_VERSION without *require* "my_gem/version", for code coverage accuracy
178
+ # See: https://github.com/simplecov-ruby/simplecov/issues/557#issuecomment-2630782358
179
+ # Kernel.load because load is overloaded in RubyGems during gemspec evaluation
180
+ Kernel.load("lib/my_gem/version.rb")
181
+ gem_version = MyGem::Version::VERSION
182
+ MyGem::Version.send(:remove_const, :VERSION)
183
+
184
+ Gem::Specification.new do |spec|
185
+ # ...
186
+ spec.version = gem_version
187
+ end
188
+ ```
217
189
 
218
- This design keeps your `version.rb` file compatible with the way `gemspec` files use them.
219
- This means that the introspection is _not_ available within the gemspec.
220
- The enhancement from this gem is only available at runtime.
190
+ ### Side benefit #2
221
191
 
222
- ### RSpec Matchers
192
+ Your `version.rb` file now abides the Ruby convention of directory / path matching the namespace / class!
193
+
194
+ ## Epoch Usage (Epoch Semantic Versioning, as of version 1.1.7)
195
+
196
+ In the standard `bundle gem my_lib` code you get the following in `lib/my_lib/version.rb`:
223
197
 
224
- In `spec_helper.rb`:
225
198
  ```ruby
226
- require 'version_gem/rspec'
199
+ module MyLib
200
+ VERSION = "0.1.0"
201
+ end
227
202
  ```
228
203
 
229
- Then you can write a test like:
204
+ Change it to a nested `Version` namespace (the one implied by the path => namespace convention):
230
205
 
231
206
  ```ruby
232
- RSpec.describe MyLib::Version do
233
- it_behaves_like 'a Version module', described_class
207
+ module MyLib
208
+ module Version
209
+ VERSION = "0.1.0"
210
+ end
234
211
  end
212
+ ```
235
213
 
236
- # Or, if you want to write your own, here is the a la carte menu:
237
- RSpec.describe MyLib::Version do
238
- it "is a Version module" do
239
- expect(described_class).is_a?(Module)
240
- expect(described_class).to have_version_constant
241
- expect(described_class).to have_version_as_string
242
- expect(described_class.to_s).to be_a(String)
243
- expect(described_class).to have_major_as_integer
244
- expect(described_class).to have_minor_as_integer
245
- expect(described_class).to have_patch_as_integer
246
- expect(described_class).to have_pre_as_nil_or_string
247
- expect(described_class.to_h.keys).to match_array(%i[major minor patch pre])
248
- expect(described_class.to_a).to be_a(Array)
249
- end
214
+ The Epoch and Major versions are derived from the formula:
215
+
216
+ ```
217
+ {EPOCH * 1000 + MAJOR}.MINOR.PATCH
218
+ ```
219
+
220
+ This will start your library with the following version segments:
221
+
222
+ * `epoch = 0`
223
+ * `major = 0`
224
+ * `minor = 1`
225
+ * `patch = 0`
226
+ * `pre = nil`
227
+
228
+ And the segments are defined as:
229
+
230
+ ```
231
+ EPOCH: Increment when you make significant or groundbreaking changes.
232
+ MAJOR: Increment when you make minor incompatible API changes.
233
+ MINOR: Increment when you add functionality in a backwards-compatible manner.
234
+ PATCH: Increment when you make backwards-compatible bug fixes.
235
+ ```
236
+
237
+ Therefore, if you set your version number to:
238
+
239
+ ```ruby
240
+ VERSION = "27016.42.86-pre.7"
241
+ ```
242
+
243
+ You will get the following version segments:
244
+
245
+ ```
246
+ {
247
+ epoch: 27,
248
+ major: 16,
249
+ minor: 42,
250
+ patch: 86,
251
+ pre: "pre-7",
252
+ }
253
+ ```
254
+
255
+ Now add the following near the top of the file the manages requiring external libraries.
256
+ Using the same example of `bundle gem my_lib`, this would be `lib/my_lib.rb`.
257
+
258
+ ```ruby
259
+ require "version_gem"
260
+ ```
261
+
262
+ Then, add the following wherever you want in the same file (recommend the bottom).
263
+
264
+ ```ruby
265
+ MyLib::Version.class_eval do
266
+ extend VersionGem::Epoch
250
267
  end
251
268
  ```
252
269
 
253
- ## Development
270
+ And now you have some version introspection methods available:
271
+
272
+ ```ruby
273
+ MyLib::Version.to_s # => "1024.3.8"
274
+ MyLib::Version.epoch # => 1
275
+ MyLib::Version.major # => 24
276
+ MyLib::Version.minor # => 3
277
+ MyLib::Version.patch # => 8
278
+ MyLib::Version.pre # => ""
279
+ MyLib::Version.to_a # => [1, 24, 3, 8]
280
+ MyLib::Version.to_h # => { epoch: 1, major: 24, minor: 3, patch: 8, pre: "" }
281
+ ```
282
+
283
+ ### Usage with Zeitwerk
254
284
 
255
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
285
+ The pattern of `version.rb` breaking the ruby convention of directory / path matching the namespace / class
286
+ is so entrenched that the `zeitwerk` library has a special carve-out for it. 🥺
287
+ RubyGems using this "bad is actually good" pattern are encouraged to use `Zeitwerk.for_gem`.
256
288
 
257
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
289
+ **Do not do that ^** if you use this gem.
258
290
 
259
- ## Contributing
291
+ #### Simple Zeitwerk Example
260
292
 
261
- See [CONTRIBUTING.md][contributing]
293
+ Create a gem like this (keeping with the `MyLib` theme):
262
294
 
263
- ## Contributors
295
+ ```shell
296
+ bundle gem my_lib
297
+ ```
264
298
 
265
- [![Contributors](https://contrib.rocks/image?repo=pboling/version_gem)]("https://github.com/pboling/version_gem/graphs/contributors")
299
+ Then following the usage instructions above, you edit your primary namespace file @ `lib/my_lib.rb`,
300
+ but inject the Zeitwerk loader.
266
301
 
267
- Made with [contributors-img](https://contrib.rocks).
302
+ ```ruby
303
+ # frozen_string_literal: true
268
304
 
269
- ## License
305
+ require_relative "my_lib/version"
270
306
 
271
- The gem is available as open source under the terms of
272
- the [MIT License][license] [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)][license-ref].
273
- See [LICENSE][license] for the official [Copyright Notice][copyright-notice-explainer].
307
+ module MyLib
308
+ class Error < StandardError; end
309
+ # Your code goes here...
310
+ end
274
311
 
275
- * Copyright (c) 2022 [Peter H. Boling][peterboling] of [Rails Bling][railsbling]
312
+ loader = Zeitwerk::Loader.new
313
+ loader.tag = File.basename(__FILE__, ".rb")
314
+ loader.push_dir("lib/my_lib", namespace: MyLib)
315
+ loader.setup # ready!
316
+ loader.eager_load(force: true) # optional!
276
317
 
277
- ## Code of Conduct
318
+ MyLib::Version.class_eval do
319
+ extend VersionGem::Basic
320
+ end
321
+ ```
278
322
 
279
- Everyone interacting in the VersionGem project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/pboling/version_gem/blob/main/CODE_OF_CONDUCT.md).
323
+ #### Complex Zeitwerk Example
280
324
 
281
- ## Versioning
325
+ Maybe you would like to contribute one?
282
326
 
283
- This library aims to adhere to [Semantic Versioning 2.0.0][semver]. Violations of this scheme should be reported as
284
- bugs. Specifically, if a minor or patch version is released that breaks backward compatibility, a new version should be
285
- immediately released that restores compatibility. Breaking changes to the public API will only be introduced with new
286
- major versions.
327
+ #### Query Ruby Version (as of version 1.1.2)
287
328
 
288
- As a result of this policy, you can (and should) specify a dependency on this gem using
289
- the [Pessimistic Version Constraint][pvc] with two digits of precision.
329
+ In Continuous Integration environments for libraries that run against many versions of Ruby,
330
+ I often need to configure things discretely per Ruby version, and doing so forced me to repeat
331
+ a significant amount of boilerplate code across each project.
290
332
 
291
- For example:
333
+ Thus `VersionGem::Ruby` was born. It has the two optimized methods I always need:
334
+
335
+ ```ruby
336
+ engine = "ruby"
337
+ version = "2.7.7"
338
+ gte_minimum_version?(version, engine) # Is the current version of Ruby greater than or equal to some minimum?
339
+
340
+ major = 3
341
+ minor = 2
342
+ actual_minor_version?(major, minor, engine) # Is the current version of Ruby precisely a specific minor version of Ruby?
343
+ ```
344
+
345
+ `Version::Ruby` is *not loaded* by default. If you want to use it, you must require it as:
346
+ ```ruby
347
+ require "version_gem/ruby"
348
+ ```
349
+
350
+ Normally I do this in my `spec/spec_helper.rb`, and/or `.simplecov` files.
351
+ Occasionally in my `Rakefile`.
352
+
353
+ ### Caveat
354
+
355
+ This design keeps your `version.rb` file compatible with the way `gemspec` files use them.
356
+ This means that the introspection is _not_ available within the gemspec.
357
+ The enhancement from this gem is only available at runtime.
358
+
359
+ ### RSpec Matchers
292
360
 
361
+ In `spec_helper.rb`:
293
362
  ```ruby
294
- spec.add_dependency "version_gem", "~> 1.1"
363
+ require "version_gem/rspec"
295
364
  ```
296
365
 
297
- ## Security
366
+ Then you can write a test like:
367
+
368
+ ```ruby
369
+ RSpec.describe(MyLib::Version) do
370
+ it_behaves_like "a Version module", described_class
371
+ end
298
372
 
299
- See [SECURITY.md](https://github.com/pboling/version_gem/blob/main/SECURITY.md).
373
+ # Or, if you want to write your own, here is the á la carte menu:
374
+ RSpec.describe(MyLib::Version) do
375
+ it "is a Version module" do
376
+ expect(described_class).is_a?(Module)
377
+ expect(described_class).to(have_version_constant)
378
+ expect(described_class).to(have_version_as_string)
379
+ expect(described_class.to_s).to(be_a(String))
380
+ expect(described_class).to(have_major_as_integer)
381
+ expect(described_class).to(have_epoch_as_integer)
382
+ expect(described_class).to(have_minor_as_integer)
383
+ expect(described_class).to(have_patch_as_integer)
384
+ expect(described_class).to(have_pre_as_nil_or_string)
385
+ # This would be %i[epoch major minor patch pre] for epoch version schemes
386
+ expect(described_class.to_h.keys).to(match_array(%i[major minor patch pre]))
387
+ expect(described_class.to_a).to(be_a(Array))
388
+ end
389
+ end
390
+ ```
300
391
 
301
- [copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
392
+ ## 🔐 Security
302
393
 
303
- [gh_discussions]: https://github.com/pboling/version_gem/discussions
394
+ See [SECURITY.md][🔐security].
304
395
 
305
- [conduct]: https://github.com/pboling/version_gem/blob/main/CODE_OF_CONDUCT.md
396
+ ## 🤝 Contributing
306
397
 
307
- [contributing]: https://github.com/pboling/version_gem/blob/main/CONTRIBUTING.md
398
+ If you need some ideas of where to help, you could work on adding more code coverage,
399
+ or if it is already 💯 (see [below](#code-coverage)) then check [issues][🤝issues], or [PRs][🤝pulls],
400
+ or use the gem and think about how it could be better.
308
401
 
309
- [security]: https://github.com/pboling/version_gem/blob/main/SECURITY.md
402
+ We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
310
403
 
311
- [license]: https://github.com/pboling/version_gem/blob/main/LICENSE.txt
404
+ See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
312
405
 
313
- [license-ref]: https://opensource.org/licenses/MIT
406
+ ### Code Coverage
314
407
 
315
- [semver]: http://semver.org/
408
+ [![Coverage Graph][🔑codecov-g♻️]][🔑codecov]
316
409
 
317
- [pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint
410
+ ### 🪇 Code of Conduct
318
411
 
319
- [railsbling]: http://www.railsbling.com
412
+ Everyone interacting in this project's codebases, issue trackers,
413
+ chat rooms and mailing lists is expected to follow the [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct].
320
414
 
321
- [peterboling]: http://www.peterboling.com
415
+ ## 🌈 Contributors
322
416
 
323
- [aboutme]: https://about.me/peter.boling
417
+ [![Contributors][🖐contributors-img]][🖐contributors]
324
418
 
325
- [angelme]: https://angel.co/peter-boling
419
+ Made with [contributors-img][🖐contrib-rocks].
326
420
 
327
- [coderme]:http://coderwall.com/pboling
421
+ Also see GitLab Contributors: [https://gitlab.com/oauth-xx/version_gem/-/graphs/main][🚎contributors-gl]
328
422
 
329
- [followme-img]: https://img.shields.io/twitter/follow/galtzo.svg?style=social&label=Follow
423
+ ## ⭐️ Star History
330
424
 
331
- [tweetme]: http://twitter.com/galtzo
425
+ <a href="https://star-history.com/#oauth-xx/version_gem&Date">
426
+ <picture>
427
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=oauth-xx/version_gem&type=Date&theme=dark" />
428
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=oauth-xx/version_gem&type=Date" />
429
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=oauth-xx/version_gem&type=Date" />
430
+ </picture>
431
+ </a>
332
432
 
333
- [politicme]: https://nationalprogressiveparty.org
433
+ ## 📌 Versioning
334
434
 
335
- [documentation]: https://rubydoc.info/github/pboling/version_gem/main
435
+ This Library adheres to [![Epoch Semantic Versioning][📌semver-img]][📌semver].
436
+ Violations of this scheme should be reported as bugs.
437
+ Specifically, if a minor or patch version is released that breaks backward compatibility,
438
+ a new version should be immediately released that restores compatibility.
439
+ Breaking changes to the public API, including dropping a supported platform (i.e. minor version of Ruby),
440
+ will only be introduced with new major versions.
441
+ Epoch will only be bumped if there are dramatic changes, and that is not expected to happen ever.
336
442
 
337
- [source]: https://github.com/pboling/version_gem/
443
+ ### 📌 Is "Platform Support" part of the public API?
338
444
 
339
- [actions]: https://github.com/pboling/version_gem/actions
445
+ Yes. But I'm obligated to include notes...
340
446
 
341
- [issues]: https://github.com/pboling/version_gem/issues
447
+ SemVer should, but doesn't explicitly, say that dropping support for specific Platforms
448
+ is a *breaking change* to an API.
449
+ It is obvious to many, but not all, and since the spec is silent, the bike shedding is endless.
342
450
 
343
- [climate_maintainability]: https://codeclimate.com/github/pboling/version_gem/maintainability
451
+ > dropping support for a platform is both obviously and objectively a breaking change
344
452
 
345
- [climate_coverage]: https://codeclimate.com/github/pboling/version_gem/test_coverage
453
+ - Jordan Harband (@ljharb, maintainer of SemVer) [in SemVer issue 716][📌semver-breaking]
346
454
 
347
- [codecov_coverage]: https://codecov.io/gh/pboling/version_gem
455
+ To get a better understanding of how SemVer is intended to work over a project's lifetime,
456
+ read this article from the creator of SemVer:
348
457
 
349
- [code_triage]: https://www.codetriage.com/pboling/version_gem
458
+ - ["Major Version Numbers are Not Sacred"][📌major-versions-not-sacred]
350
459
 
351
- [blogpage]: http://www.railsbling.com/tags/version_gem/
460
+ As a result of this policy, and the interpretive lens used by the maintainer,
461
+ you can (and should) specify a dependency on these libraries using
462
+ the [Pessimistic Version Constraint][📌pvc] with two digits of precision.
352
463
 
353
- [rubygems]: https://rubygems.org/gems/version_gem
464
+ For example:
354
465
 
355
- [chat]: https://gitter.im/pboling/version_gem?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
466
+ ```ruby
467
+ spec.add_dependency("version_gem", "~> 1.1")
468
+ ```
356
469
 
357
- [maintenancee_policy]: https://guides.rubyonrails.org/maintenance_policy.html#security-issues
470
+ See [CHANGELOG.md][📌changelog] for list of releases.
358
471
 
359
- [liberapay_donate]: https://liberapay.com/pboling/donate
472
+ ## 📄 License
360
473
 
361
- [gh_sponsors]: https://github.com/sponsors/pboling
474
+ The gem is available as open source under the terms of
475
+ the [MIT License][📄license] [![License: MIT][📄license-img]][📄license-ref].
476
+ See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright-notice-explainer].
477
+
478
+ ### © Copyright
479
+
480
+ <p>
481
+ Copyright (c) 2022 - 2025 Peter H. Boling,
482
+ <a href="https://railsbling.com">
483
+ RailsBling.com
484
+ <picture>
485
+ <img alt="Rails Bling" height="20" src="https://railsbling.com/images/logos/RailsBling-TrainLogo.svg" />
486
+ </picture>
487
+ </a>
488
+ </p>
489
+
490
+ ## 🤑 One more thing
491
+
492
+ You made it to the bottom of the page,
493
+ so perhaps you'll indulge me for another 20 seconds.
494
+ I maintain many dozens of gems, including this one,
495
+ because I want Ruby to be a great place for people to solve problems, big and small.
496
+ Please consider supporting my efforts via the giant yellow link below,
497
+ or one of the others at the head of this README.
498
+
499
+ [![Buy me a latte][🖇buyme-img]][🖇buyme]
500
+
501
+ [✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
502
+ [🏘chat]: https://gitter.im/oauth-xx/version_gem
503
+ [🏘chat-img]: https://img.shields.io/gitter/room/oauth-xx/version_gem.svg
504
+ [⛳️gem-namespace]: https://github.com/oauth-xx/version_gem/blob/main/lib/version_gem.rb
505
+ [⛳️namespace-img]: https://img.shields.io/badge/namespace-VersionGem-brightgreen.svg?style=flat&logo=ruby&logoColor=white
506
+ [⛳️gem-name]: https://rubygems.org/gems/version_gem
507
+ [⛳️name-img]: https://img.shields.io/badge/name-version__gem-brightgreen.svg?style=flat&logo=rubygems&logoColor=red
508
+ [🚂bdfl-blog]: http://www.railsbling.com/tags/version_gem
509
+ [🚂bdfl-blog-img]: https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange
510
+ [🚂bdfl-contact]: http://www.railsbling.com/contact
511
+ [🚂bdfl-contact-img]: https://img.shields.io/badge/Contact-BDFL-0093D0.svg?style=flat&logo=rubyonrails&logoColor=red
512
+ [💖🖇linkedin]: http://www.linkedin.com/in/peterboling
513
+ [💖🖇linkedin-img]: https://img.shields.io/badge/PeterBoling-LinkedIn-0B66C2?style=flat&logo=newjapanprowrestling
514
+ [💖✌️wellfound]: https://angel.co/u/peter-boling
515
+ [💖✌️wellfound-img]: https://img.shields.io/badge/peter--boling-orange?style=flat&logo=wellfound
516
+ [💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling
517
+ [💖💲crunchbase-img]: https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase
518
+ [💖🐘ruby-mast]: https://ruby.social/@galtzo
519
+ [💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https%3A%2F%2Fruby.social&style=flat&logo=mastodon&label=Ruby%20%40galtzo
520
+ [💖🦋bluesky]: https://bsky.app/profile/galtzo.com
521
+ [💖🦋bluesky-img]: https://img.shields.io/badge/@galtzo.com-0285FF?style=flat&logo=bluesky&logoColor=white
522
+ [💖🌳linktree]: https://linktr.ee/galtzo
523
+ [💖🌳linktree-img]: https://img.shields.io/badge/galtzo-purple?style=flat&logo=linktree
524
+ [💖💁🏼‍♂️devto]: https://dev.to/galtzo
525
+ [💖💁🏼‍♂️devto-img]: https://img.shields.io/badge/dev.to-0A0A0A?style=flat&logo=devdotto&logoColor=white
526
+ [💖💁🏼‍♂️aboutme]: https://about.me/peter.boling
527
+ [💖💁🏼‍♂️aboutme-img]: https://img.shields.io/badge/about.me-0A0A0A?style=flat&logo=aboutme&logoColor=white
528
+ [💖🧊berg]: https://codeberg.org/pboling
529
+ [💖🐙hub]: https://github.org/pboling
530
+ [💖🛖hut]: https://sr.ht/~galtzo/
531
+ [💖🧪lab]: https://gitlab.com/pboling
532
+ [👨🏼‍🏫expsup-upwork]: https://www.upwork.com/freelancers/~014942e9b056abdf86?mp_source=share
533
+ [👨🏼‍🏫expsup-upwork-img]: https://img.shields.io/badge/UpWork-13544E?style=for-the-badge&logo=Upwork&logoColor=white
534
+ [👨🏼‍🏫expsup-codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
535
+ [👨🏼‍🏫expsup-codementor-img]: https://img.shields.io/badge/CodeMentor-Get_Help-1abc9c?style=for-the-badge&logo=CodeMentor&logoColor=white
536
+ [🏙️entsup-tidelift]: https://tidelift.com/subscription
537
+ [🏙️entsup-tidelift-img]: https://img.shields.io/badge/Tidelift_and_Sonar-Enterprise_Support-FD3456?style=for-the-badge&logo=sonar&logoColor=white
538
+ [🏙️entsup-tidelift-sonar]: https://blog.tidelift.com/tidelift-joins-sonar
539
+ [💁🏼‍♂️peterboling]: http://www.peterboling.com
540
+ [🚂railsbling]: http://www.railsbling.com
541
+ [📜src-gl-img]: https://img.shields.io/badge/GitLab-FBA326?style=for-the-badge&logo=Gitlab&logoColor=orange
542
+ [📜src-gl]: https://gitlab.com/oauth-xx/version_gem/
543
+ [📜src-gh-img]: https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=Github&logoColor=green
544
+ [📜src-gh]: https://github.com/oauth-xx/version_gem
545
+ [📜docs-cr-rd-img]: https://img.shields.io/badge/RubyDoc-Current_Release-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
546
+ [📜docs-head-rd-img]: https://img.shields.io/badge/RubyDoc-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
547
+ [📜wiki]: https://gitlab.com/oauth-xx/version_gem/-/wikis/home
548
+ [📜wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=Wiki&logoColor=white
549
+ [👽dl-rank]: https://rubygems.org/gems/version_gem
550
+ [👽dl-ranki]: https://img.shields.io/gem/rd/version_gem.svg
551
+ [👽oss-help]: https://www.codetriage.com/oauth-xx/version_gem
552
+ [👽oss-helpi]: https://www.codetriage.com/oauth-xx/version_gem/badges/users.svg
553
+ [👽version]: https://rubygems.org/gems/version_gem
554
+ [👽versioni]: https://img.shields.io/gem/v/version_gem.svg
555
+ [🔑cc-mnt]: https://qlty.sh/gh/oauth-xx/projects/version_gem
556
+ [🔑cc-mnti♻️]: https://qlty.sh/badges/19404e90-9168-451a-8dac-882382cb768d/maintainability.svg
557
+ [🔑cc-cov]: https://qlty.sh/gh/oauth-xx/projects/version_gem
558
+ [🔑cc-covi♻️]: https://qlty.sh/badges/19404e90-9168-451a-8dac-882382cb768d/test_coverage.svg
559
+ [🔑codecov]: https://codecov.io/gh/oauth-xx/version_gem
560
+ [🔑codecovi♻️]: https://codecov.io/gh/oauth-xx/version_gem/branch/main/graph/badge.svg?token=cc6UdZCpAL
561
+ [🔑coveralls]: https://coveralls.io/github/oauth-xx/version_gem?branch=main
562
+ [🔑coveralls-img]: https://coveralls.io/repos/github/oauth-xx/version_gem/badge.svg?branch=main
563
+ [🔑depfu]: https://depfu.com/github/oauth-xx/version_gem
564
+ [🔑depfui♻️]: https://badges.depfu.com/badges/6c9b45362951b872127f9e46d39bed76/count.svg
565
+ [🖐codeQL]: https://github.com/oauth-xx/version_gem/security/code-scanning
566
+ [🖐codeQL-img]: https://github.com/oauth-xx/version_gem/actions/workflows/codeql-analysis.yml/badge.svg
567
+ [🚎1-an-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/ancient.yml
568
+ [🚎1-an-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/ancient.yml/badge.svg
569
+ [🚎2-cov-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/coverage.yml
570
+ [🚎2-cov-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/coverage.yml/badge.svg
571
+ [🚎3-hd-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/heads.yml
572
+ [🚎3-hd-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/heads.yml/badge.svg
573
+ [🚎4-lg-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/legacy.yml
574
+ [🚎4-lg-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/legacy.yml/badge.svg
575
+ [🚎5-st-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/style.yml
576
+ [🚎5-st-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/style.yml/badge.svg
577
+ [🚎6-s-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/supported.yml
578
+ [🚎6-s-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/supported.yml/badge.svg
579
+ [🚎7-us-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/unsupported.yml
580
+ [🚎7-us-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/unsupported.yml/badge.svg
581
+ [🚎9-t-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/truffle.yml
582
+ [🚎9-t-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/truffle.yml/badge.svg
583
+ [🚎10-j-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/jruby.yml
584
+ [🚎10-j-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/jruby.yml/badge.svg
585
+ [🚎11-c-wf]: https://github.com/oauth-xx/version_gem/actions/workflows/current.yml
586
+ [🚎11-c-wfi]: https://github.com/oauth-xx/version_gem/actions/workflows/current.yml/badge.svg
587
+ [⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay
588
+ [⛳liberapay]: https://liberapay.com/pboling/donate
589
+ [🖇sponsor-img]: https://img.shields.io/badge/Sponsor_Me!-pboling.svg?style=social&logo=github
590
+ [🖇sponsor]: https://github.com/sponsors/pboling
591
+ [🖇polar-img]: https://img.shields.io/badge/polar-donate-yellow.svg
592
+ [🖇polar]: https://polar.sh/pboling
593
+ [🖇kofi-img]: https://img.shields.io/badge/a_more_different_coffee-✓-yellow.svg
594
+ [🖇kofi]: https://ko-fi.com/O5O86SNP4
595
+ [🖇patreon-img]: https://img.shields.io/badge/patreon-donate-yellow.svg
596
+ [🖇patreon]: https://patreon.com/galtzo
597
+ [🖇buyme-img]: https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20latte&emoji=&slug=pboling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff
598
+ [🖇buyme]: https://www.buymeacoffee.com/pboling
599
+ [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-✓-yellow.svg?style=flat
600
+ [💎ruby-2.3i]: https://img.shields.io/badge/Ruby-2.3-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
601
+ [💎ruby-2.4i]: https://img.shields.io/badge/Ruby-2.4-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
602
+ [💎ruby-2.5i]: https://img.shields.io/badge/Ruby-2.5-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
603
+ [💎ruby-2.6i]: https://img.shields.io/badge/Ruby-2.6-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
604
+ [💎ruby-2.7i]: https://img.shields.io/badge/Ruby-2.7-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
605
+ [💎ruby-3.0i]: https://img.shields.io/badge/Ruby-3.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white
606
+ [💎ruby-3.1i]: https://img.shields.io/badge/Ruby-3.1-CC342D?style=for-the-badge&logo=ruby&logoColor=white
607
+ [💎ruby-3.2i]: https://img.shields.io/badge/Ruby-3.2-CC342D?style=for-the-badge&logo=ruby&logoColor=white
608
+ [💎ruby-3.3i]: https://img.shields.io/badge/Ruby-3.3-CC342D?style=for-the-badge&logo=ruby&logoColor=white
609
+ [💎ruby-c-i]: https://img.shields.io/badge/Ruby-current-CC342D?style=for-the-badge&logo=ruby&logoColor=green
610
+ [💎ruby-headi]: https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue
611
+ [💎truby-22.3i]: https://img.shields.io/badge/Truffle_Ruby-22.3-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
612
+ [💎truby-23.0i]: https://img.shields.io/badge/Truffle_Ruby-23.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
613
+ [💎truby-23.1i]: https://img.shields.io/badge/Truffle_Ruby-23.1-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
614
+ [💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green
615
+ [💎truby-headi]: https://img.shields.io/badge/Truffle_Ruby-HEAD-34BCB1?style=for-the-badge&logo=ruby&logoColor=blue
616
+ [💎jruby-9.1i]: https://img.shields.io/badge/JRuby-9.1-FBE742?style=for-the-badge&logo=ruby&logoColor=red
617
+ [💎jruby-9.2i]: https://img.shields.io/badge/JRuby-9.2-FBE742?style=for-the-badge&logo=ruby&logoColor=red
618
+ [💎jruby-9.3i]: https://img.shields.io/badge/JRuby-9.3-FBE742?style=for-the-badge&logo=ruby&logoColor=red
619
+ [💎jruby-9.4i]: https://img.shields.io/badge/JRuby-9.4-FBE742?style=for-the-badge&logo=ruby&logoColor=red
620
+ [💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green
621
+ [💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue
622
+ [🤝issues]: https://github.com/oauth-xx/version_gem/issues
623
+ [🤝pulls]: https://github.com/oauth-xx/version_gem/pulls
624
+ [🤝contributing]: CONTRIBUTING.md
625
+ [🔑codecov-g♻️]: https://codecov.io/gh/oauth-xx/version_gem/graphs/tree.svg?token=cc6UdZCpAL
626
+ [🖐contrib-rocks]: https://contrib.rocks
627
+ [🖐contributors]: https://github.com/oauth-xx/version_gem/graphs/contributors
628
+ [🖐contributors-img]: https://contrib.rocks/image?repo=oauth-xx/version_gem
629
+ [🚎contributors-gl]: https://gitlab.com/oauth-xx/version_gem/-/graphs/main
630
+ [🪇conduct]: CODE_OF_CONDUCT.md
631
+ [🪇conduct-img]: https://img.shields.io/badge/Contributor_Covenant-2.1-4baaaa.svg
632
+ [📌pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint
633
+ [📌semver]: https://antfu.me/posts/epoch-semver
634
+ [📌semver-img]: https://img.shields.io/badge/epoch-semver-FFDD67.svg?style=flat
635
+ [📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139
636
+ [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html
637
+ [📌changelog]: CHANGELOG.md
638
+ [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
639
+ [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-FFDD67.svg?style=flat
640
+ [📌gitmoji]:https://gitmoji.dev
641
+ [📌gitmoji-img]:https://img.shields.io/badge/gitmoji-%20😜%20😍-FFDD67.svg?style=flat-square
642
+ [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
643
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.117-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
644
+ [🔐security]: SECURITY.md
645
+ [🔐security-img]: https://img.shields.io/badge/security-policy-brightgreen.svg?style=flat
646
+ [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
647
+ [📄license]: LICENSE.txt
648
+ [📄license-ref]: https://opensource.org/licenses/MIT
649
+ [📄license-img]: https://img.shields.io/badge/License-MIT-green.svg
650
+ [📄ilo-declaration]: https://www.ilo.org/declaration/lang--en/index.htm
651
+ [📄ilo-declaration-img]: https://img.shields.io/badge/ILO_Fundamental_Principles-✓-brightgreen.svg?style=flat
652
+ [🚎yard-current]: http://rubydoc.info/gems/version_gem
653
+ [🚎yard-head]: https://rubydoc.info/github/oauth-xx/version_gem/main
654
+ [💎stone_checksums]: https://github.com/pboling/stone_checksums
655
+ [💎SHA_checksums]: https://gitlab.com/oauth-xx/version_gem/-/tree/main/checksums