Class: QB::Package::Version
- Inherits:
-
Util::Resource
- Object
- NRSER::Meta::Props::Base
- Util::Resource
- QB::Package::Version
- Includes:
- Util::DockerMixin
- Defined in:
- lib/qb/package/version.rb
Overview
An attempt to unify NPM and Gem version schemes to a reasonable extend, and hopefully cover whatever else the cat may drag in.
Intended to be immutable for practical purposes.
Constant Summary collapse
- NUMBER_SEGMENT =
Constants
t.non_neg_int
- NAME_SEGMENT =
t.str
- MIXED_SEGMENT =
t.union NUMBER_SEGMENT, NAME_SEGMENT
Constants included from Util::DockerMixin
Util::DockerMixin::DOCKER_TAG_MAX_CHARACTERS, Util::DockerMixin::DOCKER_TAG_VALID_RE
Instance Attribute Summary collapse
-
#level ⇒ Object
readonly
Attributes =====================================================================.
-
#release ⇒ Object
readonly
Attributes =====================================================================.
Class Method Summary collapse
-
.from_docker_tag(version) ⇒ QB::Package::Version
Parse Docker image tag version into a string.
-
.from_gem_version(version) ⇒ QB::Package::Version
Create a Version instance from a Version.
- .from_npm_version(version) ⇒ Object
-
.from_string(string) ⇒ QB::Package::Version
Parse string version into an instance.
-
.to_time_segment(time) ⇒ String
Time formatted to be stuck in a version segment per Semver spec.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Test for equality.
-
#build? ⇒ Boolean
"Gem" version format, so this will always be false when loading a Gem version.
- #build_commit ⇒ return_type
- #build_dirty? ⇒ return_type
-
#build_version(branch: nil, ref: nil, time: nil, dirty: nil) ⇒ QB::Package::Version
Return a new Version with build information added.
-
#dev? ⇒ Boolean
True if this version is a dev prerelease (first prerelease element is 'dev').
-
#docker_tag ⇒ String
Docker image tag for the version.
- #eql?(other) ⇒ Boolean
- #hash ⇒ Object
-
#initialize(**values) ⇒ Version
constructor
Construct a new Version.
-
#level? ⇒ Boolean
True if self is a prerelease version that starts with a string that we consider the 'level'.
-
#prerelease? ⇒ Boolean
True if any prerelease segments are present (stuff after '-' in SemVer / "NPM" format, or the first string segment and anything following it in "Gem" format).
- #prerelease_version ⇒ QB::Package::Version
-
#rc? ⇒ Boolean
True if this version is a release candidate (first prerelease element is 'rc').
-
#release? ⇒ Boolean
True if this version is a release (no prerelease or build values).
- #release_version ⇒ QB::Package::Version
-
#semver ⇒ String
(also: #normalized)
The Semver version string (
Major.minor.patch-prerelease+buildformat). -
#to_a ⇒ Array
Return array of the version elements in order from greatest to least precedence.
- #to_s ⇒ Object
Methods included from Util::DockerMixin
Constructor Details
#initialize(**values) ⇒ Version
Construct a new Version
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/qb/package/version.rb', line 194 def initialize **values super **values @release = [major, minor, patch].join '.' @level = t.match prerelease[0], { t.is(nil) => ->(_) { if build.empty? 'release' end }, NAME_SEGMENT => ->(str) { str }, NUMBER_SEGMENT => ->(int) { nil }, } end |
Instance Attribute Details
#level ⇒ Object (readonly)
Attributes
82 83 84 |
# File 'lib/qb/package/version.rb', line 82 def level @level end |
#release ⇒ Object (readonly)
Attributes
82 83 84 |
# File 'lib/qb/package/version.rb', line 82 def release @release end |
Class Method Details
.from_docker_tag(version) ⇒ QB::Package::Version
Parse Docker image tag version into a string. Reverse of #docker_tag.
166 167 168 |
# File 'lib/qb/package/version.rb', line 166 def self.from_docker_tag version from_string(version.gsub('_', '+')).merge raw: version end |
.from_gem_version(version) ⇒ QB::Package::Version
Create a Version instance from a QB::Package::Version.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/qb/package/version.rb', line 109 def self.from_gem_version version # release segments are everything before a string release_segments = version.segments.take_while { |seg| !seg.is_a?(String) } # We don't support > 3 release segments to make life somewhat # reasonable. Yeah, I think I've seen projects do it. We'll cross that # bridge if and when we get to it. if release_segments.length > 3 raise ArgumentError, "We don't handle releases with more than 3 segments " + "(found #{ release_segments.inspect } in #{ version })" end prerelease_segments = version.segments[release_segments.length..-1] new raw: version.to_s, major: release_segments[0] || 0, minor: release_segments[1] || 0, patch: release_segments[2] || 0, prerelease: prerelease_segments, build: [] end |
.from_npm_version(version) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/qb/package/version.rb', line 134 def self.from_npm_version version stmt = NRSER.squish <<-END var Semver = require('semver'); console.log( JSON.stringify( Semver(#{ JSON.dump version }) ) ); END parse = JSON.load Cmds.new( "node --eval %s", args: [stmt], chdir: QB::ROOT ).out! new raw: version, major: parse['major'], minor: parse['minor'], patch: parse['patch'], prerelease: parse['prerelease'], build: parse['build'] end |
.from_string(string) ⇒ QB::Package::Version
Parse string version into an instance. Accept Semver, Ruby Gem and Docker image tag formats.
179 180 181 182 183 184 185 186 187 |
# File 'lib/qb/package/version.rb', line 179 def self.from_string string if string.include? '_' self.from_docker_tag string elsif string.include?( '-' ) || string.include?( '+' ) self.from_npm_version string else self.from_gem_version Gem::Version.new(string) end end |
.to_time_segment(time) ⇒ String
Returns Time formatted to be stuck in a version segment per Semver spec. We also strip out '-' to avoid possible parsing weirdness.
95 96 97 |
# File 'lib/qb/package/version.rb', line 95 def self.to_time_segment time time.utc.iso8601.gsub /[^0-9A-Za-z]/, '' end |
Instance Method Details
#==(other) ⇒ Boolean
Test for equality.
Compares classes then #to_a results.
405 406 407 408 |
# File 'lib/qb/package/version.rb', line 405 def == other other.class == self.class && other.to_a == self.to_a end |
#build? ⇒ Boolean
"Gem" version format, so this will always be false when loading a Gem version.
246 247 248 |
# File 'lib/qb/package/version.rb', line 246 def build? !build.empty? end |
#build_commit ⇒ return_type
Document commit method.
Returns @todo Document return value.
325 326 327 328 329 |
# File 'lib/qb/package/version.rb', line 325 def build_commit if build? build.find { |seg| seg =~ /[0-9a-f]{7}/ } end end |
#build_dirty? ⇒ return_type
Document build_dirty? method.
Returns @todo Document return value.
259 260 261 262 263 |
# File 'lib/qb/package/version.rb', line 259 def build_dirty? if build? build.include? 'dirty' end end |
#build_version(branch: nil, ref: nil, time: nil, dirty: nil) ⇒ QB::Package::Version
Return a new QB::Package::Version with build information added.
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/qb/package/version.rb', line 363 def build_version branch: nil, ref: nil, time: nil, dirty: nil time = self.class.to_time_segment(time) unless time.nil? segments = [ branch, ref, ('dirty' if dirty), time, ].reject &:nil? if segments.empty? raise ArgumentError, "Need to provide at least one of branch, ref, time." end merge raw: nil, build: segments end |
#dev? ⇒ Boolean
Returns True if this version is a dev prerelease (first prerelease element is 'dev').
279 280 281 |
# File 'lib/qb/package/version.rb', line 279 def dev? level == 'dev' end |
#docker_tag ⇒ String
Docker image tag for the version.
338 339 340 |
# File 'lib/qb/package/version.rb', line 338 def docker_tag self.class.to_docker_tag semver end |
#eql?(other) ⇒ Boolean
448 449 450 |
# File 'lib/qb/package/version.rb', line 448 def eql? other self == other && self.hash == other.hash end |
#hash ⇒ Object
443 444 445 |
# File 'lib/qb/package/version.rb', line 443 def hash to_a.hash end |
#level? ⇒ Boolean
Returns True if self is a prerelease version that starts with a string that we consider the 'level'.
270 271 272 |
# File 'lib/qb/package/version.rb', line 270 def level? !level.nil? end |
#prerelease? ⇒ Boolean
Returns True if any prerelease segments are present (stuff after '-' in SemVer / "NPM" format, or the first string segment and anything following it in "Gem" format). Tests if @prerelease is not empty.
233 234 235 |
# File 'lib/qb/package/version.rb', line 233 def prerelease? !prerelease.empty? end |
#prerelease_version ⇒ QB::Package::Version
Returns A new QB::Package::Version created from #release and #prerelease data, but without any build information.
386 387 388 |
# File 'lib/qb/package/version.rb', line 386 def prerelease_version merge raw: nil, build: [] end |
#rc? ⇒ Boolean
Returns True if this version is a release candidate (first prerelease element is 'rc').
288 289 290 |
# File 'lib/qb/package/version.rb', line 288 def rc? level == 'rc' end |
#release? ⇒ Boolean
Returns True if this version is a release (no prerelease or build values).
222 223 224 |
# File 'lib/qb/package/version.rb', line 222 def release? prerelease.empty? && build.empty? end |
#release_version ⇒ QB::Package::Version
Returns A new QB::Package::Version created from #release. Even if self
is a release version already, still returns a new instance.
354 355 356 |
# File 'lib/qb/package/version.rb', line 354 def release_version self.class.from_string release end |
#semver ⇒ String Also known as: normalized
Returns The Semver version string
(Major.minor.patch-prerelease+build format).
300 301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/qb/package/version.rb', line 300 def semver result = release unless prerelease.empty? result += "-#{ prerelease.join '.' }" end unless build.empty? result += "+#{ build.join '.' }" end result end |
#to_a ⇒ Array
432 433 434 435 436 437 438 439 440 |
# File 'lib/qb/package/version.rb', line 432 def to_a [ major, minor, patch, prerelease, build, ] end |
#to_s ⇒ Object
453 454 455 |
# File 'lib/qb/package/version.rb', line 453 def to_s "#<QB::Package::Version #{ @raw }>" end |