2020-10-10 14:16:11 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								# typed: false
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# frozen_string_literal: true
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								module Homebrew
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  module Livecheck
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    module Strategy
							 | 
						
					
						
							
								
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      # The {Hackage} strategy identifies versions of software at
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      # hackage.haskell.org by checking directory listing pages.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      # Hackage URLs take one of the following formats:
							 | 
						
					
						
							
								
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      #
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      # * `https://hackage.haskell.org/package/example-1.2.3/example-1.2.3.tar.gz`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      # * `https://downloads.haskell.org/~ghc/8.10.1/ghc-8.10.1-src.tar.xz`
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      #
							 | 
						
					
						
							
								
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      # The default regex checks for the latest version in an `h3` heading element
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      # with a format like `<h3>example-1.2.3/</h3>`.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      #
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      # @api public
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      class Hackage
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-04 03:00:34 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        extend T::Sig
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-21 00:48:31 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # A `Regexp` used in determining if the strategy applies to the URL and
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # also as part of extracting the package name from the URL basename.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        PACKAGE_NAME_REGEX = /(?<package_name>.+?)-\d+/i.freeze
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # A `Regexp` used to extract the package name from the URL basename.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        FILENAME_REGEX = /^#{PACKAGE_NAME_REGEX.source.strip}/i.freeze
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # A `Regexp` used in determining if the strategy applies to the URL.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        URL_MATCH_REGEX = %r{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          ^https?://(?:downloads|hackage)\.haskell\.org
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          (?:/[^/]+)+ # Path before the filename
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          #{PACKAGE_NAME_REGEX.source.strip}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }ix.freeze
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # Whether the strategy can be applied to the provided URL.
							 | 
						
					
						
							
								
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        #
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # @param url [String] the URL to match against
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # @return [Boolean]
							 | 
						
					
						
							
								
									
										
										
										
											2021-08-10 18:24:51 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        sig { params(url: String).returns(T::Boolean) }
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        def self.match?(url)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          URL_MATCH_REGEX.match?(url)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # Generates a URL and regex (if one isn't provided) and passes them
							 | 
						
					
						
							
								
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # to {PageMatch.find_versions} to identify versions in the content.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        #
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # @param url [String] the URL of the content to check
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # @param regex [Regexp] a regex used for matching versions in content
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # @return [Hash]
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-04 03:00:34 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        sig {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          params(
							 | 
						
					
						
							
								
									
										
										
										
											2021-08-12 11:54:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            url:    String,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            regex:  T.nilable(Regexp),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            unused: T.nilable(T::Hash[Symbol, T.untyped]),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            block:  T.nilable(
							 | 
						
					
						
							
								
									
										
										
										
											2021-07-26 20:32:10 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								              T.proc.params(arg0: String, arg1: Regexp).returns(T.any(String, T::Array[String], NilClass)),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            ),
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-04 03:00:34 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								          ).returns(T::Hash[Symbol, T.untyped])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							
								
									
										
										
										
											2021-08-12 11:54:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        def self.find_versions(url:, regex: nil, **unused, &block)
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-21 00:48:31 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								          match = File.basename(url).match(FILENAME_REGEX)
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          # A page containing a directory listing of the latest source tarball
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-21 00:48:31 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								          page_url = "https://hackage.haskell.org/package/#{match[:package_name]}/src/"
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          # Example regex: `%r{<h3>example-(.*?)/?</h3>}i`
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-21 00:48:31 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								          regex ||= %r{<h3>#{Regexp.escape(match[:package_name])}-(.*?)/?</h3>}i
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-08-12 11:54:29 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								          PageMatch.find_versions(url: page_url, regex: regex, **unused, &block)
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								end
							 |