version: add new Version::Parser
class
This commit is contained in:
parent
f6bc3efac6
commit
568fc86676
@ -2,6 +2,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "version/null"
|
require "version/null"
|
||||||
|
require "version/parser"
|
||||||
|
|
||||||
# A formula's version.
|
# A formula's version.
|
||||||
#
|
#
|
||||||
@ -368,105 +369,86 @@ class Version
|
|||||||
|
|
||||||
spec = Pathname.new(spec) unless spec.is_a? Pathname
|
spec = Pathname.new(spec) unless spec.is_a? Pathname
|
||||||
|
|
||||||
spec_s = spec.to_s
|
VERSION_PARSERS.each do |parser|
|
||||||
|
version = parser.parse(spec)
|
||||||
stem = if spec.directory?
|
return version if version.present?
|
||||||
spec.basename.to_s
|
|
||||||
elsif spec_s.match?(%r{((?:sourceforge\.net|sf\.net)/.*)/download$})
|
|
||||||
spec.dirname.stem
|
|
||||||
elsif spec_s.match?(/\.[^a-zA-Z]+$/) # rubocop:disable Lint/DuplicateBranch
|
|
||||||
spec.basename.to_s
|
|
||||||
else
|
|
||||||
spec.stem
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
private_class_method :_parse
|
||||||
|
|
||||||
|
VERSION_PARSERS = [
|
||||||
# date-based versioning
|
# date-based versioning
|
||||||
# e.g. ltopers-v2017-04-14.tar.gz
|
# e.g. ltopers-v2017-04-14.tar.gz
|
||||||
m = /-v?(\d{4}-\d{2}-\d{2})/.match(stem)
|
StemParser.new(/-v?(\d{4}-\d{2}-\d{2})/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# GitHub tarballs
|
# GitHub tarballs
|
||||||
# e.g. https://github.com/foo/bar/tarball/v1.2.3
|
# e.g. https://github.com/foo/bar/tarball/v1.2.3
|
||||||
# e.g. https://github.com/sam-github/libnet/tarball/libnet-1.1.4
|
# e.g. https://github.com/sam-github/libnet/tarball/libnet-1.1.4
|
||||||
# e.g. https://github.com/isaacs/npm/tarball/v0.2.5-1
|
# e.g. https://github.com/isaacs/npm/tarball/v0.2.5-1
|
||||||
# e.g. https://github.com/petdance/ack/tarball/1.93_02
|
# e.g. https://github.com/petdance/ack/tarball/1.93_02
|
||||||
m = %r{github\.com/.+/(?:zip|tar)ball/(?:v|\w+-)?((?:\d+[-._])+\d*)$}.match(spec_s)
|
UrlParser.new(%r{github\.com/.+/(?:zip|tar)ball/(?:v|\w+-)?((?:\d+[-._])+\d*)$}),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. https://github.com/erlang/otp/tarball/OTP_R15B01 (erlang style)
|
# e.g. https://github.com/erlang/otp/tarball/OTP_R15B01 (erlang style)
|
||||||
m = /[-_]([Rr]\d+[AaBb]\d*(?:-\d+)?)/.match(spec_s)
|
UrlParser.new(/[-_]([Rr]\d+[AaBb]\d*(?:-\d+)?)/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. boost_1_39_0
|
# e.g. boost_1_39_0
|
||||||
m = /((?:\d+_)+\d+)$/.match(stem)
|
StemParser.new(/((?:\d+_)+\d+)$/) { |s| s.tr("_", ".") },
|
||||||
return T.must(m.captures.first).tr("_", ".") unless m.nil?
|
|
||||||
|
|
||||||
# e.g. foobar-4.5.1-1
|
# e.g. foobar-4.5.1-1
|
||||||
# e.g. unrtf_0.20.4-1
|
# e.g. unrtf_0.20.4-1
|
||||||
# e.g. ruby-1.9.1-p243
|
# e.g. ruby-1.9.1-p243
|
||||||
m = /[-_]((?:\d+\.)*\d+\.\d+-(?:p|rc|RC)?\d+)(?:[-._](?i:bin|dist|stable|src|sources?|final|full))?$/.match(stem)
|
StemParser.new(/[-_]((?:\d+\.)*\d+\.\d+-(?:p|rc|RC)?\d+)(?:[-._](?i:bin|dist|stable|src|sources?|final|full))?$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# URL with no extension
|
# URL with no extension
|
||||||
# e.g. https://waf.io/waf-1.8.12
|
# e.g. https://waf.io/waf-1.8.12
|
||||||
# e.g. https://codeload.github.com/gsamokovarov/jump/tar.gz/v0.7.1
|
# e.g. https://codeload.github.com/gsamokovarov/jump/tar.gz/v0.7.1
|
||||||
m = /[-v]((?:\d+\.)*\d+)$/.match(spec_s)
|
UrlParser.new(/[-v]((?:\d+\.)*\d+)$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. lame-398-1
|
# e.g. lame-398-1
|
||||||
m = /-(\d+-\d+)/.match(stem)
|
StemParser.new(/-(\d+-\d+)/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. foobar-4.5.1
|
# e.g. foobar-4.5.1
|
||||||
m = /-((?:\d+\.)*\d+)$/.match(stem)
|
StemParser.new(/-((?:\d+\.)*\d+)$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. foobar-4.5.1.post1
|
# e.g. foobar-4.5.1.post1
|
||||||
m = /-((?:\d+\.)*\d+(.post\d+)?)$/.match(stem)
|
StemParser.new(/-((?:\d+\.)*\d+(.post\d+)?)$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. foobar-4.5.1b
|
# e.g. foobar-4.5.1b
|
||||||
m = /-((?:\d+\.)*\d+(?:[abc]|rc|RC)\d*)$/.match(stem)
|
StemParser.new(/-((?:\d+\.)*\d+(?:[abc]|rc|RC)\d*)$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. foobar-4.5.0-alpha5, foobar-4.5.0-beta1, or foobar-4.50-beta
|
# e.g. foobar-4.5.0-alpha5, foobar-4.5.0-beta1, or foobar-4.50-beta
|
||||||
m = /-((?:\d+\.)*\d+-(?:alpha|beta|rc)\d*)$/.match(stem)
|
StemParser.new(/-((?:\d+\.)*\d+-(?:alpha|beta|rc)\d*)$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. https://ftpmirror.gnu.org/libidn/libidn-1.29-win64.zip
|
# e.g. https://ftpmirror.gnu.org/libidn/libidn-1.29-win64.zip
|
||||||
# e.g. https://ftpmirror.gnu.org/libmicrohttpd/libmicrohttpd-0.9.17-w32.zip
|
# e.g. https://ftpmirror.gnu.org/libmicrohttpd/libmicrohttpd-0.9.17-w32.zip
|
||||||
m = /-(\d+\.\d+(?:\.\d+)?)-w(?:in)?(?:32|64)$/.match(stem)
|
StemParser.new(/-(\d+\.\d+(?:\.\d+)?)-w(?:in)?(?:32|64)$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# Opam packages
|
# Opam packages
|
||||||
# e.g. https://opam.ocaml.org/archives/sha.1.9+opam.tar.gz
|
# e.g. https://opam.ocaml.org/archives/sha.1.9+opam.tar.gz
|
||||||
# e.g. https://opam.ocaml.org/archives/lablgtk.2.18.3+opam.tar.gz
|
# e.g. https://opam.ocaml.org/archives/lablgtk.2.18.3+opam.tar.gz
|
||||||
# e.g. https://opam.ocaml.org/archives/easy-format.1.0.2+opam.tar.gz
|
# e.g. https://opam.ocaml.org/archives/easy-format.1.0.2+opam.tar.gz
|
||||||
m = /\.(\d+\.\d+(?:\.\d+)?)\+opam$/.match(stem)
|
StemParser.new(/\.(\d+\.\d+(?:\.\d+)?)\+opam$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. https://ftpmirror.gnu.org/mtools/mtools-4.0.18-1.i686.rpm
|
# e.g. https://ftpmirror.gnu.org/mtools/mtools-4.0.18-1.i686.rpm
|
||||||
# e.g. https://ftpmirror.gnu.org/autogen/autogen-5.5.7-5.i386.rpm
|
# e.g. https://ftpmirror.gnu.org/autogen/autogen-5.5.7-5.i386.rpm
|
||||||
# e.g. https://ftpmirror.gnu.org/libtasn1/libtasn1-2.8-x86.zip
|
# e.g. https://ftpmirror.gnu.org/libtasn1/libtasn1-2.8-x86.zip
|
||||||
# e.g. https://ftpmirror.gnu.org/libtasn1/libtasn1-2.8-x64.zip
|
# e.g. https://ftpmirror.gnu.org/libtasn1/libtasn1-2.8-x64.zip
|
||||||
# e.g. https://ftpmirror.gnu.org/mtools/mtools_4.0.18_i386.deb
|
# e.g. https://ftpmirror.gnu.org/mtools/mtools_4.0.18_i386.deb
|
||||||
m = /[-_](\d+\.\d+(?:\.\d+)?(?:-\d+)?)[-_.](?:i[36]86|x86|x64(?:[-_](?:32|64))?)$/.match(stem)
|
StemParser.new(/[-_](\d+\.\d+(?:\.\d+)?(?:-\d+)?)[-_.](?:i[36]86|x86|x64(?:[-_](?:32|64))?)$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. https://registry.npmjs.org/@angular/cli/-/cli-1.3.0-beta.1.tgz
|
# e.g. https://registry.npmjs.org/@angular/cli/-/cli-1.3.0-beta.1.tgz
|
||||||
# e.g. https://github.com/dlang/dmd/archive/v2.074.0-beta1.tar.gz
|
# e.g. https://github.com/dlang/dmd/archive/v2.074.0-beta1.tar.gz
|
||||||
# e.g. https://github.com/dlang/dmd/archive/v2.074.0-rc1.tar.gz
|
# e.g. https://github.com/dlang/dmd/archive/v2.074.0-rc1.tar.gz
|
||||||
# e.g. https://github.com/premake/premake-core/releases/download/v5.0.0-alpha10/premake-5.0.0-alpha10-src.zip
|
# e.g. https://github.com/premake/premake-core/releases/download/v5.0.0-alpha10/premake-5.0.0-alpha10-src.zip
|
||||||
m = /[-.vV]?((?:\d+\.)+\d+[-_.]?(?i:alpha|beta|pre|rc)\.?\d{,2})/.match(stem)
|
StemParser.new(/[-.vV]?((?:\d+\.)+\d+[-_.]?(?i:alpha|beta|pre|rc)\.?\d{,2})/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. foobar4.5.1
|
# e.g. foobar4.5.1
|
||||||
m = /((?:\d+\.)*\d+)$/.match(stem)
|
StemParser.new(/((?:\d+\.)*\d+)$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. foobar-4.5.0-bin
|
# e.g. foobar-4.5.0-bin
|
||||||
m = /[-vV]((?:\d+\.)+\d+[abc]?)[-._](?i:bin|dist|stable|src|sources?|final|full)$/.match(stem)
|
StemParser.new(/[-vV]((?:\d+\.)+\d+[abc]?)[-._](?i:bin|dist|stable|src|sources?|final|full)$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# dash version style
|
# dash version style
|
||||||
# e.g. http://www.antlr.org/download/antlr-3.4-complete.jar
|
# e.g. http://www.antlr.org/download/antlr-3.4-complete.jar
|
||||||
@ -474,20 +456,16 @@ class Version
|
|||||||
# e.g. https://search.maven.org/remotecontent?filepath=com/facebook/presto/presto-cli/0.181/presto-cli-0.181-executable.jar
|
# e.g. https://search.maven.org/remotecontent?filepath=com/facebook/presto/presto-cli/0.181/presto-cli-0.181-executable.jar
|
||||||
# e.g. https://search.maven.org/remotecontent?filepath=org/fusesource/fuse-extra/fusemq-apollo-mqtt/1.3/fusemq-apollo-mqtt-1.3-uber.jar
|
# e.g. https://search.maven.org/remotecontent?filepath=org/fusesource/fuse-extra/fusemq-apollo-mqtt/1.3/fusemq-apollo-mqtt-1.3-uber.jar
|
||||||
# e.g. https://search.maven.org/remotecontent?filepath=org/apache/orc/orc-tools/1.2.3/orc-tools-1.2.3-uber.jar
|
# e.g. https://search.maven.org/remotecontent?filepath=org/apache/orc/orc-tools/1.2.3/orc-tools-1.2.3-uber.jar
|
||||||
m = /-((?:\d+\.)+\d+)-/.match(stem)
|
StemParser.new(/-((?:\d+\.)+\d+)-/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. dash_0.5.5.1.orig.tar.gz (Debian style)
|
# e.g. dash_0.5.5.1.orig.tar.gz (Debian style)
|
||||||
m = /_((?:\d+\.)+\d+[abc]?)[.]orig$/.match(stem)
|
StemParser.new(/_((?:\d+\.)+\d+[abc]?)[.]orig$/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. https://www.openssl.org/source/openssl-0.9.8s.tar.gz
|
# e.g. https://www.openssl.org/source/openssl-0.9.8s.tar.gz
|
||||||
m = /-v?(\d[^-]+)/.match(stem)
|
StemParser.new(/-v?(\d[^-]+)/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. astyle_1.23_macosx.tar.gz
|
# e.g. astyle_1.23_macosx.tar.gz
|
||||||
m = /_v?(\d[^_]+)/.match(stem)
|
StemParser.new(/_v?(\d[^_]+)/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. http://mirrors.jenkins-ci.org/war/1.486/jenkins.war
|
# e.g. http://mirrors.jenkins-ci.org/war/1.486/jenkins.war
|
||||||
# e.g. https://github.com/foo/bar/releases/download/0.10.11/bar.phar
|
# e.g. https://github.com/foo/bar/releases/download/0.10.11/bar.phar
|
||||||
@ -496,18 +474,15 @@ class Version
|
|||||||
# e.g. https://wwwlehre.dhbw-stuttgart.de/~sschulz/WORK/E_DOWNLOAD/V_1.9/E.tgz
|
# e.g. https://wwwlehre.dhbw-stuttgart.de/~sschulz/WORK/E_DOWNLOAD/V_1.9/E.tgz
|
||||||
# e.g. https://github.com/JustArchi/ArchiSteamFarm/releases/download/2.3.2.0/ASF.zip
|
# e.g. https://github.com/JustArchi/ArchiSteamFarm/releases/download/2.3.2.0/ASF.zip
|
||||||
# e.g. https://people.gnome.org/~newren/eg/download/1.7.5.2/eg
|
# e.g. https://people.gnome.org/~newren/eg/download/1.7.5.2/eg
|
||||||
m = %r{/([rvV]_?)?(\d+\.\d+(\.\d+){,2})}.match(spec_s)
|
UrlParser.new(%r{/(?:[rvV]_?)?(\d+\.\d+(?:\.\d+){,2})}),
|
||||||
return m.captures.second unless m.nil?
|
|
||||||
|
|
||||||
# e.g. https://www.ijg.org/files/jpegsrc.v8d.tar.gz
|
# e.g. https://www.ijg.org/files/jpegsrc.v8d.tar.gz
|
||||||
m = /\.v(\d+[a-z]?)/.match(stem)
|
StemParser.new(/\.v(\d+[a-z]?)/),
|
||||||
return m.captures.first unless m.nil?
|
|
||||||
|
|
||||||
# e.g. https://secure.php.net/get/php-7.1.10.tar.bz2/from/this/mirror
|
# e.g. https://secure.php.net/get/php-7.1.10.tar.bz2/from/this/mirror
|
||||||
m = /[-.vV]?((?:\d+\.)+\d+(?:[-_.]?(?i:alpha|beta|pre|rc)\.?\d{,2})?)/.match(spec_s)
|
UrlParser.new(/[-.vV]?((?:\d+\.)+\d+(?:[-_.]?(?i:alpha|beta|pre|rc)\.?\d{,2})?)/),
|
||||||
return m.captures.first unless m.nil?
|
].freeze
|
||||||
end
|
private_constant :VERSION_PARSERS
|
||||||
private_class_method :_parse
|
|
||||||
|
|
||||||
sig { params(val: T.any(String, Version), detected_from_url: T::Boolean).void }
|
sig { params(val: T.any(String, Version), detected_from_url: T::Boolean).void }
|
||||||
def initialize(val, detected_from_url: false)
|
def initialize(val, detected_from_url: false)
|
||||||
|
72
Library/Homebrew/version/parser.rb
Normal file
72
Library/Homebrew/version/parser.rb
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# typed: true
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Version
|
||||||
|
# @api private
|
||||||
|
class Parser
|
||||||
|
extend T::Sig
|
||||||
|
extend T::Helpers
|
||||||
|
abstract!
|
||||||
|
|
||||||
|
sig { abstract.params(spec: Pathname).returns(T.nilable(String)) }
|
||||||
|
def parse(spec); end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @api private
|
||||||
|
class RegexParser < Parser
|
||||||
|
extend T::Sig
|
||||||
|
extend T::Helpers
|
||||||
|
abstract!
|
||||||
|
|
||||||
|
sig { params(regex: Regexp, block: T.nilable(T.proc.params(arg0: String).returns(String))).void }
|
||||||
|
def initialize(regex, &block)
|
||||||
|
super()
|
||||||
|
@regex = regex
|
||||||
|
@block = block
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { override.params(spec: Pathname).returns(T.nilable(String)) }
|
||||||
|
def parse(spec)
|
||||||
|
match = @regex.match(process_spec(spec))
|
||||||
|
return if match.blank?
|
||||||
|
|
||||||
|
version = match.captures.first
|
||||||
|
return if version.blank?
|
||||||
|
return @block.call(version) if @block.present?
|
||||||
|
|
||||||
|
version
|
||||||
|
end
|
||||||
|
|
||||||
|
sig { abstract.params(spec: Pathname).returns(String) }
|
||||||
|
def process_spec(spec); end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @api private
|
||||||
|
class UrlParser < RegexParser
|
||||||
|
extend T::Sig
|
||||||
|
|
||||||
|
sig { override.params(spec: Pathname).returns(String) }
|
||||||
|
def process_spec(spec)
|
||||||
|
spec.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @api private
|
||||||
|
class StemParser < RegexParser
|
||||||
|
extend T::Sig
|
||||||
|
|
||||||
|
SOURCEFORGE_DOWNLOAD_REGEX = %r{((?:sourceforge\.net|sf\.net)/.*)/download$}.freeze
|
||||||
|
NO_FILE_EXTENSION_REGEX = /\.[^a-zA-Z]+$/.freeze
|
||||||
|
|
||||||
|
sig { override.params(spec: Pathname).returns(String) }
|
||||||
|
def process_spec(spec)
|
||||||
|
return spec.basename.to_s if spec.directory?
|
||||||
|
|
||||||
|
spec_s = spec.to_s
|
||||||
|
return spec.dirname.stem if spec_s.match?(SOURCEFORGE_DOWNLOAD_REGEX)
|
||||||
|
return spec.basename.to_s if spec_s.match?(NO_FILE_EXTENSION_REGEX)
|
||||||
|
|
||||||
|
spec.stem
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user