mixlib-versioning-1.1.0/0000755000175000017500000000000012703167554014540 5ustar globusglobusmixlib-versioning-1.1.0/lib/0000755000175000017500000000000012703167554015306 5ustar globusglobusmixlib-versioning-1.1.0/lib/mixlib/0000755000175000017500000000000012703167554016572 5ustar globusglobusmixlib-versioning-1.1.0/lib/mixlib/versioning/0000755000175000017500000000000012703167554020755 5ustar globusglobusmixlib-versioning-1.1.0/lib/mixlib/versioning/format.rb0000644000175000017500000003054212703167554022576 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'mixlib/versioning/format/git_describe' require 'mixlib/versioning/format/opscode_semver' require 'mixlib/versioning/format/rubygems' require 'mixlib/versioning/format/semver' module Mixlib class Versioning # @author Seth Chisamore () # # @!attribute [r] major # @return [Integer] major identifier # @!attribute [r] minor # @return [Integer] minor identifier # @!attribute [r] patch # @return [Integer] patch identifier # @!attribute [r] prerelease # @return [String] pre-release identifier # @!attribute [r] build # @return [String] build identifier # @!attribute [r] iteration # @return [String] build interation # @!attribute [r] input # @return [String] original input version string that was parsed class Format include Comparable # Returns the {Mixlib::Versioning::Format} class that maps to the given # format type. # # @example # Mixlib::Versioning::Format.for(:semver) # Mixlib::Versioning::Format.for('semver') # Mixlib::Versioning::Format.for(Mixlib::Versioning::Format::SemVer) # # @param format_type [String, Symbol, Mixlib::Versioning::Format] Name of # a valid +Mixlib::Versioning::Format+ in Class or snake-case form. # # @raise [Mixlib::Versioning::UnknownFormatError] if the given format # type doesn't exist # # @return [Class] the {Mixlib::Versioning::Format} class # def self.for(format_type) if format_type.is_a?(Class) && format_type.ancestors.include?(Mixlib::Versioning::Format) format_type else case format_type.to_s when 'semver' then Mixlib::Versioning::Format::SemVer when 'opscode_semver' then Mixlib::Versioning::Format::OpscodeSemVer when 'git_describe' then Mixlib::Versioning::Format::GitDescribe when 'rubygems' then Mixlib::Versioning::Format::Rubygems else msg = "'#{format_type}' is not a supported Mixlib::Versioning format" fail Mixlib::Versioning::UnknownFormatError, msg end end end attr_reader :major, :minor, :patch, :prerelease, :build, :iteration, :input # @param version_string [String] string representation of the version def initialize(version_string) parse(version_string) @input = version_string end # Parses the version string splitting it into it's component version # identifiers for easy comparison and sorting of versions. This method # **MUST** be overriden by all descendants of this class. # # @param version_string [String] string representation of the version # @raise [Mixlib::Versioning::ParseError] raised if parsing fails def parse(_version_string) fail Error, 'You must override the #parse' end # @return [Boolean] Whether or not this is a release version def release? @prerelease.nil? && @build.nil? end # @return [Boolean] Whether or not this is a pre-release version def prerelease? !@prerelease.nil? && @build.nil? end # @return [Boolean] Whether or not this is a release build version def release_build? @prerelease.nil? && !@build.nil? end # @return [Boolean] Whether or not this is a pre-release build version def prerelease_build? !@prerelease.nil? && !@build.nil? end # @return [Boolean] Whether or not this is a build version def build? !@build.nil? end # Returns `true` if `other` and this {Format} share the same `major`, # `minor`, and `patch` values. Pre-release and build specifiers are not # taken into consideration. # # @return [Boolean] def in_same_release_line?(other) @major == other.major && @minor == other.minor && @patch == other.patch end # Returns `true` if `other` an share the same # `major`, `minor`, and `patch` values. Pre-release and build specifiers # are not taken into consideration. # # @return [Boolean] def in_same_prerelease_line?(other) @major == other.major && @minor == other.minor && @patch == other.patch && @prerelease == other.prerelease end # @return [String] String representation of this {Format} instance def to_s @input end # Since the default implementation of `Object#inspect` uses `Object#to_s` # under the covers (which we override) we need to also override `#inspect` # to ensure useful debug information. def inspect vars = instance_variables.map do |n| "#{n}=#{instance_variable_get(n).inspect}" end format('#<%s:0x%x %s>', self.class, object_id, vars.join(', ')) end # Returns SemVer compliant string representation of this {Format} # instance. The string returned will take on the form: # # ```text # MAJOR.MINOR.PATCH-PRERELEASE+BUILD # ``` # # @return [String] SemVer compliant string representation of this # {Format} instance # @todo create a proper serialization abstraction def to_semver_string s = [@major, @minor, @patch].join('.') s += "-#{@prerelease}" if @prerelease s += "+#{@build}" if @build s end # Returns Rubygems compliant string representation of this {Format} # instance. The string returned will take on the form: # # ```text # MAJOR.MINOR.PATCH.PRERELEASE # ``` # # @return [String] Rubygems compliant string representation of this # {Format} instance # @todo create a proper serialization abstraction def to_rubygems_string s = [@major, @minor, @patch].join('.') s += ".#{@prerelease}" if @prerelease s end # Compare this version number with the given version number, following # Semantic Versioning 2.0.0-rc.1 semantics. # # @param other [Mixlib::Versioning::Format] # @return [Integer] -1, 0, or 1 depending on whether the this version is # less than, equal to, or greater than the other version def <=>(other) # Check whether the `other' is a String and if so, then get an # instance of *this* class (e.g., GitDescribe, OpscodeSemVer, # SemVer, Rubygems, etc.), so we can compare against it. other = self.class.new(other) if other.is_a?(String) # First, perform comparisons based on major, minor, and patch # versions. These are always presnt and always non-nil maj = @major <=> other.major return maj unless maj == 0 min = @minor <=> other.minor return min unless min == 0 pat = @patch <=> other.patch return pat unless pat == 0 # Next compare pre-release specifiers. A pre-release sorts # before a release (e.g. 1.0.0-alpha.1 comes before 1.0.0), so # we need to take nil into account in our comparison. # # If both have pre-release specifiers, we need to compare both # on the basis of each component of the specifiers. if @prerelease && other.prerelease.nil? return -1 elsif @prerelease.nil? && other.prerelease return 1 elsif @prerelease && other.prerelease pre = compare_dot_components(@prerelease, other.prerelease) return pre unless pre == 0 end # Build specifiers are compared like pre-release specifiers, # except that builds sort *after* everything else # (e.g. 1.0.0+build.123 comes after 1.0.0, and # 1.0.0-alpha.1+build.123 comes after 1.0.0-alpha.1) if @build.nil? && other.build return -1 elsif @build && other.build.nil? return 1 elsif @build && other.build build_ver = compare_dot_components(@build, other.build) return build_ver unless build_ver == 0 end # Some older version formats improperly include a package iteration in # the version string. This is different than a build specifier and # valid release versions may include an iteration. We'll transparently # handle this case and compare iterations if it was parsed by the # implementation class. if @iteration.nil? && other.iteration return -1 elsif @iteration && other.iteration.nil? return 1 elsif @iteration && other.iteration return @iteration <=> other.iteration end # If we get down here, they're both equal 0 end # @param other [Mixlib::Versioning::Format] # @return [Boolean] returns true if the versions are equal, false # otherwise. def eql?(other) @major == other.major && @minor == other.minor && @patch == other.patch && @prerelease == other.prerelease && @build == other.build end def hash [@major, @minor, @patch, @prerelease, @build].compact.join('.').hash end ######################################################################### private # If a String `n` can be parsed as an Integer do so; otherwise, do # nothing. # # @param n [String, nil] # @return [Integer] the parsed {Integer} def maybe_int(n) Integer(n) rescue n end # Compares prerelease and build version component strings # according to SemVer 2.0.0-rc.1 semantics. # # Returns -1, 0, or 1, just like the spaceship operator (`<=>`), # and is used in the implemntation of `<=>` for this class. # # Pre-release and build specifiers are dot-separated strings. # Numeric components are sorted numerically; otherwise, sorting is # standard ASCII order. Numerical components have a lower # precedence than string components. # # See http://www.semver.org for more. # # Both `a_item` and `b_item` should be Strings; `nil` is not a # valid input. def compare_dot_components(a_item, b_item) a_components = a_item.split('.') b_components = b_item.split('.') max_length = [a_components.length, b_components.length].max (0..(max_length - 1)).each do |i| # Convert the ith component into a number if possible a = maybe_int(a_components[i]) b = maybe_int(b_components[i]) # Since the components may be of differing lengths, the # shorter one will yield +nil+ at some point as we iterate. if a.nil? && !b.nil? # a_item was shorter return -1 elsif !a.nil? && b.nil? # b_item was shorter return 1 end # Now we need to compare appropriately based on type. # # Numbers have lower precedence than strings; therefore, if # the components are of differnt types (String vs. Integer), # we just return -1 for the numeric one and we're done. # # If both are the same type (Integer vs. Integer, or String # vs. String), we can just use the native comparison. # if a.is_a?(Integer) && b.is_a?(String) # a_item was "smaller" return -1 elsif a.is_a?(String) && b.is_a?(Integer) # b_item was "smaller" return 1 else comp = a <=> b return comp unless comp == 0 end end # each # We've compared all components of both strings; if we've gotten # down here, they're totally the same 0 end end # Format end # Versioning end # Mixlib mixlib-versioning-1.1.0/lib/mixlib/versioning/format/0000755000175000017500000000000012703167554022245 5ustar globusglobusmixlib-versioning-1.1.0/lib/mixlib/versioning/format/rubygems.rb0000644000175000017500000000416512703167554024435 0ustar globusglobus# # Author:: Seth Chisamore () # Author:: Christopher Maier () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Mixlib class Versioning class Format # Handles version strings based on {http://guides.rubygems.org/patterns/} # # SUPPORTED FORMATS # ----------------- # ```text # MAJOR.MINOR.PATCH.PRERELEASE # MAJOR.MINOR.PATCH.PRERELEASE-ITERATION # ``` # # EXAMPLES # -------- # ```text # 10.1.1 # 10.1.1.alpha.1 # 10.1.1.beta.1 # 10.1.1.rc.0 # 10.16.2 # ``` # # @author Seth Chisamore () # @author Christopher Maier () class Rubygems < Format RUBYGEMS_REGEX = /^(\d+)\.(\d+)\.(\d+)(?:\.([[:alnum:]]+(?:\.[[:alnum:]]+)?))?(?:\-(\d+))?$/ # @see Format#parse def parse(version_string) match = version_string.match(RUBYGEMS_REGEX) rescue nil unless match fail Mixlib::Versioning::ParseError, "'#{version_string}' is not a valid #{self.class} version string!" end @major, @minor, @patch, @prerelease, @iteration = match[1..5] @major, @minor, @patch, @iteration = [@major, @minor, @patch, @iteration].map(&:to_i) # Do not convert @build to an integer; SemVer sorting logic will handle the conversion @prerelease = nil if @prerelease.nil? || @prerelease.empty? end end # class Rubygems end # class Format end # module Versioning end # module Mixlib mixlib-versioning-1.1.0/lib/mixlib/versioning/format/opscode_semver.rb0000644000175000017500000000565712703167554025624 0ustar globusglobus# # Author:: Seth Chisamore () # Author:: Christopher Maier () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'mixlib/versioning/format/semver' module Mixlib class Versioning class Format # Defines the format of the semantic version scheme used for Opscode # projects. They are SemVer-2.0.0-rc.1 compliant, but we further # constrain the allowable strings for prerelease and build # signifiers for our own internal standards. # # SUPPORTED FORMATS # ----------------- # ```text # MAJOR.MINOR.PATCH # MAJOR.MINOR.PATCH-alpha.INDEX # MAJOR.MINOR.PATCH-beta.INDEX # MAJOR.MINOR.PATCH-rc.INDEX # MAJOR.MINOR.PATCH-alpha.INDEX+YYYYMMDDHHMMSS # MAJOR.MINOR.PATCH-beta.INDEX+YYYYMMDDHHMMSS # MAJOR.MINOR.PATCH-rc.INDEX+YYYYMMDDHHMMSS # MAJOR.MINOR.PATCH-alpha.INDEX+YYYYMMDDHHMMSS.git.COMMITS_SINCE.SHA1 # MAJOR.MINOR.PATCH-beta.INDEX+YYYYMMDDHHMMSS.git.COMMITS_SINCE.SHA1 # MAJOR.MINOR.PATCH-rc.INDEX+YYYYMMDDHHMMSS.git.COMMITS_SINCE.SHA1 # ``` # # EXAMPLES # -------- # ```text # 11.0.0 # 11.0.0-alpha.1 # 11.0.0-alpha1+20121218164140 # 11.0.0-alpha1+20121218164140.git.207.694b062 # ``` # # @author Seth Chisamore () # @author Christopher Maier () class OpscodeSemVer < SemVer # The pattern is: `YYYYMMDDHHMMSS.git.COMMITS_SINCE.SHA1` OPSCODE_BUILD_REGEX = /^\d{14}(\.git\.\d+\.[a-f0-9]{7})?$/ # Allows the following: # # ```text # alpha, alpha.0, alpha.1, alpha.2, etc. # beta, beta.0, beta.1, beta.2, etc. # rc, rc.0, rc.1, rc.2, etc. # ``` # OPSCODE_PRERELEASE_REGEX = /^(alpha|beta|rc)(\.\d+)?$/ # @see SemVer#parse def parse(version_string) super(version_string) fail Mixlib::Versioning::ParseError, "'#{@prerelease}' is not a valid Opscode pre-release signifier!" unless @prerelease.nil? || @prerelease.match(OPSCODE_PRERELEASE_REGEX) fail Mixlib::Versioning::ParseError, "'#{@build}' is not a valid Opscode build signifier!" unless @build.nil? || @build.match(OPSCODE_BUILD_REGEX) end end # class OpscodeSemVer end # class Format end # module Versioning end # module Mixlib mixlib-versioning-1.1.0/lib/mixlib/versioning/format/git_describe.rb0000644000175000017500000000474012703167554025222 0ustar globusglobus# # Author:: Seth Chisamore () # Author:: Christopher Maier () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Mixlib class Versioning class Format # Handles version strings based on # {https://www.kernel.org/pub/software/scm/git/docs/git-describe.html git describe} # output. # # SUPPORTED FORMATS # ----------------- # ```text # MAJOR.MINOR.PATCH-COMMITS_SINCE-gGIT_SHA1 # MAJOR.MINOR.PATCH.PRERELEASE-COMMITS_SINCE-gGIT_SHA1 # MAJOR.MINOR.PATCH-PRERELEASE-COMMITS_SINCE-gGIT_SHA1-ITERATION # ``` # # EXAMPLES # -------- # ```text # 10.16.2-49-g21353f0-1 # 10.16.2.rc.1-49-g21353f0-1 # 11.0.0-alpha-10-g642ffed # 11.0.0-alpha.1-1-gcea071e # ``` # # @author Seth Chisamore () # @author Christopher Maier () class GitDescribe < Format GIT_DESCRIBE_REGEX = /^(\d+)\.(\d+)\.(\d+)(?:\-|\.)?(.+)?\-(\d+)\-g([a-f0-9]{7,40})(?:\-)?(\d+)?$/ attr_reader :commits_since, :commit_sha # @see Format#parse def parse(version_string) match = version_string.match(GIT_DESCRIBE_REGEX) rescue nil unless match fail Mixlib::Versioning::ParseError, "'#{version_string}' is not a valid #{self.class} version string!" end @major, @minor, @patch, @prerelease, @commits_since, @commit_sha, @iteration = match[1..7] @major, @minor, @patch, @commits_since, @iteration = [@major, @minor, @patch, @commits_since, @iteration].map(&:to_i) # Our comparison logic is built around SemVer semantics, so # we'll store our internal information in that format @build = "#{@commits_since}.g#{@commit_sha}.#{@iteration}" end end # class GitDescribe end # class Format end # module Versioning end # module Mixlib mixlib-versioning-1.1.0/lib/mixlib/versioning/format/semver.rb0000644000175000017500000000431012703167554024071 0ustar globusglobus# # Author:: Seth Chisamore () # Author:: Christopher Maier () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Mixlib class Versioning class Format # Handles version strings based on {http://semver.org/ SemVer 2.0.0-rc.1}. # # SUPPORTED FORMATS # ----------------- # ```text # MAJOR.MINOR.PATCH # MAJOR.MINOR.PATCH-PRERELEASE # MAJOR.MINOR.PATCH-PRERELEASE+BUILD # ``` # # EXAMPLES # -------- # ```text # 11.0.0 # 11.0.0-alpha.1 # 11.0.0-alpha1+20121218164140 # 11.0.0-alpha1+20121218164140.git.207.694b062 # ``` # # @author Seth Chisamore () # @author Christopher Maier () class SemVer < Format SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][a-zA-Z0-9-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][a-zA-Z0-9-]*))*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/ # @see Format#parse def parse(version_string) match = version_string.match(SEMVER_REGEX) rescue nil unless match fail Mixlib::Versioning::ParseError, "'#{version_string}' is not a valid #{self.class} version string!" end @major, @minor, @patch, @prerelease, @build = match[1..5] @major, @minor, @patch = [@major, @minor, @patch].map(&:to_i) @prerelease = nil if @prerelease.nil? || @prerelease.empty? @build = nil if @build.nil? || @build.empty? end end # class SemVer end # class Format end # module Versioning end # module Mixlib mixlib-versioning-1.1.0/lib/mixlib/versioning/version.rb0000644000175000017500000000135612703167554022774 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Mixlib class Versioning VERSION = '1.1.0' end end mixlib-versioning-1.1.0/lib/mixlib/versioning/exceptions.rb0000644000175000017500000000174112703167554023466 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # module Mixlib class Versioning # Base class for all Mixlib::Versioning Errors class Error < RuntimeError; end # Exception raised if parsing fails class ParseError < Error; end # Exception raised if version format cannot be identified class UnknownFormatError < Error; end end end mixlib-versioning-1.1.0/lib/mixlib/versioning.rb0000644000175000017500000002041012703167554021277 0ustar globusglobus# # Author:: Seth Chisamore () # Author:: Christopher Maier () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'mixlib/versioning/exceptions' require 'mixlib/versioning/format' module Mixlib # @author Seth Chisamore () # @author Christopher Maier () class Versioning DEFAULT_FORMATS = [ Mixlib::Versioning::Format::GitDescribe, Mixlib::Versioning::Format::OpscodeSemVer, Mixlib::Versioning::Format::SemVer, Mixlib::Versioning::Format::Rubygems, ].freeze # Create a new {Format} instance given a version string to parse, and an # optional format type. # # @example # Mixlib::Versioning.parse('11.0.0') # Mixlib::Versioning.parse('11.0.0', :semver) # Mixlib::Versioning.parse('11.0.0', 'semver') # Mixlib::Versioning.parse('11.0.0', Mixlib::Versioning::Format::SemVer) # # @param version_string [String] String representatin of the version to # parse # @param format [String, Symbol, Mixlib::Versioning::Format, Array] Optional # format type to parse the version string as. If this is exluded all # version types will be attempted from most specific to most specific # with a preference for SemVer formats. If it is an array, only version # types in that list will be considered # @raise [Mixlib::Versioning::ParseError] if the parse fails. # @raise [Mixlib::Versioning::UnknownFormatError] if the given format type # doesn't exist. # # @return # def self.parse(version_string, format = nil) if version_string.is_a?(Mixlib::Versioning::Format) return version_string else formats = if format [format].flatten.map { |f| Mixlib::Versioning::Format.for(f) } else DEFAULT_FORMATS end # Attempt to parse from the most specific formats first. parsed_version = nil formats.each do |version| begin break parsed_version = version.new(version_string) rescue Mixlib::Versioning::ParseError next end end return parsed_version end end # Selects the most recent version from `all_versions` that satisfies the # filtering constraints provided by `filter_version`, # `use_prerelease_versions`, and `use_build_versions`. # # If `filter_version` specifies a release (e.g. 1.0.0), then the target # version that is returned will be in the same "release line" (it will have # the same major, minor, and patch versions), subject to filtering by # `use_prerelease_versions` and `use_build_versions`. # # If `filter_version` specifies a pre-release (e.g., 1.0.0-alpha.1), the # returned target version will be in the same "pre-release line", and will # only be subject to further filtering by `use_build_versions`; that is, # `use_prerelease_versions` is completely ignored. # # If `filter_version` specifies a build version (whether it is a # pre-release or not), no filtering is performed at all, and # `filter_version` *is* the target version; `use_prerelease_versions` and # `use_build_versions` are both ignored. # # If `filter_version` is `nil`, then only `use_prerelease_versions` and # `use_build_versions` are used for filtering. # # In all cases, the returned {Format} is the most recent one in # `all_versions` that satisfies the given constraints. # # @example # all = %w{ 11.0.0-beta.1 # 11.0.0-rc.1 # 11.0.0 # 11.0.1 } # # Mixlib::Versioning.find_target_version(all, # '11.0.1', # true, # true) # # # @param all_versions [Array] An array # of {Format} objects. This is the "world" of versions we will be # filtering to produce the final target version. Any strings in the array # will automatically be converted into instances of {Format} using # {Versioning.parse}. # @param filter_version [String, Mixlib::Versioning::Format] A version that # is used to perform more fine-grained filtering. If a string is passed, # {Versioning.parse} will be used to instantiate a version. # @param use_prerelease_versions [Boolean] If true, keep versions with # pre-release specifiers. When false, versions in `all_versions` that # have a pre-release specifier will be filtered out. # @param use_build_versions [Boolean] If true, keep versions with build # version specifiers. When false, versions in `all_versions` that have a # build version specifier will be filtered out. # def self.find_target_version(all_versions, filter_version = nil, use_prerelease_versions = false, use_build_versions = false) # attempt to parse a `Mixlib::Versioning::Format` instance if we were # passed a string unless filter_version.nil? || filter_version.is_a?(Mixlib::Versioning::Format) filter_version = Mixlib::Versioning.parse(filter_version) end all_versions.map! do |v| if v.is_a?(Mixlib::Versioning::Format) v else Mixlib::Versioning.parse(v) end end if filter_version && filter_version.build # If we've requested a build (whether for a pre-release or release), # there's no sense doing any other filtering; just return that version filter_version elsif filter_version && filter_version.prerelease # If we've requested a prerelease version, we only need to see if we # want a build version or not. If so, keep only the build version for # that prerelease, and then take the most recent. Otherwise, just # return the specified prerelease version if use_build_versions all_versions.select { |v| v.in_same_prerelease_line?(filter_version) }.max else filter_version end else # If we've gotten this far, we're either just interested in # variations on a specific release, or the latest of all versions # (depending on various combinations of prerelease and build status) all_versions.select do |v| # If we're given a version to filter by, then we're only # interested in other versions that share the same major, minor, # and patch versions. # # If we weren't given a version to filter by, then we don't # care, and we'll take everything in_release_line = if filter_version filter_version.in_same_release_line?(v) else true end in_release_line && if use_prerelease_versions && use_build_versions v.prerelease_build? elsif !use_prerelease_versions && use_build_versions v.release_build? elsif use_prerelease_versions && !use_build_versions v.prerelease? elsif !use_prerelease_versions && !use_build_versions v.release? end end.max # select the most recent version end # if end # self.find_target_version end # Versioning end # Mixlib mixlib-versioning-1.1.0/.rubocop.yml0000644000175000017500000000057412703167554017020 0ustar globusglobusAbcSize: Enabled: false BracesAroundHashParameters: Enabled: false ClassLength: Enabled: false CyclomaticComplexity: Enabled: false Documentation: Enabled: false Encoding: Enabled: false LineLength: Enabled: false MethodLength: Enabled: false PerceivedComplexity: Enabled: false RescueModifier: Enabled: false TrailingComma: EnforcedStyleForMultiline: comma mixlib-versioning-1.1.0/.gitignore0000644000175000017500000000026012703167554016526 0ustar globusglobus*.gem *.rbc .bundle .config .yardoc .rspec .yardopts Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp bin/ mixlib-versioning-1.1.0/Rakefile0000644000175000017500000000052712703167554016211 0ustar globusglobusrequire 'bundler/gem_tasks' require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:unit) require 'rubocop/rake_task' desc 'Run Ruby style checks' RuboCop::RakeTask.new(:style) require 'yard' YARD::Rake::YardocTask.new(:doc) namespace :travis do desc 'Run tests on Travis' task ci: [:style, :unit] end task default: [:style, :unit] mixlib-versioning-1.1.0/mixlib-versioning.gemspec0000644000175000017500000000227312703167554021556 0ustar globusglobus# -*- encoding: utf-8 -*- lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'mixlib/versioning/version' Gem::Specification.new do |spec| spec.name = 'mixlib-versioning' spec.version = Mixlib::Versioning::VERSION spec.authors = ['Seth Chisamore', 'Christopher Maier'] spec.email = ['schisamo@chef.io', 'cm@chef.io'] spec.description = 'General purpose Ruby library that allows you to parse, compare and manipulate version strings in multiple formats.' spec.summary = spec.description spec.homepage = 'https://github.com/chef/mixlib-versioning' spec.license = 'Apache 2.0' spec.required_ruby_version = '>= 1.9' spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR) spec.executables = spec.files.grep(%r{^bin/}).map { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ['lib'] # Development dependencies spec.add_development_dependency 'rubocop', '= 0.31.0' spec.add_development_dependency 'rspec', '~> 2.14' spec.add_development_dependency 'bundler' spec.add_development_dependency 'rake' end mixlib-versioning-1.1.0/spec/0000755000175000017500000000000012703167554015472 5ustar globusglobusmixlib-versioning-1.1.0/spec/mixlib/0000755000175000017500000000000012703167554016756 5ustar globusglobusmixlib-versioning-1.1.0/spec/mixlib/versioning/0000755000175000017500000000000012703167554021141 5ustar globusglobusmixlib-versioning-1.1.0/spec/mixlib/versioning/versioning_spec.rb0000644000175000017500000002363512703167554024674 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'spec_helper' describe Mixlib::Versioning do subject { described_class } let(:version_string) { '11.0.0' } describe '.parse' do describe 'parsing when format type is specified' do { '11.0.8' => { format_type: :semver, expected_format: Mixlib::Versioning::Format::SemVer, }, '11.1.1' => { format_type: :rubygems, expected_format: Mixlib::Versioning::Format::Rubygems, }, '11.1.1.alpha.1' => { format_type: :rubygems, expected_format: Mixlib::Versioning::Format::Rubygems, }, '11.1.1-alpha.1' => { format_type: :opscode_semver, expected_format: Mixlib::Versioning::Format::OpscodeSemVer, }, '11.1.1-rc.2' => { format_type: :opscode_semver, expected_format: Mixlib::Versioning::Format::SemVer, }, }.each_pair do |version_string, options| context "#{version_string} as #{options[:expected_format]}" do let(:version_string) { version_string } let(:expected_format) { options[:expected_format] } [ options[:format_type], options[:format_type].to_s, options[:expected_format], ].each do |format_type| context "format type as a: #{format_type.class}" do it "parses version string as: #{options[:expected_format]}" do result = subject.parse(version_string, format_type) result.should be_a(expected_format) end # it end # context end # each end # context end # each_pair describe 'invalid format type specified' do [ :poop, 'poop', Mixlib::Versioning, ].each do |invalid_format_type| context "invalid format as a: #{invalid_format_type.class}" do it 'raises a Mixlib::Versioning::UnknownFormatError' do expect { subject.parse(version_string, invalid_format_type) }.to raise_error(Mixlib::Versioning::UnknownFormatError) end # it end # context end # each end # describe end # describe describe 'parsing with automatic format detection' do { '11.0.8' => Mixlib::Versioning::Format::SemVer, '11.0.8-1' => Mixlib::Versioning::Format::SemVer, '11.0.8.rc.1' => Mixlib::Versioning::Format::Rubygems, '11.0.8.rc.1-1' => Mixlib::Versioning::Format::Rubygems, '11.0.8-rc.1' => Mixlib::Versioning::Format::OpscodeSemVer, '10.18.2' => Mixlib::Versioning::Format::SemVer, '10.18.2-poop' => Mixlib::Versioning::Format::SemVer, '10.18.2.poop' => Mixlib::Versioning::Format::Rubygems, '10.18.2.poop-1' => Mixlib::Versioning::Format::Rubygems, '12.1.1+20130311134422' => Mixlib::Versioning::Format::OpscodeSemVer, '12.1.1-rc.3+20130311134422' => Mixlib::Versioning::Format::OpscodeSemVer, '12.1.1+20130308110833.git.2.94a1dde' => Mixlib::Versioning::Format::OpscodeSemVer, '10.16.2-49-g21353f0' => Mixlib::Versioning::Format::GitDescribe, '10.16.2-49-g21353f0-1' => Mixlib::Versioning::Format::GitDescribe, '10.16.2.rc.2-49-g21353f0' => Mixlib::Versioning::Format::GitDescribe, '10.16.2-rc.2-49-g21353f0' => Mixlib::Versioning::Format::GitDescribe, }.each_pair do |version_string, expected_format| context version_string do let(:version_string) { version_string } it "parses version string as: #{expected_format}" do subject.parse(version_string).should be_a(expected_format) end # it end # context end # each_pair describe 'version_string cannot be parsed' do let(:version_string) { 'A.B.C' } it 'returns nil' do subject.parse(version_string).should be_nil end end end # describe "parsing with automatic format detection" describe 'parsing an Mixlib::Versioning::Format object' do it 'returns the same object' do v = Mixlib::Versioning.parse(version_string) result = subject.parse(v) v.should be result end end describe 'when formats are given' do context 'when the format is not in the list' do let(:version_string) { '10.16.2-rc.2-49-g21353f0' } it 'returns nil when the array contains a Mixlib::Versioning::Format' do subject.parse(version_string, [Mixlib::Versioning::Format::Rubygems]).should be_nil end it 'returns nil when the array contains a string' do subject.parse(version_string, ['rubygems']).should be_nil end it 'returns nil when the array contains a symbol' do subject.parse(version_string, [:rubygems]).should be_nil end end context 'when the format is in the list' do let(:version_string) { '10.16.2-rc.2-49-g21353f0' } let(:expected_format) { Mixlib::Versioning::Format::GitDescribe } it 'returns nil when the array contains a Mixlib::Versioning::Format' do subject.parse(version_string, [expected_format]).should be_a(expected_format) end it 'returns nil when the array contains a string' do subject.parse(version_string, ['git_describe']).should be_a(expected_format) end it 'returns nil when the array contains a symbol' do subject.parse(version_string, [:git_describe]).should be_a(expected_format) end end end end # describe .parse describe '.find_target_version' do let(:all_versions) do %w( 11.0.0-beta.1 11.0.0-rc.1 11.0.0 11.0.1 11.0.1+2013031116332 11.0.2-alpha.0 11.0.2-alpha.0+2013041116332 11.0.2 ) end let(:filter_version) { nil } let(:use_prerelease_versions) { false } let(:use_build_versions) { false } let(:subject_find) do subject.find_target_version( all_versions, filter_version, use_prerelease_versions, use_build_versions, ) end { nil => { releases_only: '11.0.2', prerelease_versions: '11.0.2-alpha.0', build_versions: '11.0.1+2013031116332', prerelease_and_build_versions: '11.0.2-alpha.0+2013041116332', }, '11.0.0' => { releases_only: '11.0.0', prerelease_versions: '11.0.0-rc.1', build_versions: nil, prerelease_and_build_versions: nil, }, '11.0.2' => { releases_only: '11.0.2', prerelease_versions: '11.0.2-alpha.0', build_versions: nil, prerelease_and_build_versions: '11.0.2-alpha.0+2013041116332', }, '11.0.2' => { releases_only: '11.0.2', prerelease_versions: '11.0.2-alpha.0', build_versions: nil, prerelease_and_build_versions: '11.0.2-alpha.0+2013041116332', }, '11.0.2-alpha.0' => { releases_only: '11.0.2-alpha.0', prerelease_versions: '11.0.2-alpha.0', build_versions: '11.0.2-alpha.0+2013041116332', prerelease_and_build_versions: '11.0.2-alpha.0+2013041116332', }, }.each_pair do |filter_version, options| context "filter version of: #{filter_version}" do let(:filter_version) { filter_version } let(:expected_version) { options[:releases_only] } it 'finds the most recent release version' do subject_find.should eq Mixlib::Versioning.parse(expected_version) end context 'include pre-release versions' do let(:use_prerelease_versions) { true } let(:expected_version) { options[:prerelease_versions] } it 'finds the most recent pre-release version' do subject_find.should eq Mixlib::Versioning.parse(expected_version) end # it end # context context 'include build versions' do let(:use_build_versions) { true } let(:expected_version) { options[:build_versions] } it 'finds the most recent build version' do subject_find.should eq Mixlib::Versioning.parse(expected_version) end # it end # context context 'include pre-release and build versions' do let(:use_prerelease_versions) { true } let(:use_build_versions) { true } let(:expected_version) { options[:prerelease_and_build_versions] } it 'finds the most recent pre-release build version' do subject_find.should eq Mixlib::Versioning.parse(expected_version) end # it end # context end # context end # each_pair describe 'all_versions argument is a mix of String and Mixlib::Versioning::Format instances' do let(:all_versions) do [ '11.0.0-beta.1', '11.0.0-rc.1', Mixlib::Versioning.parse('11.0.0'), ] end it 'correctly parses the array' do subject_find.should eq Mixlib::Versioning.parse('11.0.0') end end # describe describe 'filter_version argument is an instance of Mixlib::Versioning::Format' do let(:filter_version) { Mixlib::Versioning::Format::SemVer.new('11.0.0') } it 'finds the correct version' do subject_find.should eq Mixlib::Versioning.parse('11.0.0') end end end # describe end # describe Mixlib::Versioning mixlib-versioning-1.1.0/spec/mixlib/versioning/format/0000755000175000017500000000000012703167554022431 5ustar globusglobusmixlib-versioning-1.1.0/spec/mixlib/versioning/format/opscode_semver_spec.rb0000644000175000017500000000762512703167554027017 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'spec_helper' describe Mixlib::Versioning::Format::OpscodeSemVer do subject { described_class.new(version_string) } it_should_behave_like Mixlib::Versioning::Format::SemVer it_has_behavior 'rejects invalid version strings', { '1.0.0-poop.0' => 'non-valid pre-release type', '1.0.0+2010AA08010101' => 'a malformed timestamp', '1.0.0+cvs.33.e0f985a' => 'a malformed git describe: no git string', '1.0.0+git.AA.e0f985a' => 'a malformed git describe: non-numeric COMMITS_SINCE', '1.0.0+git.33.z0f985a' => 'a malformed git describe: invalid SHA1', '11.0.08-rc.1+20130308110833' => 'leading zero invalid', '01.0.8-alpha.2+20130308110833.git.2.94a1dde' => 'leading zero invalid', '11.02.8-rc.1+20130308110833' => 'leading zero invalid', '0008.1.4' => 'leading zero invalid', '11.00000000002.8-rc.1+20130308110833' => 'leading zero invalid', '4.67.00012+build.20131219' => 'leading zero invalid', '3.6.7-rc.007' => 'leading zero invalid', } it_has_behavior 'serializable', [ '1.0.0', '1.0.0-alpha.1', '1.0.0-alpha.1+20130308110833', '1.0.0+20130308110833.git.2.94a1dde', ] it_has_behavior 'sortable' do let(:unsorted_version_strings) do %w( 1.0.0-beta.2 1.0.0-alpha 1.0.0-rc.1+20130309074433 1.0.0 1.0.0-beta.11 1.0.0+20121009074433 1.0.0-rc.1 1.0.0-alpha.1 1.3.7+20131009104433.git.2.94a1dde 1.3.7+20131009104433 1.3.7+20131009074433 ) end let(:sorted_version_strings) do %w( 1.0.0-alpha 1.0.0-alpha.1 1.0.0-beta.2 1.0.0-beta.11 1.0.0-rc.1 1.0.0-rc.1+20130309074433 1.0.0 1.0.0+20121009074433 1.3.7+20131009074433 1.3.7+20131009104433 1.3.7+20131009104433.git.2.94a1dde ) end let(:min) { '1.0.0-alpha' } let(:max) { '1.3.7+20131009104433.git.2.94a1dde' } end # it_has_behavior it_has_behavior 'filterable' do let(:unsorted_version_strings) do %w( 1.0.0-beta.2 1.0.0-alpha 1.0.0-rc.1+20130309074433 1.0.0 1.0.0-beta.11 1.0.0+20121009074433 1.0.0-rc.1 1.0.0-alpha.1 1.3.7+20131009104433.git.2.94a1dde 1.3.7+20131009104433 1.3.7+20131009074433 ) end let(:release_versions) { %w(1.0.0) } let(:prerelease_versions) do %w( 1.0.0-beta.2 1.0.0-alpha 1.0.0-beta.11 1.0.0-rc.1 1.0.0-alpha.1 ) end let(:build_versions) do %w( 1.0.0-rc.1+20130309074433 1.0.0+20121009074433 1.3.7+20131009104433.git.2.94a1dde 1.3.7+20131009104433 1.3.7+20131009074433 ) end let(:release_build_versions) do %w( 1.0.0+20121009074433 1.3.7+20131009104433.git.2.94a1dde 1.3.7+20131009104433 1.3.7+20131009074433 ) end let(:prerelease_build_versions) do %w( 1.0.0-rc.1+20130309074433 ) end end # it_has_behavior it_has_behavior 'comparable', [ '0.1.0', '0.2.0', '1.0.0-alpha.1', '1.0.0', '1.2.3', '1.2.3+20121009074433', '2.0.0-beta.1', '2.0.0+20131009104433.git.2.94a1dde' ] end # describe mixlib-versioning-1.1.0/spec/mixlib/versioning/format/rubygems_spec.rb0000644000175000017500000000677112703167554025640 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'spec_helper' describe Mixlib::Versioning::Format::Rubygems do subject { described_class.new(version_string) } it_should_behave_like 'Basic SemVer' it_has_behavior 'parses valid version strings', { '10.1.1' => { major: 10, minor: 1, patch: 1, prerelease: nil, build: nil, release?: true, prerelease?: false, build?: false, release_build?: false, prerelease_build?: false, iteration: 0, }, '10.1.1.alpha.1' => { major: 10, minor: 1, patch: 1, prerelease: 'alpha.1', build: nil, release?: false, prerelease?: true, build?: false, release_build?: false, prerelease_build?: false, iteration: 0, }, '11.0.8.rc.3' => { major: 11, minor: 0, patch: 8, prerelease: 'rc.3', build: nil, release?: false, prerelease?: true, build?: false, release_build?: false, prerelease_build?: false, iteration: 0, }, '11.0.8-33' => { major: 11, minor: 0, patch: 8, prerelease: nil, build: nil, release?: true, prerelease?: false, build?: false, release_build?: false, prerelease_build?: false, iteration: 33, }, '11.0.8.rc.3-1' => { major: 11, minor: 0, patch: 8, prerelease: 'rc.3', build: nil, release?: false, prerelease?: true, build?: false, release_build?: false, prerelease_build?: false, iteration: 1, }, } it_has_behavior 'rejects invalid version strings', { '1.1.1-rutro' => 'dash for pre-release delimeter', } it_has_behavior 'serializable', [ '1.0.0', '1.0.0.alpha.1', '1.0.0.beta', ] it_has_behavior 'sortable' do let(:unsorted_version_strings) do %w( 1.0.0.beta.2 1.3.7.alpha.0 1.0.0.alpha 1.0.0.rc.1 1.0.0 ) end let(:sorted_version_strings) do %w( 1.0.0.alpha 1.0.0.beta.2 1.0.0.rc.1 1.0.0 1.3.7.alpha.0 ) end let(:min) { '1.0.0.alpha' } let(:max) { '1.3.7.alpha.0' } end # The +Rubygems+ format only produces release and prerelease versions. it_has_behavior 'filterable' do let(:unsorted_version_strings) do %w( 1.0.0.beta.2 1.3.7.alpha.0 1.0.0.alpha 1.0.0.rc.1 1.0.0 ) end let(:release_versions) { %w(1.0.0) } let(:prerelease_versions) do %w( 1.0.0.beta.2 1.3.7.alpha.0 1.0.0.alpha 1.0.0.rc.1 ) end end it_has_behavior 'comparable', [ '0.1.0', '0.2.0', '1.0.0.alpha.1', '1.0.0', '1.2.3.alpha', '1.2.3.alpha.1', '2.4.5.alpha', '2.4.5.beta', '3.0.0.beta.1', '3.0.0.rc.1', '3.1.2.rc.42', '3.1.2' ] end mixlib-versioning-1.1.0/spec/mixlib/versioning/format/git_describe_spec.rb0000644000175000017500000001217712703167554026423 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'spec_helper' describe Mixlib::Versioning::Format::GitDescribe do subject { described_class.new(version_string) } it_has_behavior 'parses valid version strings', { '0.10.8-231-g59d6185' => { major: 0, minor: 10, patch: 8, prerelease: nil, build: '231.g59d6185.0', release?: false, prerelease?: false, build?: true, release_build?: true, prerelease_build?: false, commits_since: 231, commit_sha: '59d6185', iteration: 0, }, '10.16.2-49-g21353f0-1' => { major: 10, minor: 16, patch: 2, prerelease: nil, build: '49.g21353f0.1', release?: false, prerelease?: false, build?: true, release_build?: true, prerelease_build?: false, commits_since: 49, commit_sha: '21353f0', iteration: 1, }, '10.16.2.rc.1-49-g21353f0-1' => { major: 10, minor: 16, patch: 2, prerelease: 'rc.1', build: '49.g21353f0.1', release?: false, prerelease?: false, build?: true, release_build?: false, prerelease_build?: true, commits_since: 49, commit_sha: '21353f0', iteration: 1, }, '10.16.2-alpha-49-g21353f0-1' => { major: 10, minor: 16, patch: 2, prerelease: 'alpha', build: '49.g21353f0.1', release?: false, prerelease?: false, build?: true, release_build?: false, prerelease_build?: true, commits_since: 49, commit_sha: '21353f0', iteration: 1, }, '10.16.2-alpha-49-g21353f0' => { major: 10, minor: 16, patch: 2, prerelease: 'alpha', build: '49.g21353f0.0', release?: false, prerelease?: false, build?: true, release_build?: false, prerelease_build?: true, commits_since: 49, commit_sha: '21353f0', iteration: 0, }, } it_has_behavior 'rejects invalid version strings', { '1.0.0' => 'no git describe data', '1.0.0-alpha.1' => 'no git describe data', '1.0.0-alpha.1+build.deadbeef' => 'no git describe data', '1.0.0-123-gfd0e3a65282cb5f6df3bab6a53f4fcb722340d499-1' => 'too many SHA1 characters', '1.0.0-123-gdeadbe-1' => 'too few SHA1 characters', '1.0.0-123-gNOTHEX1-1' => 'illegal SHA1 characters', '1.0.0-123-g1234567-alpha' => 'non-numeric iteration', '1.0.0-alpha-poop-g1234567-1' => "non-numeric 'commits_since'", '1.0.0-g1234567-1' => "missing 'commits_since'", '1.0.0-123-1' => 'missing SHA1', } version_strings = %w( 9.0.1-1-gdeadbee-1 9.1.2-2-g1234567-1 10.0.0-1-gabcdef3-1 10.5.7-2-g21353f0-1 10.20.2-2-gbbbbbbb-1 10.20.2-3-gaaaaaaa-1 9.0.1-2-gdeadbe1-1 9.0.1-2-gdeadbe1-2 9.0.1-2-gdeadbe2-1 9.1.1-2-g1234567-1 ) it_has_behavior 'serializable', version_strings it_has_behavior 'sortable' do let(:unsorted_version_strings) { version_strings } let(:sorted_version_strings) do %w( 9.0.1-1-gdeadbee-1 9.0.1-2-gdeadbe1-1 9.0.1-2-gdeadbe1-2 9.0.1-2-gdeadbe2-1 9.1.1-2-g1234567-1 9.1.2-2-g1234567-1 10.0.0-1-gabcdef3-1 10.5.7-2-g21353f0-1 10.20.2-2-gbbbbbbb-1 10.20.2-3-gaaaaaaa-1 ) end let(:min) { '9.0.1-1-gdeadbee-1' } let(:max) { '10.20.2-3-gaaaaaaa-1' } end # it_has_behavior # The +GitDescribe+ format only produces release build versions. it_has_behavior 'filterable' do let(:unsorted_version_strings) { version_strings } let(:build_versions) do %w( 9.0.1-1-gdeadbee-1 9.1.2-2-g1234567-1 10.0.0-1-gabcdef3-1 10.5.7-2-g21353f0-1 10.20.2-2-gbbbbbbb-1 10.20.2-3-gaaaaaaa-1 9.0.1-2-gdeadbe1-1 9.0.1-2-gdeadbe1-2 9.0.1-2-gdeadbe2-1 9.1.1-2-g1234567-1 ) end let(:release_build_versions) do %w( 9.0.1-1-gdeadbee-1 9.1.2-2-g1234567-1 10.0.0-1-gabcdef3-1 10.5.7-2-g21353f0-1 10.20.2-2-gbbbbbbb-1 10.20.2-3-gaaaaaaa-1 9.0.1-2-gdeadbe1-1 9.0.1-2-gdeadbe1-2 9.0.1-2-gdeadbe2-1 9.1.1-2-g1234567-1 ) end end # it_has_behavior it_has_behavior 'comparable', [ '9.0.1-1-gdeadbee-1', '9.0.1-2-gdeadbe1-1', '9.0.1-2-gdeadbe1-2', '9.0.1-2-gdeadbe2-1', '9.1.1-2-g1234567-1', '9.1.2-2-g1234567-1', '10.0.0-1-gabcdef3-1', '10.5.7-2-g21353f0-1', '10.20.2-2-gbbbbbbb-1', '10.20.2-3-gaaaaaaa-1' ] end # describe mixlib-versioning-1.1.0/spec/mixlib/versioning/format/semver_spec.rb0000644000175000017500000000572712703167554025304 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'spec_helper' describe Mixlib::Versioning::Format::SemVer do subject { described_class.new(version_string) } it_should_behave_like Mixlib::Versioning::Format::SemVer it_has_behavior 'serializable', [ '1.0.0', '1.0.0-alpha.1', '1.0.0-alpha.1+some.build.version', '1.0.0+build.build.build', ] it_has_behavior 'sortable' do let(:unsorted_version_strings) do %w( 1.0.0-beta.2 1.0.0-alpha 1.0.0-alpha.july 1.0.0-rc.1+build.1 1.0.0 1.0.0-beta.11 1.0.0+0.3.7 1.0.0-rc.1 1.0.0-alpha.1 1.3.7+build.2.b8f12d7 1.3.7+build.11.e0f985a 1.3.7+build ) end let(:sorted_version_strings) do %w( 1.0.0-alpha 1.0.0-alpha.1 1.0.0-alpha.july 1.0.0-beta.2 1.0.0-beta.11 1.0.0-rc.1 1.0.0-rc.1+build.1 1.0.0 1.0.0+0.3.7 1.3.7+build 1.3.7+build.2.b8f12d7 1.3.7+build.11.e0f985a ) end let(:min) { '1.0.0-alpha' } let(:max) { '1.3.7+build.11.e0f985a' } end # it_has_behavior it_has_behavior 'filterable' do let(:unsorted_version_strings) do %w( 1.0.0-beta.2 1.0.0-alpha 1.0.0-rc.1+build.1 1.0.0 1.0.0-beta.11 1.0.0+0.3.7 1.0.0-rc.1 1.0.0-alpha.1 1.3.7+build.2.b8f12d7 1.3.7+build.11.e0f985a 1.3.7+build ) end let(:release_versions) do %w( 1.0.0 ) end let(:prerelease_versions) do %w( 1.0.0-beta.2 1.0.0-alpha 1.0.0-beta.11 1.0.0-rc.1 1.0.0-alpha.1 ) end let(:build_versions) do %w( 1.0.0-rc.1+build.1 1.0.0+0.3.7 1.3.7+build.2.b8f12d7 1.3.7+build.11.e0f985a 1.3.7+build ) end let(:release_build_versions) do %w( 1.0.0+0.3.7 1.3.7+build.2.b8f12d7 1.3.7+build.11.e0f985a 1.3.7+build ) end let(:prerelease_build_versions) do %w( 1.0.0-rc.1+build.1 ) end end # it_has_behavior it_has_behavior 'comparable', [ '0.1.0', '0.2.0', '1.0.0-alpha.1', '1.0.0', '1.2.3', '1.2.3+build.123', '2.0.0-beta.1', '2.0.0-beta.1+build.123' ] end # describe mixlib-versioning-1.1.0/spec/mixlib/versioning/format_spec.rb0000644000175000017500000000363412703167554023776 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'spec_helper' describe Mixlib::Versioning::Format do describe '#initialize' do subject { described_class.new(version_string) } let(:version_string) { '11.0.0' } it 'descendants must override #parse' do expect { subject }.to raise_error end end describe '.for' do subject { described_class } [ :rubygems, 'rubygems', Mixlib::Versioning::Format::Rubygems, ].each do |format_type| context 'format_type is a: #{format_type.class}' do let(:format_type) { format_type } it 'returns the correct format class' do subject.for(format_type).should eq Mixlib::Versioning::Format::Rubygems end # it end # context end # each describe 'unknown format_type' do [ :poop, 'poop', Mixlib::Versioning, ].each do |invalid_format_type| context 'format_type is a: #{invalid_format_type.class}' do it 'raises a Mixlib::Versioning::UnknownFormatError' do expect { subject.for(invalid_format_type) }.to raise_error(Mixlib::Versioning::UnknownFormatError) end # it end # context end # each end # describe end # describe ".for" end # describe Mixlib::Versioning::Format mixlib-versioning-1.1.0/spec/support/0000755000175000017500000000000012703167554017206 5ustar globusglobusmixlib-versioning-1.1.0/spec/support/shared_examples/0000755000175000017500000000000012703167554022352 5ustar globusglobusmixlib-versioning-1.1.0/spec/support/shared_examples/behaviors/0000755000175000017500000000000012703167554024334 5ustar globusglobusmixlib-versioning-1.1.0/spec/support/shared_examples/behaviors/serializable.rb0000644000175000017500000000326512703167554027335 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # shared_examples 'serializable' do |version_strings| describe '#to_s' do version_strings.each do |v| it "reconstructs the initial input for #{v}" do described_class.new(v).to_s.should == v end # it end # version_strings end # describe describe '#to_semver_string' do version_strings.each do |v| it "generates a semver version string for #{v}" do subject = described_class.new(v) string = subject.to_semver_string semver = Mixlib::Versioning::Format::SemVer.new(string) string.should eq semver.to_s end # it end # version_strings end # describe describe '#to_rubygems_string' do version_strings.each do |v| it "generates a rubygems version string for #{v}" do subject = described_class.new(v) string = subject.to_rubygems_string rubygems = Mixlib::Versioning::Format::Rubygems.new(string) string.should eq rubygems.to_s end # it end # version_strings end # describe end # shared_examples mixlib-versioning-1.1.0/spec/support/shared_examples/behaviors/filterable.rb0000644000175000017500000000372612703167554027002 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # shared_examples 'filterable' do let(:unsorted_versions) do unsorted_version_strings.map { |v| described_class.new(v) } end # this should/will be overriden by calling spec let(:release_versions) { [] } let(:prerelease_versions) { [] } let(:build_versions) { [] } let(:release_build_versions) { [] } let(:prerelease_build_versions) { [] } it 'filters by release versions only' do unsorted_versions.select(&:release?).should eq(release_versions.map { |v| described_class.new(v) }) end # it it 'filters by pre-release versions only' do filtered = unsorted_versions.select(&:prerelease?) filtered.should eq(prerelease_versions.map { |v| described_class.new(v) }) end # it it 'filters by build versions only' do filtered = unsorted_versions.select(&:build?) filtered.should eq(build_versions.map { |v| described_class.new(v) }) end # it it 'filters by release build versions only' do filtered = unsorted_versions.select(&:release_build?) filtered.should eq(release_build_versions.map { |v| described_class.new(v) }) end # it it 'filters by pre-release build versions only' do filtered = unsorted_versions.select(&:prerelease_build?) filtered.should eq(prerelease_build_versions.map { |v| described_class.new(v) }) end # it end # shared_examples mixlib-versioning-1.1.0/spec/support/shared_examples/behaviors/rejects_invalid_version_strings.rb0000644000175000017500000000204212703167554033342 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # shared_examples 'rejects invalid version strings' do |invalid_examples| invalid_examples.each_pair do |version, reason| context version do let(:version_string) { version } it "fails because: #{reason}" do expect { subject }.to raise_error(Mixlib::Versioning::ParseError) end end # context end # invalid_examples end # shared_examples mixlib-versioning-1.1.0/spec/support/shared_examples/behaviors/sortable.rb0000644000175000017500000000240212703167554026472 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # shared_examples 'sortable' do let(:unsorted_versions) do unsorted_version_strings.map { |v| described_class.new(v) } end let(:sorted_versions) do sorted_version_strings.map { |v| described_class.new(v) } end it 'responds to <=>' do described_class.should respond_to(:<=>) end it 'sorts all properly' do unsorted_versions.sort.should eq sorted_versions end it 'finds the min' do unsorted_versions.min.should eq described_class.new(min) end it 'finds the max' do unsorted_versions.max.should eq described_class.new(max) end end # shared_examples mixlib-versioning-1.1.0/spec/support/shared_examples/behaviors/comparable.rb0000644000175000017500000000525512703167554026775 0ustar globusglobus# # Author:: Krzysztof Wilczynski () # Copyright:: Copyright (c) 2014 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # shared_examples 'comparable' do |version_matrix| describe '#<' do version_matrix.each_slice(2) do |a, b| it "confirms that #{a} is less-than #{b}" do expect(described_class.new(a) < b).to be true expect(described_class.new(a) > b).to be false end end end describe '#<=' do version_matrix.each_slice(2) do |a, b| it "confirms that #{a} less-than or equal to #{b}" do expect(described_class.new(a) <= b).to be true expect(described_class.new(a) <= a).to be true expect(described_class.new(a) > b).to be false expect(described_class.new(a) == b).to be false end end end describe '#==' do version_matrix.each do |v| it "confirms that #{v} is equal to #{v}" do expect(described_class.new(v) == v).to be true expect(described_class.new(v) < v).to be false expect(described_class.new(v) > v).to be false end end end describe '#>' do version_matrix.reverse.each_slice(2) do |a, b| it "confirms that #{a} is greather-than #{b}" do expect(described_class.new(a) > b).to be true expect(described_class.new(a) < b).to be false end end end describe '#>=' do version_matrix.reverse.each_slice(2) do |a, b| it "confirms that #{a} greater-than or equal to #{b}" do expect(described_class.new(a) >= b).to be true expect(described_class.new(a) >= a).to be true expect(described_class.new(a) < b).to be false expect(described_class.new(a) == b).to be false end end end describe '#between?' do let(:versions) { version_matrix.map { |v| described_class.new(v) }.sort } it 'comfirms that a version is between the oldest and latest release' do min, max = versions.minmax.map(&:to_s) middle = versions[versions.size / 2].to_s expect(described_class.new(middle).between?(min, max)).to be true expect(described_class.new(middle).between?(max, min)).to be false end end end mixlib-versioning-1.1.0/spec/support/shared_examples/behaviors/parses_valid_version_strings.rb0000644000175000017500000000176312703167554032662 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # shared_examples 'parses valid version strings' do |valid_examples| valid_examples.each do |version, options| context version do let(:version_string) { version } options.each_pair do |name, value| its(name) { should eq value } end end # context end # valid_examples end # shared_examples mixlib-versioning-1.1.0/spec/support/shared_examples/basic_semver.rb0000644000175000017500000000224612703167554025345 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # shared_examples 'Basic SemVer' do it_has_behavior 'parses valid version strings', { '1.2.3' => { major: 1, minor: 2, patch: 3, prerelease: nil, build: nil, release?: true, prerelease?: false, build?: false, release_build?: false, prerelease_build?: false, }, } it_has_behavior 'rejects invalid version strings', { 'a.1.1' => 'non-numeric MAJOR', '1.a.1' => 'non-numeric MINOR', '1.1.a' => 'non-numeric PATCH', } end mixlib-versioning-1.1.0/spec/support/shared_examples/semver.rb0000644000175000017500000000724512703167554024210 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'mixlib/versioning' shared_examples Mixlib::Versioning::Format::SemVer do it_should_behave_like 'Basic SemVer' it_has_behavior 'parses valid version strings', { '1.0.0-alpha.1' => { major: 1, minor: 0, patch: 0, prerelease: 'alpha.1', build: nil, release?: false, prerelease?: true, build?: false, release_build?: false, prerelease_build?: false, }, '1.0.0+20130308110833' => { major: 1, minor: 0, patch: 0, prerelease: nil, build: '20130308110833', release?: false, prerelease?: false, build?: true, release_build?: true, prerelease_build?: false, }, '1.0.0-beta.3+20130308110833' => { major: 1, minor: 0, patch: 0, prerelease: 'beta.3', build: '20130308110833', release?: false, prerelease?: false, build?: true, release_build?: false, prerelease_build?: true, }, } it_has_behavior 'rejects invalid version strings', { '8.8.8.8' => 'too many segments: MAJOR.MINOR.PATCH.EXTRA', '01.1.1' => 'leading zero invalid', '1.01.1' => 'leading zero invalid', '1.1.01' => 'leading zero invalid', '1.0.0-' => 'empty prerelease identifier', '1.0.0-alpha..' => 'empty prerelease identifier', '1.0.0-01.02.03' => 'leading zero invalid', '1.0.0-alpha.01' => 'leading zero invalid', '6.3.1+' => 'empty build identifier', '6.4.8-alpha.1.2.3+build.' => 'empty build identifier', '4.0.000000000002-alpha.1' => 'leading zero invalid', '007.2.3-rc.1+build.16' => 'leading zero invalid', '12.0005.1-alpha.12' => 'leading zero invalid', '12.2.10-beta.00000017' => 'leading zero invalid', } describe 'build qualification' do context 'release version' do let(:version_string) { '1.0.0' } its(:release?) { should be_true } its(:prerelease?) { should be_false } its(:build?) { should be_false } its(:release_build?) { should be_false } its(:prerelease_build?) { should be_false } end context 'pre-release version' do let(:version_string) { '1.0.0-alpha.1' } its(:release?) { should be_false } its(:prerelease?) { should be_true } its(:build?) { should be_false } its(:release_build?) { should be_false } its(:prerelease_build?) { should be_false } end context 'pre-release build version' do let(:version_string) { '1.0.0-alpha.1+20130308110833' } its(:release?) { should be_false } its(:prerelease?) { should be_false } its(:build?) { should be_true } its(:release_build?) { should be_false } its(:prerelease_build?) { should be_true } end context 'release build version' do let(:version_string) { '1.0.0+20130308110833' } its(:release?) { should be_false } its(:prerelease?) { should be_false } its(:build?) { should be_true } its(:release_build?) { should be_true } its(:prerelease_build?) { should be_false } end end end mixlib-versioning-1.1.0/spec/spec_helper.rb0000644000175000017500000000256512703167554020320 0ustar globusglobus# # Author:: Seth Chisamore () # Copyright:: Copyright (c) 2013 Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'mixlib/versioning' # load all shared examples and shared contexts Dir[File.expand_path('../support/**/*.rb', __FILE__)].each do |file| require(file) end RSpec.configure do |config| # a little syntactic sugar config.alias_it_should_behave_like_to :it_has_behavior, 'has behavior:' # Use color in STDOUT config.color_enabled = true # Use color not only in STDOUT but also in pagers and files config.tty = true # run the examples in random order config.order = :rand # specify metadata with symobls only (ie no '=> true' required) config.treat_symbols_as_metadata_keys_with_true_values = true config.filter_run focus: true config.run_all_when_everything_filtered = true end mixlib-versioning-1.1.0/LICENSE0000644000175000017500000002514212703167554015551 0ustar globusglobus Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. mixlib-versioning-1.1.0/CHANGELOG.md0000644000175000017500000000054412703167554016354 0ustar globusglobusv1.1.0 / 2015-06-15 ------------------- ### New features * Allow parse to take a list of formats to choose from * Update to SemVer 2.0.0 ### Improvements * Add ability to compare directly with strings. * Lock to RuboCop 0.31.0 (also fix style errors) v1.0.0 / 2013-03-29 ------------------- * The initial release. Versioning parsing shouldn't suck. mixlib-versioning-1.1.0/README.md0000644000175000017500000002431412703167554016023 0ustar globusglobus# Mixlib::Versioning [![Build Status](https://travis-ci.org/chef/mixlib-versioning.png?branch=master)](https://travis-ci.org/chef/mixlib-versioning) [![Code Climate](https://codeclimate.com/github/chef/mixlib-versioning.png)](https://codeclimate.com/github/chef/mixlib-versioning) This project is managed by the CHEF Release Engineering team. For more information on the Release Engineering team's contribution, triage, and release process, please consult the [CHEF Release Engineering OSS Management Guide](https://docs.google.com/a/chef.io/document/d/1oJB0vZb_3bl7_ZU2YMDBkMFdL-EWplW1BJv_FXTUOzg/edit). Versioning is hard! `mixlib-versioning` is a general Ruby library that allows you to parse, compare and manipulate version numbers in multiple formats. Currently the following version string formats are supported: ### SemVer 2.0.0 **Specification:** http://semver.org/ **Supported Formats:** ```text MAJOR.MINOR.PATCH MAJOR.MINOR.PATCH-PRERELEASE MAJOR.MINOR.PATCH-PRERELEASE+BUILD ``` Not much to say here except: *YUNO USE SEMVER!* The specification is focused and brief, do yourself a favor and go read it. ### Opscode SemVer **Supported Formats:** ```text MAJOR.MINOR.PATCH MAJOR.MINOR.PATCH-alpha.INDEX MAJOR.MINOR.PATCH-beta.INDEX MAJOR.MINOR.PATCH-rc.INDEX MAJOR.MINOR.PATCH-alpha.INDEX+YYYYMMDDHHMMSS MAJOR.MINOR.PATCH-beta.INDEX+YYYYMMDDHHMMSS MAJOR.MINOR.PATCH-rc.INDEX+YYYYMMDDHHMMSS MAJOR.MINOR.PATCH-alpha.INDEX+YYYYMMDDHHMMSS.git.COMMITS_SINCE.SHA1 MAJOR.MINOR.PATCH-beta.INDEX+YYYYMMDDHHMMSS.git.COMMITS_SINCE.SHA1 MAJOR.MINOR.PATCH-rc.INDEX+YYYYMMDDHHMMSS.git.COMMITS_SINCE.SHA1 ``` All the fun of regular SemVer with some extra limits around what constitutes a valid pre-release or build version string. Valid prerelease version strings use the format: `PRERELEASE_STAGE.INDEX`. Valid prerelease stages include: `alpha`, `beta` and `rc`. All of the following are acceptable Opscode SemVer pre-release versions: ```text 11.0.8-alpha.0 11.0.8-alpha.1 11.0.8-beta.7 11.0.8-beta.8 11.0.8-rc.1 11.0.8-rc.2 ``` Build version strings are limited to timestamps (`YYYYMMDDHHMMSS`), git describe strings (`git.COMMITS_SINCE.SHA1`) or a combination of the two (`YYYYMMDDHHMMSS.git.COMMITS_SINCE.SHA1`). All of the following are acceptable Opscode build versions: ```text 11.0.8+20130308110833 11.0.8+git.2.g94a1dde 11.0.8+20130308110833.git.2.94a1dde ``` And as is true with regular SemVer you can mix pre-release and build versions: ```text 11.0.8-rc.1+20130308110833 11.0.8-alpha.2+20130308110833.git.2.94a1dde ``` ### Rubygems **specification:** http://docs.rubygems.org/read/chapter/7 http://guides.rubygems.org/patterns/ **Supported Formats:** ```text MAJOR.MINOR.PATCH MAJOR.MINOR.PATCH.PRERELEASE ``` Rubygems is *almost* SemVer compliant but it separates the main version from the pre-release version using a "dot". It also does not have the notion of a build version like SemVer. Examples of valid Rubygems version strings: ```text 10.1.1 10.1.1 10.1.1.alpha.1 10.1.1.beta.1 10.1.1.rc.0 ``` ### Git Describe **Specification:** http://git-scm.com/docs/git-describe **Supported Formats:** ```text MAJOR.MINOR.PATCH-COMMITS_SINCE-gGIT_SHA1 MAJOR.MINOR.PATCH-COMMITS_SINCE-gGIT_SHA1-ITERATION MAJOR.MINOR.PATCH-PRERELEASE-COMMITS_SINCE-gGIT_SHA1 MAJOR.MINOR.PATCH-PRERELEASE-COMMITS_SINCE-gGIT_SHA1-ITERATION ``` Examples of valid Git Describe version strings: ```text 10.16.2-49-g21353f0-1 10.16.2.rc.1-49-g21353f0-1 11.0.0-alpha-10-g642ffed 11.0.0-alpha.1-1-gcea071e ``` ## Installation Add this line to your application's Gemfile: gem 'mixlib-versioning' And then execute: $ bundle Or install it yourself as: $ gem install mixlib-semver ## Usage ### Basic Version String Parsing ```irb >> require 'mixlib/versioning' true >> v1 = Mixlib::Versioning.parse("11.0.3") # >> v1.release? true >> v1.prerelease? false >> v1.build? false >> v1.prerelease_build? false >> v2 = Mixlib::Versioning.parse("11.0.0-beta.1") # >> v2.release? false >> v2.prerelease? true >> v2.build? false >> v2.prerelease_build? false >> v3 = Mixlib::Versioning.parse("11.0.6+20130216075209") # >> v3.release? false >> v3.prerelease? false >> v3.build? true >> v3.prerelease_build? false >> v4 = Mixlib::Versioning.parse("11.0.8-rc.1+20130302083119") # >> v4.release? false >> v4.prerelease? false >> v4.build? true >> v4.prerelease_build? true >> v5 = Mixlib::Versioning.parse("10.16.8.alpha.0") # >> v5.major 10 >> v5.minor 16 >> v5.patch 8 >> v5.prerelease "alpha.0" >> v5.release? false >> v5.prerelease? true ``` ### Version Comparison and Sorting ```irb >> require 'mixlib/versioning' true >> v1 = Mixlib::Versioning.parse("11.0.0-beta.1") # >> v2 = Mixlib::Versioning.parse("11.0.0-rc.1") # >> v3 = Mixlib::Versioning.parse("11.0.0") # >> v1 < v2 true >> v3 < v1 false >> v1 == v2 false >> [v3, v1, v2].sort [ [0] #, [1] #, [2] # ] >> [v3, v1, v2].map { |v| v.to_s}.sort [ [0] "11.0.0", [1] "11.0.0-beta.1", [2] "11.0.0-rc.1" ] ``` ### Target Version Selection Basic usage: ```ruby >> require 'mixlib/versioning' true >> all_versions = %w{ 11.0.0-alpha.1 11.0.0-alpha.1-1-gcea071e 11.0.0-alpha.3+20130103213604.git.11.3fe70b5 11.0.0-alpha.3+20130129075201.git.38.3332a80 11.0.0-alpha.3+20130130075202.git.38.3332a80 11.0.0-beta.0+20130131044557 11.0.0-beta.1+20130201023059.git.5.c9d3320 11.0.0-beta.2+20130201035911 11.0.0-beta.2+20130201191308.git.4.9aa4cb2 11.0.0-rc.1 11.0.0+20130204053034.git.1.1802643 11.0.4 11.0.6-alpha.0+20130208045134.git.2.298c401 11.0.6-alpha.0+20130214075209.git.11.5d72e1c 11.0.6-alpha.0+20130215075208.git.11.5d72e1c 11.0.6-rc.0 11.0.6 11.0.6+20130216075209 11.0.6+20130221075213 11.0.8-rc.1 11.0.8-rc.1+20130302083119 11.0.8-rc.1+20130304083118 11.0.8-rc.1+20130305083118 11.0.8-rc.1+20130305195925.git.2.94a1dde 11.0.8-rc.1+20130306083036.git.2.94a1dde 11.0.8-rc.1+20130319083111.git.6.dc8613e };'' "" >> Mixlib::Versioning.find_target_version(all_versions, "11.0.6", false, false) # >> target = Mixlib::Versioning.find_target_version(all_versions, "11.0.6", false, false) # >> target.to_s "11.0.6" ``` Select latest release version: ```irb >> target = Mixlib::Versioning.find_target_version(all_versions, nil, false, false) # >> target.to_s "11.0.6" ``` Select latest pre-release version: ```irb >> target = Mixlib::Versioning.find_target_version(all_versions, nil, true, false) # >> target.to_s "11.0.8-rc.1" ``` Select the latest release build version: ```irb >> target = Mixlib::Versioning.find_target_version(all_versions, nil, false, true) # >> target.to_s "11.0.6+20130221075213" ``` Select the latest pre-release build version: ```irb >> target = Mixlib::Versioning.find_target_version(all_versions, nil, true, true) # >> target.to_s "11.0.8-rc.1+20130319083111.git.6.dc8613e" ``` ## How to Run the Tests To run the unit tests, run ``` rake spec ``` ## Documentation All documentation is written using YARD. You can generate a by running: ``` rake yard ``` ## License | | | |:---------------------|:-----------------------------------------| | **Author:** | Seth Chisamore (schisamo@chef.io) | **Author:** | Christopher Maier (cm@chef.io) | **Copyright:** | Copyright (c) 2013 Opscode, Inc. | **License:** | Apache License, Version 2.0 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. mixlib-versioning-1.1.0/.travis.yml0000644000175000017500000000125512703167554016654 0ustar globusglobusrvm: - 1.9.3 - 2.0.0 - 2.1.0 bundler_args: --jobs 7 branches: only: - master script: bundle exec rake travis:ci notifications: hipchat: on_change: true on_failure: true on_success: false on_pull_requests: false rooms: # Build Statuses - secure: IycrY52k8dhilnU3B2c8mem9LzofQlMISUZSDk2tys0cvW0U3lnCQQiSvT5kTtiKztUABEiT2UqU2QYwUfeW/yYrO3NjB2OBqehRKnEn2oEaapcIugvtsQMySfYqJ7IsKpyh3vTMmgyKPw3OCKh5OJn26lMdHH2R91SXcbUezKI= # Release Engineering - secure: JJlujHzKxsY74bfJHNxH6fQOF5IULeJECXkxx6uU/T+CjxydINwAH5lQ1RUleLZlH0BmQDgxK+O46hiuWdYAyhgCJY9bQOBWG+aQusXIoLvV3qj+rU0dX1wvjEuO/NzkZTPZy7HMGqmCxTdmx/OawoNnpXU8qsI/OJqbISv2bGo= mixlib-versioning-1.1.0/Gemfile0000644000175000017500000000023212703167554016030 0ustar globusglobussource 'https://rubygems.org' gemspec group :docs do gem 'yard', '~> 0.8' gem 'redcarpet', '~> 2.2' gem 'github-markup', '~> 0.7' end