Simplify Hbc::SystemCommand::Result#plist.

This commit is contained in:
Markus Reiter 2018-07-05 09:31:29 +02:00
parent 15ac935ed6
commit e07eddc391
3 changed files with 80 additions and 54 deletions

View File

@ -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

View File

@ -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

View File

@ -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