Class: Maestro::Util::Shell
- Inherits:
-
Object
- Object
- Maestro::Util::Shell
- Defined in:
- lib/util/shell.rb,
lib/util/version.rb
Defined Under Namespace
Classes: ExitCode
Constant Summary collapse
- IS_WINDOWS =
Utility variables
ChildProcess.windows?
- SEPARATOR =
IS_WINDOWS ? "\\" : "/"
- MOVE_COMMAND =
IS_WINDOWS ? 'move' : 'mv'
- ENV_EXPORT_COMMAND =
IS_WINDOWS ? 'set' : 'export'
- COMMAND_SEPARATOR =
IS_WINDOWS ? ‘&&’ : ‘&&’
'&&'- SCRIPT_EXTENSION =
IS_WINDOWS ? '.bat' : '.shell'
- BASH_EXECUTABLE =
'bash'- VERSION =
'1.0.0'
Instance Attribute Summary collapse
-
#exit_code ⇒ Object
readonly
Returns the value of attribute exit_code.
-
#output_file ⇒ Object
readonly
Returns the value of attribute output_file.
-
#script_file ⇒ Object
readonly
Returns the value of attribute script_file.
-
#shell ⇒ Object
readonly
Returns the value of attribute shell.
Class Method Summary collapse
Instance Method Summary collapse
- #create_script(contents) ⇒ Object
- #run_script ⇒ Object
-
#run_script_with_delegate(delegate, on_output) ⇒ Object
if
delegateprovided, the method named/symbolized byon_outputvalue will be called for each line of output to either stdout or stderr. - #to_s ⇒ Object (also: #output)
Instance Attribute Details
#exit_code ⇒ Object (readonly)
Returns the value of attribute exit_code.
14 15 16 |
# File 'lib/util/shell.rb', line 14 def exit_code @exit_code end |
#output_file ⇒ Object (readonly)
Returns the value of attribute output_file.
12 13 14 |
# File 'lib/util/shell.rb', line 12 def output_file @output_file end |
#script_file ⇒ Object (readonly)
Returns the value of attribute script_file.
11 12 13 |
# File 'lib/util/shell.rb', line 11 def script_file @script_file end |
#shell ⇒ Object (readonly)
Returns the value of attribute shell.
13 14 15 |
# File 'lib/util/shell.rb', line 13 def shell @shell end |
Class Method Details
.run_command(command) ⇒ Object
41 42 43 44 45 46 |
# File 'lib/util/shell.rb', line 41 def Shell.run_command(command) shell = Shell.new shell.create_script(command) shell.run_script return shell.exit_code, shell.to_s end |
.unset_env_variable(var) ⇒ Object
37 38 39 |
# File 'lib/util/shell.rb', line 37 def Shell.unset_env_variable(var) IS_WINDOWS ? "set #{var}=" : "unset #{var}" end |
Instance Method Details
#create_script(contents) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/util/shell.rb', line 48 def create_script(contents) raise "Script Cannot Be Empty" if contents.nil? or contents.empty? @script_file = Tempfile.new(["script", SCRIPT_EXTENSION]) @output_file = Tempfile.new(['output','log']) # Add @echo off in windows if the script doesn't already use @echo pre = (IS_WINDOWS and !contents.include?("@echo ")) ? "@echo off\n" : "" # Run any commands in the default system Ruby environment, rather # than the one the agent is currently using (which within the wrapper, # sets clean values for these to avoid RVM or System gems that might # conflict). If the caller needs a specific Ruby environment, it should # establish that itself (as the rake task does through rvm if chosen) # Add clear env variable commands to head of script, since we don't necessarily have access to env here (depending on # version of ruby/bugs) contents = "#{pre}#{Shell.unset_env_variable('GEM_HOME')}\n#{Shell.unset_env_variable('GEM_PATH')}\n#{contents}" @script_file.write(contents) @script_file.close Maestro.log.debug "Writing Script File To #{@script_file.path}" return get_command(@script_file.path) end |
#run_script ⇒ Object
71 72 73 |
# File 'lib/util/shell.rb', line 71 def run_script run_script_with_delegate(nil, nil) end |
#run_script_with_delegate(delegate, on_output) ⇒ Object
if delegate provided, the method named/symbolized by on_output value will be called for each line of output to either stdout or stderr. two parameters are passed:
+text+ String Output text. This may be any amount of data from 1 character to many lines.
do not assume it always represents a single line.
+err+ Boolean True if line is from stderr
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/util/shell.rb', line 81 def run_script_with_delegate(delegate, on_output) File.open(@output_file.path, 'a') do |out_file| r, w = IO.pipe ChildProcess.posix_spawn = true if IS_WINDOWS if ChildProcess.jruby? # Due to https://github.com/jarib/childprocess/issues/26, we # must use a different implementation of ChildProcess on # Windows + JRuby process = ChildProcess::JRuby::Process.new([@command_line]) else process = ChildProcess.build(@command_line) end else process = ChildProcess.build(BASH_EXECUTABLE, @command_line) end process.io.stdout = process.io.stderr = w process.start # On Windows, can't close the pipe until process has exited or you # get an EOF, see # https://github.com/jarib/childprocess/pull/22#issuecomment-3395687 w.close unless IS_WINDOWS potential_eof = false begin loop { text = r.read_nonblock(1024) potential_eof = false out_file.write(text) if delegate && on_output delegate.send(on_output, text) end } rescue IO::WaitReadable => e if !process.exited? # process still running, block for input here to avoid a busy # loop, but with a timeout in case the process exited with no # further output IO.select([r], nil, nil, 1) retry elsif !potential_eof # process is done, but keep looping while there is input to # read potential_eof = true retry end rescue EOFError # expected when we reach end of output from the process end r.close process.wait unless process.exited? w.close if IS_WINDOWS @exit_code = ExitCode.new(process.exit_code) end return @exit_code end |
#to_s ⇒ Object Also known as: output
141 142 143 |
# File 'lib/util/shell.rb', line 141 def to_s @output_file.read if @output_file end |