class XSemVer::SemVer
def self.parse(version_string, format = nil, allow_missing = true)
def self.parse(version_string, format = nil, allow_missing = true) format ||= TAG_FORMAT regex_str = Regexp.escape format # Convert all the format characters to named capture groups regex_str = regex_str. gsub('%M', '(?<major>\d+)'). gsub('%m', '(?<minor>\d+)'). gsub('%p', '(?<patch>\d+)'). gsub('%s', '(?:-(?<special>[A-Za-z][0-9A-Za-z\.]+))?'). gsub('%d', '(?:\\\+(?<metadata>[0-9A-Za-z][0-9A-Za-z\.]*))?') regex = Regexp.new(regex_str) match = regex.match version_string if match major = minor = patch = nil special = metadata = '' # Extract out the version parts major = match[:major].to_i if match.names.include? 'major' minor = match[:minor].to_i if match.names.include? 'minor' patch = match[:patch].to_i if match.names.include? 'patch' special = match[:special] || '' if match.names.include? 'special' metadata = match[:metadata] || '' if match.names.include? 'metadata' # Failed parse if major, minor, or patch wasn't found # and allow_missing is false return nil if !allow_missing and [major, minor, patch].any? {|x| x.nil? } # Otherwise, allow them to default to zero major ||= 0 minor ||= 0 patch ||= 0 SemVer.new major, minor, patch, special, metadata end end