# # File:: console.rb # Description:: Console command prompt-like shell implementation. # # Author:: David Muir # Date:: 13 Novemeber 2008 # #---------------------------------------------------------------------------- # Uses #---------------------------------------------------------------------------- require "source/builder/shell/shell" require 'pipeline/win32/stdin_nonblock_gets' #---------------------------------------------------------------------------- # Implementation #---------------------------------------------------------------------------- module Assetbuild module Builder module Shell # # == Description # Console implementation of the Builder Shell. This shell creates a # command prompt which acts like a DOS-shell allowing users to # submit commands to the builder application when they have local # access to the machine. # class Console < ShellBase HOST = ENV['COMPUTERNAME'] USER = ENV['USERNAME'] attr_reader :active attr_reader :commands def initialize( commands = nil, server = ENV['COMPUTERNAME'], port = CommandQueue::DEFAULT_PORT, prompt = DEFAULT_PROMPT ) super( server, port ) @prompt = prompt @commands = commands end # # Runs a commmand and waits for it to get a result. # def run_command( command ) @active = true process_command( command ) result = nil # Start result processing loop start_result_processing( HOST, USER ) do |cmdres| result = cmdres.result @active = false # will kill the thread loop end @queue_thread.join puts "\n#{result}" result end # # Start the console shell blocking for user input and processing # commands as they are entered. # def start( &block ) Thread.current[:name] = THREAD_NAME @active = true # Start result processing loop start_result_processing( HOST, USER) do |cmdres| puts "\nCommand Result : #{cmdres.result}" prompt( ) end # Command Loop puts "\nType 'help' for interactive shell usage." while ( @active ) do begin prompt( ) command = $stdin.wt_gets().chomp().strip() process_command( command ) rescue InvalidCommand => ex puts "Command not recognised: #{command}." rescue Exception => ex puts "Unhandled exception in shell loop: #{ex.inspect}" puts ex.backtrace.join( "\n" ) end end end def stop( ) @active = false end def prompt( append = '' ) print "\n#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}> #{append}" end #--------------------------------------------------------------------------- # Private #--------------------------------------------------------------------------- private THREAD_NAME = '__BuilderFramework_ConsoleShell' REGEXP_FORMAT = /([A-Z0-9_ \?]+)/i DEFAULT_PROMPT = '> ' # # Process or rather 'enqueue' a command for processing. # def process_command( command_string ) throw ArgumentError.new( 'Invalid command object.' ) \ unless ( ( command_string.is_a?( String ) ) ) begin # Do some very basic regexp authentication on command. remd = ( command_string.match( REGEXP_FORMAT ) ) puts "Unrecognised command format. Ignored." if ( remd.nil? ) next if ( remd.nil? ) trailing = command_string.split(" ") command_name = trailing.delete_at( 0 ) command = Command.new(command_name, nil, nil, trailing, nil) enqueue_command( command, HOST, USER ) rescue Exception => ex puts "Unhandled exception in process_command: #{ex.inspect}" puts ex.backtrace.join( "\n" ) end end end end # Shell module end # Builder module end # Pipeline module # console.rb