# # 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 # 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_type [String, Symbol, Mixlib::Versioning::Format] 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 # # @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_type=nil) if version_string.kind_of?(Mixlib::Versioning::Format) return version_string elsif format_type return Mixlib::Versioning::Format.for(format_type).new(version_string) else # Attempt to parse from the most specific formats first. parsed_version = nil [ Mixlib::Versioning::Format::GitDescribe, Mixlib::Versioning::Format::OpscodeSemVer, Mixlib::Versioning::Format::SemVer, Mixlib::Versioning::Format::Rubygems ].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.kind_of?(Mixlib::Versioning::Format) filter_version = Mixlib::Versioning.parse(filter_version) end all_versions.map! do |v| if v.kind_of?(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