require 'open3'
require_relative('./array.rb')
require_relative('./hash.rb')
require_relative('./timer.rb')
# = Command
#
# execution of system commands
#
# = Keys
#
# - :input The input of the commands.
# - :timeout The timeout in seconds.
# a value of zero is to infinite timeout.
# defaults to zero
# - :directory The working directory for the command.
# defaults to the current directory
# - :exit_code The exit code of the command
# - :output The output contains the stdout output of the command
# - :error The error contains stderr output of the command
# - :machine The name of the machine the command executed on
# - :user The user name
# - :start_time
# - :end_time
#
class Command < Hash
def initialize command
self[:input] = ''
self[:timeout] = 0
self[:directory] = ''
self[:exit_code] = 0
self[:output] = ''
self[:error] = ''
self[:machine] = ''
self[:user] = ''
self[:start_time] = nil
self[:end_time] = nil
if(command.kind_of?(String))
self[:input] = command
end
if(command.kind_of?(Hash))
command.each{|k,v|
self[k.to_sym]=v
}
end
end
def execute
puts "#{self[:input]}" if(!self.has_key?(:quiet) || !self[:quiet])
pwd=Dir.pwd
Dir.chdir(self[:directory]) if(self.has_key?(:directory) && File.exists?(self[:directory]))
self[:directory] = pwd if(self[:directory].length==0)
self[:machine] = Command.machine
self[:user] = Command.user
self[:start_time]=Time.now
timer=Timer.new
if self[:input].include?('<%') && self[:input].include?('%>')
ruby = self[:input].gsub("<%","").gsub("%>","")
begin
self[:output]=eval(ruby)
rescue
self[:exit_code]=1
self[:error]="unable to eval(#{ruby})"
end
self[:elapsed] = timer.elapsed_str
self[:end_time] = Time.now
else
begin
self[:output],self[:error],status= Open3.capture3(self[:input])
self[:exit_code]=status.to_i
self[:elapsed] = timer.elapsed_str
self[:end_time] = Time.now
rescue Exception => e
self[:elapsed] = timer.elapsed_str
self[:end_time] = Time.now
self[:error] = "Exception: " + e.to_s
self[:exit_code]=1
end
end
Dir.chdir(pwd) if pwd != Dir.pwd
if(self[:exit_code] != 0)
if(!self.has_key?(:quiet) || !self[:quiet])
puts ' '
puts "exit_code=#{self[:exit_code]}"
puts ' '
puts self[:output]
puts self[:error]
puts ' '
end
if(!self.has_key?(:ignore_failure) || !self[:ignore_failure])
raise "#{self[:input]} failed"
end #unless (self.has_key?(:ignore_failure) && self[:ignore_failure]==true)
end
end
def self.machine
if !ENV['COMPUTERNAME'].nil?
return ENV['COMPUTERNAME']
end
machine = `hostname`
machine = machine.split('.')[0] if machine.include?('.')
return machine.strip
end
def self.user
ENV['USER'].nil? ? ENV['USERNAME'] : ENV['USER']
end
def self.home
["USERPROFILE","HOME"].each {|v|
return ENV[v].gsub('\\','/') unless ENV[v].nil?
}
dir="~"
dir=ENV["HOME"] unless ENV["HOME"].nil?
dir=ENV["USERPROFILE"].gsub('\\','/') unless ENV["USERPROFILE"].nil?
return dir
end
def self.dev_root
["DEV_HOME","DEV_ROOT"].each {|v|
return ENV[v].gsub('\\','/') unless ENV[v].nil?
}
dir=home
#dir=ENV["DEV_ROOT"].gsub('\\','/') unless ENV["DEV_ROOT"].nil?
return dir
end
def self.exit_code command
cmd = Command.new(command)
cmd[:ignore_failure]=true
cmd[:quiet]=true
cmd.execute
cmd[:exit_code]
end
def self.output command
cmd = Command.new(command)
cmd[:ignore_failure]=true
cmd[:quiet]=true
cmd.execute
cmd[:output]
end
def to_html
if self[:exit_code] == 0
[
'
'
].join
else
[
' | ',
self[:input],
' | ',
map { |k, v| ["#{k} | ", v.respond_to?(:to_html) ? v.to_html : "#{v} | "] },
' ',
' |
|
'
].join
end
end
end