lib/run_loop/version.rb in run_loop-0.2.1 vs lib/run_loop/version.rb in run_loop-1.0.0.pre3

- old
+ new

@@ -1,3 +1,163 @@ module RunLoop - VERSION = '0.2.1' + VERSION = '1.0.0.pre3' + + # A model of a software release version that can be used to compare two versions. + # + # Calabash and RunLoop try very hard to comply with Semantic Versioning rules. + # However, the semantic versioning spec is incompatible with RubyGem's patterns + # for pre-release gems. + # + # > "But returning to the practical: No release version of SemVer is compatible with Rubygems." - _David Kellum_ + # + # Calabash and RunLoop version numbers will be in the form `<major>.<minor>.<patch>[.pre<N>]`. + # + # @see http://semver.org/ + # @see http://gravitext.com/2012/07/22/versioning.html + class Version + + # @!attribute [rw] major + # @return [Integer] the major version + attr_accessor :major + + # @!attribute [rw] minor + # @return [Integer] the minor version + attr_accessor :minor + + # @!attribute [rw] patch + # @return [Integer] the patch version + attr_accessor :patch + + # @!attribute [rw] pre + # @return [Boolean] true if this is a pre-release version + attr_accessor :pre + + # @!attribute [rw] pre_version + # @return [Integer] if this is a pre-release version, returns the + # pre-release version; otherwise this is nil + attr_accessor :pre_version + + # Creates a new Version instance with all the attributes set. + # + # @example + # version = Version.new(0.10.1) + # version.major => 0 + # version.minor => 10 + # version.patch => 1 + # version.pre => false + # version.pre_release => nil + # + # @example + # version = Version.new(1.6.3.pre5) + # version.major => 1 + # version.minor => 6 + # version.patch => 3 + # version.pre => true + # version.pre_release => 5 + # + # @param [String] version the version string to parse. + # @raise [ArgumentError] if version is not in the form 5, 6.1, 7.1.2, 8.2.3.pre1 + def initialize(version) + tokens = version.strip.split('.') + count = tokens.count + if tokens.empty? + raise ArgumentError, "expected '#{version}' to be like 5, 6.1, 7.1.2, 8.2.3.pre1" + end + + if count < 4 and tokens.any? { |elm| elm =~ /\D/ } + raise ArgumentError, "expected '#{version}' to be like 5, 6.1, 7.1.2, 8.2.3.pre1" + end + + if count == 4 + @pre = tokens[3] + pre_tokens = @pre.scan(/\D+|\d+/) + @pre_version = pre_tokens[1].to_i if pre_tokens.count == 2 + end + + @major, @minor, @patch = version.split('.').map(&:to_i) + end + + # Returns an string representation of this version. + # @return [String] a string in the form `<major>.<minor>.<patch>[.pre<N>]` + def to_s + str = [major, minor, patch].compact.join('.') + str = "#{str}.#{pre}" if pre + str + end + + # Compare this version to another for equality. + # @param [Version] other the version to compare against + # @return [Boolean] true if this Version is the same as `other` + def == (other) + Version.compare(self, other) == 0 + end + + # Compare this version to another for inequality. + # @param [Version] other the version to compare against + # @return [Boolean] true if this Version is not the same as `other` + def != (other) + Version.compare(self, other) != 0 + end + + # Is this version less-than another version? + # @param [Version] other the version to compare against + # @return [Boolean] true if this Version is less-than `other` + def < (other) + Version.compare(self, other) < 0 + end + + # Is this version greater-than another version? + # @param [Version] other the version to compare against + # @return [Boolean] true if this Version is greater-than `other` + def > (other) + Version.compare(self, other) > 0 + end + + # Is this version less-than or equal to another version? + # @param [Version] other the version to compare against + # @return [Boolean] true if this Version is less-than or equal `other` + def <= (other) + Version.compare(self, other) <= 0 + end + + # Is this version greater-than or equal to another version? + # @param [Version] other the version to compare against + # @return [Boolean] true if this Version is greater-than or equal `other` + def >= (other) + Version.compare(self, other) >= 0 + end + + # Compare version `a` to version `b`. + # + # @example + # compare Version.new(0.10.0), Version.new(0.9.0) => 1 + # compare Version.new(0.9.0), Version.new(0.10.0) => -1 + # compare Version.new(0.9.0), Version.new(0.9.0) => 0 + # + # @return [Integer] an integer `(-1, 1)` + def self.compare(a, b) + + if a.major != b.major + return a.major > b.major ? 1 : -1 + end + + if a.minor != b.minor + return a.minor.to_i > b.minor.to_i ? 1 : -1 + end + + if a.patch != b.patch + return a.patch.to_i > b.patch.to_i ? 1 : -1 + end + + return 1 if a.pre and (not b.pre) + return -1 if (not a.pre) and b.pre + + return 1 if a.pre_version and (not b.pre_version) + return -1 if (not a.pre_version) and b.pre_version + + if a.pre_version != b.pre_version + return a.pre_version.to_i > b.pre_version.to_i ? 1 : -1 + end + 0 + end + end end