| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-03 16:28:16 -07:00
										 |  |  | require "version/null" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  | class Version | 
					
						
							| 
									
										
										
										
											2012-08-18 13:34:31 -05:00
										 |  |  |   include Comparable | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-18 14:36:51 +01:00
										 |  |  |   def self.formula_optionally_versioned_regex(name, full: true) | 
					
						
							|  |  |  |     /#{"^" if full}#{Regexp.escape(name)}(@\d[\d.]*)?#{"$" if full}/ | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |   class Token | 
					
						
							|  |  |  |     include Comparable | 
					
						
							| 
									
										
										
										
											2012-08-18 13:34:31 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |     attr_reader :value | 
					
						
							| 
									
										
										
										
											2013-04-15 15:00:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |     def initialize(value) | 
					
						
							|  |  |  |       @value = value | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def inspect | 
					
						
							| 
									
										
										
										
											2014-07-01 15:07:06 -05:00
										 |  |  |       "#<#{self.class.name} #{value.inspect}>" | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-06-05 23:30:55 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def to_s | 
					
						
							|  |  |  |       value.to_s | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-03-17 21:37:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def numeric? | 
					
						
							|  |  |  |       false | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-08-18 13:34:31 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |   class NullToken < Token | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     def initialize(value = nil) | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |       super | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def <=>(other) | 
					
						
							|  |  |  |       case other | 
					
						
							| 
									
										
										
										
											2015-03-17 21:37:03 -04:00
										 |  |  |       when NullToken | 
					
						
							|  |  |  |         0
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |       when NumericToken | 
					
						
							| 
									
										
										
										
											2016-09-17 15:17:27 +01:00
										 |  |  |         other.value.zero? ? 0 : -1
 | 
					
						
							| 
									
										
										
										
											2017-06-27 03:17:23 -07:00
										 |  |  |       when AlphaToken, BetaToken, PreToken, RCToken | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |         1
 | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         -1
 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def inspect | 
					
						
							| 
									
										
										
										
											2014-07-01 15:07:06 -05:00
										 |  |  |       "#<#{self.class.name}>" | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-08-18 13:34:31 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-19 21:46:20 +09:00
										 |  |  |   NULL_TOKEN = NullToken.new.freeze | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   class StringToken < Token | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |     PATTERN = /[a-z]+[0-9]*/i.freeze | 
					
						
							| 
									
										
										
										
											2013-01-15 18:20:52 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |     def initialize(value) | 
					
						
							|  |  |  |       @value = value.to_s | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2013-01-15 18:20:52 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |     def <=>(other) | 
					
						
							|  |  |  |       case other | 
					
						
							|  |  |  |       when StringToken | 
					
						
							|  |  |  |         value <=> other.value | 
					
						
							|  |  |  |       when NumericToken, NullToken | 
					
						
							|  |  |  |         -Integer(other <=> self) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-08-18 13:34:31 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |   class NumericToken < Token | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |     PATTERN = /[0-9]+/i.freeze | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def initialize(value) | 
					
						
							|  |  |  |       @value = value.to_i | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def <=>(other) | 
					
						
							|  |  |  |       case other | 
					
						
							|  |  |  |       when NumericToken | 
					
						
							|  |  |  |         value <=> other.value | 
					
						
							|  |  |  |       when StringToken | 
					
						
							|  |  |  |         1
 | 
					
						
							|  |  |  |       when NullToken | 
					
						
							|  |  |  |         -Integer(other <=> self) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-03-17 21:37:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def numeric? | 
					
						
							|  |  |  |       true | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-08-18 13:34:31 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |   class CompositeToken < StringToken | 
					
						
							|  |  |  |     def rev | 
					
						
							| 
									
										
										
										
											2014-10-06 13:55:23 -05:00
										 |  |  |       value[/[0-9]+/].to_i | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-07-09 22:51:10 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |   class AlphaToken < CompositeToken | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |     PATTERN = /alpha[0-9]*|a[0-9]+/i.freeze | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def <=>(other) | 
					
						
							|  |  |  |       case other | 
					
						
							|  |  |  |       when AlphaToken | 
					
						
							|  |  |  |         rev <=> other.rev | 
					
						
							| 
									
										
										
										
											2017-06-27 03:17:23 -07:00
										 |  |  |       when BetaToken, RCToken, PreToken, PatchToken | 
					
						
							|  |  |  |         -1
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |       else | 
					
						
							|  |  |  |         super | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-07-10 16:10:16 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |   class BetaToken < CompositeToken | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |     PATTERN = /beta[0-9]*|b[0-9]+/i.freeze | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def <=>(other) | 
					
						
							|  |  |  |       case other | 
					
						
							|  |  |  |       when BetaToken | 
					
						
							|  |  |  |         rev <=> other.rev | 
					
						
							|  |  |  |       when AlphaToken | 
					
						
							|  |  |  |         1
 | 
					
						
							| 
									
										
										
										
											2017-06-27 03:17:23 -07:00
										 |  |  |       when PreToken, RCToken, PatchToken | 
					
						
							|  |  |  |         -1
 | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         super | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   class PreToken < CompositeToken | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |     PATTERN = /pre[0-9]*/i.freeze | 
					
						
							| 
									
										
										
										
											2017-06-27 03:17:23 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def <=>(other) | 
					
						
							|  |  |  |       case other | 
					
						
							|  |  |  |       when PreToken | 
					
						
							|  |  |  |         rev <=> other.rev | 
					
						
							|  |  |  |       when AlphaToken, BetaToken | 
					
						
							|  |  |  |         1
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |       when RCToken, PatchToken | 
					
						
							|  |  |  |         -1
 | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         super | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-07-09 22:51:10 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |   class RCToken < CompositeToken | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |     PATTERN = /rc[0-9]*/i.freeze | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def <=>(other) | 
					
						
							|  |  |  |       case other | 
					
						
							|  |  |  |       when RCToken | 
					
						
							|  |  |  |         rev <=> other.rev | 
					
						
							| 
									
										
										
										
											2017-06-27 03:17:23 -07:00
										 |  |  |       when AlphaToken, BetaToken, PreToken | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |         1
 | 
					
						
							|  |  |  |       when PatchToken | 
					
						
							|  |  |  |         -1
 | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         super | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-07-09 23:00:40 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |   class PatchToken < CompositeToken | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |     PATTERN = /p[0-9]*/i.freeze | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def <=>(other) | 
					
						
							|  |  |  |       case other | 
					
						
							|  |  |  |       when PatchToken | 
					
						
							|  |  |  |         rev <=> other.rev | 
					
						
							| 
									
										
										
										
											2017-06-27 03:17:23 -07:00
										 |  |  |       when AlphaToken, BetaToken, RCToken, PreToken | 
					
						
							| 
									
										
										
										
											2013-06-05 21:52:48 -05:00
										 |  |  |         1
 | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         super | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2012-08-18 13:34:31 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-03 11:19:57 -05:00
										 |  |  |   SCAN_PATTERN = Regexp.union( | 
					
						
							|  |  |  |     AlphaToken::PATTERN, | 
					
						
							|  |  |  |     BetaToken::PATTERN, | 
					
						
							| 
									
										
										
										
											2017-06-27 03:17:23 -07:00
										 |  |  |     PreToken::PATTERN, | 
					
						
							| 
									
										
										
										
											2014-04-03 11:19:57 -05:00
										 |  |  |     RCToken::PATTERN, | 
					
						
							|  |  |  |     PatchToken::PATTERN, | 
					
						
							|  |  |  |     NumericToken::PATTERN, | 
					
						
							| 
									
										
										
										
											2017-02-12 15:06:54 +00:00
										 |  |  |     StringToken::PATTERN, | 
					
						
							| 
									
										
										
										
											2019-04-19 21:46:20 +09:00
										 |  |  |   ).freeze | 
					
						
							| 
									
										
										
										
											2014-04-03 11:19:57 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-07 15:21:20 -05:00
										 |  |  |   class FromURL < Version | 
					
						
							|  |  |  |     def detected_from_url? | 
					
						
							|  |  |  |       true | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-14 01:58:17 -04:00
										 |  |  |   def self.detect(url, specs) | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |     if specs.key?(:tag) | 
					
						
							| 
									
										
										
										
											2020-02-27 10:27:02 -08:00
										 |  |  |       FromURL.parse(specs[:tag]) | 
					
						
							| 
									
										
										
										
											2013-06-28 21:17:12 -05:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2015-01-07 15:21:20 -05:00
										 |  |  |       FromURL.parse(url) | 
					
						
							| 
									
										
										
										
											2013-06-28 21:17:12 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-18 20:33:03 +03:00
										 |  |  |   def self.create(val) | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     raise TypeError, "Version value must be a string; got a #{val.class} (#{val})" unless val.respond_to?(:to_str) | 
					
						
							| 
									
										
										
										
											2016-06-18 20:33:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if val.to_str.start_with?("HEAD") | 
					
						
							|  |  |  |       HeadVersion.new(val) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       Version.new(val) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self.parse(spec) | 
					
						
							| 
									
										
										
										
											2013-02-06 22:25:02 -06:00
										 |  |  |     version = _parse(spec) | 
					
						
							| 
									
										
										
										
											2016-11-03 16:36:20 -07:00
										 |  |  |     version.nil? ? NULL : new(version) | 
					
						
							| 
									
										
										
										
											2013-02-06 22:25:02 -06:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-03 13:09:07 +01:00
										 |  |  |   def self._parse(spec) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     spec = Pathname.new(spec) unless spec.is_a? Pathname | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-16 14:32:28 -05:00
										 |  |  |     spec_s = spec.to_s | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     stem = if spec.directory? | 
					
						
							| 
									
										
										
										
											2017-04-27 20:17:06 +02:00
										 |  |  |       spec.basename | 
					
						
							| 
									
										
										
										
											2019-10-13 19:26:39 +01:00
										 |  |  |     elsif spec_s.match?(%r{((?:sourceforge\.net|sf\.net)/.*)/download$}) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |       Pathname.new(spec.dirname).stem | 
					
						
							| 
									
										
										
										
											2019-10-13 19:26:39 +01:00
										 |  |  |     elsif spec_s.match?(/\.[^a-zA-Z]+$/) | 
					
						
							| 
									
										
										
										
											2016-08-18 04:53:34 -07:00
										 |  |  |       Pathname.new(spec_s).basename | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     else | 
					
						
							|  |  |  |       spec.stem | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 22:42:57 +02:00
										 |  |  |     # date-based versioning | 
					
						
							|  |  |  |     # e.g. ltopers-v2017-04-14.tar.gz | 
					
						
							|  |  |  |     m = /-v?(\d{4}-\d{2}-\d{2})/.match(stem) | 
					
						
							|  |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-27 15:21:05 -05:00
										 |  |  |     # GitHub tarballs | 
					
						
							|  |  |  |     # e.g. https://github.com/foo/bar/tarball/v1.2.3 | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     # 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/petdance/ack/tarball/1.93_02 | 
					
						
							| 
									
										
										
										
											2016-07-13 16:19:51 +08:00
										 |  |  |     m = %r{github\.com/.+/(?:zip|tar)ball/(?:v|\w+-)?((?:\d+[-._])+\d*)$}.match(spec_s) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-25 10:20:48 -07:00
										 |  |  |     # e.g. https://github.com/erlang/otp/tarball/OTP_R15B01 (erlang style) | 
					
						
							| 
									
										
										
										
											2013-06-03 20:52:21 +01:00
										 |  |  |     m = /[-_]([Rr]\d+[AaBb]\d*(?:-\d+)?)/.match(spec_s) | 
					
						
							| 
									
										
										
										
											2012-08-25 10:20:48 -07:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     # e.g. boost_1_39_0 | 
					
						
							| 
									
										
										
										
											2013-04-27 15:21:06 -05:00
										 |  |  |     m = /((?:\d+_)+\d+)$/.match(stem) | 
					
						
							| 
									
										
										
										
											2015-08-06 15:45:52 +08:00
										 |  |  |     return m.captures.first.tr("_", ".") unless m.nil? | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # e.g. foobar-4.5.1-1 | 
					
						
							| 
									
										
										
										
											2015-01-29 23:56:40 +01:00
										 |  |  |     # e.g. unrtf_0.20.4-1 | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     # e.g. ruby-1.9.1-p243 | 
					
						
							| 
									
										
										
										
											2020-02-23 10:23:35 -08:00
										 |  |  |     m = /[-_]((?:\d+\.)*\d+\.\d+-(?:p|rc|RC)?\d+)(?:[-._](?:bin|dist|stable|src|sources))?$/.match(stem) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-19 11:11:14 -08:00
										 |  |  |     # URL with no extension | 
					
						
							|  |  |  |     # e.g. https://waf.io/waf-1.8.12 | 
					
						
							|  |  |  |     # e.g. https://codeload.github.com/gsamokovarov/jump/tar.gz/v0.7.1 | 
					
						
							|  |  |  |     m = /[-v]((?:\d+\.)*\d+)$/.match(spec_s) | 
					
						
							| 
									
										
										
										
											2015-12-26 19:55:19 +01:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     # e.g. lame-398-1 | 
					
						
							| 
									
										
										
										
											2020-02-23 10:23:35 -08:00
										 |  |  |     m = /-(\d+-\d+)/.match(stem) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # e.g. foobar-4.5.1 | 
					
						
							| 
									
										
										
										
											2013-04-27 15:21:06 -05:00
										 |  |  |     m = /-((?:\d+\.)*\d+)$/.match(stem) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # e.g. foobar-4.5.1b | 
					
						
							| 
									
										
										
										
											2013-04-27 15:21:06 -05:00
										 |  |  |     m = /-((?:\d+\.)*\d+(?:[abc]|rc|RC)\d*)$/.match(stem) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 04:13:29 -04:00
										 |  |  |     # 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) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-12 19:44:01 +00:00
										 |  |  |     # 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 | 
					
						
							| 
									
										
										
										
											2015-01-28 09:28:20 +01:00
										 |  |  |     m = /-(\d+\.\d+(?:\.\d+)?)-w(?:in)?(?:32|64)$/.match(stem) | 
					
						
							|  |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-02 22:52:25 +02:00
										 |  |  |     # Opam packages | 
					
						
							|  |  |  |     # 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/easy-format.1.0.2+opam.tar.gz | 
					
						
							|  |  |  |     m = /\.(\d+\.\d+(?:\.\d+)?)\+opam$/.match(stem) | 
					
						
							|  |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-12 19:44:01 +00:00
										 |  |  |     # 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/libtasn1/libtasn1-2.8-x86.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 | 
					
						
							| 
									
										
										
										
											2015-01-29 23:56:40 +01:00
										 |  |  |     m = /[-_](\d+\.\d+(?:\.\d+)?(?:-\d+)?)[-_.](?:i[36]86|x86|x64(?:[-_](?:32|64))?)$/.match(stem) | 
					
						
							| 
									
										
										
										
											2015-01-28 09:28:20 +01:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 19:56:26 -04:00
										 |  |  |     # devel spec | 
					
						
							|  |  |  |     # 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-rc1.tar.gz | 
					
						
							|  |  |  |     # 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) | 
					
						
							|  |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     # e.g. foobar4.5.1 | 
					
						
							| 
									
										
										
										
											2013-04-27 15:21:06 -05:00
										 |  |  |     m = /((?:\d+\.)*\d+)$/.match(stem) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # e.g. foobar-4.5.0-bin | 
					
						
							| 
									
										
										
										
											2013-04-27 15:21:06 -05:00
										 |  |  |     m = /-((?:\d+\.)+\d+[abc]?)[-._](?:bin|dist|stable|src|sources?)$/.match(stem) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 19:56:26 -04:00
										 |  |  |     # dash version style | 
					
						
							|  |  |  |     # e.g. http://www.antlr.org/download/antlr-3.4-complete.jar | 
					
						
							|  |  |  |     # e.g. https://cdn.nuxeo.com/nuxeo-9.2/nuxeo-server-9.2-tomcat.zip | 
					
						
							|  |  |  |     # 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/apache/orc/orc-tools/1.2.3/orc-tools-1.2.3-uber.jar | 
					
						
							|  |  |  |     m = /-((?:\d+\.)+\d+)-/.match(stem) | 
					
						
							|  |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     # e.g. dash_0.5.5.1.orig.tar.gz (Debian style) | 
					
						
							| 
									
										
										
										
											2013-04-27 15:21:06 -05:00
										 |  |  |     m = /_((?:\d+\.)+\d+[abc]?)[.]orig$/.match(stem) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 05:02:27 +01:00
										 |  |  |     # e.g. https://www.openssl.org/source/openssl-0.9.8s.tar.gz | 
					
						
							| 
									
										
										
										
											2020-02-28 14:33:34 -05:00
										 |  |  |     m = /-v?(\d[^-]+)/.match(stem) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # e.g. astyle_1.23_macosx.tar.gz | 
					
						
							| 
									
										
										
										
											2020-02-28 14:33:34 -05:00
										 |  |  |     m = /_v?(\d[^_]+)/.match(stem) | 
					
						
							| 
									
										
										
										
											2012-07-09 23:24:27 -05:00
										 |  |  |     return m.captures.first unless m.nil? | 
					
						
							| 
									
										
										
										
											2012-10-16 10:31:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # e.g. http://mirrors.jenkins-ci.org/war/1.486/jenkins.war | 
					
						
							| 
									
										
										
										
											2016-02-17 12:26:45 +01:00
										 |  |  |     # e.g. https://github.com/foo/bar/releases/download/0.10.11/bar.phar | 
					
						
							| 
									
										
										
										
											2017-06-26 16:16:45 -04:00
										 |  |  |     # e.g. https://github.com/clojure/clojurescript/releases/download/r1.9.293/cljs.jar | 
					
						
							|  |  |  |     # e.g. https://github.com/fibjs/fibjs/releases/download/v0.6.1/fullsrc.zip | 
					
						
							|  |  |  |     # 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://people.gnome.org/~newren/eg/download/1.7.5.2/eg | 
					
						
							| 
									
										
										
										
											2020-02-23 10:23:35 -08:00
										 |  |  |     m = %r{/([rvV]_?)?(\d+\.\d+(\.\d+){,2})}.match(spec_s) | 
					
						
							| 
									
										
										
										
											2018-09-17 19:44:12 +02:00
										 |  |  |     return m.captures.second unless m.nil? | 
					
						
							| 
									
										
										
										
											2013-01-27 22:34:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 21:03:22 +00:00
										 |  |  |     # e.g. https://www.ijg.org/files/jpegsrc.v8d.tar.gz | 
					
						
							| 
									
										
										
										
											2013-01-27 22:34:53 +00:00
										 |  |  |     m = /\.v(\d+[a-z]?)/.match(stem) | 
					
						
							|  |  |  |     return m.captures.first unless m.nil? | 
					
						
							| 
									
										
										
										
											2017-10-03 23:29:33 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # 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) | 
					
						
							|  |  |  |     return m.captures.first unless m.nil? | 
					
						
							| 
									
										
										
										
											2012-07-09 22:51:10 -05:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   private_class_method :_parse | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def initialize(val) | 
					
						
							| 
									
										
										
										
											2019-02-19 13:11:32 +00:00
										 |  |  |     raise TypeError, "Version value must be a string; got a #{val.class} (#{val})" unless val.respond_to?(:to_str) | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |     @version = val.to_str | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def detected_from_url? | 
					
						
							|  |  |  |     false | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def head? | 
					
						
							|  |  |  |     false | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def null? | 
					
						
							|  |  |  |     false | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def <=>(other) | 
					
						
							|  |  |  |     # Needed to retain API compatibility with older string comparisons | 
					
						
							|  |  |  |     # for compiler versions, etc. | 
					
						
							|  |  |  |     other = Version.new(other) if other.is_a? String | 
					
						
							|  |  |  |     # Used by the *_build_version comparisons, which formerly returned Fixnum | 
					
						
							|  |  |  |     other = Version.new(other.to_s) if other.is_a? Integer | 
					
						
							|  |  |  |     return 1 if other.nil? | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-26 14:41:37 +02:00
										 |  |  |     return 1 if other.respond_to?(:null?) && other.null? | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |     return unless other.is_a?(Version) | 
					
						
							|  |  |  |     return 0 if version == other.version | 
					
						
							|  |  |  |     return 1 if head? && !other.head? | 
					
						
							|  |  |  |     return -1 if !head? && other.head? | 
					
						
							|  |  |  |     return 0 if head? && other.head? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ltokens = tokens | 
					
						
							|  |  |  |     rtokens = other.tokens | 
					
						
							|  |  |  |     max = max(ltokens.length, rtokens.length) | 
					
						
							|  |  |  |     l = r = 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while l < max | 
					
						
							|  |  |  |       a = ltokens[l] || NULL_TOKEN | 
					
						
							|  |  |  |       b = rtokens[r] || NULL_TOKEN | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if a == b | 
					
						
							|  |  |  |         l += 1
 | 
					
						
							|  |  |  |         r += 1
 | 
					
						
							|  |  |  |         next | 
					
						
							|  |  |  |       elsif a.numeric? && b.numeric? | 
					
						
							|  |  |  |         return a <=> b | 
					
						
							|  |  |  |       elsif a.numeric? | 
					
						
							|  |  |  |         return 1 if a > NULL_TOKEN | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |         l += 1
 | 
					
						
							|  |  |  |       elsif b.numeric? | 
					
						
							|  |  |  |         return -1 if b > NULL_TOKEN | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |         r += 1
 | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         return a <=> b | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     0
 | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   alias eql? == | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def hash | 
					
						
							|  |  |  |     version.hash | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def to_f | 
					
						
							|  |  |  |     version.to_f | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 12:11:57 +00:00
										 |  |  |   def to_i | 
					
						
							|  |  |  |     version.to_i | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-07 00:31:28 +02:00
										 |  |  |   def to_s | 
					
						
							|  |  |  |     version.dup | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   alias to_str to_s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   protected | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   attr_reader :version | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def tokens | 
					
						
							|  |  |  |     @tokens ||= tokenize | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def max(a, b) | 
					
						
							|  |  |  |     (a > b) ? a : b | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def tokenize | 
					
						
							|  |  |  |     version.scan(SCAN_PATTERN).map! do |token| | 
					
						
							|  |  |  |       case token | 
					
						
							|  |  |  |       when /\A#{AlphaToken::PATTERN}\z/o   then AlphaToken | 
					
						
							|  |  |  |       when /\A#{BetaToken::PATTERN}\z/o    then BetaToken | 
					
						
							|  |  |  |       when /\A#{RCToken::PATTERN}\z/o      then RCToken | 
					
						
							|  |  |  |       when /\A#{PreToken::PATTERN}\z/o     then PreToken | 
					
						
							|  |  |  |       when /\A#{PatchToken::PATTERN}\z/o   then PatchToken | 
					
						
							|  |  |  |       when /\A#{NumericToken::PATTERN}\z/o then NumericToken | 
					
						
							|  |  |  |       when /\A#{StringToken::PATTERN}\z/o  then StringToken | 
					
						
							|  |  |  |       end.new(token) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2012-07-09 22:51:10 -05:00
										 |  |  | end | 
					
						
							| 
									
										
										
										
											2016-06-18 20:33:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | class HeadVersion < Version | 
					
						
							|  |  |  |   attr_reader :commit | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def initialize(val) | 
					
						
							|  |  |  |     super | 
					
						
							|  |  |  |     @commit = @version[/^HEAD-(.+)$/, 1] | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def update_commit(commit) | 
					
						
							|  |  |  |     @commit = commit | 
					
						
							|  |  |  |     @version = if commit | 
					
						
							|  |  |  |       "HEAD-#{commit}" | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       "HEAD" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def head? | 
					
						
							|  |  |  |     true | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |