Xml: Add #element_text method
This refactors verbose code in the `Sparkle` strategy where we access element text into a reusable `Xml#element_text` method, replacing chained calls like `item.elements["title"]&.text&.strip&.presence` with `Xml.element_text(item, "title")`. `#element_text` is only used to retrieve the text of a child element in the `Sparkle` strategy but it can also retrieve the text from the provided element if the `child_path` argument is omitted (i.e., `Xml.element_text(item)`). This will allow us to also avoid similar calls like `item.text.strip.presence` in the future.
This commit is contained in:
parent
5fa5f3b0aa
commit
9bfe423a5a
@ -95,16 +95,16 @@ module Homebrew
|
|||||||
os = enclosure["os"].presence
|
os = enclosure["os"].presence
|
||||||
end
|
end
|
||||||
|
|
||||||
title = item.elements["title"]&.text&.strip&.presence
|
title = Xml.element_text(item, "title")
|
||||||
link = item.elements["link"]&.text&.strip&.presence
|
link = Xml.element_text(item, "link")
|
||||||
url ||= link
|
url ||= link
|
||||||
channel = item.elements["channel"]&.text&.strip&.presence
|
channel = Xml.element_text(item, "channel")
|
||||||
release_notes_link = item.elements["releaseNotesLink"]&.text&.strip&.presence
|
release_notes_link = Xml.element_text(item, "releaseNotesLink")
|
||||||
short_version ||= item.elements["shortVersionString"]&.text&.strip&.presence
|
short_version ||= Xml.element_text(item, "shortVersionString")
|
||||||
version ||= item.elements["version"]&.text&.strip&.presence
|
version ||= Xml.element_text(item, "version")
|
||||||
|
|
||||||
minimum_system_version_text =
|
minimum_system_version_text =
|
||||||
item.elements["minimumSystemVersion"]&.text&.strip&.gsub(/\A\D+|\D+\z/, "")&.presence
|
Xml.element_text(item, "minimumSystemVersion")&.gsub(/\A\D+|\D+\z/, "")
|
||||||
if minimum_system_version_text.present?
|
if minimum_system_version_text.present?
|
||||||
minimum_system_version = begin
|
minimum_system_version = begin
|
||||||
MacOSVersion.new(minimum_system_version_text)
|
MacOSVersion.new(minimum_system_version_text)
|
||||||
@ -113,7 +113,7 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pub_date = item.elements["pubDate"]&.text&.strip&.presence&.then do |date_string|
|
pub_date = Xml.element_text(item, "pubDate")&.then do |date_string|
|
||||||
Time.parse(date_string)
|
Time.parse(date_string)
|
||||||
rescue ArgumentError
|
rescue ArgumentError
|
||||||
# Omit unparsable strings (e.g. non-English dates)
|
# Omit unparsable strings (e.g. non-English dates)
|
||||||
|
@ -72,6 +72,30 @@ module Homebrew
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Retrieves the stripped inner text of an `REXML` element. Returns
|
||||||
|
# `nil` if the optional child element doesn't exist or the text is
|
||||||
|
# blank.
|
||||||
|
# @param element [REXML::Element] an `REXML` element to retrieve text
|
||||||
|
# from, either directly or from a child element
|
||||||
|
# @param child_path [String, nil] the XPath of a child element to
|
||||||
|
# retrieve text from
|
||||||
|
# @return [String, nil]
|
||||||
|
sig {
|
||||||
|
params(
|
||||||
|
element: REXML::Element,
|
||||||
|
child_path: T.nilable(String),
|
||||||
|
).returns(T.nilable(String))
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
# Parses XML text and identifies versions using a `strategy` block.
|
# Parses XML text and identifies versions using a `strategy` block.
|
||||||
# If a regex is provided, it will be passed as the second argument to
|
# If a regex is provided, it will be passed as the second argument to
|
||||||
# the `strategy` block (after the parsed XML data).
|
# the `strategy` block (after the parsed XML data).
|
||||||
|
@ -79,6 +79,24 @@ describe Homebrew::Livecheck::Strategy::Xml do
|
|||||||
EOS
|
EOS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let(:parent_child_text) { { parent: "1.2.3", child: "4.5.6" } }
|
||||||
|
let(:content_parent_child) do
|
||||||
|
# This XML deliberately includes unnecessary whitespace, to ensure that
|
||||||
|
# Xml#element_text properly strips the retrieved text.
|
||||||
|
<<~EOS
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<elements>
|
||||||
|
<parent>
|
||||||
|
#{parent_child_text[:parent]}
|
||||||
|
<child> #{parent_child_text[:child]} </child>
|
||||||
|
</parent>
|
||||||
|
<blank-parent>
|
||||||
|
<blank-child></blank-child>
|
||||||
|
</blank-parent>
|
||||||
|
</elements>
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
|
||||||
let(:content_matches) { ["1.1.2", "1.1.1", "1.1.0", "1.0.3", "1.0.2", "1.0.1", "1.0.0"] }
|
let(:content_matches) { ["1.1.2", "1.1.1", "1.1.0", "1.0.3", "1.0.2", "1.0.1", "1.0.0"] }
|
||||||
let(:content_simple_matches) { ["1.2.3"] }
|
let(:content_simple_matches) { ["1.2.3"] }
|
||||||
|
|
||||||
@ -123,6 +141,29 @@ describe Homebrew::Livecheck::Strategy::Xml do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "::element_text" do
|
||||||
|
let(:parent_child_doc) { xml.parse_xml(content_parent_child) }
|
||||||
|
let(:parent) { parent_child_doc.get_elements("/elements/parent").first }
|
||||||
|
let(:blank_parent) { parent_child_doc.get_elements("/elements/blank-parent").first }
|
||||||
|
|
||||||
|
it "returns the element text if child_name is not provided" do
|
||||||
|
expect(xml.element_text(parent)).to eq(parent_child_text[:parent])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the child element text if child_name is provided" do
|
||||||
|
expect(xml.element_text(parent, "child")).to eq(parent_child_text[:child])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns `nil` if the provided child element does not exist" do
|
||||||
|
expect(xml.element_text(parent, "nonexistent")).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns `nil` if the retrieved text is blank" do
|
||||||
|
expect(xml.element_text(blank_parent)).to be_nil
|
||||||
|
expect(xml.element_text(blank_parent, "blank-child")).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "::versions_from_content" do
|
describe "::versions_from_content" do
|
||||||
it "returns an empty array when given a block but content is blank" do
|
it "returns an empty array when given a block but content is blank" do
|
||||||
expect(xml.versions_from_content("", regex) { "1.2.3" }).to eq([])
|
expect(xml.versions_from_content("", regex) { "1.2.3" }).to eq([])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user