Simplify Hbc::SystemCommand::Result#plist.
This commit is contained in:
parent
15ac935ed6
commit
e07eddc391
@ -137,48 +137,35 @@ module Hbc
|
||||
@exit_status = exit_status
|
||||
end
|
||||
|
||||
def plist
|
||||
@plist ||= self.class._parse_plist(@command, @stdout.dup)
|
||||
end
|
||||
|
||||
def success?
|
||||
@exit_status.zero?
|
||||
end
|
||||
|
||||
def merged_output
|
||||
@merged_output ||= @stdout + @stderr
|
||||
end
|
||||
def plist
|
||||
@plist ||= begin
|
||||
output = stdout
|
||||
|
||||
def to_s
|
||||
@stdout
|
||||
end
|
||||
if /\A(?<garbage>.*?)<\?\s*xml/m =~ output
|
||||
output = output.sub(/\A#{Regexp.escape(garbage)}/m, "")
|
||||
warn_plist_garbage(garbage)
|
||||
end
|
||||
|
||||
def self._warn_plist_garbage(command, garbage)
|
||||
return true unless garbage =~ /\S/
|
||||
external = File.basename(command.first)
|
||||
lines = garbage.strip.split("\n")
|
||||
opoo "Non-XML stdout from #{external}:"
|
||||
$stderr.puts lines.map { |l| " #{l}" }
|
||||
end
|
||||
if %r{<\s*/\s*plist\s*>(?<garbage>.*?)\Z}m =~ output
|
||||
output = output.sub(/#{Regexp.escape(garbage)}\Z/, "")
|
||||
warn_plist_garbage(garbage)
|
||||
end
|
||||
|
||||
def self._parse_plist(command, output)
|
||||
raise CaskError, "Empty plist input" unless output =~ /\S/
|
||||
output.sub!(/\A(.*?)(<\?\s*xml)/m, '\2')
|
||||
_warn_plist_garbage(command, Regexp.last_match[1]) if ARGV.debug?
|
||||
output.sub!(%r{(<\s*/\s*plist\s*>)(.*?)\Z}m, '\1')
|
||||
_warn_plist_garbage(command, Regexp.last_match[2])
|
||||
xml = Plist.parse_xml(output)
|
||||
unless xml.respond_to?(:keys) && !xml.keys.empty?
|
||||
raise CaskError, <<~EOS
|
||||
Empty result parsing plist output from command.
|
||||
command was:
|
||||
#{command}
|
||||
output we attempted to parse:
|
||||
#{output}
|
||||
EOS
|
||||
Plist.parse_xml(output)
|
||||
end
|
||||
xml
|
||||
end
|
||||
|
||||
def warn_plist_garbage(garbage)
|
||||
return unless ARGV.verbose?
|
||||
return unless garbage =~ /\S/
|
||||
opoo "Received non-XML output from #{Formatter.identifier(command.first)}:"
|
||||
$stderr.puts garbage.strip
|
||||
end
|
||||
private :warn_plist_garbage
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,10 +1,21 @@
|
||||
require "hbc/system_command"
|
||||
|
||||
describe Hbc::SystemCommand::Result, :cask do
|
||||
describe "::_parse_plist" do
|
||||
subject { described_class._parse_plist(command, input) }
|
||||
describe "#plist" do
|
||||
subject { described_class.new(command, stdout, "", 0).plist }
|
||||
|
||||
let(:command) { Hbc::SystemCommand.new("/usr/bin/true", {}) }
|
||||
let(:command) { ["/usr/bin/true"] }
|
||||
let(:garbage) {
|
||||
<<~EOS
|
||||
Hello there! I am in no way XML am I?!?!
|
||||
|
||||
That's a little silly... you were expecting XML here!
|
||||
|
||||
What is a parser to do?
|
||||
|
||||
Hopefully <not> explode!
|
||||
EOS
|
||||
}
|
||||
let(:plist) {
|
||||
<<~EOS
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@ -53,29 +64,56 @@ describe Hbc::SystemCommand::Result, :cask do
|
||||
EOS
|
||||
}
|
||||
|
||||
context "when output contains garbage" do
|
||||
let(:input) {
|
||||
context "when stdout contains garbage before XML" do
|
||||
let(:stdout) {
|
||||
<<~EOS
|
||||
Hello there! I am in no way XML am I?!?!
|
||||
|
||||
That's a little silly... you were expexting XML here!
|
||||
|
||||
What is a parser to do?
|
||||
|
||||
Hopefully <not> explode!
|
||||
|
||||
#{garbage}
|
||||
#{plist}
|
||||
EOS
|
||||
}
|
||||
|
||||
it "ignores garbage before xml" do
|
||||
expect(subject.keys).to eq(["system-entities"])
|
||||
it "ignores garbage" do
|
||||
expect(subject["system-entities"].length).to eq(3)
|
||||
end
|
||||
|
||||
context "when verbose" do
|
||||
before(:each) do
|
||||
allow(ARGV).to receive(:verbose?).and_return(true)
|
||||
end
|
||||
|
||||
it "warns about garbage" do
|
||||
expect { subject }
|
||||
.to output(a_string_containing(garbage)).to_stderr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "given a hdiutil output as input" do
|
||||
let(:input) { plist }
|
||||
context "when stdout contains garbage after XML" do
|
||||
let(:stdout) {
|
||||
<<~EOS
|
||||
#{plist}
|
||||
#{garbage}
|
||||
EOS
|
||||
}
|
||||
|
||||
it "ignores garbage" do
|
||||
expect(subject["system-entities"].length).to eq(3)
|
||||
end
|
||||
|
||||
context "when verbose" do
|
||||
before(:each) do
|
||||
allow(ARGV).to receive(:verbose?).and_return(true)
|
||||
end
|
||||
|
||||
it "warns about garbage" do
|
||||
expect { subject }
|
||||
.to output(a_string_containing(garbage)).to_stderr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "given a hdiutil stdout" do
|
||||
let(:stdout) { plist }
|
||||
|
||||
it "successfully parses it" do
|
||||
expect(subject.keys).to eq(["system-entities"])
|
||||
@ -85,11 +123,11 @@ describe Hbc::SystemCommand::Result, :cask do
|
||||
end
|
||||
end
|
||||
|
||||
context "given an empty input" do
|
||||
let(:input) { "" }
|
||||
context "when the stdout of the command is empty" do
|
||||
let(:stdout) { "" }
|
||||
|
||||
it "raises an error" do
|
||||
expect { subject }.to raise_error(Hbc::CaskError, /Empty plist input/)
|
||||
it "returns nil" do
|
||||
expect(subject).to be nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -166,3 +166,4 @@ end
|
||||
|
||||
RSpec::Matchers.define_negated_matcher :not_to_output, :output
|
||||
RSpec::Matchers.alias_matcher :have_failed, :be_failed
|
||||
RSpec::Matchers.alias_matcher :a_string_containing, :include
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user