class Shellany::Sheller
The Guard sheller abstract the actual subshell calls and allow easier stubbing.
Attributes
Public Class Methods
Only needed on JRUBY, because MRI properly detects ‘;’ and metachars
# File lib/shellany/sheller.rb, line 128 def self._shellize_if_needed(args) return args unless RUBY_PLATFORM == "java" return args unless args.size == 1 return args unless /[;<>]/ =~ args.first # NOTE: Sheller was originally meant for Guard (which basically only uses # UNIX commands anyway) and JRuby doesn't support options to # Kernel.system (and doesn't automatically shell when there's a # metacharacter in the command). # # So ... I'm assuming /bin/sh exists - if not, PRs are welcome, # because I have no clue what to do if /bin/sh doesn't exist. # (use ENV["RUBYSHELL"] ? Detect cmd.exe ?) ["/bin/sh", "-c", args.first] end
# File lib/shellany/sheller.rb, line 110 def self._system_with_capture(*args) # We use popen3, because it started working on recent versions # of JRuby, while JRuby doesn't handle options to Kernel.system args = _shellize_if_needed(args) stdout, stderr, status = nil Open3.popen3(*args) do |_stdin, _stdout, _stderr, _thr| stdout = _stdout.read stderr = _stderr.read status = _thr.value end [status, stdout, stderr] rescue Errno::ENOENT, IOError => e [nil, nil, "Guard::Sheller failed (#{e.inspect})"] end
# File lib/shellany/sheller.rb, line 103 def self._system_with_no_capture(*args) Kernel.system(*args) result = $? errors = (result == 0) || "Guard failed to run: #{args.inspect}" [result, nil, errors] end
Creates a new Guard::Sheller object.
@param [String] args a command to run in a subshell @param [Array<String>] args an array of command parts to run in a subshell @param [*String] args a list of command parts to run in a subshell
# File lib/shellany/sheller.rb, line 16 def initialize(*args) fail ArgumentError, "no command given" if args.empty? @command = args @ran = false end
Shortcut for new(command).run
# File lib/shellany/sheller.rb, line 24 def self.run(*args) new(*args).run end
Shortcut for new(command).run.stderr
# File lib/shellany/sheller.rb, line 36 def self.stderr(*args) new(*args).stderr end
Shortcut for new(command).run.stdout
# File lib/shellany/sheller.rb, line 30 def self.stdout(*args) new(*args).stdout end
No output capturing
NOTE: ‘$stdout.puts system(’cls’)‘ on Windows won’t work like it does for on systems with ansi terminals, so we need to be able to call Kernel.system directly.
# File lib/shellany/sheller.rb, line 99 def self.system(*args) _system_with_no_capture(*args) end
Public Instance Methods
Returns true if the command succeeded, false otherwise.
@return [Boolean] whether or not the command succeeded
# File lib/shellany/sheller.rb, line 68 def ok? run unless ran? @status && @status.success? end
Returns true if the command has already been run, false otherwise.
@return [Boolean] whether or not the command has already been run
# File lib/shellany/sheller.rb, line 60 def ran? @ran end
Runs the command.
@return [Boolean] whether or not the command succeeded.
# File lib/shellany/sheller.rb, line 44 def run unless ran? status, output, errors = self.class._system_with_capture(*@command) @ran = true @stdout = output @stderr = errors @status = status end ok? end
Returns the command’s error output.
@return [String] the command output
# File lib/shellany/sheller.rb, line 88 def stderr run unless ran? @stderr end
Returns the command’s output.
@return [String] the command output
# File lib/shellany/sheller.rb, line 78 def stdout run unless ran? @stdout end