| 
									
										
										
										
											2020-10-10 14:16:11 +02:00
										 |  |  | # typed: false | 
					
						
							| 
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | require "open-uri" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Homebrew | 
					
						
							|  |  |  |   module Livecheck | 
					
						
							|  |  |  |     module Strategy | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |       # The {PageMatch} strategy fetches content at a URL and scans it for | 
					
						
							| 
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 |  |  |       # matching text using the provided regex. | 
					
						
							|  |  |  |       # | 
					
						
							|  |  |  |       # This strategy can be used in a `livecheck` block when no specific | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |       # strategies apply to a given URL. Though {PageMatch} will technically | 
					
						
							| 
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 |  |  |       # match any HTTP URL, the strategy also requires a regex to function. | 
					
						
							|  |  |  |       # | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |       # The {find_versions} method is also used within other | 
					
						
							| 
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 |  |  |       # strategies, to handle the process of identifying version text in | 
					
						
							|  |  |  |       # content. | 
					
						
							|  |  |  |       # | 
					
						
							|  |  |  |       # @api public | 
					
						
							|  |  |  |       class PageMatch | 
					
						
							|  |  |  |         NICE_NAME = "Page match" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # A priority of zero causes livecheck to skip the strategy. We do this | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |         # for PageMatch so we can selectively apply the strategy only when a | 
					
						
							| 
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 |  |  |         # regex is provided in a `livecheck` block. | 
					
						
							|  |  |  |         PRIORITY = 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # The `Regexp` used to determine if the strategy applies to the URL. | 
					
						
							|  |  |  |         URL_MATCH_REGEX = %r{^https?://}i.freeze | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Whether the strategy can be applied to the provided URL. | 
					
						
							| 
									
										
										
										
											2020-12-12 21:56:07 +01:00
										 |  |  |         # PageMatch will technically match any HTTP URL but is only | 
					
						
							|  |  |  |         # usable with a `livecheck` block containing a regex. | 
					
						
							| 
									
										
										
										
											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] | 
					
						
							|  |  |  |         def self.match?(url) | 
					
						
							|  |  |  |           URL_MATCH_REGEX.match?(url) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 22:46:52 -05:00
										 |  |  |         # Uses the regex to match text in the content or, if a block is | 
					
						
							|  |  |  |         # provided, passes the page content to the block to handle matching. | 
					
						
							|  |  |  |         # With either approach, an array of unique matches is returned. | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |         # | 
					
						
							| 
									
										
										
										
											2020-12-22 22:46:52 -05:00
										 |  |  |         # @param content [String] the page content to check | 
					
						
							| 
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 |  |  |         # @param regex [Regexp] a regex used for matching versions in the | 
					
						
							|  |  |  |         #   content | 
					
						
							|  |  |  |         # @return [Array] | 
					
						
							| 
									
										
										
										
											2020-12-22 22:46:52 -05:00
										 |  |  |         def self.page_matches(content, regex, &block) | 
					
						
							| 
									
										
										
										
											2020-12-14 02:07:07 +01:00
										 |  |  |           if block | 
					
						
							| 
									
										
										
										
											2020-12-22 22:46:52 -05:00
										 |  |  |             case (value = block.call(content)) | 
					
						
							| 
									
										
										
										
											2020-12-14 02:07:07 +01:00
										 |  |  |             when String | 
					
						
							|  |  |  |               return [value] | 
					
						
							|  |  |  |             when Array | 
					
						
							|  |  |  |               return value | 
					
						
							|  |  |  |             else | 
					
						
							| 
									
										
										
										
											2020-12-14 02:16:01 +01:00
										 |  |  |               raise TypeError, "Return value of `strategy :page_match` block must be a string or array of strings." | 
					
						
							| 
									
										
										
										
											2020-12-14 02:07:07 +01:00
										 |  |  |             end | 
					
						
							| 
									
										
										
										
											2020-12-13 12:24:25 +01:00
										 |  |  |           end | 
					
						
							| 
									
										
										
										
											2020-12-14 02:07:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 22:46:52 -05:00
										 |  |  |           content.scan(regex).map do |match| | 
					
						
							| 
									
										
										
										
											2020-12-15 20:08:53 +01:00
										 |  |  |             case match | 
					
						
							|  |  |  |             when String | 
					
						
							|  |  |  |               match | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |               match.first | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |           end.uniq | 
					
						
							| 
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Checks the content at the URL for new versions, using the provided | 
					
						
							|  |  |  |         # regex for matching. | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |         # | 
					
						
							| 
									
										
										
										
											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] | 
					
						
							| 
									
										
										
										
											2020-12-14 02:07:07 +01:00
										 |  |  |         def self.find_versions(url, regex, &block) | 
					
						
							| 
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 |  |  |           match_data = { matches: {}, regex: regex, url: url } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-22 22:46:52 -05:00
										 |  |  |           match_data.merge!(Strategy.page_content(url)) | 
					
						
							|  |  |  |           content = match_data.delete(:content) | 
					
						
							|  |  |  |           return match_data if content.blank? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           page_matches(content, regex, &block).each do |match_text| | 
					
						
							|  |  |  |             match_data[:matches][match_text] = Version.new(match_text) | 
					
						
							| 
									
										
										
										
											2020-08-08 07:16:06 +05:30
										 |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           match_data | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |