| 
									
										
										
										
											2021-09-11 01:00:23 +01:00
										 |  |  | # typed: true | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-06 08:29:14 +02:00
										 |  |  | module Cask | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |   class DSL | 
					
						
							| 
									
										
										
										
											2020-08-24 23:09:43 +02:00
										 |  |  |     # Class corresponding to the `version` stanza. | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     # @api private | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |     class Version < ::String | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       extend T::Sig | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       DIVIDERS = { | 
					
						
							| 
									
										
										
										
											2016-10-14 20:33:16 +02:00
										 |  |  |         "." => :dots, | 
					
						
							|  |  |  |         "-" => :hyphens, | 
					
						
							|  |  |  |         "_" => :underscores, | 
					
						
							|  |  |  |       }.freeze | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |       DIVIDER_REGEX = /(#{DIVIDERS.keys.map { |v| Regexp.quote(v) }.join('|')})/.freeze | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-02 09:49:23 +01:00
										 |  |  |       MAJOR_MINOR_PATCH_REGEX = /^([^.,:]+)(?:.([^.,:]+)(?:.([^.,:]+))?)?/.freeze | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-30 15:49:47 +01:00
										 |  |  |       INVALID_CHARACTERS = /[^0-9a-zA-Z.,:\-_+ ]/.freeze | 
					
						
							| 
									
										
										
										
											2019-03-19 04:57:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       class << self | 
					
						
							|  |  |  |         private | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def define_divider_methods(divider) | 
					
						
							|  |  |  |           define_divider_deletion_method(divider) | 
					
						
							|  |  |  |           define_divider_conversion_methods(divider) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def define_divider_deletion_method(divider) | 
					
						
							|  |  |  |           method_name = deletion_method_name(divider) | 
					
						
							|  |  |  |           define_method(method_name) do | 
					
						
							|  |  |  |             version { delete(divider) } | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def deletion_method_name(divider) | 
					
						
							|  |  |  |           "no_#{DIVIDERS[divider]}" | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def define_divider_conversion_methods(left_divider) | 
					
						
							|  |  |  |           (DIVIDERS.keys - [left_divider]).each do |right_divider| | 
					
						
							|  |  |  |             define_divider_conversion_method(left_divider, right_divider) | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def define_divider_conversion_method(left_divider, right_divider) | 
					
						
							|  |  |  |           method_name = conversion_method_name(left_divider, right_divider) | 
					
						
							|  |  |  |           define_method(method_name) do | 
					
						
							|  |  |  |             version { gsub(left_divider, right_divider) } | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def conversion_method_name(left_divider, right_divider) | 
					
						
							|  |  |  |           "#{DIVIDERS[left_divider]}_to_#{DIVIDERS[right_divider]}" | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 20:12:58 +01:00
										 |  |  |       DIVIDERS.each_key do |divider| | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |         define_divider_methods(divider) | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       attr_reader :raw_version | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { params(raw_version: T.nilable(T.any(String, Symbol))).void } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def initialize(raw_version) | 
					
						
							|  |  |  |         @raw_version = raw_version | 
					
						
							|  |  |  |         super(raw_version.to_s) | 
					
						
							| 
									
										
										
										
											2021-03-30 14:15:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         invalid = invalid_characters | 
					
						
							|  |  |  |         raise TypeError, "#{raw_version} contains invalid characters: #{invalid.uniq.join}!" if invalid.present? | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-19 04:57:33 +01:00
										 |  |  |       def invalid_characters | 
					
						
							| 
									
										
										
										
											2021-03-30 14:15:14 +01:00
										 |  |  |         return [] if raw_version.blank? || latest? | 
					
						
							| 
									
										
										
										
											2019-03-19 04:57:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         raw_version.scan(INVALID_CHARACTERS) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2019-03-19 04:57:33 +01:00
										 |  |  |       def unstable? | 
					
						
							|  |  |  |         return false if latest? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         s = downcase.delete(".").gsub(/[^a-z\d]+/, "-") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true if s.match?(/(\d+|\b)(alpha|beta|preview|rc|dev|canary|snapshot)(\d+|\b)/i) | 
					
						
							| 
									
										
										
										
											2020-06-02 09:49:23 +01:00
										 |  |  |         return true if s.match?(/\A[a-z\d]+(-\d+)*-?(a|b|pre)(\d+|\b)/i) | 
					
						
							| 
									
										
										
										
											2019-03-19 04:57:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         false | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def latest? | 
					
						
							|  |  |  |         to_s == "latest" | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def major | 
					
						
							|  |  |  |         version { slice(MAJOR_MINOR_PATCH_REGEX, 1) } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def minor | 
					
						
							|  |  |  |         version { slice(MAJOR_MINOR_PATCH_REGEX, 2) } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def patch | 
					
						
							|  |  |  |         version { slice(MAJOR_MINOR_PATCH_REGEX, 3) } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def major_minor | 
					
						
							|  |  |  |         version { [major, minor].reject(&:empty?).join(".") } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def major_minor_patch | 
					
						
							|  |  |  |         version { [major, minor, patch].reject(&:empty?).join(".") } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2018-06-15 22:40:33 +10:00
										 |  |  |       def minor_patch | 
					
						
							|  |  |  |         version { [minor, patch].reject(&:empty?).join(".") } | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 12:49:51 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T::Array[Version]) } # Only top-level T.self_type is supported https://sorbet.org/docs/self-type | 
					
						
							|  |  |  |       def csv | 
					
						
							|  |  |  |         split(",").map(&self.class.method(:new)) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def before_comma | 
					
						
							| 
									
										
										
										
											2018-09-17 19:44:12 +02:00
										 |  |  |         version { split(",", 2).first } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def after_comma | 
					
						
							| 
									
										
										
										
											2018-09-17 19:44:12 +02:00
										 |  |  |         version { split(",", 2).second } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def before_colon | 
					
						
							| 
									
										
										
										
											2022-05-30 14:59:14 +01:00
										 |  |  |         odisabled "Cask::DSL::Version#before_colon", "Cask::DSL::Version#csv" | 
					
						
							| 
									
										
										
										
											2018-09-17 19:44:12 +02:00
										 |  |  |         version { split(":", 2).first } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def after_colon | 
					
						
							| 
									
										
										
										
											2022-05-30 14:59:14 +01:00
										 |  |  |         odisabled "Cask::DSL::Version#after_colon", "Cask::DSL::Version#csv" | 
					
						
							| 
									
										
										
										
											2018-09-17 19:44:12 +02:00
										 |  |  |         version { split(":", 2).second } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-24 11:44:12 -08:00
										 |  |  |       # @api public | 
					
						
							|  |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def no_dividers | 
					
						
							|  |  |  |         version { gsub(DIVIDER_REGEX, "") } | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       private | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 12:03:48 +02:00
										 |  |  |       sig { returns(T.self_type) } | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |       def version | 
					
						
							|  |  |  |         return self if empty? || latest? | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-24 13:52:43 +02:00
										 |  |  |         self.class.new(yield) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | end |