Class: Homebrew::Livecheck::Strategy::Xml
- Extended by:
 - Homebrew::Livecheck::Strategic
 
- Defined in:
 - livecheck/strategy/xml.rb
 
Overview
The Xml strategy fetches content at a URL, parses it as XML using
REXML and provides the REXML::Document to a strategy block.
If a regex is present in the livecheck block, it should be passed
as the second argument to the strategy block.
This is a generic strategy that doesn't contain any logic for finding
versions, as the structure of XML data varies. Instead, a strategy
block must be used to extract version information from the XML data.
For more information on how to work with an REXML::Document object,
please refer to the REXML::Document
and REXML::Element
documentation.
This strategy is not applied automatically and it is necessary to use
strategy :xml in a livecheck block (in conjunction with a
strategy block) to use it.
This strategy's Xml.find_versions method can be used in other strategies that work with XML content, so it should only be necessary to write the version-finding logic that works with the parsed XML data.
Constant Summary collapse
- NICE_NAME =
          
 "XML"- PRIORITY =
          
This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.
A priority of zero causes livecheck to skip the strategy. We do this for Homebrew::Livecheck::Strategy::Xml so we can selectively apply it only when a strategy block is provided in a
livecheckblock. 0- URL_MATCH_REGEX =
          
This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.
The
Regexpused to determine if the strategy applies to the URL. %r{^https?://}i
Class Method Summary collapse
- 
  
    
      .element_text(element, child_path = nil)  ⇒ String? 
    
    
  
  
  
  
  
  
  
  private
  
    
Retrieves the stripped inner text of an
REXMLelement. - 
  
    
      .find_versions(url:, regex: nil, provided_content: nil, options: Options.new, &block)  ⇒ Hash{Symbol => T.anything} 
    
    
  
  
  
  
  
  
  
  private
  
    
Checks the XML content at the URL for versions, using the provided
strategyblock to extract version information. - 
  
    
      .match?(url)  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  private
  
    
Whether the strategy can be applied to the provided URL.
 - 
  
    
      .parse_xml(content)  ⇒ REXML::Document? 
    
    
  
  
  
  
  
  
  
  private
  
    
Parses XML text and returns an
REXML::Documentobject. - 
  
    
      .versions_from_content(content, regex = nil, &block)  ⇒ Array<String> 
    
    
  
  
  
  
  
  
  
  private
  
    
Parses XML text and identifies versions using a
strategyblock. 
Methods included from Homebrew::Livecheck::Strategic
Class Method Details
.element_text(element, child_path = nil) ⇒ String?
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Retrieves the stripped inner text of an REXML element. Returns
nil if the optional child element doesn't exist or the text is
blank.
      93 94 95 96 97 98 99 100 101  | 
    
      # File 'livecheck/strategy/xml.rb', line 93 def self.element_text(element, child_path = nil) element = element.get_elements(child_path).first if child_path.present? return if element.nil? text = element.text return if text.blank? text.strip end  | 
  
.find_versions(url:, regex: nil, provided_content: nil, options: Options.new, &block) ⇒ Hash{Symbol => T.anything}
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Checks the XML content at the URL for versions, using the provided
strategy block to extract version information.
      152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172  | 
    
      # File 'livecheck/strategy/xml.rb', line 152 def self.find_versions(url:, regex: nil, provided_content: nil, options: Options.new, &block) raise ArgumentError, "#{Utils.demodulize(name)} requires a `strategy` block" unless block_given? match_data = { matches: {}, regex:, url: } return match_data if url.blank? content = if provided_content.is_a?(String) match_data[:cached] = true provided_content else match_data.merge!(Strategy.page_content(url, options:)) match_data[:content] end return match_data if content.blank? versions_from_content(content, regex, &block).each do |match_text| match_data[:matches][match_text] = Version.new(match_text) end match_data end  | 
  
.match?(url) ⇒ Boolean
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Whether the strategy can be applied to the provided URL.
Homebrew::Livecheck::Strategy::Xml will technically match any HTTP URL but is only usable with
a livecheck block containing a strategy block.
      51 52 53  | 
    
      # File 'livecheck/strategy/xml.rb', line 51 def self.match?(url) URL_MATCH_REGEX.match?(url) end  | 
  
.parse_xml(content) ⇒ REXML::Document?
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Parses XML text and returns an REXML::Document object.
      59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77  | 
    
      # File 'livecheck/strategy/xml.rb', line 59 def self.parse_xml(content) parsing_tries = 0 begin REXML::Document.new(content) rescue REXML::UndefinedNamespaceException => e undefined_prefix = e.to_s[/Undefined prefix ([^ ]+) found/i, 1] raise "Could not identify undefined prefix." if undefined_prefix.blank? # Only retry parsing once after removing prefix from content parsing_tries += 1 raise "Could not parse XML after removing undefined prefix." if parsing_tries > 1 # When an XML document contains a prefix without a corresponding # namespace, it's necessary to remove the prefix from the content # to be able to successfully parse it using REXML content = content.gsub(%r{(</?| )#{Regexp.escape(undefined_prefix)}:}, '\1') retry end end  | 
  
.versions_from_content(content, regex = nil, &block) ⇒ Array<String>
This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.
Parses XML text and identifies versions using a strategy block.
If a regex is provided, it will be passed as the second argument to
the strategy block (after the parsed XML data).
      117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132  | 
    
      # File 'livecheck/strategy/xml.rb', line 117 def self.versions_from_content(content, regex = nil, &block) return [] if content.blank? || !block_given? require "rexml" xml = parse_xml(content) return [] if xml.blank? block_return_value = if regex.present? yield(xml, regex) elsif block.arity == 2 raise "Two arguments found in `strategy` block but no regex provided." else yield(xml) end Strategy.handle_block_return(block_return_value) end  |