Class: DataMetaDom::SemVer

Inherits:
Object
  • Object
show all
Defined in:
lib/dataMetaDom/ver.rb

Overview

Semantic Version implementation.

See this page for details

Defined Under Namespace

Classes: DiffLevel

Constant Summary collapse

DOTS_SPLIT =

Split by dots pattern

%r<\.>
DIGITS =

Any Integral part of the Version - just digits

%r<^[0-9]+$>
MAJOR_INDEX =

Major part index in the @items array

0
MINOR_INDEX =

Minor part index in the @items array

MAJOR_INDEX + 1
UPDATE_INDEX =

Update part index in the @items array

MINOR_INDEX + 1
BUILD_INDEX =

Build part index in the @items array

UPDATE_INDEX + 1
ITEMS_MIN_SIZE =

Minimal size of the @items array

UPDATE_INDEX + 1
ITEMS_MAX_SIZE =

Max size of the @items array

BUILD_INDEX + 1
EQ =

Equality for the saucer operator <=>

0
GT =

Strictly “greater than” for the saucer operator <=>

1
LT =

Strictly “lesser than” for the saucer operator <=>

-1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(src) ⇒ SemVer

Parsing constructor

Raises:

  • (ArgumentError)


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/dataMetaDom/ver.rb', line 52

def initialize(src)
    raise ArgumentError, "Attempted to create an instance of #{self.class.name} from a nil" if src.nil?
    @source = src
    # put everything in an array -- this provides free eql? and hash() methods
    @items = []
    src.split(DOTS_SPLIT).each { |i|
        if i =~ DIGITS
            @items << i.to_i
        else
            break
        end
    }
    raise ArgumentError, %<Invalid semantic version format: #{src}> if items.size < ITEMS_MIN_SIZE ||
            items.size > ITEMS_MAX_SIZE

    raise ArgumentError,
          %<Invalid semantic version format: "#{src}": build version can not be zero.> unless build.nil? ||
            build != 0

    @semanticPartsOnly  = @items.map{|i| i.to_s}.join('.')

end

Instance Attribute Details

#itemsObject (readonly)

Returns the value of attribute items.



16
17
18
# File 'lib/dataMetaDom/ver.rb', line 16

def items
  @items
end

#semanticPartsOnlyObject (readonly)

Returns the value of attribute semanticPartsOnly.



16
17
18
# File 'lib/dataMetaDom/ver.rb', line 16

def semanticPartsOnly
  @semanticPartsOnly
end

#sourceObject (readonly)

Returns the value of attribute source.



16
17
18
# File 'lib/dataMetaDom/ver.rb', line 16

def source
  @source
end

Class Method Details

.fromSpecs(specs) ⇒ Object

Builds an instance of SemVer from the given specs whatever they are



153
154
155
156
157
158
159
160
161
162
# File 'lib/dataMetaDom/ver.rb', line 153

def fromSpecs(specs)
    case specs
        when SemVer
            specs
        when String
            SemVer.new(specs)
        else
            raise ArgumentError, %<Unsupported SemVer specs type #{specs}==#{specs.inspect}>
    end
end

Instance Method Details

#<(other) ⇒ Object

Overload the lesser-than operator



145
# File 'lib/dataMetaDom/ver.rb', line 145

def <(other); self.<=>(other) == LT end

#<=(other) ⇒ Object

Overload the lesser-than-or-equals operator



149
# File 'lib/dataMetaDom/ver.rb', line 149

def <=(other); self.<=>(other) <= EQ end

#<=>(o) ⇒ Object

The Saucer Operator, Ruby equivalent of Java’s compareTo(…)

Raises:

  • (ArgumentError)


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/dataMetaDom/ver.rb', line 109

def <=>(o)
    raise ArgumentError, %<Attempt to compare #{self.class.name} "#{self}" to a nil> if o.nil?

    0.upto(UPDATE_INDEX) { |x|
        cmp = items[x] <=> o.items[x]
        return cmp unless cmp == EQ #  not equal: end of the story, that's the comparison result
    }
    # if we are here, the Minor, Major and the Update are equal. See what's up with the build if any:

    # this object is newer (version bigger) because it has a build number but the other does not
    return GT if items.size > o.items.size

    # this object is older (version lesser) because it does not have a build number but the other does
    return LT if items.size < o.items.size

    # We got build part in self and the other, return the build part comparison:
    build <=> o.build
end

#==(other) ⇒ Object

Overload the equals operator



141
# File 'lib/dataMetaDom/ver.rb', line 141

def ==(other); self.<=>(other) == EQ end

#>(other) ⇒ Object

Overload the greater-than operator



143
# File 'lib/dataMetaDom/ver.rb', line 143

def >(other); self.<=>(other) == GT end

#>=(other) ⇒ Object

Overload the greater-than-or-equals operator



147
# File 'lib/dataMetaDom/ver.rb', line 147

def >=(other); self.<=>(other) >= EQ end

#buildObject

Build part of the version or nil



85
# File 'lib/dataMetaDom/ver.rb', line 85

def build; items.size > BUILD_INDEX ? @items[BUILD_INDEX] : nil end

#diffLevel(other) ⇒ Object

Difference Level, computes one of the DiffLevel values



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/dataMetaDom/ver.rb', line 88

def diffLevel(other)
    return DiffLevel::MAJOR if major != other.major
    return DiffLevel::MINOR if minor != other.minor
    return DiffLevel::UPDATE if update != other.update
    if (
       !build.nil? && !other.build.nil? && (build <=> other.build) != EQ
    ) || (
       build.nil? && !other.build.nil?
    ) || ( !build.nil? && other.build.nil? )
        return DiffLevel::BUILD
    end
    DiffLevel::NONE
end

#eql?(o) ⇒ Boolean

Override the eql? for the == operator to work

Returns:

  • (Boolean)


103
# File 'lib/dataMetaDom/ver.rb', line 103

def eql?(o); @items == o.items end

#hashObject

Override the hash() method for the sets and maps to work



106
# File 'lib/dataMetaDom/ver.rb', line 106

def hash; @items.hash end

#majorObject

Major part of the version



76
# File 'lib/dataMetaDom/ver.rb', line 76

def major; @items[MAJOR_INDEX] end

#minorObject

Minor part of the version



79
# File 'lib/dataMetaDom/ver.rb', line 79

def minor; @items[MINOR_INDEX] end

#to_long_sObject

Long string for debugging and detailed logging - shows semantic parts as parsed



132
# File 'lib/dataMetaDom/ver.rb', line 132

def to_long_s; "#{self.class.name}{#{@source}(#{@semanticPartsOnly})}" end

#to_sObject

For a simple string representation, just show the source



129
# File 'lib/dataMetaDom/ver.rb', line 129

def to_s; @source end

#toVarNameObject

Consistently and reproducibly convert the version specs to the text suitable for making it a part of a class name or a variable name



138
# File 'lib/dataMetaDom/ver.rb', line 138

def toVarName; @items.join('_') end

#updateObject

Update part of the version



82
# File 'lib/dataMetaDom/ver.rb', line 82

def update; @items[UPDATE_INDEX] end