version_gem-1.1.12/0000755000004100000410000000000015214007330014134 5ustar www-datawww-dataversion_gem-1.1.12/certs/0000755000004100000410000000000015214007330015254 5ustar www-datawww-dataversion_gem-1.1.12/certs/pboling.pem0000644000004100000410000000312715214007330017414 0ustar www-datawww-data-----BEGIN CERTIFICATE----- MIIEgDCCAuigAwIBAgIBATANBgkqhkiG9w0BAQsFADBDMRUwEwYDVQQDDAxwZXRl ci5ib2xpbmcxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkW A2NvbTAeFw0yNTA1MDQxNTMzMDlaFw00NTA0MjkxNTMzMDlaMEMxFTATBgNVBAMM DHBldGVyLmJvbGluZzEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy LGQBGRYDY29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAruUoo0WA uoNuq6puKWYeRYiZekz/nsDeK5x/0IEirzcCEvaHr3Bmz7rjo1I6On3gGKmiZs61 LRmQ3oxy77ydmkGTXBjruJB+pQEn7UfLSgQ0xa1/X3kdBZt6RmabFlBxnHkoaGY5 mZuZ5+Z7walmv6sFD9ajhzj+oIgwWfnEHkXYTR8I6VLN7MRRKGMPoZ/yvOmxb2DN coEEHWKO9CvgYpW7asIihl/9GMpKiRkcYPm9dGQzZc6uTwom1COfW0+ZOFrDVBuV FMQRPswZcY4Wlq0uEBLPU7hxnCL9nKK6Y9IhdDcz1mY6HZ91WImNslOSI0S8hRpj yGOWxQIhBT3fqCBlRIqFQBudrnD9jSNpSGsFvbEijd5ns7Z9ZMehXkXDycpGAUj1 to/5cuTWWw1JqUWrKJYoifnVhtE1o1DZ+LkPtWxHtz5kjDG/zR3MG0Ula0UOavlD qbnbcXPBnwXtTFeZ3C+yrWpE4pGnl3yGkZj9SMTlo9qnTMiPmuWKQDatAgMBAAGj fzB9MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQE8uWvNbPVNRXZ HlgPbc2PCzC4bjAhBgNVHREEGjAYgRZwZXRlci5ib2xpbmdAZ21haWwuY29tMCEG A1UdEgQaMBiBFnBldGVyLmJvbGluZ0BnbWFpbC5jb20wDQYJKoZIhvcNAQELBQAD ggGBAJbnUwfJQFPkBgH9cL7hoBfRtmWiCvdqdjeTmi04u8zVNCUox0A4gT982DE9 wmuN12LpdajxZONqbXuzZvc+nb0StFwmFYZG6iDwaf4BPywm2e/Vmq0YG45vZXGR L8yMDSK1cQXjmA+ZBKOHKWavxP6Vp7lWvjAhz8RFwqF9GuNIdhv9NpnCAWcMZtpm GUPyIWw/Cw/2wZp74QzZj6Npx+LdXoLTF1HMSJXZ7/pkxLCsB8m4EFVdb/IrW/0k kNSfjtAfBHO8nLGuqQZVH9IBD1i9K6aSs7pT6TW8itXUIlkIUI2tg5YzW6OFfPzq QekSkX3lZfY+HTSp/o+YvKkqWLUV7PQ7xh1ZYDtocpaHwgxe/j3bBqHE+CUPH2vA 0V/FwdTRWcwsjVoOJTrYcff8pBZ8r2MvtAc54xfnnhGFzeRHfcltobgFxkAXdE6p DVjBtqT23eugOqQ73umLcYDZkc36vnqGxUBSsXrzY9pzV5gGr2I8YUxMqf6ATrZt L9nRqA== -----END CERTIFICATE----- version_gem-1.1.12/FUNDING.md0000644000004100000410000001307215214007330015553 0ustar www-datawww-data Official Discord 👉️ [![Live Chat on Discord][✉️discord-invite-img]][✉️discord-invite] Many paths lead to being a sponsor or a backer of this project. Are you on such a path? [![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon] [⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat [⛳liberapay]: https://liberapay.com/pboling/donate [🖇osc-backers]: https://opencollective.com/ruby-oauth#backer [🖇osc-backers-i]: https://opencollective.com/ruby-oauth/backers/badge.svg?style=flat [🖇osc-sponsors]: https://opencollective.com/ruby-oauth#sponsor [🖇osc-sponsors-i]: https://opencollective.com/ruby-oauth/sponsors/badge.svg?style=flat [🖇sponsor-img]: https://img.shields.io/badge/Sponsor_Me!-pboling.svg?style=social&logo=github [🖇sponsor]: https://github.com/sponsors/pboling [🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat [🖇polar]: https://polar.sh/pboling [🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat [🖇kofi]: https://ko-fi.com/pboling [🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat [🖇patreon]: https://patreon.com/galtzo [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat [🖇buyme]: https://www.buymeacoffee.com/pboling [🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal [🖇paypal]: https://www.paypal.com/paypalme/peterboling [✉️discord-invite]: https://discord.gg/3qme4XHNKN [✉️discord-invite-img]: https://img.shields.io/discord/1373797679469170758?style=flat # 🤑 A request for help Maintainers have teeth and need to pay their dentists. After getting laid off in an RIF in March, and encountering difficulty finding a new one, I began spending most of my time building open source tools. I'm hoping to be able to pay for my kids' health insurance this month, so if you value the work I am doing, I need your support. Please consider sponsoring me or the project. To join the community or get help 👇️ Join the Discord. [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] To say "thanks!" ☝️ Join the Discord or 👇️ send money. [![Sponsor ruby-oauth/version_gem 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] # Another Way to Support Open Source Software 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). 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`. 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. **[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags** [⛳liberapay-bottom-img]: https://img.shields.io/liberapay/goal/pboling.svg?style=for-the-badge&logo=liberapay&color=a51611 [🖇osc-all-img]: https://img.shields.io/opencollective/all/ruby-oauth [🖇osc-sponsors-img]: https://img.shields.io/opencollective/sponsors/ruby-oauth [🖇osc-backers-img]: https://img.shields.io/opencollective/backers/ruby-oauth [🖇osc-all-bottom-img]: https://img.shields.io/opencollective/all/ruby-oauth?style=for-the-badge [🖇osc-sponsors-bottom-img]: https://img.shields.io/opencollective/sponsors/ruby-oauth?style=for-the-badge [🖇osc-backers-bottom-img]: https://img.shields.io/opencollective/backers/ruby-oauth?style=for-the-badge [🖇osc]: https://opencollective.com/ruby-oauth [🖇sponsor-bottom-img]: https://img.shields.io/badge/Sponsor_Me!-pboling-blue?style=for-the-badge&logo=github [🖇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 [🖇paypal-bottom-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=for-the-badge&logo=paypal&color=0A0A0A [🖇floss-funding.dev]: https://floss-funding.dev [🖇floss-funding-gem]: https://github.com/galtzo-floss/floss_funding [✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge version_gem-1.1.12/RUBOCOP.md0000644000004100000410000000653115214007330015574 0ustar www-datawww-data# RuboCop Usage Guide ## Overview A tale of two RuboCop plugin gems. ### RuboCop Gradual 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. ### RuboCop LTS This project uses `rubocop-lts` to ensure, on a best-effort basis, compatibility with Ruby >= 1.9.2. 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. ## Checking RuboCop Violations To check for RuboCop violations in this project, always use: ```bash bundle exec rake rubocop_gradual:check ``` **Do not use** the standard RuboCop commands like: - `bundle exec rubocop` - `rubocop` ## Understanding the Lock File The `.rubocop_gradual.lock` file tracks all current RuboCop violations in the project. This allows the team to: 1. Prevent new violations while gradually fixing existing ones 2. Track progress on code style improvements 3. Ensure CI builds don't fail due to pre-existing violations ## Common Commands - **Check violations** - `bundle exec rake rubocop_gradual` - `bundle exec rake rubocop_gradual:check` - **(Safe) Autocorrect violations, and update lockfile if no new violations** - `bundle exec rake rubocop_gradual:autocorrect` - **Force update the lock file (w/o autocorrect) to match violations present in code** - `bundle exec rake rubocop_gradual:force_update` ## Workflow 1. Before submitting a PR, run `bundle exec rake rubocop_gradual:autocorrect` a. or just the default `bundle exec rake`, as autocorrection is a pre-requisite of the default task. 2. If there are new violations, either: - Fix them in your code - Run `bundle exec rake rubocop_gradual:force_update` to update the lock file (only for violations you can't fix immediately) 3. Commit the updated `.rubocop_gradual.lock` file along with your changes ## Never add inline RuboCop disables Do not add inline `rubocop:disable` / `rubocop:enable` comments anywhere in the codebase (including specs, except when following the few existing `rubocop:disable` patterns for a rule already being disabled elsewhere in the code). We handle exceptions in two supported ways: - Permanent/structural exceptions: prefer adjusting the RuboCop configuration (e.g., in `.rubocop.yml`) to exclude a rule for a path or file pattern when it makes sense project-wide. - Temporary exceptions while improving code: record the current violations in `.rubocop_gradual.lock` via the gradual workflow: - `bundle exec rake rubocop_gradual:autocorrect` (preferred; will autocorrect what it can and update the lock only if no new violations were introduced) - If needed, `bundle exec rake rubocop_gradual:force_update` (as a last resort when you cannot fix the newly reported violations immediately) 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. ## Benefits of rubocop_gradual - Allows incremental adoption of code style rules - Prevents CI failures due to pre-existing violations - Provides a clear record of code style debt - Enables focused efforts on improving code quality over time version_gem-1.1.12/CONTRIBUTING.md0000644000004100000410000003272315214007330016374 0ustar www-datawww-data# Contributing Bug reports and pull requests are welcome on [CodeBerg][📜src-cb], [GitLab][📜src-gl], or [GitHub][📜src-gh]. This project should be a safe, welcoming space for collaboration, so contributors agree to adhere to the [code of conduct][🤝conduct]. To submit a patch, please fork the project, create a patch with tests, and send a pull request. Remember to [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] if you make changes. ## Developer Certificate of Origin In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed. ## Help out! Take a look at the open issues and pull requests, or use the gem and find something to improve. Follow these instructions: 1. Join the Discord: [![Live Chat on Discord][✉️discord-invite-img]][✉️discord-invite] 2. Fork the repository 3. Create your feature branch (`git checkout -b my-new-feature`) 4. Make some fixes. 5. Commit your changes (`git commit -am 'Added some feature'`) 6. Push to the branch (`git push origin my-new-feature`) 7. Make sure to add tests for it. This is important, so it doesn't break in a future release. 8. Create new Pull Request. 9. Announce it in the channel for this org in the [Discord][✉️discord-invite]! ## Executables vs Rake tasks Executables shipped by dependencies, such as kettle-dev, and stone_checksums, are available after running `bin/setup`. These include: - gem_checksums - kettle-changelog - kettle-commit-msg - kettle-dev-setup - kettle-dvcs - kettle-pre-release - kettle-readme-backers - kettle-release There are many Rake tasks available as well. You can see them by running: ```shell bin/rake -T ``` ## Code quality checks Run the Reek task when you want a smell check that fails on current findings: ```shell bin/rake reek ``` Refresh the checked-in `REEK` backlog through the rake task, not by redirecting the raw `reek` executable output. The rake task uses the project bundle and avoids stale generated binstubs shadowing the Reek gem executable: ```shell bin/rake reek:update ``` ## Environment Variables for Local Development Below are the primary environment variables recognized by stone_checksums (and its integrated tools). Unless otherwise noted, set boolean values to the string "true" to enable. General/runtime - DEBUG: Enable extra internal logging for this library (default: false) - REQUIRE_BENCH: Enable `require_bench` to profile requires (default: false) - CI: When set to true, adjusts default rake tasks toward CI behavior Coverage (kettle-soup-cover / SimpleCov) - K_SOUP_COV_DO: Enable coverage collection (default: true in `mise.toml`) - K_SOUP_COV_FORMATTERS: Comma-separated list of formatters (html, xml, rcov, lcov, json, tty) - K_SOUP_COV_MIN_LINE: Minimum line coverage threshold (integer, e.g., 100) - K_SOUP_COV_MIN_BRANCH: Minimum branch coverage threshold (integer, e.g., 100) - K_SOUP_COV_MIN_HARD: Fail the run if thresholds are not met (true/false) - K_SOUP_COV_MULTI_FORMATTERS: Enable multiple formatters at once (true/false) - K_SOUP_COV_OPEN_BIN: Path to browser opener for HTML (empty disables auto-open) - MAX_ROWS: Limit console output rows for simplecov-console (e.g., 1) Tip: When running a single spec file locally, you may want `K_SOUP_COV_MIN_HARD=false` to avoid failing thresholds for a partial run. GitHub API and CI helpers - GITHUB_TOKEN or GH_TOKEN: Token used by `ci:act` and release workflow checks to query GitHub Actions status at higher rate limits Releasing and signing - SKIP_GEM_SIGNING: If set, skip gem signing during build/release - GEM_CERT_USER: Username for selecting your public cert in `certs/.pem` (defaults to $USER) - SOURCE_DATE_EPOCH: Reproducible build timestamp. - `kettle-release` will set this automatically for the session. - Not needed on bundler >= 2.7.0, as reproducible builds have become the default. Git hooks and commit message helpers (exe/kettle-commit-msg) - GIT_HOOK_BRANCH_VALIDATE: Branch name validation mode (e.g., `jira`) or `false` to disable - GIT_HOOK_FOOTER_APPEND: Append a footer to commit messages when goalie allows (true/false) - GIT_HOOK_FOOTER_SENTINEL: Required when footer append is enabled — a unique first-line sentinel to prevent duplicates - GIT_HOOK_FOOTER_APPEND_DEBUG: Extra debug output in the footer template (true/false) Git diff driver setup - Local setup writes repository `.gitattributes` entries and local Git `diff.smorg-*` command config so this checkout uses StructuredMerge semantic diffs. - Global setup registers `diff.smorg-*` commands once in the user Git config; use it when you work across several StructuredMerge-enabled repositories. - Include-file setup writes `.git/smorg/config` and includes it from local Git config, keeping command registrations out of the repository files. - Git hosting forges generally ignore external diff drivers, so pull request views may still show raw textual diffs even when local `git diff` uses semantic drivers. ```console K_JEM_TEMPLATING=true bundle exec kettle-jem install ``` Troubleshooting Git diffs - Use `git diff --no-ext-diff` to compare against Git's built-in diff output. - Use `git diff --no-textconv` when a textconv projection obscures the raw file bytes you need to inspect. - If Git reports a missing `smorg-*` executable, rerun `bundle install` and the setup command above, then check `git config --local --get-regexp '^diff\.smorg-'`. - To remove managed local entries, run `K_JEM_TEMPLATING=true bundle exec kettle-jem install --undo`; remove global command registrations with `git config --global --unset-all diff.smorg-ruby.command`. For a quick starting point, this repository’s `mise.toml` defines the shared defaults, and `.env.local` can override them locally. Copy `.env.local.example` to `.env.local`, use `KEY=value` lines, and either activate `mise` in your shell or run commands through `mise exec -C /path/to/project -- ...`. ## Appraisals From time to time the [appraisal2][🚎appraisal2] gemfiles in `gemfiles/` will need to be updated. Generated appraisal and CI workflow floors are controlled by `ruby.test_minimum` in `.structuredmerge/kettle-jem.yml`; this project was templated with `ruby.test_minimum: 2.4`. That value describes the lowest Ruby version expected to run the test/development toolchain, and it may be higher than the gemspec runtime floor. They are created and updated with the commands: ```console bin/rake appraisal:update ``` If you need to reset all gemfiles/*.gemfile.lock files: ```console bin/rake appraisal:reset ``` When adding an appraisal to CI, check the [runner tool cache][🏃‍♂️runner-tool-cache] to see which runner to use. ## Run Tests Run tests via `kettle-test` (provided by `kettle-test`). It runs RSpec, writes the full log to `tmp/kettle-test/rspec-TIMESTAMP.log`, and prints a compact highlight block with timing, seed, pass/fail count, failing example list, and SimpleCov coverage percentages. ```console bundle exec kettle-test ``` For targeted runs, disable the hard coverage threshold to avoid false failures: ```console K_SOUP_COV_MIN_HARD=false bundle exec kettle-test spec/path/to/spec.rb ``` ### Spec organization (required) - One spec file per class/module. For each class or module under `lib/`, keep all of its unit tests in a single spec file under `spec/` that mirrors the path and file name exactly: `lib/version_gem/my_class.rb` -> `spec/version_gem/my_class_spec.rb`. - Exception: Integration specs that intentionally span multiple classes. Place these under `spec/integration/` (or a clearly named integration folder), and do not directly mirror a single class. Name them after the scenario, not a class. ## Lint It Run all the default tasks, which includes running the gradually autocorrecting linter, `rubocop-gradual`. ```console bundle exec rake ``` Or just run the linter. ```console bundle exec rake rubocop_gradual:autocorrect ``` For more detailed information about using RuboCop in this project, please see the [RUBOCOP.md](RUBOCOP.md) guide. This project uses `rubocop_gradual` instead of vanilla RuboCop, which requires specific commands for checking violations. ### Important: Do not add inline RuboCop disables Never add `# rubocop:disable ...` / `# rubocop:enable ...` comments to code or specs (except when following the few existing `rubocop:disable` patterns for a rule already being disabled elsewhere in the code). Instead: - Prefer configuration-based exclusions when a rule should not apply to certain paths or files (e.g., via `.rubocop.yml`). - When a violation is temporary, and you plan to fix it later, record it in `.rubocop_gradual.lock` using the gradual workflow: - `bundle exec rake rubocop_gradual:autocorrect` (preferred) - `bundle exec rake rubocop_gradual:force_update` (only when you cannot fix the violations immediately) As a general rule, fix style issues rather than ignoring them. For example, our specs should follow RSpec conventions like using `described_class` for the class under test. ## Contributors Your picture could be here! [![Contributors][🖐contributors-img]][🖐contributors] Made with [contributors-img][🖐contrib-rocks]. Also see GitLab Contributors: [https://gitlab.com/ruby-oauth/version_gem/-/graphs/main][🚎contributors-gl] ## For Maintainers ### One-time, Per-maintainer, Setup **IMPORTANT**: To sign a build, a public key for signing gems will need to be picked up by the line in the `gemspec` defining the `spec.cert_chain` (check the relevant ENV variables there). All releases are signed releases. See: [RubyGems Security Guide][🔒️rubygems-security-guide] NOTE: To build without signing the gem set `SKIP_GEM_SIGNING` to any value in the environment. ### To release a new version: #### Automated process 1. Update version.rb to contain the correct version-to-be-released. 2. Run `bundle exec kettle-changelog`. 3. Run `bundle exec kettle-release`. 4. Stay awake and monitor the release process for any errors, and answer any prompts. #### Manual process 1. Run `bin/setup && bin/rake` as a "test, coverage, & linting" sanity check 2. Update the version number in `version.rb`, and ensure `CHANGELOG.md` reflects changes 3. Run `bin/setup && bin/rake` again as a secondary check, and to update `Gemfile.lock` 4. Run `bin/rake yard` to regenerate the docs site using the canonical docs task 5. Run `git commit -am "🔖 Prepare release v"` to commit the changes 6. Run `git push` to trigger the final CI pipeline before release, and merge PRs - NOTE: Remember to [check the build][🧪build]. 7. Run `export GIT_TRUNK_BRANCH_NAME="$(git remote show origin | grep 'HEAD branch' | cut -d ' ' -f5)" && echo $GIT_TRUNK_BRANCH_NAME` 8. Run `git checkout $GIT_TRUNK_BRANCH_NAME` 9. Run `git pull origin $GIT_TRUNK_BRANCH_NAME` to ensure latest trunk code 10. Optional for older Bundler (< 2.7.0): Set `SOURCE_DATE_EPOCH` so `rake build` and `rake release` use the same timestamp and generate the same checksums - If your Bundler is >= 2.7.0, you can skip this; builds are reproducible by default. - Run `export SOURCE_DATE_EPOCH=$EPOCHSECONDS && echo $SOURCE_DATE_EPOCH` - If the echo above has no output, then it didn't work. - Note: `zsh/datetime` module is needed, if running `zsh`. - In older versions of `bash` you can use `date +%s` instead, i.e. `export SOURCE_DATE_EPOCH=$(date +%s) && echo $SOURCE_DATE_EPOCH` 11. Run `bundle exec rake build` 12. Run `bin/gem_checksums` (more context [1][🔒️rubygems-checksums-pr], [2][🔒️rubygems-guides-pr]) to create SHA-256 and SHA-512 checksums. This functionality is provided by the `stone_checksums` [gem][💎stone_checksums]. - The script automatically commits but does not push the checksums 13. Sanity check the SHA256, comparing with the output from the `bin/gem_checksums` command: - `sha256sum pkg/-.gem` 14. Run `bundle exec rake release` which will create a git tag for the version, push git commits and tags, and push the `.gem` file to the gem host configured in the gemspec. [📜src-gl]: https://gitlab.com/ruby-oauth/version_gem [📜src-cb]: https://codeberg.org/ruby-oauth/version_gem [📜src-gh]: https://github.com/ruby-oauth/version_gem [🧪build]: https://github.com/ruby-oauth/version_gem/actions [🤝conduct]: https://github.com/ruby-oauth/version_gem/blob/main/CODE_OF_CONDUCT.md [🖐contrib-rocks]: https://contrib.rocks [🖐contributors]: https://github.com/ruby-oauth/version_gem/graphs/contributors [🚎contributors-gl]: https://gitlab.com/ruby-oauth/version_gem/-/graphs/main [🖐contributors-img]: https://contrib.rocks/image?repo=ruby-oauth/version_gem [💎gem-coop]: https://gem.coop [🔒️rubygems-security-guide]: https://guides.rubygems.org/security/#building-gems [🔒️rubygems-checksums-pr]: https://github.com/rubygems/rubygems/pull/6022 [🔒️rubygems-guides-pr]: https://github.com/rubygems/guides/pull/325 [💎stone_checksums]: https://github.com/galtzo-floss/stone_checksums [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/ [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-FFDD67.svg?style=flat [📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139 [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html [🚎appraisal2]: https://github.com/appraisal-rb/appraisal2 [🏃‍♂️runner-tool-cache]: https://github.com/ruby/ruby-builder/releases/tag/toolcache [✉️discord-invite]: https://discord.gg/3qme4XHNKN version_gem-1.1.12/SECURITY.md0000755000004100000410000000110215214007330015722 0ustar www-datawww-data# Security Policy ## Supported Versions | Version | Supported | |----------|-----------| | 1.1.latest | ✅ | ## Security contact information To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. ## Additional Support If you are interested in support for versions older than the latest release, please consider sponsoring the project / maintainer @ https://liberapay.com/pboling/donate, or find other sponsorship links in the [README]. [README]: README.md version_gem-1.1.12/lib/0000755000004100000410000000000015214007330014702 5ustar www-datawww-dataversion_gem-1.1.12/lib/version_gem.rb0000755000004100000410000000040615214007330017547 0ustar www-datawww-data# frozen_string_literal: true require_relative "version_gem/version" require_relative "version_gem/basic" require_relative "version_gem/epoch" # Namespace of this library module VersionGem end VersionGem::Version.class_eval do extend VersionGem::Basic end version_gem-1.1.12/lib/version_gem/0000755000004100000410000000000015214007330017217 5ustar www-datawww-dataversion_gem-1.1.12/lib/version_gem/error.rb0000755000004100000410000000021515214007330020676 0ustar www-datawww-data# frozen_string_literal: true module VersionGem # Errors raised by VersionGem will be of this class class Error < RuntimeError; end end version_gem-1.1.12/lib/version_gem/rspec.rb0000755000004100000410000000457515214007330020676 0ustar www-datawww-data# frozen_string_literal: true RSpec::Matchers.define(:have_version_constant) do match do |version_mod| version_mod.const_defined?(:VERSION, false) end end RSpec::Matchers.define(:have_version_as_string) do match do |version_mod| !version_mod::VERSION.nil? && version_mod::VERSION.is_a?(String) end end RSpec::Matchers.define(:have_epoch_as_integer) do match do |version_mod| version_mod.epoch.is_a?(Integer) end end RSpec::Matchers.define(:have_major_as_integer) do match do |version_mod| version_mod.major.is_a?(Integer) end end RSpec::Matchers.define(:have_minor_as_integer) do match do |version_mod| version_mod.minor.is_a?(Integer) end end RSpec::Matchers.define(:have_patch_as_integer) do match do |version_mod| version_mod.patch.is_a?(Integer) end end RSpec::Matchers.define(:have_pre_as_nil_or_string) do match do |version_mod| version_mod.pre.nil? || version_mod.pre.is_a?(String) end end RSpec.shared_examples_for("a Version module") do |version_mod| it "is introspectable" do aggregate_failures "introspectable api" do expect(version_mod).is_a?(Module) expect(version_mod).to(have_version_constant) expect(version_mod).to(have_version_as_string) expect(version_mod.to_s).to(be_a(String)) expect(version_mod).to(have_major_as_integer) expect(version_mod).to(have_minor_as_integer) expect(version_mod).to(have_patch_as_integer) expect(version_mod).to(have_pre_as_nil_or_string) expect(version_mod.to_h.keys).to(match_array(%i[major minor patch pre])) expect(version_mod.to_a).to(be_a(Array)) end end end # This one is more Epoch ;) RSpec.shared_examples_for("an Epoch Version module") do |version_mod| it "is introspectable" do aggregate_failures "introspectable api" do expect(version_mod).is_a?(Module) expect(version_mod).to(have_version_constant) expect(version_mod).to(have_version_as_string) expect(version_mod.to_s).to(be_a(String)) expect(version_mod).to(have_epoch_as_integer) expect(version_mod).to(have_major_as_integer) expect(version_mod).to(have_minor_as_integer) expect(version_mod).to(have_patch_as_integer) expect(version_mod).to(have_pre_as_nil_or_string) expect(version_mod.to_h.keys).to(match_array(%i[epoch major minor patch pre])) expect(version_mod.to_a).to(be_a(Array)) end end end version_gem-1.1.12/lib/version_gem/version.rb0000644000004100000410000000024015214007330021225 0ustar www-datawww-data# frozen_string_literal: true module VersionGem module Version VERSION = "1.1.12" end VERSION = Version::VERSION # Traditional Constant Location end version_gem-1.1.12/lib/version_gem/api.rb0000755000004100000410000000223715214007330020324 0ustar www-datawww-data# frozen_string_literal: true module VersionGem # Public API of this library module Api # The version number as a string # # @return [String] def to_s self::VERSION end # The major version # # @return [Integer] def major @major ||= _to_a[0].to_i end # The minor version # # @return [Integer] def minor @minor ||= _to_a[1].to_i end # The patch version # # @return [Integer] def patch @patch ||= _to_a[2].to_i end # The pre-release version, if any # # @return [String, NilClass] def pre @pre ||= _to_a[3] end # The version number as a hash # # @return [Hash] def to_h @to_h ||= { major: major, minor: minor, patch: patch, pre: pre } end # The version number as an array of cast values # # @return [Array<[Integer, String, NilClass]>] def to_a @to_a ||= [major, minor, patch, pre] end private # The version number as an array of strings # # @return [Array] def _to_a @_to_a = self::VERSION.split(".") end end end version_gem-1.1.12/lib/version_gem/basic.rb0000755000004100000410000000062015214007330020626 0ustar www-datawww-data# frozen_string_literal: true require_relative "error" require_relative "api" module VersionGem # This is a very *basic* version parser. Others could be built based on this pattern! module Basic class << self def extended(base) raise Error, "VERSION must be defined before 'extend #{name}'" unless defined?(base::VERSION) base.extend(Api) end end end end version_gem-1.1.12/lib/version_gem/epoch.rb0000755000004100000410000000303715214007330020650 0ustar www-datawww-data# frozen_string_literal: true require_relative "error" require_relative "api" module VersionGem # Support for Epoch Semantic Versioning # See: https://antfu.me/posts/epoch-semver module Epoch EPOCH_SIZE = 1_000 class << self def extended(base) raise Error, "VERSION must be defined before 'extend #{name}'" unless defined?(base::VERSION) base.extend(Api) base.extend(OverloadApiForEpoch) end end # Tweak the basic API so it will support Epoch Semantic Versioning module OverloadApiForEpoch # *** OVERLOAD METHODS FROM API *** # # The epoch version # # @return [Integer] def epoch @epoch ||= _major / EPOCH_SIZE end # The major version # # @return [Integer] def major @major ||= _major % EPOCH_SIZE end # The version number as a hash # # @return [Hash] def to_h @to_h ||= { epoch: epoch, major: major, minor: minor, patch: patch, pre: pre } end # NOTE: This is not the same as _to_a, which returns an array of strings # # The version number as an array of cast values # where epoch and major are derived from a single string: # EPOCH * 1000 + MAJOR # # @return [Array<[Integer, String, NilClass]>] def to_a @to_a ||= [epoch, major, minor, patch, pre] end private def _major @_major ||= _to_a[0].to_i end end end end version_gem-1.1.12/lib/version_gem/ruby.rb0000755000004100000410000000142515214007330020532 0ustar www-datawww-data# frozen_string_literal: true module VersionGem # Helpers for library CI integration against many different versions of Ruby module Ruby RUBY_VER = ::Gem::Version.new(RUBY_VERSION) # Check if the current Ruby version is greater than or equal to the given version def gte_minimum_version?(version, engine = "ruby") ::Gem::Version.new(version) <= RUBY_VER && engine == ::RUBY_ENGINE end module_function :gte_minimum_version? # Check if the current Ruby version (MAJOR.MINOR) is equal to the given version def actual_minor_version?(major, minor, engine = "ruby") segs = RUBY_VER.segments major.to_i == segs[0] && minor.to_i == segs[1] && engine == ::RUBY_ENGINE end module_function :actual_minor_version? end end version_gem-1.1.12/CITATION.cff0000644000004100000410000000106515214007330016030 0ustar www-datawww-datacff-version: 1.2.0 title: "version_gem" message: >- If you use this work and you want to cite it, then you can use the metadata from this file. type: software authors: - given-names: "Peter H." family-names: "Boling" email: "floss@galtzo.com" affiliation: "galtzo.com" orcid: 'https://orcid.org/0009-0008-8519-441X' identifiers: - type: url value: 'https://github.com/ruby-oauth/version_gem' description: "version_gem" repository-code: 'https://github.com/ruby-oauth/version_gem' abstract: >- version_gem license: See license file version_gem-1.1.12/checksums.yaml.gz.sig0000444000004100000410000000060015214007330020177 0ustar www-datawww-dataH3ܤ-H~LC9}J taA,V,lY'dr*e.E XOC͵S HhFReF:VG5alhGm؁ 佑ljZ1DzE&%`Co $M!!xr&\nj<5Uv;lPHb5H:트P}r|4Up ;j} A>B_o#rPsom螬`& 7j|mSkҮt_"'ߴ>&F%K7^7IVy,jjcgC|Af1,Ѥversion_gem-1.1.12/version_gem.gemspec0000644000004100000410000001312415214007330020017 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: version_gem 1.1.12 ruby lib Gem::Specification.new do |s| s.name = "version_gem".freeze s.version = "1.1.12".freeze s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.metadata = { "bug_tracker_uri" => "https://github.com/ruby-oauth/version_gem/issues", "changelog_uri" => "https://github.com/ruby-oauth/version_gem/blob/v1.1.12/CHANGELOG.md", "discord_uri" => "https://discord.gg/3qme4XHNKN", "documentation_uri" => "https://www.rubydoc.info/gems/version_gem/1.1.12", "funding_uri" => "https://github.com/sponsors/pboling", "homepage_uri" => "https://structuredmerge.org", "news_uri" => "https://www.railsbling.com/tags/version_gem", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/ruby-oauth/version_gem/tree/v1.1.12", "wiki_uri" => "https://github.com/ruby-oauth/version_gem/wiki" } if s.respond_to? :metadata= s.require_paths = ["lib".freeze] s.authors = ["Peter H. Boling".freeze, "Aboling0".freeze] s.bindir = "exe".freeze s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIEgDCCAuigAwIBAgIBATANBgkqhkiG9w0BAQsFADBDMRUwEwYDVQQDDAxwZXRl\nci5ib2xpbmcxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkW\nA2NvbTAeFw0yNTA1MDQxNTMzMDlaFw00NTA0MjkxNTMzMDlaMEMxFTATBgNVBAMM\nDHBldGVyLmJvbGluZzEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy\nLGQBGRYDY29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAruUoo0WA\nuoNuq6puKWYeRYiZekz/nsDeK5x/0IEirzcCEvaHr3Bmz7rjo1I6On3gGKmiZs61\nLRmQ3oxy77ydmkGTXBjruJB+pQEn7UfLSgQ0xa1/X3kdBZt6RmabFlBxnHkoaGY5\nmZuZ5+Z7walmv6sFD9ajhzj+oIgwWfnEHkXYTR8I6VLN7MRRKGMPoZ/yvOmxb2DN\ncoEEHWKO9CvgYpW7asIihl/9GMpKiRkcYPm9dGQzZc6uTwom1COfW0+ZOFrDVBuV\nFMQRPswZcY4Wlq0uEBLPU7hxnCL9nKK6Y9IhdDcz1mY6HZ91WImNslOSI0S8hRpj\nyGOWxQIhBT3fqCBlRIqFQBudrnD9jSNpSGsFvbEijd5ns7Z9ZMehXkXDycpGAUj1\nto/5cuTWWw1JqUWrKJYoifnVhtE1o1DZ+LkPtWxHtz5kjDG/zR3MG0Ula0UOavlD\nqbnbcXPBnwXtTFeZ3C+yrWpE4pGnl3yGkZj9SMTlo9qnTMiPmuWKQDatAgMBAAGj\nfzB9MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQE8uWvNbPVNRXZ\nHlgPbc2PCzC4bjAhBgNVHREEGjAYgRZwZXRlci5ib2xpbmdAZ21haWwuY29tMCEG\nA1UdEgQaMBiBFnBldGVyLmJvbGluZ0BnbWFpbC5jb20wDQYJKoZIhvcNAQELBQAD\nggGBAJbnUwfJQFPkBgH9cL7hoBfRtmWiCvdqdjeTmi04u8zVNCUox0A4gT982DE9\nwmuN12LpdajxZONqbXuzZvc+nb0StFwmFYZG6iDwaf4BPywm2e/Vmq0YG45vZXGR\nL8yMDSK1cQXjmA+ZBKOHKWavxP6Vp7lWvjAhz8RFwqF9GuNIdhv9NpnCAWcMZtpm\nGUPyIWw/Cw/2wZp74QzZj6Npx+LdXoLTF1HMSJXZ7/pkxLCsB8m4EFVdb/IrW/0k\nkNSfjtAfBHO8nLGuqQZVH9IBD1i9K6aSs7pT6TW8itXUIlkIUI2tg5YzW6OFfPzq\nQekSkX3lZfY+HTSp/o+YvKkqWLUV7PQ7xh1ZYDtocpaHwgxe/j3bBqHE+CUPH2vA\n0V/FwdTRWcwsjVoOJTrYcff8pBZ8r2MvtAc54xfnnhGFzeRHfcltobgFxkAXdE6p\nDVjBtqT23eugOqQ73umLcYDZkc36vnqGxUBSsXrzY9pzV5gGr2I8YUxMqf6ATrZt\nL9nRqA==\n-----END CERTIFICATE-----\n".freeze] s.date = "1980-01-02" s.description = "\u{1F372} Versions are good. Versions are cool. Versions will win.".freeze s.email = ["floss@galtzo.com".freeze] s.extra_rdoc_files = ["CHANGELOG.md".freeze, "CITATION.cff".freeze, "CODE_OF_CONDUCT.md".freeze, "CONTRIBUTING.md".freeze, "FUNDING.md".freeze, "LICENSE.md".freeze, "README.md".freeze, "RUBOCOP.md".freeze, "SECURITY.md".freeze] s.files = ["CHANGELOG.md".freeze, "CITATION.cff".freeze, "CODE_OF_CONDUCT.md".freeze, "CONTRIBUTING.md".freeze, "FUNDING.md".freeze, "LICENSE.md".freeze, "README.md".freeze, "RUBOCOP.md".freeze, "SECURITY.md".freeze, "certs/pboling.pem".freeze, "lib/version_gem.rb".freeze, "lib/version_gem/api.rb".freeze, "lib/version_gem/basic.rb".freeze, "lib/version_gem/epoch.rb".freeze, "lib/version_gem/error.rb".freeze, "lib/version_gem/rspec.rb".freeze, "lib/version_gem/ruby.rb".freeze, "lib/version_gem/version.rb".freeze, "sig/all_formatters.rbs".freeze, "sig/debug.rbs".freeze, "sig/debug_ide.rbs".freeze, "sig/debug_jruby.rbs".freeze, "sig/debugging.rbs".freeze, "sig/run_coverage.rbs".freeze, "sig/version_gem.rbs".freeze, "sig/version_gem/api.rbs".freeze, "sig/version_gem/basic.rbs".freeze, "sig/version_gem/epoch.rbs".freeze, "sig/version_gem/error.rbs".freeze, "sig/version_gem/ruby.rbs".freeze, "sig/version_gem/version.rbs".freeze] s.homepage = "https://github.com/ruby-oauth/version_gem".freeze s.licenses = ["MIT".freeze] s.rdoc_options = ["--title".freeze, "version_gem - \u{1F372} Enhance your VERSION! Sugar for Version modules.".freeze, "--main".freeze, "README.md".freeze, "--exclude".freeze, "^sig/".freeze, "--line-numbers".freeze, "--inline-source".freeze, "--quiet".freeze] s.required_ruby_version = Gem::Requirement.new(">= 2.2.0".freeze) s.rubygems_version = "4.0.10".freeze s.summary = "\u{1F372} Enhance your VERSION! Sugar for Version modules.".freeze s.specification_version = 4 s.add_development_dependency(%q.freeze, ["~> 3.1".freeze, ">= 3.1.2".freeze]) s.add_development_dependency(%q.freeze, ["~> 0.9.3".freeze]) s.add_development_dependency(%q.freeze, ["~> 2.0".freeze, ">= 2.0.2".freeze]) s.add_development_dependency(%q.freeze, ["~> 2.2".freeze, ">= 2.2.9".freeze]) s.add_development_dependency(%q.freeze, ["~> 2.0".freeze, ">= 2.0.5".freeze]) s.add_development_dependency(%q.freeze, ["~> 13.0".freeze]) s.add_development_dependency(%q.freeze, ["~> 1.0".freeze, ">= 1.0.4".freeze]) s.add_development_dependency(%q.freeze, ["~> 1.13".freeze]) s.add_development_dependency(%q.freeze, ["~> 1.0".freeze, ">= 1.0.3".freeze]) s.add_development_dependency(%q.freeze, ["~> 3.1".freeze, ">= 3.1.3".freeze]) end version_gem-1.1.12/CODE_OF_CONDUCT.md0000644000004100000410000001311615214007330016735 0ustar www-datawww-data# Contributor Covenant Code of Conduct ## Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards Examples of behavior that contributes to a positive environment for our community include: * Demonstrating empathy and kindness toward other people * Being respectful of differing opinions, viewpoints, and experiences * Giving and gracefully accepting constructive feedback * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience * Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: * The use of sexualized language or imagery, and sexual attention or advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or email address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [![Contact Maintainer][🚂maint-contact-img]][🚂maint-contact]. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. ## Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. ### 2. Warning **Community Impact**: A violation through a single incident or series of actions. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. [homepage]: https://www.contributor-covenant.org [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html [Mozilla CoC]: https://github.com/mozilla/diversity [FAQ]: https://www.contributor-covenant.org/faq [translations]: https://www.contributor-covenant.org/translations [🚂maint-contact]: http://www.railsbling.com/contact [🚂maint-contact-img]: https://img.shields.io/badge/Contact-Maintainer-0093D0.svg?style=flat&logo=rubyonrails&logoColor=red version_gem-1.1.12/LICENSE.md0000644000004100000410000000036615214007330015545 0ustar www-datawww-data# License This project is made available under the following license. Choose the option that best fits your use case: - [MIT](MIT.md) ## Copyright Notice - Copyright (c) 2022-2023, 2025-2026 Peter H. Boling - Copyright (c) 2024-2025 Aboling0 version_gem-1.1.12/data.tar.gz.sig0000444000004100000410000000060015214007330016747 0ustar www-datawww-datas "WUmo|ޕ/{!&Wv;0g.PR_h 5&L7nw->ozducR\yࡄ- ێãbY `;;A0-#[=L?QJF3Ņ5[jx)y[&PykNwe;N2k`4Taz-!laՔ5"7[r@DJnf{!I+[8Cwm儠_ G l>a2C]$O [`cdm\zc@ZR8փr QFA-GmeVkF'.`(42G%AL鴛਎7f/version_gem-1.1.12/metadata.gz.sig0000444000004100000410000000060015214007330017031 0ustar www-datawww-data UlIt=%BL,8;p)ǃ S {e*1}%;Z42{Pƫ(S ? \-4if[Sl8a2"!T͉S \j F {r˲ MP2ǬөyR&[ 2R۳*qȞQ_Y40uWt);&OG -K2[[mo rD$cGwyz39O$7g \& wظ!;z}uSw2TNK^v/ҒMVRI4 ~rMversion_gem-1.1.12/README.md0000644000004100000410000013255615214007330015427 0ustar www-datawww-dataruby-oauth Logo by Aboling0, CC BY-SA 4.0 # 🍲 VersionGem [![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license] [![Downloads Rank][👽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] [![Apache SkyWalking Eyes License Compatibility Check][🚎15-🪪-wfi]][🚎15-🪪-wf] `if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][✉️discord-invite], as I may have missed the [discord notification][✉️discord-invite]. --- `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. [![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate at ko-fi.com][🖇kofi-img]][🖇kofi]
👣 How will this project approach the September 2025 hostile takeover of RubyGems? 🚑️ I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-takeover-of-rubygems-my-thoughts-5hlo).
## 🌻 Synopsis Galtzo FLOSS Logo by Aboling0, CC BY-SA 4.0 ruby-lang Logo, Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5 Give your next library an introspectable `Version` module without breaking your Gemspec. ```ruby MyLib::Version.to_s # => "1.2.3.rc3" MyLib::Version.major # => 1 MyLib::Version.minor # => 2 MyLib::Version.patch # => 3 MyLib::Version.pre # => "rc3" MyLib::Version.to_a # => [1, 2, 3, "rc3"] MyLib::Version.to_h # => { major: 1, minor: 2, patch: 3, pre: "rc3" } ``` This library was extracted from the gem _[oauth2](https://gitlab.com/oauth-xx/oauth2)_. This gem has no runtime dependencies. ### 🧐 Alternatives This gem has a very niche purpose, which is: 1. providing introspection of a `Version` module based on a `VERSION` constant string within it, 2. while not interfering with `gemspec` parsing where the `VERSION` string is traditionally used, 3. allowing 100% test coverage of Ruby code, including the `Version` module. As proof in the pudding, this gem achieves 100% test coverage for lines and branches, all 118 and 4 of them, respectively; coverage enabled in part by patterns from this library. You can make it happen for your library too! If this isn't **precisely** your use case you may be better off looking at _[versionaire](https://www.alchemists.io/projects/versionaire)_, a wonderful, performant, well-maintained, gem from the Alchemists, or _[version_sorter](https://rubygems.org/gems/version_sorter)_ from GitHub. For more discussion about this [see issue #2](https://gitlab.com/oauth-xx/version_gem/-/issues/2) ## 💡 Info you can shake a stick at | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] | |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Works with JRuby | [![JRuby 9.2 Compat][💎jruby-9.2i]][🚎jruby-9.2-wf] [![JRuby 9.3 Compat][💎jruby-9.3i]][🚎jruby-9.3-wf]
[![JRuby 9.4 Compat][💎jruby-9.4i]][🚎jruby-9.4-wf] [![JRuby current Compat][💎jruby-c-i]][🚎10-j-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf]| | 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]
[![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 current Compat][💎truby-c-i]][🚎9-t-wf]| | Works with MRI Ruby 4 | [![Ruby 4.0 Compat][💎ruby-4.0i]][🚎11-c-wf] [![Ruby current Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf]| | 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]| | Works with MRI Ruby 2 | ![Ruby 2.2 Compat][💎ruby-2.2i] ![Ruby 2.3 Compat][💎ruby-2.3i]
[![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]| | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![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] | | 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] | | 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] | | Compliance | [![License: MIT][📄license-img]][📄license] [![Apache license compatibility: Category A][📄license-compat-img]][📄license-compat] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] | | 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] | | 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] | | `...` 💖 | [![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] | ### Compatibility Compatible with MRI Ruby 2.2.0+, and concordant releases of JRuby, and TruffleRuby. CI workflows and Appraisals are generated for MRI Ruby 2.4+. This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and may be higher than the gem's runtime compatibility floor when legacy Rubies are not practical for the current toolchain. | 🚚 _Amazing_ test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 | |------------------------------------------------|--------------------------------------------------------| | 👟 Check it out! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ | ### Federated DVCS
Find this repo on federated forges (Coming soon!) | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions | |-------------------------------------------------|-----------------------------------------------------------------------|---------------------------|--------------------------|---------------------------|--------------------------|------------------------------| | 🧪 [ruby-oauth/version_gem on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜gl-wiki] | 🐭 Tiny Matrix | ➖ | | 🧊 [ruby-oauth/version_gem on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | ➖ | | 🐙 [ruby-oauth/version_gem on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | [💚][📜gh-wiki] | 💯 Full Matrix | [💚][gh-discussions] | | 🎮️ [Discord Server][✉️discord-invite] | [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] | [Let's][✉️discord-invite] | [talk][✉️discord-invite] | [about][✉️discord-invite] | [this][✉️discord-invite] | [library!][✉️discord-invite] |
[gh-discussions]: https://github.com/ruby-oauth/version_gem/discussions ### Enterprise Support [![Tidelift](https://tidelift.com/badges/package/rubygems/version_gem)](https://tidelift.com/subscription/pkg/rubygems-version_gem?utm_source=rubygems-version_gem&utm_medium=referral&utm_campaign=readme) Available as part of the Tidelift Subscription.
Need enterprise-level guarantees? 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. [![Get help from me on Tidelift][🏙️entsup-tidelift-img]][🏙️entsup-tidelift] - 💡Subscribe for support guarantees covering _all_ your FLOSS dependencies - 💡Tidelift is part of [Sonar][🏙️entsup-tidelift-sonar] - 💡Tidelift pays maintainers to maintain the software you depend on!
📊`@`Pointy Haired Boss: An [enterprise support][🏙️entsup-tidelift] subscription is "[never gonna let you down][🧮kloc]", and *supports* open source maintainers Alternatively: - [![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]
## ✨ Installation Install the gem and add to the application's Gemfile by executing: ```console bundle add version_gem ``` If bundler is not being used to manage dependencies, install the gem by executing: ```console gem install version_gem ``` ## ⚙️ Configuration In the standard `bundle gem my_lib` code you get the following in `lib/my_lib/version.rb`: ```ruby module MyLib VERSION = "0.1.0" end ``` Change it to a nested `Version` namespace (the one implied by the path => namespace convention): ```ruby module MyLib module Version VERSION = "0.1.0" end end ``` Now add the following near the top of the file the manages requiring external libraries. Using the same example of `bundle gem my_lib`, this would be `lib/my_lib.rb`. ```ruby require "version_gem" ``` Then, add the following wherever you want in the same file (recommend the bottom). ```ruby MyLib::Version.class_eval do extend VersionGem::Basic end ``` ## 🔧 Basic Usage Now you have some version introspection methods available: ```ruby MyLib::Version.to_s # => "0.1.0" MyLib::Version.major # => 0 MyLib::Version.minor # => 1 MyLib::Version.patch # => 0 MyLib::Version.pre # => "" MyLib::Version.to_a # => [0, 1, 0] MyLib::Version.to_h # => { major: 0, minor: 1, patch: 0, pre: "" } ``` ### Side benefit #1 You can reference the version from your gemspec, keeping the version string DRY, *and* still get accurate code coverage! ```ruby # Get the GEMFILE_VERSION without *require* "my_gem/version", for code coverage accuracy # See: https://github.com/simplecov-ruby/simplecov/issues/557#issuecomment-2630782358 # Kernel.load because load is overloaded in RubyGems during gemspec evaluation Kernel.load("lib/my_gem/version.rb") gem_version = MyGem::Version::VERSION MyGem::Version.send(:remove_const, :VERSION) Gem::Specification.new do |spec| # ... spec.version = gem_version end ``` ### Side benefit #2 Your `version.rb` file now abides the Ruby convention of directory / path matching the namespace / class! ### Epoch Usage (Epoch Semantic Versioning, as of version 1.1.7) In the standard `bundle gem my_epoch_lib` code you get the following in `lib/my_epoch_lib/version.rb`: ```ruby module MyEpochLib VERSION = "0.1.0" end ``` Change it to a nested `Version` namespace (the one implied by the path => namespace convention): ```ruby module MyEpochLib module Version VERSION = "0.1.0" end end ``` The Epoch and Major versions are derived from the formula: ``` {EPOCH * 1000 + MAJOR}.MINOR.PATCH ``` This will start your library with the following version segments: * `epoch = 0` * `major = 0` * `minor = 1` * `patch = 0` * `pre = nil` And the segments are defined as: ``` EPOCH: Increment when you make significant or groundbreaking changes. MAJOR: Increment when you make minor incompatible API changes. MINOR: Increment when you add functionality in a backwards-compatible manner. PATCH: Increment when you make backwards-compatible bug fixes. ``` Therefore, if you set your version number to: ```ruby VERSION = "27016.42.86-pre.7" ``` You will get the following version segments: ``` { epoch: 27, major: 16, minor: 42, patch: 86, pre: "pre-7" } ``` Following the same setup as [Basic Usage](#-basic-usage) above (add `require "version_gem"` at the top of your main lib file), then add the following wherever you want in the same file (recommend the bottom): ```ruby MyLib::Version.class_eval do extend VersionGem::Epoch end ``` And now you have some version introspection methods available: ```ruby MyLib::Version.to_s # => "1024.3.8" MyLib::Version.epoch # => 1 MyLib::Version.major # => 24 MyLib::Version.minor # => 3 MyLib::Version.patch # => 8 MyLib::Version.pre # => "" MyLib::Version.to_a # => [1, 24, 3, 8] MyLib::Version.to_h # => { epoch: 1, major: 24, minor: 3, patch: 8, pre: "" } ``` ### Usage with Zeitwerk The pattern of `version.rb` breaking the ruby convention of directory / path matching the namespace / class is so entrenched that the `zeitwerk` library has a special carve-out for it. 🥺 RubyGems using this "bad is actually good" pattern are encouraged to use `Zeitwerk.for_gem`. **Do not do that ^** if you use this gem. #### Simple Zeitwerk Example Create a gem like this (keeping with the `MyLib` theme): ```shell bundle gem my_lib ``` Then following the usage instructions above, you edit your primary namespace file @ `lib/my_lib.rb`, but inject the Zeitwerk loader. ```ruby # frozen_string_literal: true require_relative "my_lib/version" module MyLib class Error < StandardError; end # Your code goes here... end loader = Zeitwerk::Loader.new loader.tag = File.basename(__FILE__, ".rb") loader.push_dir("lib/my_lib", namespace: MyLib) loader.setup # ready! loader.eager_load(force: true) # optional! MyLib::Version.class_eval do extend VersionGem::Basic end ``` #### Complex Zeitwerk Example Maybe you would like to contribute one? #### Query Ruby Version (as of version 1.1.2) In Continuous Integration environments for libraries that run against many versions of Ruby, I often need to configure things discretely per Ruby version, and doing so forced me to repeat a significant amount of boilerplate code across each project. Thus `VersionGem::Ruby` was born. It has the two optimized methods I always need: ```ruby engine = "ruby" version = "2.7.7" gte_minimum_version?(version, engine) # Is the current version of Ruby greater than or equal to some minimum? major = 3 minor = 2 actual_minor_version?(major, minor, engine) # Is the current version of Ruby precisely a specific minor version of Ruby? ``` `Version::Ruby` is *not loaded* by default. If you want to use it, you must require it as: ```ruby require "version_gem/ruby" ``` Normally I do this in my `spec/spec_helper.rb`, and/or `.simplecov` files. Occasionally in my `Rakefile`. ### Caveat This design keeps your `version.rb` file compatible with the way `gemspec` files use them. This means that the introspection is _not_ available within the gemspec. The enhancement from this gem is only available at runtime. ### RSpec Matchers In `spec_helper.rb`: ```ruby require "version_gem/rspec" ``` Then you can write a test like: ```ruby RSpec.describe(MyLib::Version) do it_behaves_like "a Version module", described_class end # Or, if you want to write your own, here is the á la carte menu: RSpec.describe(MyLib::Version) do it "is a Version module" do expect(described_class).is_a?(Module) expect(described_class).to(have_version_constant) expect(described_class).to(have_version_as_string) expect(described_class.to_s).to(be_a(String)) expect(described_class).to(have_major_as_integer) expect(described_class).to(have_epoch_as_integer) expect(described_class).to(have_minor_as_integer) expect(described_class).to(have_patch_as_integer) expect(described_class).to(have_pre_as_nil_or_string) # This would be %i[epoch major minor patch pre] for epoch version schemes expect(described_class.to_h.keys).to(match_array(%i[major minor patch pre])) expect(described_class.to_a).to(be_a(Array)) end end ``` ## 🦷 FLOSS Funding While ruby-oauth tools are free software and will always be, the project would benefit immensely from some funding. Raising a monthly budget of... "dollars" would make the project more sustainable. We welcome both individual and corporate sponsors! We also offer a wide array of funding channels to account for your preferences. Currently, [Open Collective][🖇osc] is our preferred funding platform. **If you're working in a company that's making significant use of ruby-oauth tools we'd appreciate it if you suggest to your company to become a ruby-oauth sponsor.** You can support the development of ruby-oauth tools via [GitHub Sponsors][🖇sponsor], [Liberapay][⛳liberapay], [PayPal][🖇paypal], [Open Collective][🖇osc] and [Tidelift][🏙️entsup-tidelift]. | 📍 NOTE | |----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | If doing a sponsorship in the form of donation is problematic for your company
from an accounting standpoint, we'd recommend the use of Tidelift,
where you can get a support-like subscription instead. | ### Open Collective for Individuals Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/ruby-oauth#backer)] NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically. No backers yet. Be the first! ### Open Collective for Organizations Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor](https://opencollective.com/ruby-oauth#sponsor)] NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically. No sponsors yet. Be the first! [kettle-readme-backers]: https://github.com/ruby-oauth/version_gem/blob/main/exe/kettle-readme-backers ### Another way to support open-source 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). 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`. 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. **[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags** [![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate to my FLOSS efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon] ## 🔐 Security See [SECURITY.md][🔐security]. ## 🤝 Contributing If you need some ideas of where to help, you could work on adding more code coverage, or if it is already 💯 (see [below](#code-coverage)) check [issues][🤝gh-issues] or [PRs][🤝gh-pulls], or use the gem and think about how it could be better. We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it. See [CONTRIBUTING.md][🤝contributing] for more detailed instructions. ### 🚀 Release Instructions See [CONTRIBUTING.md][🤝contributing]. ### Code Coverage
Coverage service badges [![Coverage Graph][🏀codecov-g]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov]
### 🪇 Code of Conduct Everyone interacting with this project's codebases, issue trackers, chat rooms and mailing lists agrees to follow the [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct]. ## 🌈 Contributors [![Contributors][🖐contributors-img]][🖐contributors] Made with [contributors-img][🖐contrib-rocks]. Also see GitLab Contributors: [https://gitlab.com/ruby-oauth/version_gem/-/graphs/main][🚎contributors-gl]
⭐️ Star History Star History Chart
## 📌 Versioning This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical. For most applications, prefer the [Pessimistic Version Constraint][📌pvc] with two digits of precision. For example: ```ruby spec.add_dependency("version_gem", "~> 1.0") ```
📌 Is "Platform Support" part of the public API? More details inside. Dropping support for a platform can be a breaking change for affected users. If a release changes supported platforms, it should be called out clearly in the changelog and versioned with that impact in mind. To get a better understanding of how SemVer is intended to work over a project's lifetime, read this article from the creator of SemVer: - ["Major Version Numbers are Not Sacred"][📌major-versions-not-sacred]
See [CHANGELOG.md][📌changelog] for a list of releases. ## 📄 License The gem is available as open source under the terms of the [MIT](MIT.md) [![License: MIT][📄license-img]][📄license-ref]. ### © Copyright See [LICENSE.md][📄license] for the official copyright notice.
Copyright holders - Copyright (c) 2022-2023, 2025-2026 Peter H. Boling - Copyright (c) 2024-2025 Aboling0
## 🤑 A request for help Maintainers have teeth and need to pay their dentists. After getting laid off in an RIF in March, and encountering difficulty finding a new one, I began spending most of my time building open source tools. I'm hoping to be able to pay for my kids' health insurance this month, so if you value the work I am doing, I need your support. Please consider sponsoring me or the project. To join the community or get help 👇️ Join the Discord. [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] To say "thanks!" ☝️ Join the Discord or 👇️ send money. [![Sponsor ruby-oauth/version_gem 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] ### Please give the project a star ⭐ ♥. 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. Thanks for RTFM. ☺️ [⛳liberapay-img]: https://img.shields.io/liberapay/goal/pboling.svg?logo=liberapay&color=a51611&style=flat [⛳liberapay-bottom-img]: https://img.shields.io/liberapay/goal/pboling.svg?style=for-the-badge&logo=liberapay&color=a51611 [⛳liberapay]: https://liberapay.com/pboling/donate [🖇osc-all-img]: https://img.shields.io/opencollective/all/ruby-oauth [🖇osc-sponsors-img]: https://img.shields.io/opencollective/sponsors/ruby-oauth [🖇osc-backers-img]: https://img.shields.io/opencollective/backers/ruby-oauth [🖇osc-backers]: https://opencollective.com/ruby-oauth#backer [🖇osc-backers-i]: https://opencollective.com/ruby-oauth/backers/badge.svg?style=flat [🖇osc-sponsors]: https://opencollective.com/ruby-oauth#sponsor [🖇osc-sponsors-i]: https://opencollective.com/ruby-oauth/sponsors/badge.svg?style=flat [🖇osc-all-bottom-img]: https://img.shields.io/opencollective/all/ruby-oauth?style=for-the-badge [🖇osc-sponsors-bottom-img]: https://img.shields.io/opencollective/sponsors/ruby-oauth?style=for-the-badge [🖇osc-backers-bottom-img]: https://img.shields.io/opencollective/backers/ruby-oauth?style=for-the-badge [🖇osc]: https://opencollective.com/ruby-oauth [🖇sponsor-img]: https://img.shields.io/badge/Sponsor_Me!-pboling.svg?style=social&logo=github [🖇sponsor-bottom-img]: https://img.shields.io/badge/Sponsor_Me!-pboling-blue?style=for-the-badge&logo=github [🖇sponsor]: https://github.com/sponsors/pboling [🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat [🖇polar]: https://polar.sh/pboling [🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat [🖇kofi]: https://ko-fi.com/pboling [🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat [🖇patreon]: https://patreon.com/galtzo [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat [🖇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 [🖇buyme]: https://www.buymeacoffee.com/pboling [🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal [🖇paypal-bottom-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=for-the-badge&logo=paypal&color=0A0A0A [🖇paypal]: https://www.paypal.com/paypalme/peterboling [🖇floss-funding.dev]: https://floss-funding.dev [🖇floss-funding-gem]: https://github.com/galtzo-floss/floss_funding [✉️discord-invite]: https://discord.gg/3qme4XHNKN [✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord [✉️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 [✉️ruby-friends]: https://app.daily.dev/squads/rubyfriends [✇bundle-group-pattern]: https://gist.github.com/pboling/4564780 [⛳️gem-namespace]: https://github.com/ruby-oauth/version_gem [⛳️namespace-img]: https://img.shields.io/badge/namespace-VersionGem-3C2D2D.svg?style=square&logo=ruby&logoColor=white [⛳️gem-name]: https://bestgems.org/gems/version_gem [⛳️name-img]: https://img.shields.io/badge/name-version__gem-3C2D2D.svg?style=square&logo=rubygems&logoColor=red [⛳️tag-img]: https://img.shields.io/github/tag/ruby-oauth/version_gem.svg [⛳️tag]: https://github.com/ruby-oauth/version_gem/releases [🚂maint-blog]: http://www.railsbling.com/tags/version_gem [🚂maint-blog-img]: https://img.shields.io/badge/blog-railsbling-0093D0.svg?style=for-the-badge&logo=rubyonrails&logoColor=orange [🚂maint-contact]: http://www.railsbling.com/contact [🚂maint-contact-img]: https://img.shields.io/badge/Contact-Maintainer-0093D0.svg?style=flat&logo=rubyonrails&logoColor=red [💖🖇linkedin]: http://www.linkedin.com/in/peterboling [💖🖇linkedin-img]: https://img.shields.io/badge/LinkedIn-Profile-0B66C2?style=flat&logo=newjapanprowrestling [💖✌️wellfound]: https://wellfound.com/u/peter-boling [💖✌️wellfound-img]: https://img.shields.io/badge/peter--boling-orange?style=flat&logo=wellfound [💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling [💖💲crunchbase-img]: https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase [💖🐘ruby-mast]: https://ruby.social/@galtzo [💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https://ruby.social&style=flat&logo=mastodon&label=Ruby%20@galtzo [💖🦋bluesky]: https://bsky.app/profile/galtzo.com [💖🦋bluesky-img]: https://img.shields.io/badge/@galtzo.com-0285FF?style=flat&logo=bluesky&logoColor=white [💖🌳linktree]: https://linktr.ee/galtzo [💖🌳linktree-img]: https://img.shields.io/badge/galtzo-purple?style=flat&logo=linktree [💖💁🏼‍♂️devto]: https://dev.to/galtzo [💖💁🏼‍♂️devto-img]: https://img.shields.io/badge/dev.to-0A0A0A?style=flat&logo=devdotto&logoColor=white [💖💁🏼‍♂️aboutme]: https://about.me/peter.boling [💖💁🏼‍♂️aboutme-img]: https://img.shields.io/badge/about.me-0A0A0A?style=flat&logo=aboutme&logoColor=white [💖🧊berg]: https://codeberg.org/pboling [💖🐙hub]: https://github.org/pboling [💖🛖hut]: https://sr.ht/~galtzo/ [💖🧪lab]: https://gitlab.com/pboling [👨🏼‍🏫expsup-upwork]: https://www.upwork.com/freelancers/~014942e9b056abdf86?mp_source=share [👨🏼‍🏫expsup-upwork-img]: https://img.shields.io/badge/UpWork-13544E?style=for-the-badge&logo=Upwork&logoColor=white [👨🏼‍🏫expsup-codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github [👨🏼‍🏫expsup-codementor-img]: https://img.shields.io/badge/CodeMentor-Get_Help-1abc9c?style=for-the-badge&logo=CodeMentor&logoColor=white [🏙️entsup-tidelift]: https://tidelift.com/subscription/pkg/rubygems-version_gem?utm_source=rubygems-version_gem&utm_medium=referral&utm_campaign=readme [🏙️entsup-tidelift-img]: https://img.shields.io/badge/Tidelift_and_Sonar-Enterprise_Support-FD3456?style=for-the-badge&logo=sonar&logoColor=white [🏙️entsup-tidelift-sonar]: https://blog.tidelift.com/tidelift-joins-sonar [💁🏼‍♂️peterboling]: http://www.peterboling.com [🚂railsbling]: http://www.railsbling.com [📜src-gl-img]: https://img.shields.io/badge/GitLab-FBA326?style=for-the-badge&logo=Gitlab&logoColor=orange [📜src-gl]: https://gitlab.com/ruby-oauth/version_gem [📜src-cb-img]: https://img.shields.io/badge/CodeBerg-4893CC?style=for-the-badge&logo=CodeBerg&logoColor=blue [📜src-cb]: https://codeberg.org/ruby-oauth/version_gem [📜src-gh-img]: https://img.shields.io/badge/GitHub-238636?style=for-the-badge&logo=Github&logoColor=green [📜src-gh]: https://github.com/ruby-oauth/version_gem [📜docs-cr-rd-img]: https://img.shields.io/badge/RubyDoc-Current_Release-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white [📜docs-head-rd-img]: https://img.shields.io/badge/YARD_on_Galtzo.com-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white [📜gl-wiki]: https://gitlab.com/ruby-oauth/version_gem/-/wikis/home [📜gh-wiki]: https://github.com/ruby-oauth/version_gem/wiki [📜gl-wiki-img]: https://img.shields.io/badge/wiki-gitlab-943CD2.svg?style=for-the-badge&logo=gitlab&logoColor=white [📜gh-wiki-img]: https://img.shields.io/badge/wiki-github-943CD2.svg?style=for-the-badge&logo=github&logoColor=white [👽dl-rank]: https://bestgems.org/gems/version_gem [👽dl-ranki]: https://img.shields.io/gem/rd/version_gem.svg [👽version]: https://bestgems.org/gems/version_gem [👽versioni]: https://img.shields.io/gem/v/version_gem.svg [🏀qlty-mnt]: https://qlty.sh/gh/ruby-oauth/projects/version_gem [🏀qlty-mnti]: https://qlty.sh/gh/ruby-oauth/projects/version_gem/maintainability.svg [🏀qlty-cov]: https://qlty.sh/gh/ruby-oauth/projects/version_gem/metrics/code?sort=coverageRating [🏀qlty-covi]: https://qlty.sh/gh/ruby-oauth/projects/version_gem/coverage.svg [🏀codecov]: https://codecov.io/gh/ruby-oauth/version_gem [🏀codecovi]: https://codecov.io/gh/ruby-oauth/version_gem/graph/badge.svg [🏀coveralls]: https://coveralls.io/github/ruby-oauth/version_gem?branch=main [🏀coveralls-img]: https://coveralls.io/repos/github/ruby-oauth/version_gem/badge.svg?branch=main [🚎ruby-2.4-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/ruby-2.4.yml [🚎ruby-2.5-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/ruby-2.5.yml [🚎ruby-2.6-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/ruby-2.6.yml [🚎ruby-2.7-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/ruby-2.7.yml [🚎ruby-3.0-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/ruby-3.0.yml [🚎ruby-3.1-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/ruby-3.1.yml [🚎ruby-3.2-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/ruby-3.2.yml [🚎ruby-3.3-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/ruby-3.3.yml [🚎ruby-3.4-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/ruby-3.4.yml [🚎jruby-9.2-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/jruby-9.2.yml [🚎jruby-9.3-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/jruby-9.3.yml [🚎jruby-9.4-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/jruby-9.4.yml [🚎truby-22.3-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/truffleruby-22.3.yml [🚎truby-23.0-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/truffleruby-23.0.yml [🚎truby-23.1-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/truffleruby-23.1.yml [🚎truby-24.2-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/truffleruby-24.2.yml [🚎truby-25.0-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/truffleruby-25.0.yml [🚎2-cov-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/coverage.yml [🚎2-cov-wfi]: https://github.com/ruby-oauth/version_gem/actions/workflows/coverage.yml/badge.svg [🚎3-hd-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/heads.yml [🚎3-hd-wfi]: https://github.com/ruby-oauth/version_gem/actions/workflows/heads.yml/badge.svg [🚎5-st-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/style.yml [🚎5-st-wfi]: https://github.com/ruby-oauth/version_gem/actions/workflows/style.yml/badge.svg [🚎9-t-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/truffle.yml [🚎9-t-wfi]: https://github.com/ruby-oauth/version_gem/actions/workflows/truffle.yml/badge.svg [🚎10-j-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/jruby.yml [🚎10-j-wfi]: https://github.com/ruby-oauth/version_gem/actions/workflows/jruby.yml/badge.svg [🚎11-c-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/current.yml [🚎11-c-wfi]: https://github.com/ruby-oauth/version_gem/actions/workflows/current.yml/badge.svg [🚎12-crh-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/dep-heads.yml [🚎12-crh-wfi]: https://github.com/ruby-oauth/version_gem/actions/workflows/dep-heads.yml/badge.svg [🚎13-🔒️-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/locked_deps.yml [🚎13-🔒️-wfi]: https://github.com/ruby-oauth/version_gem/actions/workflows/locked_deps.yml/badge.svg [🚎14-🔓️-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/unlocked_deps.yml [🚎14-🔓️-wfi]: https://github.com/ruby-oauth/version_gem/actions/workflows/unlocked_deps.yml/badge.svg [🚎15-🪪-wf]: https://github.com/ruby-oauth/version_gem/actions/workflows/license-eye.yml [🚎15-🪪-wfi]: https://github.com/ruby-oauth/version_gem/actions/workflows/license-eye.yml/badge.svg [💎ruby-2.2i]: https://img.shields.io/badge/Ruby-2.2_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.3i]: https://img.shields.io/badge/Ruby-2.3_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.4i]: https://img.shields.io/badge/Ruby-2.4-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.5i]: https://img.shields.io/badge/Ruby-2.5-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.6i]: https://img.shields.io/badge/Ruby-2.6-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-2.7i]: https://img.shields.io/badge/Ruby-2.7-DF00CA?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-3.0i]: https://img.shields.io/badge/Ruby-3.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-3.1i]: https://img.shields.io/badge/Ruby-3.1-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-3.2i]: https://img.shields.io/badge/Ruby-3.2-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-3.3i]: https://img.shields.io/badge/Ruby-3.3-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-3.4i]: https://img.shields.io/badge/Ruby-3.4-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-4.0i]: https://img.shields.io/badge/Ruby-4.0-CC342D?style=for-the-badge&logo=ruby&logoColor=white [💎ruby-c-i]: https://img.shields.io/badge/Ruby-current-CC342D?style=for-the-badge&logo=ruby&logoColor=green [💎ruby-headi]: https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue [💎truby-22.3i]: https://img.shields.io/badge/Truffle_Ruby-22.3-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-23.0i]: https://img.shields.io/badge/Truffle_Ruby-23.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-23.1i]: https://img.shields.io/badge/Truffle_Ruby-23.1-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-24.2i]: https://img.shields.io/badge/Truffle_Ruby-24.2-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-25.0i]: https://img.shields.io/badge/Truffle_Ruby-25.0-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink [💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green [💎jruby-9.2i]: https://img.shields.io/badge/JRuby-9.2-FBE742?style=for-the-badge&logo=ruby&logoColor=red [💎jruby-9.3i]: https://img.shields.io/badge/JRuby-9.3-FBE742?style=for-the-badge&logo=ruby&logoColor=red [💎jruby-9.4i]: https://img.shields.io/badge/JRuby-9.4-FBE742?style=for-the-badge&logo=ruby&logoColor=red [💎jruby-c-i]: https://img.shields.io/badge/JRuby-current-FBE742?style=for-the-badge&logo=ruby&logoColor=green [💎jruby-headi]: https://img.shields.io/badge/JRuby-HEAD-FBE742?style=for-the-badge&logo=ruby&logoColor=blue [🤝gh-issues]: https://github.com/ruby-oauth/version_gem/issues [🤝gh-pulls]: https://github.com/ruby-oauth/version_gem/pulls [🤝gl-issues]: https://gitlab.com/ruby-oauth/version_gem/-/issues [🤝gl-pulls]: https://gitlab.com/ruby-oauth/version_gem/-/merge_requests [🤝cb-issues]: https://codeberg.org/ruby-oauth/version_gem/issues [🤝cb-pulls]: https://codeberg.org/ruby-oauth/version_gem/pulls [🤝cb-donate]: https://donate.codeberg.org/ [🤝contributing]: https://github.com/ruby-oauth/version_gem/blob/main/CONTRIBUTING.md [🏀codecov-g]: https://codecov.io/gh/ruby-oauth/version_gem/graph/badge.svg [🖐contrib-rocks]: https://contrib.rocks [🖐contributors]: https://github.com/ruby-oauth/version_gem/graphs/contributors [🖐contributors-img]: https://contrib.rocks/image?repo=ruby-oauth/version_gem [🚎contributors-gl]: https://gitlab.com/ruby-oauth/version_gem/-/graphs/main [🪇conduct]: https://github.com/ruby-oauth/version_gem/blob/main/CODE_OF_CONDUCT.md [🪇conduct-img]: https://img.shields.io/badge/Contributor_Covenant-2.1-259D6C.svg [📌pvc]: http://guides.rubygems.org/patterns/#pessimistic-version-constraint [📌semver]: https://semver.org/spec/v2.0.0.html [📌semver-img]: https://img.shields.io/badge/semver-2.0.0-259D6C.svg?style=flat [📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139 [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html [📌changelog]: https://github.com/ruby-oauth/version_gem/blob/main/CHANGELOG.md [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/ [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat [📌gitmoji]: https://gitmoji.dev [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.058-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue [🔐security]: https://github.com/ruby-oauth/version_gem/blob/main/SECURITY.md [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year [📄license]: LICENSE.md [📄license-ref]: MIT.md [📄license-img]: https://img.shields.io/badge/License-MIT-259D6C.svg [📄license-compat]: https://www.apache.org/legal/resolved.html#category-a [📄license-compat-img]: https://img.shields.io/badge/Apache_Compatible:_Category_A-%E2%9C%93-259D6C.svg?style=flat&logo=Apache [📄ilo-declaration]: https://www.ilo.org/declaration/lang--en/index.htm [📄ilo-declaration-img]: https://img.shields.io/badge/ILO_Fundamental_Principles-✓-259D6C.svg?style=flat [🚎yard-current]: http://rubydoc.info/gems/version_gem [🚎yard-head]: https://version-gem.galtzo.com [💎stone_checksums]: https://github.com/galtzo-floss/stone_checksums [💎SHA_checksums]: https://gitlab.com/ruby-oauth/version_gem/-/tree/main/checksums [💎rlts]: https://github.com/rubocop-lts/rubocop-lts [💎rlts-img]: https://img.shields.io/badge/code_style_&_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white [💎appraisal2]: https://github.com/appraisal-rb/appraisal2 [💎appraisal2-img]: https://img.shields.io/badge/appraised_by-appraisal2-34495e.svg?plastic&logo=ruby&logoColor=white [💎d-in-dvcs]: https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/ | Field | Value | |---|---| | Package | version_gem | | Description | 🍲 Versions are good. Versions are cool. Versions will win. | | Homepage | https://github.com/ruby-oauth/version_gem | | Source | https://github.com/ruby-oauth/version_gem/tree/v1.1.11 | | License | `MIT` | | Funding | https://github.com/sponsors/pboling, https://issuehunt.io/u/pboling, https://ko-fi.com/pboling, https://liberapay.com/pboling/donate, https://opencollective.com/ruby-oauth, https://patreon.com/galtzo, https://polar.sh/pboling, https://thanks.dev/u/gh/pboling, https://tidelift.com/funding/github/rubygems/version_gem, https://www.buymeacoffee.com/pboling | version_gem-1.1.12/sig/0000755000004100000410000000000015214007330014716 5ustar www-datawww-dataversion_gem-1.1.12/sig/debugging.rbs0000755000004100000410000000002015214007330017354 0ustar www-datawww-dataDEBUGGING: bool version_gem-1.1.12/sig/all_formatters.rbs0000755000004100000410000000002515214007330020444 0ustar www-datawww-dataALL_FORMATTERS: bool version_gem-1.1.12/sig/debug_jruby.rbs0000755000004100000410000000002215214007330017724 0ustar www-datawww-dataDEBUG_JRUBY: bool version_gem-1.1.12/sig/run_coverage.rbs0000755000004100000410000000002315214007330020103 0ustar www-datawww-dataRUN_COVERAGE: bool version_gem-1.1.12/sig/version_gem/0000755000004100000410000000000015214007330017233 5ustar www-datawww-dataversion_gem-1.1.12/sig/version_gem/version.rbs0000644000004100000410000000012315214007330021424 0ustar www-datawww-datamodule VersionGem module Version VERSION: String end VERSION: String end version_gem-1.1.12/sig/version_gem/error.rbs0000644000004100000410000000007315214007330021074 0ustar www-datawww-datamodule VersionGem class Error < ::RuntimeError end end version_gem-1.1.12/sig/version_gem/epoch.rbs0000644000004100000410000000117015214007330021040 0ustar www-datawww-datamodule VersionGem module Epoch EPOCH_SIZE: Integer # Hook used when this module is extended def self.extended: (untyped) -> void module OverloadApiForEpoch # The epoch component (derived) def epoch: () -> Integer # Override of Api#major returning the derived major component def major: () -> Integer # Hash representation including epoch def to_h: () -> Hash[Symbol, (Integer | String | nil)] # Array of components [epoch, major, minor, patch, pre] def to_a: () -> Array[Integer | String | nil] private def _major: () -> Integer end end end version_gem-1.1.12/sig/version_gem/api.rbs0000644000004100000410000000116415214007330020516 0ustar www-datawww-datamodule VersionGem module Api # Internal memoized version string segments @_to_a: Array[String] # Memoized components @major: Integer @minor: Integer @patch: Integer @pre: String? @to_a: Array[Integer | String | nil] @to_h: Hash[Symbol, (Integer | String | nil)] # Public API def to_s: () -> String def major: () -> Integer def minor: () -> Integer def patch: () -> Integer def pre: () -> String? def to_a: () -> Array[Integer | String | nil] def to_h: () -> Hash[Symbol, (Integer | String | nil)] private def _to_a: () -> Array[String] end end version_gem-1.1.12/sig/version_gem/ruby.rbs0000644000004100000410000000060215214007330020722 0ustar www-datawww-datamodule VersionGem module Ruby RUBY_VER: ::Gem::Version # Check if the current Ruby version is >= given version for the engine def self.gte_minimum_version?: (String, ?String) -> bool # Check if the current Ruby MAJOR.MINOR equals the given values for the engine def self.actual_minor_version?: ((Integer | String), (Integer | String), ?String) -> bool end end version_gem-1.1.12/sig/version_gem/basic.rbs0000644000004100000410000000011515214007330021021 0ustar www-datawww-datamodule VersionGem module Basic def self.extended: () -> void end end version_gem-1.1.12/sig/debug_ide.rbs0000755000004100000410000000002015214007330017330 0ustar www-datawww-dataDEBUG_IDE: bool version_gem-1.1.12/sig/version_gem.rbs0000644000004100000410000000002615214007330017741 0ustar www-datawww-datamodule VersionGem end version_gem-1.1.12/sig/debug.rbs0000755000004100000410000000001415214007330016512 0ustar www-datawww-dataDEBUG: bool version_gem-1.1.12/CHANGELOG.md0000644000004100000410000002677315214007330015764 0ustar www-datawww-data# Changelog [![SemVer 2.0.0][📌semver-img]][📌semver] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog][📗keep-changelog], and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and [yes][📌major-versions-not-sacred], platform and engine support are part of the [public API][📌semver-breaking]. Please file a bug if you notice a violation of semantic versioning. [📌semver]: https://semver.org/spec/v2.0.0.html [📌semver-img]: https://img.shields.io/badge/semver-2.0.0-FFDD67.svg?style=flat [📌semver-breaking]: https://github.com/semver/semver/issues/716#issuecomment-869336139 [📌major-versions-not-sacred]: https://tom.preston-werner.com/2022/05/23/major-version-numbers-are-not-sacred.html [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/ [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-FFDD67.svg?style=flat ## [Unreleased] ### Added ### Changed ### Deprecated ### Removed ### Fixed ### Security ## [1.1.12] - 2026-06-14 - TAG: [v1.1.12][1.1.12t] - COVERAGE: 100.00% -- 58/58 lines in 2 files - BRANCH COVERAGE: 0.00% -- 0/0 branches in 2 files - 85.19% documented ### Changed - Retemplated repository metadata, workflows, modular gemfiles, and documentation scaffolding with the current `kettle-jem` template. ### Fixed - Restored `docs/CNAME` so the generated documentation site keeps its custom domain. - Corrected misspelled contact metadata to use `galtzo.com`. ## [1.1.11] - 2026-06-06 - TAG: [v1.1.11][1.1.11t] - COVERAGE: 100.00% -- 58/58 lines in 2 files - BRANCH COVERAGE: 0.00% -- 0/0 branches in 2 files - 85.19% documented ### Added - Added the generated `appraisal2` binstub. ### Changed - Refreshed generated CI workflows, README support badges, gemspec development dependency floors, and template metadata from the current kettle-jem template. - Updated generated Appraisal2 integration to use the `appraisal2-rubocop` plugin DSL and raised the generated `appraisal2` / `appraisal2-rubocop` dependency floors. ## [1.1.10] - 2026-06-02 - TAG: [v1.1.10][1.1.10t] - COVERAGE: 100.00% -- 58/58 lines in 2 files - BRANCH COVERAGE: 0.00% -- 0/0 branches in 2 files - 85.19% documented ### Added - StructuredMerge-managed template configuration under `.structuredmerge/`, including semantic Git diff driver settings and kettle-drift integration. - `rubocop-gradual` baseline tracking for style checks. ### Changed - Re-templated the project with the current kettle-jem / StructuredMerge template. - Development and test dependency floors now use current template floors: `kettle-dev` 2.0.7, `kettle-test` 2.0.3, `kettle-soup-cover` 2.0.0, `turbo_tests2` 3.1.1, `rubocop-lts` 8.3.0, and `rubocop-lts-rspec` 1.0.3. - Development and test tooling now targets Ruby 2.4 or newer while the published runtime Ruby requirement remains Ruby 2.2 or newer. - RSpec setup now loads `kettle-test` helpers and kettle-soup-cover coverage bootstrap from `spec/spec_helper.rb`. - Templating dependencies now load only when `K_JEM_TEMPLATING=true`, with local StructuredMerge and Kettle workspace dependencies wired through `SMORG_RB_DEV`, `KETTLE_RB_DEV`, and `nomono`. - Gem metadata and packaging inventory were refreshed by the template, including homepage, wiki, license-file, and packaged file handling. ### Removed - Removed the obsolete `.yard_gfm_support.rb` documentation hook; YARD setup now uses the current template-managed plugin configuration. - Removed obsolete CI workflows for Ruby 2.3, JRuby 9.1, TruffleRuby 23.2, CodeQL, framework CI, and Discord notifications. - Removed legacy generated binstubs in favor of the current curated `kettle-check-eof`, `kettle-test`, and retained documentation binstubs. ### Fixed - logo at top of README.md - Fixed the Style workflow RBS validation command so CI uses the bundled `rbs` executable instead of the non-executable `bin/rbs` binstub. - Fixed the Coverage workflow so Codecov repository-registration/upload errors do not fail CI after local coverage reports have already been generated and verified. ## [1.1.9] - 2025-09-02 - TAG: [v1.1.9][1.1.9t] - COVERAGE: 100.00% -- 118/118 lines in 8 files - BRANCH COVERAGE: 100.00% -- 4/4 branches in 8 files - 84.62% documented ### Added - re-templated gem using kettle-dev v1.1.2 - new binstubs for changelog, readme, commit message, & release management - new CI workflows - enhanced project documentation - More RBS types - docs site: https://version-gem.galtzo.com ### Fixed - RBS types are more accurate ## [1.1.8] 2025-05-06 - TAG: [1.1.8][1.1.8t] - COVERAGE: 100.00% -- 118/118 lines in 8 files - BRANCH COVERAGE: 100.00% -- 4/4 branches in 8 files - 84.62% documented ### Added - CITATION.cff (@pboling) - Cryptographically signed with new 20-year cert (@pboling) - expires 2045-04-29 - Improved documentation (@pboling) - Addressed entire REEK list (@pboling) - GitLab CI, as an addition to existing GHA (@pboling) ## [1.1.7] 2025-04-15 - TAG: [1.1.7][1.1.7t] - Line Coverage: 100.0% (117 / 117) - Branch Coverage: 100.0% (4 / 4) - 76.92% documented ### Added - Support for Epoch Semantic Versioning (@pboling) - `extend VersionGem::Epoch` in your library's `MyLib::Version` module - Support for JRuby 10 (@pboling) - More documentation (@pboling) ### Removed - Ruby 2.2 removed from CI, though technically still supported - can't run directly in GHA anymore ## [1.1.6] 2025-02-24 - TAG: [1.1.6][1.1.6t] - Line Coverage: 100.0% (77 / 77) - Branch Coverage: 100.0% (2 / 2) - 77.78% documented ### Added - Support for JRuby 9.1, 9.2, 9.3, 9.4, and head (@pboling) - Support for Truffle Ruby 22.3, 23.0, 23.1, 24.1, and head (@pboling) - Evergreen current latest engine release workflow (@pboling) - Runs ruby, truffleruby, and jruby, always latest release - Improved developer experience for contributors (@pboling) - More documentation (@pboling) - Switch to stone_checksums for checksum generation (@pboling) ### Changed - Code of Conduct updated - Contributor Covenant v2.0 => v2.1 (@pboling) ## [1.1.5] 2025-02-22 - TAG: [1.1.5][1.1.5t] - Line Coverage: 100.0% (77 / 77) - Branch Coverage: 100.0% (2 / 2) - 77.78% documented ### Added - Document approach to get code coverage on your gem's version.rb file (@pboling) - More documentation, and yard task for documentation (@pboling) - Documentation of Ruby version and SemVer support (@pboling) ### Fixed - [#3](https://gitlab.com/ruby-oauth/version_gem/-/issues/3) - Allow packaging without signing (@pboling) - to support secure linux distros which have alternate means of signing packages within their package managers - Code coverage tracking (@pboling) - Documentation of usage in gemspec via `Kernel.load` (@pboling) - Improved gemspec config (@pboling) ## [1.1.4] 2024-03-21 - TAG: [1.1.4][1.1.4t] ### Added - Ruby 3.3 to CI (@pboling) ### Fixed - Remove the executable bit from non-executable files (@Fryguy) ## [1.1.3] 2023-06-05 - TAG: [1.1.3][1.1.3t] ### Added - More test coverage (now 100% 🎉) (@pboling) - Improved documentation (now 77% 🎉) (@pboling) - Gemfile context pattern (@pboling) - Improved linting (via rubocop-lts) (@pboling) - More robust GHA config (@pboling) - (dev) Dependencies (@pboling) - yard-junk - redcarpet - pry, IRB alternative - pry-suite - debase, for IDE debugging - (dev) Rake task for rubocop_gradual (@pboling) ### Fixed - (dev) `yard` documentation task (@pboling) ### Removed - Formally drop Ruby 2.2 support - Ruby 2.2 was already de facto minimum version supported, which is why this wasn't a 2.0 release. ## [1.1.2] - 2023-03-17 - TAG: [1.1.2][1.1.2t] ### Added - `VersionGem::Ruby` to help library CI integration against many different versions of Ruby (@pboling) - Experimental, optional, require (not loaded by default, which is why this can be in a patch) - Spec coverage is now 100%, lines and branches, including the fabled `version.rb` (@pboling) - Full RBS Signatures (@pboling) ## [1.1.1] - 2022-09-19 - TAG: [1.1.1][1.1.1t] ### Added - Alternatives section to README.md (@pboling) - Signing cert for gem releases (@pboling) - Mailing List and other metadata URIs (@pboling) - Checksums for released gems (@pboling) ### Changed - SECURITY.md policy (@pboling) - Version methods are now memoized (||=) on initial call for performance (@pboling) - Gem releases are now cryptographically signed (@pboling) ## [1.1.0] - 2022-06-24 - TAG: [1.1.0][1.1.0t] ### Added - RSpec Matchers and Shared Example (@pboling) ### Fixed - `to_a` uses same type casting as major, minor, patch, and pre (@pboling) ## [1.0.2] - 2022-06-23 - TAG: [1.0.2][1.0.2t] ### Added - Delay loading of library code until after code coverage tool is loaded (@pboling) ## [1.0.1] - 2022-06-23 - TAG: [1.0.1][1.0.1t] ### Added - CI Build improvements (@pboling) - Code coverage reporting (@pboling) - Documentation improvements (@pboling) - Badges! (@pboling) ## [1.0.0] - 2022-06-21 - TAG: [1.0.0][1.0.0t] ### Added - Initial release, with basic version parsing API (@pboling) [Unreleased]: https://github.com/ruby-oauth/version_gem/compare/v1.1.12...HEAD [1.1.12]: https://github.com/ruby-oauth/version_gem/compare/v1.1.11...v1.1.12 [1.1.12t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.12 [1.1.11]: https://github.com/ruby-oauth/version_gem/compare/v1.1.10...v1.1.11 [1.1.11t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.11 [1.1.10]: https://github.com/ruby-oauth/version_gem/compare/v1.1.9...v1.1.10 [1.1.10t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.10 [1.1.9]: https://github.com/ruby-oauth/version_gem/compare/v1.1.8...v1.1.9 [1.1.9t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.9 [1.1.8]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.1.7...v1.1.8 [1.1.8t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.8 [1.1.7]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.1.6...v1.1.7 [1.1.7t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.7 [1.1.6]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.1.5...v1.1.6 [1.1.6t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.6 [1.1.5]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.1.4...v1.1.5 [1.1.5t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.5 [1.1.4]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.1.3...v1.1.4 [1.1.4t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.4 [1.1.3]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.1.2...v1.1.3 [1.1.3t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.3 [1.1.2]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.1.1...v1.1.2 [1.1.2t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.2 [1.1.1]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.1.0...v1.1.1 [1.1.1t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.1 [1.1.0]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.0.2...v1.1.0 [1.1.0t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.1.0 [1.0.2]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.0.1...v1.0.2 [1.0.2t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.0.2 [1.0.1]: https://gitlab.com/ruby-oauth/version_gem/-/compare/v1.0.0...v1.0.1 [1.0.1t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.0.1 [1.0.0]: https://github.com/ruby-oauth/version_gem/compare/a3055964517c159bf214712940982034b75264be...v1.0.0 [1.0.0t]: https://github.com/ruby-oauth/version_gem/releases/tag/v1.0.0