Module: Albacore::CrossPlatformCmd
- Extended by:
- CrossPlatformCmd
- Includes:
- Logging
- Included in:
- AppSpec::IisSite, Build::Cmd, Albacore::CpackAppSpec::Task, CrossPlatformCmd, DSL, FpmAppSpec::Task, NugetsPack::Cmd, NugetsRestore::AddSourceCmd, NugetsRestore::Cmd, NugetsRestore::RemoveSourceCmd, TestRunner::Cmd, Tools::FluentMigrator::Cmd
- Defined in:
- lib/albacore/cross_platform_cmd.rb
Overview
module for normalising slashes across operating systems and running commands
Defined Under Namespace
Classes: PseudoStatus
Constant Summary collapse
- KILL_TIMEOUT =
seconds
2
Instance Attribute Summary collapse
-
#pid ⇒ Object
readonly
Returns the value of attribute pid.
Instance Method Summary collapse
- #chdir(wd, &block) ⇒ Object
- #initialize ⇒ Object
-
#make_command ⇒ Object
create a new command string.
- #normalise_slashes(path) ⇒ Object
-
#sh(*cmd, &block) ⇒ Object
run in shell.
-
#shie(*cmd, &block) ⇒ Object
shell ignore exit code returns: [ok, status] where status: #exitstatus : Int #pid : Int.
- #stop ⇒ Object
-
#system(*cmd, &block) ⇒ Object
run executable.
- #which(executable) ⇒ Object
Methods included from Logging
#debug, #err, #error, #fatal, #info, #puts, #trace, #warn
Instance Attribute Details
#pid ⇒ Object (readonly)
Returns the value of attribute pid.
41 42 43 |
# File 'lib/albacore/cross_platform_cmd.rb', line 41 def pid @pid end |
Instance Method Details
#chdir(wd, &block) ⇒ Object
219 220 221 222 223 224 225 226 227 |
# File 'lib/albacore/cross_platform_cmd.rb', line 219 def chdir wd, &block return block.call if wd.nil? Dir.chdir wd do debug { "pushd #{wd} [cross_platform_cmd #chdir]" } res = block.call debug { "popd #{wd} [cross_platform_cmd #chdir]" } return res end end |
#initialize ⇒ Object
45 46 47 48 |
# File 'lib/albacore/cross_platform_cmd.rb', line 45 def initialize pid = Process.pid at_exit { stop if Process.pid == pid } end |
#make_command ⇒ Object
create a new command string
182 183 184 |
# File 'lib/albacore/cross_platform_cmd.rb', line 182 def make_command ::Albacore::Paths.make_command @executable, @parameters end |
#normalise_slashes(path) ⇒ Object
177 178 179 |
# File 'lib/albacore/cross_platform_cmd.rb', line 177 def normalise_slashes path ::Albacore::Paths.normalise_slashes path end |
#sh(*cmd, &block) ⇒ Object
run in shell
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/albacore/cross_platform_cmd.rb', line 140 def sh *cmd, &block raise ArgumentError, "cmd is nil" if cmd.nil? # don't allow nothing to be passed opts = Map.((Hash === cmd.last) ? cmd.pop : {}) # same arg parsing as rake cmd = cmd.join(' ') # shell needs a single string block = cmd unless block_given? chdir opts.get(:work_dir) do trace { "#sh( ..., options: #{opts.to_s}) [cross_platform_cmd #sh]" } puts cmd unless opts.getopt :silent, false # log cmd verbatim lines = '' handle_not_found block do IO.popen(cmd, 'r') do |io| io.each do |line| lines << line puts line if opts.getopt(:output, true) or not opts.getopt(:silent, false) end end end return block.call($? == 0 && lines, $?, lines) end end |
#shie(*cmd, &block) ⇒ Object
shell ignore exit code returns:
[ok, status]
where status:
#exitstatus : Int
#pid : Int
172 173 174 175 |
# File 'lib/albacore/cross_platform_cmd.rb', line 172 def shie *cmd, &block block = lambda { |ok, status, output| ok } unless block_given? sh *cmd, &block end |
#stop ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/albacore/cross_platform_cmd.rb', line 115 def stop if pid begin Process.kill('TERM', pid) begin Timeout.timeout(KILL_TIMEOUT) { Process.wait(pid) } rescue Timeout::Error Process.kill('KILL', pid) Process.wait(pid) end rescue Errno::ESRCH, Errno::ECHILD # Zed's dead, baby end @out_thread.kill @pid = nil end end |
#system(*cmd, &block) ⇒ Object
run executable
system(cmd, [args array], Hash(opts), block|ok,status|)
ok => false if bad exit code, or the output otherwise
options are passed as the last argument
options:
work_dir: a file path (default '.')
silent: whether to supress all output or not (default false)
output: whether to supress the command's output (default false)
out: output pipe
err: error pipe
clr_command:
whether to include 'mono' in front of the things to run
if the command is a clr command
67 68 69 70 71 72 73 74 75 76 77 78 79 80 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 |
# File 'lib/albacore/cross_platform_cmd.rb', line 67 def system *cmd, &block raise ArgumentError, "cmd is nil" if cmd.nil? # don't allow nothing to be passed opts = Map.((Hash === cmd.last) ? cmd.pop : {}). # same arg parsing as rake apply({ :silent => false, :output => true, :work_dir => FileUtils.pwd, :out => Albacore.application.output, :err => Albacore.application.output_err, :clr_command => false }) exe, pars, printable, block = prepare_command cmd, (opts.get('clr_command')), &block # TODO: figure out how to interleave output and error streams out, _, inmem = opts.get(:out), opts.get(:err), StringIO.new trace { "system( exe=#{exe}, pars=[#{pars.join(', ')}], options=#{opts.to_s}), in directory: #{opts.getopt(:work_dir, '<<current>>')} [cross_platform_cmd #system]" } puts printable unless opts.get :silent, false # log cmd verbatim handle_not_found block do # create a pipe for the process to work with read, write = IO.pipe eread, ewrite = IO.pipe # this thread chews through the output @out_thread = Thread.new { while !read.eof? data = read.readpartial(1024) out.write data inmem.write data # to give the block at the end end } debug 'execute the new process, letting it write to the write FD (file descriptor)' @pid = Process.spawn(*[exe, *pars], { :out => write, #:err => ewrite, :chdir => opts.get(:work_dir) }) debug 'waiting for process completion' _, status = Process.wait2 @pid ret_str = inmem.string.encode 'utf-8', invalid: :replace, undef: :replace, replace: '' return block.call(status.success? && ret_str, status, ret_str) end end |
#which(executable) ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/albacore/cross_platform_cmd.rb', line 186 def which executable raise ArgumentError, "executable to #which is nil" unless executable dir = File.dirname executable file = File.basename executable cmd = ::Rake::Win32.windows? ? 'where' : 'which' parameters = [] pattern = if dir == '.' then file elsif ::Rake::Win32.windows? then "#{dir}:#{file}" else executable end parameters << Paths.normalise_slashes("\"#{pattern}\"") parameters << '2> nul' if ::Rake::Win32.windows? cmd, parameters = Paths.normalise cmd, parameters cmd = "#{cmd} #{parameters.join(' ')}" trace { "#{cmd} [cross_platform_cmd #which]" } res = IO.popen(cmd) do |io| io.read.chomp end unless $? == 0 nil else res end rescue Errno::ENOENT => e trace "which/where returned #{$?}: #{e} [cross_platform_cmd #which]" nil end |