Last active
September 3, 2022 13:42
-
-
Save nsmmrs/4e73b23850ed884527ddc3e01da4a066 to your computer and use it in GitHub Desktop.
A convenience wrapper around `Open3.capture3` for easily running commands, capturing the output, and handling failures.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "open3" | |
require "json" | |
class ShellCommand | |
attr_reader :line, :stdin, :binmode, :stdout, :stderr, :status | |
def initialize(line, stdin, binmode, stdout, stderr, status) | |
@line = line | |
@stdin = stdin | |
@binmode = binmode | |
@stdout = stdout | |
@stderr = stderr | |
@status = status | |
end | |
private_class_method :new | |
def success?() status.success? end | |
def pid() status.pid end | |
def exit_code() status.exitstatus end | |
def self.run(*line, **options) | |
line = line.map(&:to_s) | |
stdin = options[:stdin_data] || "" | |
binmode = options[:binmode] || false | |
args = line + [options] | |
captures = begin | |
Open3.capture3(*args) | |
rescue | |
raise Invalid.new(args) | |
end | |
command = new(line, stdin, binmode, *captures) | |
case | |
when block_given? | |
yield command | |
when command.success? | |
command.stdout.rstrip | |
else | |
raise Failed.new(command) | |
end | |
end | |
class Failed < StandardError | |
attr_reader :command | |
def initialize(command) | |
@command = command | |
end | |
def message | |
"Shell command failed: #{command.to_json}" | |
end | |
end | |
class Invalid < StandardError | |
def initialize(line) | |
super "Shell command invalid (did not run): #{line.to_json}" | |
end | |
end | |
def as_json | |
{ | |
line: line, | |
stdin: stdin, | |
binmode: binmode, | |
stdout: stdout, | |
stderr: stderr, | |
pid: pid, | |
exit_code: exit_code, | |
} | |
end | |
def to_json(*args) | |
as_json.to_json(*args) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks a lot!