Class: Chutzen::Command
- Inherits:
-
Object
- Object
- Chutzen::Command
- Defined in:
- lib/chutzen/command.rb,
lib/chutzen/command/execution_failed.rb
Overview
Holds a description for a command and executes it.
Defined Under Namespace
Classes: ExecutionFailed
Constant Summary collapse
- ALLOW_EVAL =
/\A[\d<>=\s]+\z/.freeze
Instance Attribute Summary collapse
-
#exit_status ⇒ Object
readonly
Returns a Process::Status object after the command has run.
-
#stderr ⇒ Object
readonly
Returns a StringIO object with all data the command wrote to stderr.
-
#stdout ⇒ Object
readonly
Returns a StringIO object with all data the command wrote to stdout.
Instance Method Summary collapse
-
#initialize(description, dictionary:, work_path:) ⇒ Command
constructor
Creates a new command with a description hash, dictionary, and the current work path.
-
#name ⇒ Object
Attempts to return the name of the binary that is being executed.
-
#optional? ⇒ Boolean
Return true when the command should be performed but does not need to exit successfully.
-
#perform ⇒ Object
Runs the job based on its description.
- #perform_command ⇒ Object
-
#perform_when ⇒ Object
Returns the value expressed by the perform_when section but with its variables instantiated.
-
#result ⇒ Object
Returns the result expressed by the result section but with its variables instantiated.
-
#skip_when ⇒ Object
Returns the value expressed by the skip_when section but with its variables instantiated.
-
#to_s ⇒ Object
Joins all the arguments from the execute sections to build a command that can be executed by a shell.
Constructor Details
#initialize(description, dictionary:, work_path:) ⇒ Command
Creates a new command with a description hash, dictionary, and the current work path.
Command.new(
{ 'execute' => 'ls -al' },
dictionary: dictionary,
work_path: Dir.pwd
)
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/chutzen/command.rb', line 28 def initialize(description, dictionary:, work_path:) defaults description.each do |name, value| instance_variable_set("@#{name}", value) end @dictionary = dictionary @work_path = work_path @stdout = StringIO.new @stderr = StringIO.new end |
Instance Attribute Details
#exit_status ⇒ Object (readonly)
Returns a Process::Status object after the command has run.
18 19 20 |
# File 'lib/chutzen/command.rb', line 18 def exit_status @exit_status end |
#stderr ⇒ Object (readonly)
Returns a StringIO object with all data the command wrote to stderr.
16 17 18 |
# File 'lib/chutzen/command.rb', line 16 def stderr @stderr end |
#stdout ⇒ Object (readonly)
Returns a StringIO object with all data the command wrote to stdout.
14 15 16 |
# File 'lib/chutzen/command.rb', line 14 def stdout @stdout end |
Instance Method Details
#name ⇒ Object
Attempts to return the name of the binary that is being executed.
52 53 54 |
# File 'lib/chutzen/command.rb', line 52 def name to_s.split(' ')[0].split('/').last end |
#optional? ⇒ Boolean
Return true when the command should be performed but does not need to exit successfully.
41 42 43 |
# File 'lib/chutzen/command.rb', line 41 def optional? @optional end |
#perform ⇒ Object
Runs the job based on its description. Returns the job itself for convenience.
58 59 60 61 62 63 64 |
# File 'lib/chutzen/command.rb', line 58 def perform return if skip? result = @execute ? perform_command : self merge_remember_into_dictionary result end |
#perform_command ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/chutzen/command.rb', line 66 def perform_command trace_execution do # We use the STOP signal to instruct Sidekiq to stop reading from the queue and the TERM # signal to kill and re-queue running jobs. Unfortunately the command opened by popen would # also receive the signal and stop or terminate the command. When stopped the command would # never complete and when killed it would probably fail the job. # # Chutzen can't trap the signals because it runs in the same process. We don't want to wrap # the command in a runner because that's even more inconvenient. # # As a tradeoff we start the command in its own process group. Upside is that it ignores the # signals of its parent process. Downside is that it may orphan the process when Sidekiq # stops. Open3.popen3(to_s, chdir: @work_path, pgroup: true) do |stdin, stdout, stderr, thread| stdin.close_write monitor(stdout, stderr, thread) @exit_status = thread.value end verify_exit_status merge_output_into_dictionary self end end |
#perform_when ⇒ Object
Returns the value expressed by the perform_when section but with its variables instantiated.
110 111 112 113 114 |
# File 'lib/chutzen/command.rb', line 110 def perform_when return nil unless @perform_when Expression.new(Template.new(@perform_when, @dictionary).result, @dictionary) end |
#result ⇒ Object
Returns the result expressed by the result section but with its variables instantiated.
92 93 94 95 96 97 98 |
# File 'lib/chutzen/command.rb', line 92 def result return nil unless @result result = Dictionary.new Apply.new(result, @dictionary).merge(@result) result.to_hash end |
#skip_when ⇒ Object
Returns the value expressed by the skip_when section but with its variables instantiated.
102 103 104 105 106 |
# File 'lib/chutzen/command.rb', line 102 def skip_when return nil unless @skip_when Expression.new(Template.new(@skip_when, @dictionary).result, @dictionary) end |