:toc: macro :toclevels: 5 :figure-caption!: = Versionaire [link=http://badge.fury.io/rb/versionaire] image::https://badge.fury.io/rb/versionaire.svg[Gem Version] [link=https://circleci.com/gh/bkuhlmann/versionaire] image::https://circleci.com/gh/bkuhlmann/versionaire.svg?style=svg[Circle CI Status] Provides an immutable, thread-safe, and semantic version type when managing versions within your applications. toc::[] == Features * Provides https://semver.org[Semantic Versioning]. * Provides immutable, thread-safe version instances. * Converts (casts) from a `String`, `Array`, `Hash`, or `Version` to a `Version`. == Screencasts [link=https://www.alchemists.io/screencasts/versionaire.html] image::https://www.alchemists.io/images/screencasts/versionaire/cover-original.png[Screencast,role=focal_point] == Requirements . https://www.ruby-lang.org[Ruby 2.7.x]. == Setup === Production To install, run: [source,bash] ---- gem install versionaire ---- Add the following to your Gemfile: [source,ruby] ---- gem "versionaire" ---- === Development To contribute, run: [source,bash] ---- git clone https://github.com/bkuhlmann/versionaire.git cd versionaire bin/setup ---- You can also use the IRB console for direct access to all objects: [source,bash] ---- bin/console ---- == Usage === Initialization A new version can be initialized in a variety of ways: [source,ruby] ---- Versionaire::Version.new # "0.0.0" Versionaire::Version[major: 1] # "1.0.0" Versionaire::Version[major: 1, minor: 2] # "1.2.0" Versionaire::Version[major: 1, minor: 2, patch: 3] # "1.2.3" ---- === Equality ==== Value (`+#==+`) Equality is deterimined by the state of the object. This means that a version is equal to another version as long as all of the values (i.e. state) are equal to each other. Example: [source,ruby] ---- version_a = Versionaire::Version[major: 1] version_b = Versionaire::Version[major: 2] version_c = Versionaire::Version[major: 1] version_a == version_a # true version_a == version_b # false version_a == version_c # true ---- Knowning this, versions can be compared against one another too: [source,ruby] ---- version_a > version_b # false version_a < version_b # true version_a.between? version_c, version_b # true ---- ==== Hash (`#eql?`) Behaves exactly as `#==`. ==== Case (`#===`) Behaves exactly as `#==`. ==== Identity (`#equal?`) Works like any other standard Ruby object where an object is equal only to itself. [source,ruby] ---- version_a = Versionaire::Version[major: 1] version_b = Versionaire::Version[major: 2] version_c = Versionaire::Version[major: 1] version_a.equal? version_a # true version_a.equal? version_b # false version_a.equal? version_c # false ---- === Conversions ==== Function (Casting) The `Versionaire::Version` function is provided for explicit casting to a version: [source,ruby] ---- version = Versionaire::Version[major: 1] Versionaire::Version "1.0.0" Versionaire::Version [1, 0, 0] Versionaire::Version major: 1, minor: 0, patch: 0 Versionaire::Version version ---- Each of these conversions will result in a version object that represents "`1.0.0`". When attempting to convert an unsupported type, a `+Versionaire::Errors::Conversion+` exception will be thrown. ==== Implicit Implicit conversion to a `+String+` is supported: [source,ruby] ---- "1.0.0".match Versionaire::Version[major: 1] # ---- ==== Explicit Explicit conversion to a `String`, `Array`, or `Hash` is supported: [source,ruby] ---- version = Versionaire::Version.new version.to_s # "0.0.0" version.to_a # [0, 0, 0] version.to_h # {major: 0, minor: 0, patch: 0} ---- === Comparisons All versions are comparable which means any of the operators from the `+Comparable+` module will work. Example: [source,ruby] ---- version_1 = Versionaire::Version "1.0.0" version_2 = Versionaire::Version "2.0.0" version_1 < version_2 # true version_1 <= version_2 # true version_1 == version_2 # false (see Equality section above for details) version_1 > version_2 # false version_1 >= version_2 # false version_1.between? version_1, version_2 # true version_1.clamp version_1, version_2 # version_1 (added in Ruby 2.4.0) ---- === Math Versions can be added and subtracted from each other. ==== Addition [source,ruby] ---- version_1 = Versionaire::Version[major: 1, minor: 2, patch: 3] version_2 = Versionaire::Version[major: 2, minor: 5, patch: 7] version_1 + version_2 # "3.7.10" ---- ==== Subtraction [source,ruby] ---- version_1 = Versionaire::Version[major: 1, minor: 2, patch: 3] version_2 = Versionaire::Version[major: 1, minor: 1, patch: 1] version_1 - version_2 # "0.1.2" version_1 = Versionaire::Version[major: 1] version_2 = Versionaire::Version[major: 5] version_1 - version_2 # Fails with a Versionaire::Errors::NegativeNumber ---- == Tests To test, run: [source,bash] ---- bundle exec rake ---- == Versioning Read link:https://semver.org[Semantic Versioning] for details. Briefly, it means: * Major (X.y.z) - Incremented for any backwards incompatible public API changes. * Minor (x.Y.z) - Incremented for new, backwards compatible, public API enhancements/fixes. * Patch (x.y.Z) - Incremented for small, backwards compatible, bug fixes. == Code of Conduct Please note that this project is released with a link:CODE_OF_CONDUCT.adoc[CODE OF CONDUCT]. By participating in this project you agree to abide by its terms. == Contributions Read link:CONTRIBUTING.adoc[CONTRIBUTING] for details. == License Read link:LICENSE.adoc[LICENSE] for details. == History Read link:CHANGES.adoc[CHANGES] for details. == Credits Engineered by link:https://www.alchemists.io/team/brooke_kuhlmann.html[Brooke Kuhlmann].