VersionNumber class models a dot-separated sequence of numbers or strings according to the most common rational versioning practices in the Ruby community.
Version numbers consist of major, minor and patch segements along with an optional build segement which can itself be seperated into a state and revision count.
The VersionNumber class is immutable. All methods that manipulate the verison return a new VersioNumber object.
Shortcut for creating a new verison number given segmented elements.
VersionNumber[1,0,0].to_s #=> "1.0.0" VersionNumber[1,0,0,:pre,2].to_s #=> "1.0.0.pre.2"
# File lib/pom/version_number.rb, line 33 def self.[](*args) new(args) end
Parses a string constraint returning the operation as a lambda.
# File lib/pom/version_number.rb, line 338 def self.constraint_lambda( constraint ) op, val = *parse_constraint( constraint ) lambda { |t| t.send(op, val) } end
Create a new VersionNumber.
version - a String, Hash or Array repsenting the version number
VersionNumber.new("1.0.0") VersionNumber.new([1,0,0]) VersionNumber.new(:major=>1,:minor=>0,:patch=>0)
Returns a new VersionNumber object.
# File lib/pom/version_number.rb, line 46 def initialize(version) case version when String version = version.split('.') @segments = version.map{ |s| /\d+/ =~ s ? s.to_i : s.to_s } when Hash version - version.inject({}){|h,(k,v)| h[k.to_sym] = v; h} version = version.values_at(:major, :minor, :patch, :state, :build).compact @segments = version.split('.').map{ |s| /\d+/ =~ s ? s.to_i : s.to_s } when Array version = version.join('.') @segments = version.split('.').map{ |s| /\d+/ =~ s ? s.to_i : s.to_s } when VersionNumber @segments = version.segments end end
Parses a string constraint returning the operator and value.
# File lib/pom/version_number.rb, line 344 def self.parse_constraint( constraint ) constraint = constraint.strip re = %{^(=~|~>|<=|>=|==|=|<|>)?\s*(\d+(:?[-.]\d+)*)$} if md = re.match( constraint ) if op = md[1] op = '=~' if op == '~>' op = '==' if op == '=' val = new( *md[2].split(/\W+/) ) else op = '==' val = new( *constraint.split(/\W+/) ) end else raise ArgumentError, "invalid constraint" end return op, val end
“Spaceship” comparsion operator.
FIXME: Ensure it can handle state.
# File lib/pom/version_number.rb, line 111 def <=>( other ) #other = other.to_t [@segments.size, other.size].max.times do |i| c = @segments[i] <=> other[i] return c if c != 0 end 0 end
For pessimistic constraint (like ‘~>’ in gems).
FIXME: Ensure it can handle state.
# File lib/pom/version_number.rb, line 123 def =~( other ) #other = other.to_t upver = other.dup upver[0] += 1 @segments >= other and @segments < upver end
Fetch a sepecific segement by index number. In no value is found at that position than zero (0) is returned instead.
v = VersionNumber[1,2,0] v[0] #=> 1 v[1] #=> 2 v[3] #=> 0 v[4] #=> 0
Zero is returned instead of nil to make different version numbers easier to compare.
# File lib/pom/version_number.rb, line 104 def [](index) @segments.fetch(index,0) end
The build number is everything from state segment onward. If no state entries exists then nil is returned.
VersionNumber[1,2,0,:pre,6].build #=> 'pre.6' VersionNumber[1,2,0].build #=> nil
# File lib/pom/version_number.rb, line 166 def build if i = state_index b = @segments[i..-1].join('.') else b = @segments[3..-1].join('.') end b.empty? ? nil : b end
Bump the version returning a new version number object. Select which segement to bump by name: major, minor, patch, state, build and also last.
VersionNumber[1,2,0].bump(:patch).to_s #=> "1.2.1" VersionNumber[1,2,1].bump(:minor).to_s #=> "1.3.0" VersionNumber[1,3,0].bump(:major).to_s #=> "2.0.0" VersionNumber[1,3,0,:pre,1].bump(:build).to_s #=> "1.3.0.pre.2" VersionNumber[1,3,0,:pre,2].bump(:state).to_s #=> "1.3.0.rc.1"
# File lib/pom/version_number.rb, line 223 def bump(which=:patch) case which.to_sym when :major, :first v = [inc(major), 0, 0] when :minor v = [major, inc(minor), 0] when :patch v = [major, minor, inc(patch)] when :state if i = state_index if n = inc(@segments[i]) v = @segments[0...i] + [n] + (@segments[i+1] ? [1] : []) else v = @segments[0...i] end else v = @segments.dup end when :build if i = state_index if i == @segments.size - 1 v = @segments + [1] else v = @segments[0...-1] + [inc(@segments.last)] end else if @segments.size <= 3 v = @segments + [1] else v = @segments[0...-1] + [inc(@segments.last)] end end when :revision if i = state_index v = @segments[0...-1] + [inc(@segments.last)] else v = @segments[0..2] + ['alpha', 1] end when :last v = @segments[0...-1] + [inc(@segments.last)] else v = @segments.dup end self.class.new(v.compact) end
Iterate of each segment of the version. This allows all enumerable methods to be used.
VersionNumber[1,2,3].map{|i| i + 1} #=> [2,3,4]
Though keep in mind that the state segment is not a number (and techincally any segment can be a string instead of an integer).
# File lib/pom/version_number.rb, line 296 def each(&block) @segments.each(&block) end
Major is the first number in the version series.
VersionNumber[1,2,0].major #=> 1
# File lib/pom/version_number.rb, line 135 def major @segments[0] || 0 end
Minor is the second number in the version series.
VersionNumber[1,2,0].minor #=> 2
# File lib/pom/version_number.rb, line 144 def minor @segments[1] || 0 end
Patch is third number in the version series.
VersionNumber[1,5,3].patch #=> 3
# File lib/pom/version_number.rb, line 153 def patch @segments[2] || 0 end
Return a new version have the same major, minor and patch levels, but with a new state and revision count.
VersionNumber[1,2,3].restate(:pre,2).to_s #=> "1.2.3.pre.2" VersionNumber[1,2,3,:pre,2].restate(:rc,4).to_s #=> "1.2.3.rc.4"
# File lib/pom/version_number.rb, line 278 def restate(state, revision=1) if i = state_index v = @segments[0...i] + [state.to_s] + [revision] else v = @segments[0...3] + [state.to_s] + [revision] end self.class.new(v) end
Return the state revision count. This is the number that occurs after the state.
VersionNumber[1,2,0,:rc,4].revision #=> 4
# File lib/pom/version_number.rb, line 196 def revision if i = state_index @segments[i+1] || 0 else nil end end
Return the number of version segements.
VersionNumber[1,2,3].size #=> 3
# File lib/pom/version_number.rb, line 305 def size @segments.size end
State is the version segment that matches any entry in the STATES constant. These include pre, beta, alpha, and so on.
VersionNumber[1,2,0,:pre,6].state #=> 'pre'
# File lib/pom/version_number.rb, line 182 def state if i = state_index @segments[i] else nil end end
Generated with the Darkfish Rdoc Generator 2.