class Raykit::Command

Functionality to support executing and logging system commands

Attributes

command[RW]
directory[RW]

The working directory, defaults the current directory if not specified

elapsed[RW]

The execution time in seconds

error[RW]
exitstatus[RW]
machine[RW]
output[RW]
start_time[RW]

The start time

timeout[RW]

The timeout in seconds, defaults to 0 if not specified

user[RW]

Public Class Methods

get_script_commands(hash) click to toggle source
# File lib/raykit/command.rb, line 185
def self.get_script_commands(hash)
    commands=Array.new
    if(hash.key?('script'))
        hash['script'].each{|cmd|
            commands << cmd
        }
    end
    hash.each{|k,v|
        if(v.is_a?(Hash))
            subcommands=get_script_commands(v)
            subcommands.each{|c|
                commands << c
            }
        end
    }
    commands
end
new(command,timeout=0) click to toggle source
# File lib/raykit/command.rb, line 34
def initialize(command,timeout=0)
    @@commands=Array.new
    init_defaults
    @command=command
    @timeout=timeout
    if(@command.length > 0)
        run
    end
    self
end
parse(json) click to toggle source
# File lib/raykit/command.rb, line 173
def self.parse(json)
    cmd=Command.new('')
    cmd.from_hash(JSON.parse(json))
    cmd
end
parse_yaml_commands(yaml) click to toggle source
# File lib/raykit/command.rb, line 179
def self.parse_yaml_commands(yaml)
    #commands=Array.new()
    data = YAML.load(yaml)
    commands = get_script_commands(data)
end

Public Instance Methods

details() click to toggle source
# File lib/raykit/command.rb, line 126
def details
    #summary
    puts @output
    puts @error
    puts 
end
elapsed_str() click to toggle source
# File lib/raykit/command.rb, line 104
def elapsed_str()
    if(elapsed < 1.0)
        "%.0f" % (elapsed) + "s"
    else
        "%.0f" % (elapsed) + "s"
    end
end
from_hash(hash) click to toggle source
# File lib/raykit/command.rb, line 160
def from_hash(hash)
    @command = hash["command"]
    @directory=hash["directory"]
    @timeout=hash["timeout"]
    @start_time=hash["start_time"]
    @elapsed=hash["elapsed"]
    @output=hash["output"]
    @error=hash["error"]
    @exitstatus=hash["exitstatus"]
    @user=hash["user"] if(hash.include?("user"))
    @machine=hash["machine"] if(hash.include?("machine"))
end
init_defaults() click to toggle source
# File lib/raykit/command.rb, line 24
def init_defaults 
    @timeout=0
    @directory = Dir.pwd
    @output = ''
    @error = ''
    @exitstatus = 0
    @user = Environment.user
    @machine=Environment.machine
end
log() click to toggle source
# File lib/raykit/command.rb, line 85
def log
    begin
        json=JSON.generate(to_hash)
        log_filename = Environment.get_dev_dir('log') + '/Raykit.Command/' + SecureRandom.uuid + '.json'
        log_dir = File.dirname(log_filename)
        FileUtils.mkdir_p(log_dir) if(!Dir.exist?(log_dir))
        File.open(log_filename, 'w') {|f| f.write(json) }
        if(@exitstatus == 0)
            LOG.log('Raykit.Command',Logger::Severity::INFO,json)
        else
            LOG.log('Raykit.Command',Logger::Severity::ERROR,json)
        end
    rescue JSON::GeneratorError => ge
        puts to_hash.to_s
        puts ge.to_s
        json=JSON.generate(to_hash)
    end
end
run() click to toggle source
# File lib/raykit/command.rb, line 45
def run() 
    @start_time = Time.now
    timer = Timer.new
    if(@timeout == 0)
        @output,@error,process_status = Open3.capture3(@command) 
        @exitstatus=process_status.exitstatus
    else
        Open3.popen3(@command, :chdir=>@directory) { |stdin,stdout,stderr,thread|
            tick=2
            pid = thread.pid
            start = Time.now
            elapsed = Time.now-start
            while (elapsed) < @timeout and thread.alive?
                Kernel.select([stdout,stderr], nil, nil, tick)
                begin
                    @output << stdout.read_nonblock(BUFFER_SIZE)
                    @error << stderr.read_nonblock(BUFFER_SIZE)
                rescue IO::WaitReadable
                rescue EOFError
                    @exitstatus=thread.value.exitstatus
                    break
                end
                elapsed = Time.now-start
            end
            if thread.alive?
                if(Gem.win_platform?)
                    `taskkill /f /pid #{pid}`
                else
                    Process.kill("TERM", pid)
                end
                @exitstatus=5
            else
                @exitstatus=thread.value.exitstatus
            end
          }
    end
    @elapsed = timer.elapsed
    log
end
save() click to toggle source
# File lib/raykit/command.rb, line 133
def save()
    filename = Environment.get_dev_dir('log') + '/Commands/' + SecureRandom.uuid
    log_dir=File.dirname(filename)
    FileUtils.mkdir_p(log_dir) if(!Dir.exist?(log_dir))

    File.open(filename,'w'){|f|
        f.write(JSON.pretty_generate(self.to_hash))
    }
    self
end
summary(show_directory=false) click to toggle source
# File lib/raykit/command.rb, line 112
def summary(show_directory=false)
    checkmark="\u2713"
    #warning="\u26A0"
    error="\u0058"
    symbol=Rainbow(checkmark.encode('utf-8')).green
    symbol=Rainbow(error.encode('utf-8')).red if(@exitstatus!=0)
    if(show_directory)
        puts symbol + "  " + elapsed_str.rjust(4) + " " + Rainbow(SECRETS.hide(@command)).yellow + " (#{@directory})"
    else
        puts symbol + "  " + elapsed_str.rjust(4) + " " + Rainbow(SECRETS.hide(@command)).yellow# + " (#{@directory})"
    end
    #puts symbol + "  " + elapsed_str.rjust(4) + " " + Rainbow(SECRETS.hide(@command)).yellow# + " (#{@directory})"
end
to_hash() click to toggle source
# File lib/raykit/command.rb, line 144
def to_hash()
    hash = Hash.new
    hash[:command] = @command
    hash[:directory] = @directory
    hash[:timeout] = @timeout
    hash[:start_time] = @start_time
    hash[:elapsed] = @elapsed
    hash[:output] = @output.force_encoding("ISO-8859-1").encode("UTF-8")
    hash[:error] = @error.force_encoding("ISO-8859-1").encode("UTF-8")
    hash[:exitstatus] = @exitstatus
    hash[:user] = @user
    hash[:machine] = @machine
    hash[:context] = "Raykit.Command"
    hash
end