homebrew-cask-versions/lib/cask/system_command.rb
Roland Walker 768b21eae8 always submit external commands in list form
For safety.
- This is a step toward reworking system_command.rb so that
invocations are done in list form on the back end, avoiding
surprises from quoting and shell metacharacters.
- There is one transitional hack here: the _quote method in
Cask::SystemCommand is modified to avoid double-quoting.  The
_quote method itself will go away in a future revision when
only list-forms are used.
- Casks using system are not touched. It seems natural to
address that when creating the DSL for after_install/before_install.
2014-01-24 20:58:03 -05:00

70 lines
1.6 KiB
Ruby

class Cask::SystemCommand
def self.run(command, options={})
command = _process_options(command, options)
output = ''
IO.popen(command, 'r+') do |pipe|
if options[:input]
options[:input].each { |line| pipe.puts line }
end
pipe.close_write
while line = pipe.gets
output << line
ohai line.chomp if options[:print]
end
end
_assert_success($?, command, output) if options[:must_succeed]
if options[:plist]
_parse_plist(command, output)
else
output
end
end
def self.run!(command, options)
run(command, options.merge(:must_succeed => true))
end
def self._process_options(command, options)
if options[:sudo]
command = "/usr/bin/sudo -E #{_quote(command)}"
end
if options[:args]
command = "#{command} #{options[:args].map { |arg| _quote(arg) }.join(' ')}"
end
case options[:stderr]
when :silence then
command = "#{command} 2>/dev/null"
when :merge, nil then
command = "#{command} 2>&1"
end
command
end
def self._assert_success(status, command, output)
unless status.success?
raise CaskCommandFailedError.new(command, output)
end
end
def self._quote(string)
if %r{^(['"]).*\1$}.match(string)
string
else
%Q('#{string}')
end
end
def self._parse_plist(command, output)
begin
Plist::parse_xml(output)
rescue Plist::ParseError
raise CaskError.new(<<-ERRMSG)
Error parsing plist output from command.
command was:
#{command}
output we attempted to parse:
#{output}
ERRMSG
end
end
end