rhcp_shell 0.0.9 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/rhcp_shell +25 -5
- data/bin/rhcp_shell.log +11 -0
- data/lib/base_shell.rb +14 -2
- data/lib/display_types/table.rb +106 -0
- data/lib/local_commands/context.rb +24 -0
- data/lib/local_commands/detail.rb +33 -0
- data/lib/local_commands/exit.rb +9 -0
- data/lib/local_commands/help.rb +74 -0
- data/lib/local_commands/set_prompt.rb +17 -0
- data/lib/rhcp_shell_backend.rb +184 -330
- data/lib/util/colorize.rb +15 -0
- data/lib/version.rb +2 -2
- data/test/rhcp_shell_backend_test.rb +54 -17
- data/test/setup_test_registry.rb +36 -0
- metadata +41 -13
    
        data/bin/rhcp_shell
    CHANGED
    
    | @@ -12,6 +12,8 @@ require 'base_shell' | |
| 12 12 | 
             
            require 'rhcp_shell_backend'
         | 
| 13 13 | 
             
            require 'version'
         | 
| 14 14 |  | 
| 15 | 
            +
            require 'uri'
         | 
| 16 | 
            +
             | 
| 15 17 | 
             
            module RHCP
         | 
| 16 18 | 
             
              class Shell
         | 
| 17 19 |  | 
| @@ -51,8 +53,14 @@ EOF | |
| 51 53 | 
             
                  [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
         | 
| 52 54 | 
             
                  [ '--username', '-u', GetoptLong::REQUIRED_ARGUMENT ],
         | 
| 53 55 | 
             
                  [ '--password', '-p', GetoptLong::REQUIRED_ARGUMENT ],
         | 
| 54 | 
            -
                  [ '--hostname', GetoptLong::REQUIRED_ARGUMENT ]
         | 
| 56 | 
            +
                  [ '--hostname', GetoptLong::REQUIRED_ARGUMENT ],
         | 
| 57 | 
            +
                  [ '--port', '-P', GetoptLong::REQUIRED_ARGUMENT ]
         | 
| 55 58 | 
             
                )
         | 
| 59 | 
            +
                
         | 
| 60 | 
            +
                options = {
         | 
| 61 | 
            +
                  "hostname" => "localhost",
         | 
| 62 | 
            +
                  "port" => 42000      
         | 
| 63 | 
            +
                }
         | 
| 56 64 |  | 
| 57 65 | 
             
                options = Hash.new
         | 
| 58 66 | 
             
                opts.each do |opt, arg|
         | 
| @@ -62,7 +70,7 @@ EOF | |
| 62 70 | 
             
                      Kernel.exit(1)
         | 
| 63 71 | 
             
                    else
         | 
| 64 72 | 
             
                      opt =~ /--(.+)/
         | 
| 65 | 
            -
                      $logger.debug "setting #{arg} for #{$1}" unless $1 == "password"
         | 
| 73 | 
            +
                      $logger.debug "setting #{arg} for #{$1}" unless $1 == "password"          
         | 
| 66 74 | 
             
                      options[$1] = arg
         | 
| 67 75 | 
             
                  end
         | 
| 68 76 | 
             
                end
         | 
| @@ -70,10 +78,8 @@ EOF | |
| 70 78 | 
             
                host = options["hostname"]
         | 
| 71 79 | 
             
                if host == nil then
         | 
| 72 80 | 
             
                  host = "http://localhost:42000"
         | 
| 73 | 
            -
                 | 
| 74 | 
            -
                  if host !~ /http:/ then
         | 
| 81 | 
            +
                elsif host !~ /http:/ then
         | 
| 75 82 | 
             
                    host = "http://#{host}:42000/rhcp"
         | 
| 76 | 
            -
                  end
         | 
| 77 83 | 
             
                end
         | 
| 78 84 | 
             
                $logger.debug "now connecting to #{host}"
         | 
| 79 85 |  | 
| @@ -81,6 +87,19 @@ EOF | |
| 81 87 |  | 
| 82 88 | 
             
                begin
         | 
| 83 89 | 
             
                  url = URI.parse(host)
         | 
| 90 | 
            +
                  
         | 
| 91 | 
            +
                if (false)       
         | 
| 92 | 
            +
                  http_options = {
         | 
| 93 | 
            +
                    :host => options["hostname"],
         | 
| 94 | 
            +
                    :port => 80,
         | 
| 95 | 
            +
                    :path => "/rhcp"
         | 
| 96 | 
            +
                  }
         | 
| 97 | 
            +
                  if options.has_key?('username')
         | 
| 98 | 
            +
                    http_options[:userinfo] = "#{options['username']}:#{options['password']}"
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
                  url = URI::HTTP.build(http_options)
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
                
         | 
| 84 103 | 
             
                  @http_broker = RHCP::Client::HttpBroker.new(url)
         | 
| 85 104 |  | 
| 86 105 | 
             
                  backend = RHCPShellBackend.new(@http_broker)
         | 
| @@ -105,6 +124,7 @@ end | |
| 105 124 |  | 
| 106 125 | 
             
            # TODO introduce something like the RAILS_ENVs
         | 
| 107 126 | 
             
            $logger = Logger.new("rhcp_shell.log")
         | 
| 127 | 
            +
            $logger.level = Logger::DEBUG
         | 
| 108 128 | 
             
            RHCP::ModuleHelper.instance().logger = $logger
         | 
| 109 129 |  | 
| 110 130 | 
             
            shell = RHCP::Shell.new
         | 
    
        data/bin/rhcp_shell.log
    ADDED
    
    | @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            # Logfile created on Sat Jun 25 20:16:10 +0000 2011 by logger.rb/22285
         | 
| 2 | 
            +
            D, [2011-06-25T20:16:10.643948 #1686] DEBUG -- : now connecting to http://localhost:42000
         | 
| 3 | 
            +
            D, [2011-06-25T20:16:10.644097 #1686] DEBUG -- : connecting to http://localhost:42000
         | 
| 4 | 
            +
            D, [2011-06-25T20:16:31.881621 #1688] DEBUG -- : setting http://localhost for hostname
         | 
| 5 | 
            +
            D, [2011-06-25T20:16:31.881756 #1688] DEBUG -- : now connecting to http://localhost
         | 
| 6 | 
            +
            D, [2011-06-25T20:16:31.881865 #1688] DEBUG -- : connecting to http://localhost
         | 
| 7 | 
            +
            E, [2011-06-25T20:16:31.883273 #1688] ERROR -- : cannot connect to 'http://localhost' : got http status code 404
         | 
| 8 | 
            +
            D, [2011-06-25T20:16:45.728319 #1690] DEBUG -- : setting http://localhost/rhcp for hostname
         | 
| 9 | 
            +
            D, [2011-06-25T20:16:45.728460 #1690] DEBUG -- : now connecting to http://localhost/rhcp
         | 
| 10 | 
            +
            D, [2011-06-25T20:16:45.728582 #1690] DEBUG -- : connecting to http://localhost/rhcp
         | 
| 11 | 
            +
            E, [2011-06-25T20:16:45.730109 #1690] ERROR -- : cannot connect to 'http://localhost/rhcp' : got http status code 404
         | 
    
        data/lib/base_shell.rb
    CHANGED
    
    | @@ -89,10 +89,22 @@ class BaseShell | |
| 89 89 | 
             
                      else
         | 
| 90 90 | 
             
                        @logger.debug "got an empty line"      
         | 
| 91 91 | 
             
                      end
         | 
| 92 | 
            -
             | 
| 92 | 
            +
             | 
| 93 93 | 
             
                      backend.process_input line
         | 
| 94 94 | 
             
                  }
         | 
| 95 | 
            -
                   | 
| 95 | 
            +
                  begin
         | 
| 96 | 
            +
                    @thread.join
         | 
| 97 | 
            +
                  rescue
         | 
| 98 | 
            +
                    error = $!
         | 
| 99 | 
            +
                    if error == "exit"
         | 
| 100 | 
            +
                      puts "exiting"
         | 
| 101 | 
            +
                      Kernel.exit
         | 
| 102 | 
            +
                    else
         | 
| 103 | 
            +
                      puts "got an error in @thread.join: #{error}"
         | 
| 104 | 
            +
                    end
         | 
| 105 | 
            +
                    
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
                  
         | 
| 96 108 | 
             
                end
         | 
| 97 109 | 
             
                $stderr.puts "Exiting shell..."      
         | 
| 98 110 | 
             
              end
         | 
| @@ -0,0 +1,106 @@ | |
| 1 | 
            +
            def format_table_output(command, response)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
                # TODO make sure that the response really holds the correct data types and that we've got at least one column
         | 
| 4 | 
            +
                # TODO check that all columns in overview_columns are valid
         | 
| 5 | 
            +
                # TODO check that all columns in column_titles are valid and match overview_columns
         | 
| 6 | 
            +
                output = ""         
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
                # let's find out which columns we want to display
         | 
| 9 | 
            +
                $logger.debug "overview columns : #{command.result_hints[:overview_columns]}"
         | 
| 10 | 
            +
                # TODO this will probably fail if no overview_columns are specified
         | 
| 11 | 
            +
                columns_to_display = command.result_hints.has_key?(:overview_columns) ?
         | 
| 12 | 
            +
                  command.result_hints[:overview_columns].clone() :
         | 
| 13 | 
            +
                  # by default, we'll display all columns, sorted alphabetically
         | 
| 14 | 
            +
                  columns_to_display = response.data[0].keys.sort
         | 
| 15 | 
            +
                
         | 
| 16 | 
            +
                # and which titles they should have (default : column names)
         | 
| 17 | 
            +
                $logger.debug "column titles : #{command.result_hints[:column_titles].length}"
         | 
| 18 | 
            +
                column_title_list = command.result_hints[:column_titles].length > 0 ?
         | 
| 19 | 
            +
                  command.result_hints[:column_titles].clone() :
         | 
| 20 | 
            +
                  column_title_list = columns_to_display
         | 
| 21 | 
            +
                $logger.debug "column title list : #{column_title_list}"
         | 
| 22 | 
            +
                
         | 
| 23 | 
            +
                # TODO the sorting column should be configurable
         | 
| 24 | 
            +
                first_column = columns_to_display[0]
         | 
| 25 | 
            +
                $logger.debug "sorting by #{first_column}"
         | 
| 26 | 
            +
                response.data = response.data.sort { |a,b| a[first_column] <=> b[first_column] }          
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
                # add the index column
         | 
| 29 | 
            +
                columns_to_display.unshift "__idx"
         | 
| 30 | 
            +
                column_title_list.unshift "\#"
         | 
| 31 | 
            +
                count = 1
         | 
| 32 | 
            +
                response.data.each do |row|
         | 
| 33 | 
            +
                  row["__idx"] = count
         | 
| 34 | 
            +
                  count = count+1
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
                column_titles = {}
         | 
| 38 | 
            +
                0.upto(column_title_list.length - 1) do |i|
         | 
| 39 | 
            +
                  column_titles[columns_to_display[i]] = column_title_list[i]
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
                $logger.debug "column titles : #{column_titles}"
         | 
| 42 | 
            +
                
         | 
| 43 | 
            +
                # initialize the max_width for all columns
         | 
| 44 | 
            +
                @max_width = {}
         | 
| 45 | 
            +
                column_titles.each do |key, value|
         | 
| 46 | 
            +
                  @max_width[key] = 0
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
                # find the maximum column width for each column
         | 
| 49 | 
            +
                response.data.each do |row|
         | 
| 50 | 
            +
                  row.each do |k,v|
         | 
| 51 | 
            +
                    if ! @max_width.has_key?(k) || v.to_s.length >  @max_width[k]
         | 
| 52 | 
            +
                      @max_width[k] = v.to_s.length
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
                
         | 
| 57 | 
            +
                # check the column_title for max width
         | 
| 58 | 
            +
                columns_to_display.each do |col_name|
         | 
| 59 | 
            +
                  if column_titles[col_name].length > @max_width[col_name]
         | 
| 60 | 
            +
                    @max_width[col_name] = column_titles[col_name].length
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
                #@max_width["row_count"] = response.data.length.to_s.length
         | 
| 64 | 
            +
                $logger.debug "max width : #{@max_width}"
         | 
| 65 | 
            +
                
         | 
| 66 | 
            +
                # and build headers
         | 
| 67 | 
            +
                @total_width = 2 + columns_to_display.length-1 # separators at front and end of table and between the values
         | 
| 68 | 
            +
                columns_to_display.each do |col|
         | 
| 69 | 
            +
                  @total_width += @max_width[col] + 2 # each column has a space in front and behind the value
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
                output += print_line
         | 
| 72 | 
            +
                
         | 
| 73 | 
            +
                columns_to_display.each do |col|
         | 
| 74 | 
            +
                  output += print_cell(col, column_titles[col])
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
                output += "|\n"
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                output += print_line
         | 
| 79 | 
            +
                
         | 
| 80 | 
            +
                # print the table values
         | 
| 81 | 
            +
                response.data.each do |row|            
         | 
| 82 | 
            +
                  columns_to_display.each do |col|
         | 
| 83 | 
            +
                    output += print_cell(col, row[col])
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
                  output += "|\n"
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
                output += print_line
         | 
| 88 | 
            +
              
         | 
| 89 | 
            +
            end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
            def print_cell(col_name, the_value)
         | 
| 92 | 
            +
                result = "| "
         | 
| 93 | 
            +
                result += the_value.to_s
         | 
| 94 | 
            +
                1.upto(@max_width[col_name] - the_value.to_s.length) { |i| 
         | 
| 95 | 
            +
                  result += " " 
         | 
| 96 | 
            +
                }
         | 
| 97 | 
            +
                result += " "
         | 
| 98 | 
            +
                result
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
              
         | 
| 101 | 
            +
              def print_line
         | 
| 102 | 
            +
                result = ""
         | 
| 103 | 
            +
                @total_width.times { |i| result += "-" }
         | 
| 104 | 
            +
                result += "\n"
         | 
| 105 | 
            +
                result
         | 
| 106 | 
            +
              end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            def add_context_commands(broker, context_aware_broker)
         | 
| 2 | 
            +
              
         | 
| 3 | 
            +
              command = RHCP::Command.new("show_context", "displays the context currently stored in the local ContextAwareBroker",
         | 
| 4 | 
            +
                lambda { |req,res| 
         | 
| 5 | 
            +
                  result = []
         | 
| 6 | 
            +
                  @command_broker.context.cookies.each do |k,v|
         | 
| 7 | 
            +
                    result << {
         | 
| 8 | 
            +
                      "key" => k,
         | 
| 9 | 
            +
                      "value" => v
         | 
| 10 | 
            +
                    }
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                  result
         | 
| 13 | 
            +
                }
         | 
| 14 | 
            +
              )
         | 
| 15 | 
            +
              
         | 
| 16 | 
            +
              command.result_hints[:display_type] = "table"
         | 
| 17 | 
            +
              command.result_hints[:overview_columns] = [ "key", "value" ]
         | 
| 18 | 
            +
              command.result_hints[:column_titles] = [ "key", "value" ]
         | 
| 19 | 
            +
              command.mark_as_read_only
         | 
| 20 | 
            +
              command.result_hints[:cache] = false
         | 
| 21 | 
            +
              
         | 
| 22 | 
            +
              broker.register_command command
         | 
| 23 | 
            +
              
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            def add_detail_command(broker)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              command = RHCP::Command.new("detail", "shows details about a single record of the last response\n" + (" " * 43)  + "(makes sense if you executed a command that returned a table)",
         | 
| 4 | 
            +
                lambda { |req,res| 
         | 
| 5 | 
            +
                  if @last_response == nil
         | 
| 6 | 
            +
                    puts "did not find any old response data...is it possible that you did not execute a command yet that returned a table?"
         | 
| 7 | 
            +
                    return
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                  row_count = @last_response.data.length
         | 
| 10 | 
            +
                  begin
         | 
| 11 | 
            +
                    row_index = req.get_param_value("row_index").to_i
         | 
| 12 | 
            +
                    raise "invalid index" if (row_index < 1 || row_index > row_count)
         | 
| 13 | 
            +
                  rescue
         | 
| 14 | 
            +
                    puts "invalid row index - please specify a number between 1 and #{row_count}"  
         | 
| 15 | 
            +
                    return
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                  puts "displaying details about row \# #{row_index}"          
         | 
| 18 | 
            +
                  @last_response.data[row_index - 1].each do |k,v|
         | 
| 19 | 
            +
                    puts "  #{k}\t#{v}"
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                }
         | 
| 23 | 
            +
                ).add_param(RHCP::CommandParam.new("row_index", "the index of the row you want to see details about",
         | 
| 24 | 
            +
                  {
         | 
| 25 | 
            +
                    :is_default_param => true,
         | 
| 26 | 
            +
                    :mandatory => true            
         | 
| 27 | 
            +
                  }
         | 
| 28 | 
            +
                )
         | 
| 29 | 
            +
              )
         | 
| 30 | 
            +
              command.result_hints[:display_type] = "hidden"
         | 
| 31 | 
            +
              broker.register_command command
         | 
| 32 | 
            +
              
         | 
| 33 | 
            +
            end  
         | 
| @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            def param_example(param, suffix = "")
         | 
| 2 | 
            +
              result = ""
         | 
| 3 | 
            +
              result += "<" if param.is_default_param
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              if param.is_default_param then
         | 
| 6 | 
            +
                result += "#{param.name}#{suffix}"
         | 
| 7 | 
            +
              else
         | 
| 8 | 
            +
                result += "#{param.name}"
         | 
| 9 | 
            +
                result += "=<value#{suffix}>"
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              result += ">" if param.is_default_param
         | 
| 13 | 
            +
              result
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            def add_help_commands(broker)
         | 
| 17 | 
            +
              command = RHCP::Command.new("help", "displays help about this shell",
         | 
| 18 | 
            +
                lambda { 
         | 
| 19 | 
            +
                  |req,res|
         | 
| 20 | 
            +
                    
         | 
| 21 | 
            +
                  if (req.has_param_value("command"))
         | 
| 22 | 
            +
                    command_name = req.get_param_value("command")
         | 
| 23 | 
            +
                    puts "Syntax:"
         | 
| 24 | 
            +
                    command_line = "  #{command_name}"
         | 
| 25 | 
            +
                    command = @command_broker.get_command(command_name)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    command.params.sort { |a,b| a.name <=> b.name }.each do |param|
         | 
| 28 | 
            +
                      command_line += " "
         | 
| 29 | 
            +
                      command_line += "[" unless param.mandatory
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                      command_line += param_example(param)  
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                      if param.allows_multiple_values then
         | 
| 34 | 
            +
                        command_line += " "
         | 
| 35 | 
            +
                        command_line += param_example(param, "2")
         | 
| 36 | 
            +
                        command_line += " ..."
         | 
| 37 | 
            +
                      end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                      command_line += "]" unless param.mandatory
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
                    puts command_line
         | 
| 42 | 
            +
                    puts "Description:"
         | 
| 43 | 
            +
                    puts "  #{command.description}"
         | 
| 44 | 
            +
                    if command.params.size > 0 then
         | 
| 45 | 
            +
                      puts "Parameters:"
         | 
| 46 | 
            +
                      command.params.sort { |a,b| a.name <=> b.name }.each do |param|
         | 
| 47 | 
            +
                        puts sprintf("  %-20s %s\n", param.name, param.description)
         | 
| 48 | 
            +
                      end
         | 
| 49 | 
            +
                   end
         | 
| 50 | 
            +
                   puts ""
         | 
| 51 | 
            +
                  else
         | 
| 52 | 
            +
                    puts "The following commands are available:"
         | 
| 53 | 
            +
                    @command_broker.get_command_list.values.sort { |a,b| a.name <=> b.name }.each do |command|
         | 
| 54 | 
            +
                      # TODO calculate the maximum command name length dynamically
         | 
| 55 | 
            +
                      # TODO and allow for multiple lines of description (check if it's an array?)
         | 
| 56 | 
            +
                      puts sprintf("  %-40s %s\n", command.name, command.description)
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
                    puts ""
         | 
| 59 | 
            +
                    puts "Type help <command name> for detailed information about a command."
         | 
| 60 | 
            +
                  end          
         | 
| 61 | 
            +
                }
         | 
| 62 | 
            +
                ).add_param(RHCP::CommandParam.new("command", "the name of the command to display help for", 
         | 
| 63 | 
            +
                    { 
         | 
| 64 | 
            +
                      :mandatory => false,
         | 
| 65 | 
            +
                      :is_default_param => true,
         | 
| 66 | 
            +
                      :lookup_method => lambda {
         | 
| 67 | 
            +
                        @command_broker.get_command_list.values.map { |c| c.name }
         | 
| 68 | 
            +
                      }
         | 
| 69 | 
            +
                    }
         | 
| 70 | 
            +
                )
         | 
| 71 | 
            +
              )
         | 
| 72 | 
            +
              command.result_hints[:display_type] = "hidden"
         | 
| 73 | 
            +
              broker.register_command command
         | 
| 74 | 
            +
            end      
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            def add_set_prompt_command(broker, shell_backend)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              command = RHCP::Command.new("set_prompt", "changes the current prompt",
         | 
| 4 | 
            +
                lambda { |req,res| 
         | 
| 5 | 
            +
                  res.set_context("prompt" => req.get_param_value("new_prompt"))      
         | 
| 6 | 
            +
                }
         | 
| 7 | 
            +
                ).add_param(RHCP::CommandParam.new("new_prompt", "the new prompt that should be used from now on",
         | 
| 8 | 
            +
                  {
         | 
| 9 | 
            +
                    :is_default_param => true,
         | 
| 10 | 
            +
                    :mandatory => true            
         | 
| 11 | 
            +
                  }
         | 
| 12 | 
            +
                )
         | 
| 13 | 
            +
              )
         | 
| 14 | 
            +
              command.result_hints[:display_type] = "hidden"
         | 
| 15 | 
            +
              broker.register_command command
         | 
| 16 | 
            +
              
         | 
| 17 | 
            +
            end  
         | 
    
        data/lib/rhcp_shell_backend.rb
    CHANGED
    
    | @@ -1,7 +1,16 @@ | |
| 1 1 | 
             
            require 'shell_backend.rb'
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'local_commands/help'
         | 
| 4 | 
            +
            require 'local_commands/detail'
         | 
| 5 | 
            +
            require 'local_commands/exit'
         | 
| 6 | 
            +
            require 'local_commands/context'
         | 
| 7 | 
            +
            require 'local_commands/set_prompt'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            require 'display_types/table'
         | 
| 10 | 
            +
             | 
| 3 11 | 
             
            require 'rubygems'
         | 
| 4 12 | 
             
            require 'rhcp'
         | 
| 13 | 
            +
            require 'rhcp/memcached_broker'
         | 
| 5 14 |  | 
| 6 15 | 
             
            # This shell presents RHCP commands to the user and handles all the parameter
         | 
| 7 16 | 
             
            # lookup, validation and command completion stuff
         | 
| @@ -18,132 +27,44 @@ class RHCPShellBackend < ShellBackend | |
| 18 27 | 
             
              # TODO refactor this monstrosity
         | 
| 19 28 |  | 
| 20 29 | 
             
              attr_reader :last_response
         | 
| 21 | 
            -
              attr_reader :prompt
         | 
| 22 30 | 
             
              attr_accessor :banner
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              attr_reader :command_broker
         | 
| 33 | 
            +
              attr_accessor :lookup_broker    
         | 
| 23 34 |  | 
| 24 | 
            -
              def initialize(command_broker)
         | 
| 35 | 
            +
              def initialize(command_broker, options = {})
         | 
| 25 36 | 
             
                super()
         | 
| 26 | 
            -
             | 
| 37 | 
            +
             | 
| 27 38 | 
             
                local_broker = setup_local_broker
         | 
| 28 | 
            -
                 | 
| 29 | 
            -
                 | 
| 30 | 
            -
                 | 
| 39 | 
            +
                dispatcher = RHCP::DispatchingBroker.new()
         | 
| 40 | 
            +
                dispatcher.add_broker(command_broker)
         | 
| 41 | 
            +
                dispatcher.add_broker(local_broker)
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                @command_broker = RHCP::Client::ContextAwareBroker.new(dispatcher)
         | 
| 44 | 
            +
                @lookup_broker = @command_broker    
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                @lookup_cache = {}
         | 
| 47 | 
            +
                
         | 
| 48 | 
            +
                @current_prompt = nil
         | 
| 49 | 
            +
                
         | 
| 50 | 
            +
                @prompt_color_enabled = options.has_key?(:color_prompt) ?
         | 
| 51 | 
            +
                  options[:color_prompt] : false
         | 
| 31 52 |  | 
| 32 53 | 
             
                reset_to_command_mode
         | 
| 33 | 
            -
              end | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
              
         | 
| 56 | 
            +
              def wrap_lookup_broker
         | 
| 57 | 
            +
                @lookup_broker = RHCP::MemcachedBroker.new(@lookup_broker)
         | 
| 58 | 
            +
              end
         | 
| 34 59 |  | 
| 35 60 | 
             
              def setup_local_broker    
         | 
| 36 61 | 
             
                broker = RHCP::Broker.new()
         | 
| 37 62 | 
             
                begin
         | 
| 38 | 
            -
                  broker | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
                  )
         | 
| 44 | 
            -
                  
         | 
| 45 | 
            -
                  def param_example(param, suffix = "")
         | 
| 46 | 
            -
                    result = ""
         | 
| 47 | 
            -
                    result += "<" if param.is_default_param
         | 
| 48 | 
            -
             | 
| 49 | 
            -
                    if param.is_default_param then
         | 
| 50 | 
            -
                      result += "#{param.name}#{suffix}"
         | 
| 51 | 
            -
                    else
         | 
| 52 | 
            -
                      result += "#{param.name}"
         | 
| 53 | 
            -
                      result += "=<value#{suffix}>"
         | 
| 54 | 
            -
                    end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                    result += ">" if param.is_default_param
         | 
| 57 | 
            -
                    result
         | 
| 58 | 
            -
                  end
         | 
| 59 | 
            -
                        
         | 
| 60 | 
            -
                  command = RHCP::Command.new("help", "displays help about this shell",
         | 
| 61 | 
            -
                    lambda { 
         | 
| 62 | 
            -
                      |req,res|
         | 
| 63 | 
            -
                        
         | 
| 64 | 
            -
                      if (req.has_param_value("command"))
         | 
| 65 | 
            -
                        command_name = req.get_param_value("command")
         | 
| 66 | 
            -
                        puts "Syntax:"
         | 
| 67 | 
            -
                        command_line = "  #{command_name}"
         | 
| 68 | 
            -
                        command = @command_broker.get_command(command_name)
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                        command.params.values.sort { |a,b| a.name <=> b.name }.each do |param|
         | 
| 71 | 
            -
                          command_line += " "
         | 
| 72 | 
            -
                          command_line += "[" unless param.mandatory
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                          command_line += param_example(param)  
         | 
| 75 | 
            -
             | 
| 76 | 
            -
                          if param.allows_multiple_values then
         | 
| 77 | 
            -
                            command_line += ", "
         | 
| 78 | 
            -
                            command_line += param_example(param, "2")
         | 
| 79 | 
            -
                            command_line += ", ..."
         | 
| 80 | 
            -
                          end
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                          command_line += "]" unless param.mandatory
         | 
| 83 | 
            -
                        end
         | 
| 84 | 
            -
                        puts command_line
         | 
| 85 | 
            -
                        puts "Description:"
         | 
| 86 | 
            -
                        puts "  #{command.description}"
         | 
| 87 | 
            -
                        if command.params.size > 0 then
         | 
| 88 | 
            -
                          puts "Parameters:"
         | 
| 89 | 
            -
                          command.params.values.sort { |a,b| a.name <=> b.name }.each do |param|
         | 
| 90 | 
            -
                            puts sprintf("  %-20s %s\n", param.name, param.description)
         | 
| 91 | 
            -
                          end
         | 
| 92 | 
            -
                       end
         | 
| 93 | 
            -
                       puts ""
         | 
| 94 | 
            -
                      else
         | 
| 95 | 
            -
                        puts "The following commands are available:"
         | 
| 96 | 
            -
                        @command_broker.get_command_list.values.sort { |a,b| a.name <=> b.name }.each do |command|
         | 
| 97 | 
            -
                          # TODO calculate the maximum command name length dynamically
         | 
| 98 | 
            -
                          puts sprintf("  %-40s %s\n", command.name, command.description)
         | 
| 99 | 
            -
                        end
         | 
| 100 | 
            -
                        puts ""
         | 
| 101 | 
            -
                        puts "Type help <command name> for detailed information about a command."
         | 
| 102 | 
            -
                      end          
         | 
| 103 | 
            -
                    }
         | 
| 104 | 
            -
                    ).add_param(RHCP::CommandParam.new("command", "the name of the command to display help for", 
         | 
| 105 | 
            -
                        { 
         | 
| 106 | 
            -
                          :mandatory => false,
         | 
| 107 | 
            -
                          :is_default_param => true,
         | 
| 108 | 
            -
                          :lookup_method => lambda {
         | 
| 109 | 
            -
                            @command_broker.get_command_list.values.map { |c| c.name }
         | 
| 110 | 
            -
                          }
         | 
| 111 | 
            -
                        }
         | 
| 112 | 
            -
                    )
         | 
| 113 | 
            -
                  )
         | 
| 114 | 
            -
                  command.result_hints[:display_type] = "hidden"
         | 
| 115 | 
            -
                  broker.register_command command
         | 
| 116 | 
            -
                  
         | 
| 117 | 
            -
                  command = RHCP::Command.new("detail", "shows details about a single record of the last response\n" + (" " * 43)  + "(makes sense if you executed a command that returned a table)",
         | 
| 118 | 
            -
                    lambda { |req,res| 
         | 
| 119 | 
            -
                      if @last_response == nil
         | 
| 120 | 
            -
                        puts "did not find any old response data...is it possible that you did not execute a command yet that returned a table?"
         | 
| 121 | 
            -
                        return
         | 
| 122 | 
            -
                      end
         | 
| 123 | 
            -
                      row_count = @last_response.data.length
         | 
| 124 | 
            -
                      begin
         | 
| 125 | 
            -
                        row_index = req.get_param_value("row_index").to_i
         | 
| 126 | 
            -
                        raise "invalid index" if (row_index < 1 || row_index > row_count)
         | 
| 127 | 
            -
                      rescue
         | 
| 128 | 
            -
                        puts "invalid row index - please specify a number between 1 and #{row_count}"  
         | 
| 129 | 
            -
                        return
         | 
| 130 | 
            -
                      end
         | 
| 131 | 
            -
                      puts "displaying details about row \# #{row_index}"          
         | 
| 132 | 
            -
                      @last_response.data[row_index - 1].each do |k,v|
         | 
| 133 | 
            -
                        puts "  #{k}\t#{v}"
         | 
| 134 | 
            -
                      end
         | 
| 135 | 
            -
             | 
| 136 | 
            -
                    }
         | 
| 137 | 
            -
                    ).add_param(RHCP::CommandParam.new("row_index", "the index of the row you want to see details about",
         | 
| 138 | 
            -
                      {
         | 
| 139 | 
            -
                        :is_default_param => true,
         | 
| 140 | 
            -
                        :mandatory => true            
         | 
| 141 | 
            -
                      }
         | 
| 142 | 
            -
                    )
         | 
| 143 | 
            -
                  )
         | 
| 144 | 
            -
                  command.result_hints[:display_type] = "hidden"
         | 
| 145 | 
            -
                  broker.register_command command
         | 
| 146 | 
            -
                  
         | 
| 63 | 
            +
                  add_exit_command(broker)
         | 
| 64 | 
            +
                  add_help_commands(broker)
         | 
| 65 | 
            +
                  add_detail_command(broker)
         | 
| 66 | 
            +
                  add_context_commands(broker, @command_broker)
         | 
| 67 | 
            +
                  add_set_prompt_command(broker, self)
         | 
| 147 68 | 
             
                rescue RHCP::RhcpException => ex
         | 
| 148 69 | 
             
                  # TODO do we really want to catch this here?
         | 
| 149 70 | 
             
                  raise ex unless /duplicate command name/ =~ ex.to_s
         | 
| @@ -152,8 +73,6 @@ class RHCPShellBackend < ShellBackend | |
| 152 73 | 
             
              end
         | 
| 153 74 |  | 
| 154 75 | 
             
              def reset_to_command_mode
         | 
| 155 | 
            -
                set_prompt nil
         | 
| 156 | 
            -
                
         | 
| 157 76 | 
             
                # this shell has two modes that determine the available tab completion proposals
         | 
| 158 77 | 
             
                # command_mode
         | 
| 159 78 | 
             
                #    we're waiting for the user to pick a command that should be executed
         | 
| @@ -164,7 +83,8 @@ class RHCPShellBackend < ShellBackend | |
| 164 83 |  | 
| 165 84 | 
             
                # if the user selected a command already, we'll have to collect parameters for this command until
         | 
| 166 85 | 
             
                # we've got all mandatory parameters so that we can execute the command
         | 
| 167 | 
            -
                @ | 
| 86 | 
            +
                @collected_values = {}
         | 
| 87 | 
            +
             | 
| 168 88 |  | 
| 169 89 | 
             
                # the mandatory params that are still missing (valid in parameter mode only) 
         | 
| 170 90 | 
             
                @missing_params = Array.new    
         | 
| @@ -175,13 +95,13 @@ class RHCPShellBackend < ShellBackend | |
| 175 95 |  | 
| 176 96 | 
             
              def execute_command_if_possible
         | 
| 177 97 | 
             
                # check if we got all mandatory params now
         | 
| 178 | 
            -
                mandatory_params = @command_selected. | 
| 179 | 
            -
                 | 
| 98 | 
            +
                mandatory_params = @command_broker.get_mandatory_params(@command_selected.name)
         | 
| 99 | 
            +
                #mandatory_params = @command_selected.get_mandatory_params()
         | 
| 100 | 
            +
                @missing_params = mandatory_params.select { |p| ! @collected_values.include? p.name }
         | 
| 180 101 |  | 
| 181 102 | 
             
                if (@missing_params.size > 0) then
         | 
| 182 103 | 
             
                  $logger.debug "got #{@missing_params.size} missing params : #{@missing_params.map{|param| param.name}}"    
         | 
| 183 104 | 
             
                  @current_param = @missing_params[0]
         | 
| 184 | 
            -
                  set_prompt "#{@command_selected.name}.#{@current_param.name}"
         | 
| 185 105 | 
             
                else 
         | 
| 186 106 | 
             
                  execute_command
         | 
| 187 107 | 
             
                end
         | 
| @@ -199,7 +119,7 @@ class RHCPShellBackend < ShellBackend | |
| 199 119 | 
             
                  # convert "*" into regexp notation ".*"
         | 
| 200 120 | 
             
                  regex_str = new_value.gsub(/\*/, '.*')
         | 
| 201 121 |  | 
| 202 | 
            -
                  # handle ranges ( | 
| 122 | 
            +
                  # handle ranges (42..45)
         | 
| 203 123 | 
             
                  result = /(.+?)(\d+)(\.{2})(\d+)(.*)/.match(regex_str)
         | 
| 204 124 | 
             
                  ranged_regex = nil
         | 
| 205 125 | 
             
                  if result then
         | 
| @@ -214,7 +134,7 @@ class RHCPShellBackend < ShellBackend | |
| 214 134 | 
             
                      end
         | 
| 215 135 | 
             
                    end
         | 
| 216 136 | 
             
                  else
         | 
| 217 | 
            -
                    ranged_regex = Regexp.new(regex_str) | 
| 137 | 
            +
                    ranged_regex = Regexp.new('^' + regex_str + '$')
         | 
| 218 138 | 
             
                  end
         | 
| 219 139 |  | 
| 220 140 | 
             
                  $logger.debug "wildcard regexp : #{ranged_regex}"
         | 
| @@ -222,7 +142,9 @@ class RHCPShellBackend < ShellBackend | |
| 222 142 | 
             
                  re = ranged_regex
         | 
| 223 143 |  | 
| 224 144 | 
             
                  # get lookup values, filter and return them
         | 
| 225 | 
            -
                   | 
| 145 | 
            +
                  request = RHCP::Request.new(@command_selected, @collected_values)
         | 
| 146 | 
            +
                  lookup_values = @command_broker.get_lookup_values(request, @current_param.name )
         | 
| 147 | 
            +
                  #lookup_values = @current_param.get_lookup_values()
         | 
| 226 148 | 
             
                  lookup_values.select { |lookup_value| re.match(lookup_value) }
         | 
| 227 149 | 
             
                else
         | 
| 228 150 | 
             
                  [ new_value ]
         | 
| @@ -234,137 +156,43 @@ class RHCPShellBackend < ShellBackend | |
| 234 156 | 
             
              # returns the values that have been added (might be more than 'new_value' when wildcards are used)
         | 
| 235 157 | 
             
              def add_parameter_value(new_value)
         | 
| 236 158 | 
             
                # pre-process the value if necessary
         | 
| 237 | 
            -
                 | 
| 159 | 
            +
                # TODO reactivate wildcard checking (too expensive right now and we aren't using it)
         | 
| 160 | 
            +
                #processed_param_values = pre_process_param_value(new_value)
         | 
| 161 | 
            +
                processed_param_values = [ new_value ]
         | 
| 162 | 
            +
             | 
| 238 163 | 
             
                # TODO this check is already part of check_param_is_valid (which is called later in this method and when the request is created) - we do not want to check this three times...?
         | 
| 239 164 | 
             
                if processed_param_values.size == 0
         | 
| 240 165 | 
             
                  raise RHCP::RhcpException.new("invalid value '#{new_value}' for parameter '#{@current_param.name}'")
         | 
| 241 166 | 
             
                end
         | 
| 242 | 
            -
                 | 
| 167 | 
            +
                
         | 
| 243 168 | 
             
                processed_param_values.each do |value|
         | 
| 244 | 
            -
                   | 
| 245 | 
            -
                  @ | 
| 169 | 
            +
                  request = RHCP::Request.new(@command_selected, @collected_values)
         | 
| 170 | 
            +
                  @command_broker.check_param_is_valid(request, @current_param.name, [ value ])
         | 
| 246 171 | 
             
                  $logger.debug "accepted value #{value} for param #{@current_param.name}"
         | 
| 247 172 |  | 
| 248 | 
            -
                  @ | 
| 249 | 
            -
                  @ | 
| 173 | 
            +
                  @collected_values[@current_param.name] = Array.new if @collected_values[@current_param.name] == nil
         | 
| 174 | 
            +
                  @collected_values[@current_param.name] << value
         | 
| 250 175 | 
             
                end
         | 
| 251 176 | 
             
                processed_param_values
         | 
| 252 177 | 
             
              end
         | 
| 253 178 |  | 
| 254 | 
            -
              def print_cell(col_name, the_value)
         | 
| 255 | 
            -
                result = "| "
         | 
| 256 | 
            -
                result += the_value.to_s
         | 
| 257 | 
            -
                1.upto(@max_width[col_name] - the_value.to_s.length) { |i| 
         | 
| 258 | 
            -
                  result += " " 
         | 
| 259 | 
            -
                }
         | 
| 260 | 
            -
                result += " "
         | 
| 261 | 
            -
                result
         | 
| 262 | 
            -
              end
         | 
| 263 | 
            -
              
         | 
| 264 | 
            -
              def print_line
         | 
| 265 | 
            -
                result = ""
         | 
| 266 | 
            -
                @total_width.times { |i| result += "-" }
         | 
| 267 | 
            -
                result += "\n"
         | 
| 268 | 
            -
                result
         | 
| 269 | 
            -
              end
         | 
| 270 | 
            -
              
         | 
| 271 179 | 
             
              def execute_command
         | 
| 272 180 | 
             
                begin
         | 
| 273 | 
            -
                  command  | 
| 274 | 
            -
                   | 
| 275 | 
            -
                   | 
| 276 | 
            -
                   | 
| 181 | 
            +
                  $logger.debug("(ShellBackend) gonna execute command '#{@command_selected.name}' on broker '#{@command_broker}'")
         | 
| 182 | 
            +
                  command = @command_broker.get_command(@command_selected.name)
         | 
| 183 | 
            +
                  request = RHCP::Request.new(command, @collected_values)
         | 
| 184 | 
            +
                  response = @command_broker.execute(request)
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                  # we might want to access this response in further commands
         | 
| 187 | 
            +
                  @last_response = response
         | 
| 188 | 
            +
             | 
| 277 189 | 
             
                  if (response.status == RHCP::Response::Status::OK)
         | 
| 190 | 
            +
                    
         | 
| 278 191 | 
             
                    $logger.debug "raw result : #{response.data}"
         | 
| 279 | 
            -
             | 
| 192 | 
            +
                    $logger.debug "result hints: #{command.result_hints}"
         | 
| 280 193 | 
             
                    $logger.debug "display_type : #{command.result_hints[:display_type]}"
         | 
| 281 194 | 
             
                    if command.result_hints[:display_type] == "table"
         | 
| 282 | 
            -
                       | 
| 283 | 
            -
                      # TODO check that all columns in overview_columns are valid
         | 
| 284 | 
            -
                      # TODO check that all columns in column_titles are valid and match overview_columns
         | 
| 285 | 
            -
                      output = ""         
         | 
| 286 | 
            -
                      
         | 
| 287 | 
            -
                      # let's find out which columns we want to display
         | 
| 288 | 
            -
                      $logger.debug "overview columns : #{command.result_hints[:overview_columns]}"
         | 
| 289 | 
            -
                      # TODO this will probably fail if no overview_columns are specified
         | 
| 290 | 
            -
                      columns_to_display = command.result_hints.has_key?(:overview_columns) ?
         | 
| 291 | 
            -
                        command.result_hints[:overview_columns].clone() :
         | 
| 292 | 
            -
                        # by default, we'll display all columns, sorted alphabetically
         | 
| 293 | 
            -
                        columns_to_display = response.data[0].keys.sort
         | 
| 294 | 
            -
                      
         | 
| 295 | 
            -
                      # and which titles they should have (default : column names)
         | 
| 296 | 
            -
                      $logger.debug "column titles : #{command.result_hints[:column_titles].length}"
         | 
| 297 | 
            -
                      column_title_list = command.result_hints[:column_titles].length > 0 ?
         | 
| 298 | 
            -
                        command.result_hints[:column_titles].clone() :
         | 
| 299 | 
            -
                        column_title_list = columns_to_display
         | 
| 300 | 
            -
                      $logger.debug "column title list : #{column_title_list}"
         | 
| 301 | 
            -
                      
         | 
| 302 | 
            -
                      # TODO the sorting column should be configurable
         | 
| 303 | 
            -
                      first_column = columns_to_display[0]
         | 
| 304 | 
            -
                      $logger.debug "sorting by #{first_column}"
         | 
| 305 | 
            -
                      response.data = response.data.sort { |a,b| a[first_column] <=> b[first_column] }          
         | 
| 306 | 
            -
                      
         | 
| 307 | 
            -
                      # add the index column
         | 
| 308 | 
            -
                      columns_to_display.unshift "__idx"
         | 
| 309 | 
            -
                      column_title_list.unshift "\#"
         | 
| 310 | 
            -
                      count = 1
         | 
| 311 | 
            -
                      response.data.each do |row|
         | 
| 312 | 
            -
                        row["__idx"] = count
         | 
| 313 | 
            -
                        count = count+1
         | 
| 314 | 
            -
                      end
         | 
| 315 | 
            -
                      
         | 
| 316 | 
            -
                      column_titles = {}
         | 
| 317 | 
            -
                      0.upto(column_title_list.length - 1) do |i|
         | 
| 318 | 
            -
                        column_titles[columns_to_display[i]] = column_title_list[i]
         | 
| 319 | 
            -
                      end
         | 
| 320 | 
            -
                      $logger.debug "column titles : #{column_titles}"
         | 
| 321 | 
            -
                      
         | 
| 322 | 
            -
                      # initialize the max_width for all columns
         | 
| 323 | 
            -
                      @max_width = {}
         | 
| 324 | 
            -
                      column_titles.each do |key, value|
         | 
| 325 | 
            -
                        @max_width[key] = 0
         | 
| 326 | 
            -
                      end
         | 
| 327 | 
            -
                      # find the maximum column width for each column
         | 
| 328 | 
            -
                      response.data.each do |row|
         | 
| 329 | 
            -
                        row.each do |k,v|
         | 
| 330 | 
            -
                          if ! @max_width.has_key?(k) || v.to_s.length >  @max_width[k]
         | 
| 331 | 
            -
                            @max_width[k] = v.to_s.length
         | 
| 332 | 
            -
                          end
         | 
| 333 | 
            -
                        end
         | 
| 334 | 
            -
                      end
         | 
| 335 | 
            -
                      
         | 
| 336 | 
            -
                      # check the column_title for max width
         | 
| 337 | 
            -
                      columns_to_display.each do |col_name|
         | 
| 338 | 
            -
                        if column_titles[col_name].length > @max_width[col_name]
         | 
| 339 | 
            -
                          @max_width[col_name] = column_titles[col_name].length
         | 
| 340 | 
            -
                        end
         | 
| 341 | 
            -
                      end
         | 
| 342 | 
            -
                      #@max_width["row_count"] = response.data.length.to_s.length
         | 
| 343 | 
            -
                      $logger.debug "max width : #{@max_width}"
         | 
| 344 | 
            -
                      
         | 
| 345 | 
            -
                      # and build headers
         | 
| 346 | 
            -
                      @total_width = 2 + columns_to_display.length-1 # separators at front and end of table and between the values
         | 
| 347 | 
            -
                      columns_to_display.each do |col|
         | 
| 348 | 
            -
                        @total_width += @max_width[col] + 2 # each column has a space in front and behind the value
         | 
| 349 | 
            -
                      end
         | 
| 350 | 
            -
                      output += print_line
         | 
| 351 | 
            -
                      
         | 
| 352 | 
            -
                      columns_to_display.each do |col|
         | 
| 353 | 
            -
                        output += print_cell(col, column_titles[col])
         | 
| 354 | 
            -
                      end
         | 
| 355 | 
            -
                      output += "|\n"
         | 
| 356 | 
            -
             | 
| 357 | 
            -
                      output += print_line
         | 
| 358 | 
            -
                      
         | 
| 359 | 
            -
                      # print the table values
         | 
| 360 | 
            -
                      response.data.each do |row|            
         | 
| 361 | 
            -
                        columns_to_display.each do |col|
         | 
| 362 | 
            -
                          output += print_cell(col, row[col])
         | 
| 363 | 
            -
                        end
         | 
| 364 | 
            -
                        output += "|\n"
         | 
| 365 | 
            -
                      end
         | 
| 366 | 
            -
                      output += print_line
         | 
| 367 | 
            -
                      
         | 
| 195 | 
            +
                      output = format_table_output(command, response)
         | 
| 368 196 | 
             
                      puts output
         | 
| 369 197 | 
             
                    elsif command.result_hints[:display_type] == "list"
         | 
| 370 198 | 
             
                      output = ""
         | 
| @@ -375,16 +203,35 @@ class RHCPShellBackend < ShellBackend | |
| 375 203 | 
             
                    elsif command.result_hints[:display_type] == "hidden"
         | 
| 376 204 | 
             
                      $logger.debug "suppressing output due to display_type 'hidden'"
         | 
| 377 205 | 
             
                    else
         | 
| 378 | 
            -
                      puts "executed '#{@command_selected.name}' successfully : #{response.data}"
         | 
| 206 | 
            +
                      puts "executed '#{@command_selected.name}' successfully : #{@prompt_color_enabled ? green(response.data) : response.data}"
         | 
| 207 | 
            +
                    end
         | 
| 208 | 
            +
                    
         | 
| 209 | 
            +
                    # if the command has been executed successfully, we might have to update the prompt
         | 
| 210 | 
            +
                    if @command_broker.context.cookies.has_key?('prompt')
         | 
| 211 | 
            +
                      set_prompt @command_broker.context.cookies['prompt']
         | 
| 379 212 | 
             
                    end
         | 
| 213 | 
            +
                    
         | 
| 380 214 | 
             
                  else
         | 
| 381 | 
            -
                     | 
| 215 | 
            +
                    if @command_selected.name == 'exit'
         | 
| 216 | 
            +
                      $logger.debug "exiting on user request"
         | 
| 217 | 
            +
                      Kernel.exit(0)
         | 
| 218 | 
            +
                    end
         | 
| 219 | 
            +
                    
         | 
| 220 | 
            +
                    puts "could not execute '#{@command_selected.name}' : #{@prompt_color_enabled ? red(response.error_text) : response.error_text}"
         | 
| 382 221 | 
             
                    $logger.error "#{response.error_text} : #{response.error_detail}"
         | 
| 222 | 
            +
                    
         | 
| 223 | 
            +
                    set_prompt nil
         | 
| 383 224 | 
             
                  end
         | 
| 384 225 | 
             
                  reset_to_command_mode
         | 
| 385 226 | 
             
                rescue
         | 
| 386 | 
            -
                   | 
| 387 | 
            -
                   | 
| 227 | 
            +
                  error = $!
         | 
| 228 | 
            +
                  if (error == "exit")
         | 
| 229 | 
            +
                    puts "exiting"
         | 
| 230 | 
            +
                    Kernel.exit
         | 
| 231 | 
            +
                  else
         | 
| 232 | 
            +
                    puts "got an error : >>#{$!}<<"
         | 
| 233 | 
            +
                    raise
         | 
| 234 | 
            +
                  end
         | 
| 388 235 | 
             
                end
         | 
| 389 236 | 
             
              end  
         | 
| 390 237 |  | 
| @@ -393,107 +240,103 @@ class RHCPShellBackend < ShellBackend | |
| 393 240 | 
             
              def process_input(command_line)
         | 
| 394 241 | 
             
                $logger.debug "processing input '#{command_line}'"
         | 
| 395 242 |  | 
| 396 | 
            -
                 | 
| 397 | 
            -
             | 
| 398 | 
            -
             | 
| 399 | 
            -
             | 
| 400 | 
            -
                   | 
| 401 | 
            -
             | 
| 402 | 
            -
             | 
| 403 | 
            -
             | 
| 404 | 
            -
                     | 
| 405 | 
            -
                     | 
| 406 | 
            -
             | 
| 407 | 
            -
             | 
| 408 | 
            -
                     | 
| 409 | 
            -
                       | 
| 410 | 
            -
             | 
| 411 | 
            -
                       | 
| 412 | 
            -
                      if  | 
| 413 | 
            -
                         | 
| 414 | 
            -
                         | 
| 415 | 
            -
                         | 
| 416 | 
            -
             | 
| 417 | 
            -
             | 
| 243 | 
            +
                # we might have to setup the context aware broker for this thread
         | 
| 244 | 
            +
                Thread.current['broker'] = @command_broker
         | 
| 245 | 
            +
                
         | 
| 246 | 
            +
                begin
         | 
| 247 | 
            +
                  if (@command_selected) then
         | 
| 248 | 
            +
                    # we're in parameter processing mode - so check which parameter 
         | 
| 249 | 
            +
                    # we've got now and switch modes if necessary
         | 
| 250 | 
            +
              
         | 
| 251 | 
            +
                    # we might have been waiting for multiple param values - check if the user finished
         | 
| 252 | 
            +
                    # adding values by selecting an empty string as value
         | 
| 253 | 
            +
                    if (@current_param.allows_multiple_values and command_line == "") then
         | 
| 254 | 
            +
                      $logger.debug "finished multiple parameter input mode for param #{@current_param.name}"
         | 
| 255 | 
            +
                      @missing_params.shift        
         | 
| 256 | 
            +
                      execute_command_if_possible
         | 
| 257 | 
            +
                    else       
         | 
| 258 | 
            +
                      accepted_params = add_parameter_value(command_line)
         | 
| 259 | 
            +
                      if accepted_params
         | 
| 260 | 
            +
                        # stop asking for more values if
         | 
| 261 | 
            +
                        # a) the parameter does not allow more than one value
         | 
| 262 | 
            +
                        # b) the user entered a wildcard parameter that has been expanded to multiple values
         | 
| 263 | 
            +
                        if (! @current_param.allows_multiple_values or accepted_params.length > 1) then
         | 
| 264 | 
            +
                          $logger.debug "finished parameter input mode for param #{@current_param.name}"
         | 
| 265 | 
            +
                          @missing_params.shift        
         | 
| 266 | 
            +
                          execute_command_if_possible
         | 
| 267 | 
            +
                        else
         | 
| 268 | 
            +
                          $logger.debug "param '#{@current_param.name}' expects multiple values...deferring mode switching"
         | 
| 269 | 
            +
                        end
         | 
| 418 270 | 
             
                      end
         | 
| 419 271 | 
             
                    end
         | 
| 420 | 
            -
                   | 
| 421 | 
            -
             | 
| 422 | 
            -
             | 
| 423 | 
            -
             | 
| 424 | 
            -
             | 
| 425 | 
            -
             | 
| 426 | 
            -
             | 
| 427 | 
            -
             | 
| 428 | 
            -
             | 
| 429 | 
            -
             | 
| 430 | 
            -
             | 
| 431 | 
            -
             | 
| 432 | 
            -
                      
         | 
| 433 | 
            -
             | 
| 434 | 
            -
             | 
| 435 | 
            -
             | 
| 436 | 
            -
            # | 
| 437 | 
            -
             | 
| 438 | 
            -
             | 
| 439 | 
            -
            #            $logger.debug "presetting global parameter '#{name}' to '#{values}'"
         | 
| 440 | 
            -
            #            values.each do |value|
         | 
| 441 | 
            -
            #              add_parameter_value(value)
         | 
| 442 | 
            -
            #            end
         | 
| 443 | 
            -
            #          end
         | 
| 444 | 
            -
            #        end
         | 
| 445 | 
            -
                    
         | 
| 446 | 
            -
                    # process the params specified on the command line          
         | 
| 447 | 
            -
                    if (params != nil) then            
         | 
| 448 | 
            -
                      params.each do |param|
         | 
| 449 | 
            -
                        if param =~ /(.+?)=(.+)/ then
         | 
| 450 | 
            -
                          # --> named param
         | 
| 451 | 
            -
                          key = $1
         | 
| 452 | 
            -
                          value = $2
         | 
| 453 | 
            -
                        else
         | 
| 454 | 
            -
                          # TODO if there's only one param, we can always use this as default param (maybe do this in the command?)
         | 
| 455 | 
            -
                          # --> unnamed param
         | 
| 456 | 
            -
                          value = param
         | 
| 457 | 
            -
                          default_param = @command_selected.default_param
         | 
| 458 | 
            -
                          if default_param != nil then
         | 
| 459 | 
            -
                            key = default_param.name
         | 
| 460 | 
            -
                            $logger.debug "collecting value '#{value}' for default param '#{default_param.name}'"
         | 
| 272 | 
            +
                  else
         | 
| 273 | 
            +
                    # we're waiting for the user to enter a command
         | 
| 274 | 
            +
                    # we might have a command with params
         | 
| 275 | 
            +
                    command, *params = command_line.split
         | 
| 276 | 
            +
                    $logger.debug "got command '#{command}' (params: #{params})"
         | 
| 277 | 
            +
              
         | 
| 278 | 
            +
                    # remember what the user specified so far
         | 
| 279 | 
            +
                    begin
         | 
| 280 | 
            +
                      @command_selected = @command_broker.get_command(command)
         | 
| 281 | 
            +
                      #if (@command_selected != nil) then
         | 
| 282 | 
            +
                      $logger.debug "command_selected: #{@command_selected}"
         | 
| 283 | 
            +
                        
         | 
| 284 | 
            +
                      # process the params specified on the command line          
         | 
| 285 | 
            +
                      if (params != nil) then            
         | 
| 286 | 
            +
                        params.each do |param|
         | 
| 287 | 
            +
                          if param =~ /(.+?)=(.+)/ then
         | 
| 288 | 
            +
                            # --> named param
         | 
| 289 | 
            +
                            key = $1
         | 
| 290 | 
            +
                            value = $2
         | 
| 461 291 | 
             
                          else
         | 
| 462 | 
            -
                             | 
| 292 | 
            +
                            # TODO if there's only one param, we can always use this as default param (maybe do this in the command?)
         | 
| 293 | 
            +
                            # --> unnamed param
         | 
| 294 | 
            +
                            value = param
         | 
| 295 | 
            +
                            default_param = @command_selected.default_param
         | 
| 296 | 
            +
                            if default_param != nil then
         | 
| 297 | 
            +
                              key = default_param.name
         | 
| 298 | 
            +
                              $logger.debug "collecting value '#{value}' for default param '#{default_param.name}'"
         | 
| 299 | 
            +
                            else
         | 
| 300 | 
            +
                              $logger.info "ignoring param '#{value}' because there's no default param"
         | 
| 301 | 
            +
                            end
         | 
| 463 302 | 
             
                          end
         | 
| 464 | 
            -
             | 
| 465 | 
            -
             | 
| 466 | 
            -
             | 
| 467 | 
            -
             | 
| 468 | 
            -
             | 
| 469 | 
            -
                             | 
| 470 | 
            -
             | 
| 471 | 
            -
                             | 
| 303 | 
            +
              
         | 
| 304 | 
            +
                          if key then
         | 
| 305 | 
            +
                            begin
         | 
| 306 | 
            +
                              @current_param = @command_selected.get_param(key)
         | 
| 307 | 
            +
                              add_parameter_value(value)
         | 
| 308 | 
            +
                            rescue RHCP::RhcpException => ex
         | 
| 309 | 
            +
                              puts "ignoring parameter value '#{value}' for param '#{key}' : " + ex.to_s
         | 
| 310 | 
            +
                            end
         | 
| 472 311 | 
             
                          end
         | 
| 473 312 | 
             
                        end
         | 
| 474 313 | 
             
                      end
         | 
| 314 | 
            +
                                  
         | 
| 315 | 
            +
                      $logger.debug "selected command #{@command_selected.name}" 
         | 
| 316 | 
            +
                      execute_command_if_possible
         | 
| 317 | 
            +
                    rescue RHCP::RhcpException => ex
         | 
| 318 | 
            +
                      puts "#{ex}"
         | 
| 319 | 
            +
                      reset_to_command_mode
         | 
| 475 320 | 
             
                    end
         | 
| 476 | 
            -
                                
         | 
| 477 | 
            -
                    $logger.debug "selected command #{@command_selected.name}" 
         | 
| 478 | 
            -
                    execute_command_if_possible
         | 
| 479 | 
            -
                  rescue RHCP::RhcpException => ex
         | 
| 480 | 
            -
                    puts "#{ex}"
         | 
| 481 321 | 
             
                  end
         | 
| 322 | 
            +
                rescue RHCP::RhcpException => ex
         | 
| 323 | 
            +
                  $logger.error ex
         | 
| 324 | 
            +
                  puts "exception raised: #{ex.to_s}"
         | 
| 325 | 
            +
                  reset_to_command_mode
         | 
| 482 326 | 
             
                end
         | 
| 483 | 
            -
             rescue => err
         | 
| 484 | 
            -
               $logger.error err
         | 
| 485 | 
            -
                puts "exception raised: #{err.to_s}"
         | 
| 486 327 | 
             
              end
         | 
| 487 328 |  | 
| 488 329 | 
             
              def complete(word = "")
         | 
| 489 | 
            -
                $logger.debug " | 
| 330 | 
            +
                $logger.debug "collecting completion values for '#{word}'"
         | 
| 331 | 
            +
                
         | 
| 332 | 
            +
                Thread.current['broker'] = @command_broker
         | 
| 490 333 |  | 
| 491 334 | 
             
                if (@command_selected) then
         | 
| 492 | 
            -
                  #  | 
| 493 | 
            -
                   | 
| 494 | 
            -
                   | 
| 335 | 
            +
                  $logger.debug("asking for lookup values for command '#{@command_selected.name}' and param '#{@current_param.name}'")
         | 
| 336 | 
            +
                  request = RHCP::Request.new(@command_selected, @collected_values, @command_broker.context)
         | 
| 337 | 
            +
                  props = @lookup_broker.get_lookup_values(request, @current_param.name)
         | 
| 495 338 | 
             
                else
         | 
| 496 | 
            -
                  props = @ | 
| 339 | 
            +
                  props = @lookup_broker.get_command_list(@command_broker.context).values.map{|command| command.name}.sort
         | 
| 497 340 | 
             
                end
         | 
| 498 341 |  | 
| 499 342 | 
             
                proposal_list = props.map { |p| "'#{p}'" }.join(" ")
         | 
| @@ -503,12 +346,23 @@ class RHCPShellBackend < ShellBackend | |
| 503 346 | 
             
                props.select{|name|name[0...(prefix.size)] == prefix}
         | 
| 504 347 | 
             
              end
         | 
| 505 348 |  | 
| 506 | 
            -
            def show_banner
         | 
| 349 | 
            +
              def show_banner
         | 
| 507 350 | 
             
                puts @banner
         | 
| 508 351 | 
             
              end
         | 
| 509 352 |  | 
| 353 | 
            +
              require 'util/colorize'
         | 
| 354 | 
            +
              
         | 
| 355 | 
            +
              def prompt
         | 
| 356 | 
            +
                if @current_param != nil
         | 
| 357 | 
            +
                  "#{@command_selected.name}.#{@current_param.name} $ "
         | 
| 358 | 
            +
                else    
         | 
| 359 | 
            +
                  @current_prompt || "$ "
         | 
| 360 | 
            +
                  #"#{@current_prompt and @current_prompt != '' ? @current_prompt + " " : ""}$ "
         | 
| 361 | 
            +
                end
         | 
| 362 | 
            +
              end
         | 
| 363 | 
            +
              
         | 
| 510 364 | 
             
              def set_prompt(string)
         | 
| 511 | 
            -
                @ | 
| 365 | 
            +
                @current_prompt = string    
         | 
| 512 366 | 
             
              end
         | 
| 513 367 |  | 
| 514 368 | 
             
              def process_ctrl_c
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            def colorize(text, color_code)
         | 
| 2 | 
            +
              "\e[#{color_code}m#{text}\e[0m"
         | 
| 3 | 
            +
            end
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            def red(text)
         | 
| 6 | 
            +
              colorize(text, 31)
         | 
| 7 | 
            +
            end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            def green(text)
         | 
| 10 | 
            +
              colorize(text, 32)
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            # Actual example
         | 
| 14 | 
            +
            #puts 'Importing categories [ ' + green('DONE') + ' ]'
         | 
| 15 | 
            +
            #puts 'Importing tags       [' + red('FAILED') + ']'
         | 
    
        data/lib/version.rb
    CHANGED
    
    
| @@ -50,7 +50,7 @@ class RhcpShellBackendTest < Test::Unit::TestCase | |
| 50 50 |  | 
| 51 51 | 
             
              def setup
         | 
| 52 52 | 
             
                # set up a local broker that we'll use for testing
         | 
| 53 | 
            -
                # TODO do something about this - it shouldn't be necessary to instantiate  | 
| 53 | 
            +
                # TODO do something about this - it shouldn't be necessary to instantiate the logger beforehand
         | 
| 54 54 | 
             
                $logger = Logger.new($stdout)
         | 
| 55 55 | 
             
                @log = Array.new()
         | 
| 56 56 | 
             
                @backend = BackendMock.new($broker, self.method(:add_to_log))
         | 
| @@ -127,6 +127,8 @@ class RhcpShellBackendTest < Test::Unit::TestCase | |
| 127 127 | 
             
                commands << "help"
         | 
| 128 128 | 
             
                commands << "exit"
         | 
| 129 129 | 
             
                commands << "detail"
         | 
| 130 | 
            +
                commands << "show_context"
         | 
| 131 | 
            +
                commands << "set_prompt"
         | 
| 130 132 | 
             
                assert_equal commands.sort, @backend.complete.sort
         | 
| 131 133 | 
             
                assert_no_error
         | 
| 132 134 | 
             
              end
         | 
| @@ -138,7 +140,7 @@ class RhcpShellBackendTest < Test::Unit::TestCase | |
| 138 140 |  | 
| 139 141 | 
             
              def test_invalid_param_value
         | 
| 140 142 | 
             
                @backend.process_input "reverse input=bla"
         | 
| 141 | 
            -
                assert_received [ "invalid value 'bla' for parameter 'input'" ]
         | 
| 143 | 
            +
                assert_received [ "ignoring parameter value 'bla' for param 'input' : invalid value 'bla' for parameter 'input'" ]
         | 
| 142 144 | 
             
              end
         | 
| 143 145 |  | 
| 144 146 | 
             
              def test_multi_params
         | 
| @@ -164,24 +166,25 @@ class RhcpShellBackendTest < Test::Unit::TestCase | |
| 164 166 | 
             
                @backend.process_input "perpetuum_mobile"
         | 
| 165 167 | 
             
                assert_received [ "could not execute 'perpetuum_mobile' : don't know how to do this" ]
         | 
| 166 168 | 
             
              end
         | 
| 167 | 
            -
             | 
| 168 | 
            -
              def test_wildcard_support
         | 
| 169 | 
            -
                @backend.process_input "cook ingredient=m*"
         | 
| 170 | 
            -
                assert_received [ "executed 'cook' successfully : mascarpone marzipan" ]
         | 
| 171 | 
            -
              end
         | 
| 172 | 
            -
              
         | 
| 169 | 
            +
             | 
| 173 170 | 
             
              def test_preprocess_without_lookup_values
         | 
| 174 171 | 
             
                @backend.process_input "test thoroughly=yes"
         | 
| 175 172 | 
             
                assert_no_error
         | 
| 176 173 | 
             
              end
         | 
| 177 | 
            -
             | 
| 178 | 
            -
             | 
| 179 | 
            -
             | 
| 180 | 
            -
                 | 
| 181 | 
            -
                
         | 
| 182 | 
            -
             | 
| 183 | 
            -
             | 
| 184 | 
            -
               | 
| 174 | 
            +
             | 
| 175 | 
            +
            # TODO reactivate wildcards
         | 
| 176 | 
            +
            #  def test_wildcard_support
         | 
| 177 | 
            +
            #    @backend.process_input "cook ingredient=m*"
         | 
| 178 | 
            +
            #    assert_received [ "executed 'cook' successfully : mascarpone marzipan" ]
         | 
| 179 | 
            +
            #  end
         | 
| 180 | 
            +
            #
         | 
| 181 | 
            +
            #  def test_wildcard_ranges
         | 
| 182 | 
            +
            #    @backend.process_input "echo input=string01..05"
         | 
| 183 | 
            +
            #    assert_received [ "executed 'echo' successfully : string01 string02 string03 string04 string05" ]
         | 
| 184 | 
            +
            #
         | 
| 185 | 
            +
            #    @backend.process_input "echo input=string17..20"
         | 
| 186 | 
            +
            #    assert_received [ "executed 'echo' successfully : string17 string18 string19 string20" ]
         | 
| 187 | 
            +
            #  end
         | 
| 185 188 |  | 
| 186 189 | 
             
              def test_help
         | 
| 187 190 | 
             
                @backend.process_input "help"
         | 
| @@ -196,7 +199,7 @@ class RhcpShellBackendTest < Test::Unit::TestCase | |
| 196 199 | 
             
                @backend.process_input "help cook"
         | 
| 197 200 | 
             
                puts "LOG >>#{@log}<<"
         | 
| 198 201 | 
             
                assert_log_contains "Syntax:"
         | 
| 199 | 
            -
                assert_log_contains "cook ingredient=<value | 
| 202 | 
            +
                assert_log_contains "cook ingredient=<value> ingredient=<value2> ..."
         | 
| 200 203 | 
             
              end
         | 
| 201 204 |  | 
| 202 205 | 
             
              def test_help_with_default_param
         | 
| @@ -267,5 +270,39 @@ class RhcpShellBackendTest < Test::Unit::TestCase | |
| 267 270 | 
             
            #  ./virtualop_rhcp.rb:131:in `setup_local_shell'
         | 
| 268 271 | 
             
            #  ./virtualop_rhcp.rb:168
         | 
| 269 272 | 
             
            #  exception raised: comparison of Fixnum with nil failed
         | 
| 273 | 
            +
             | 
| 274 | 
            +
              # say_hello should be workable with normal parameters
         | 
| 275 | 
            +
              def test_context_handling_normal_parameter
         | 
| 276 | 
            +
                @backend.command_broker.context.cookies.clear
         | 
| 277 | 
            +
                @backend.process_input "say_hello the_host=zaphod"
         | 
| 278 | 
            +
                assert_received [ "executed 'say_hello' successfully : hello from zaphod" ]
         | 
| 279 | 
            +
              end
         | 
| 280 | 
            +
             | 
| 281 | 
            +
              def test_command_completion_with_context
         | 
| 282 | 
            +
                # we should not see let_explode_host, but both say_hello and switch_host
         | 
| 283 | 
            +
                assert @backend.complete.select { |command| command == "say_hello" }.size() > 0
         | 
| 284 | 
            +
                assert @backend.complete.select { |command| command == "switch_host" }.size() > 0
         | 
| 285 | 
            +
                assert @backend.complete.select { |command| command == "let_explode_host" }.size() == 0
         | 
| 286 | 
            +
             | 
| 287 | 
            +
                # test if this changes with context
         | 
| 288 | 
            +
                @backend.process_input "switch_host new_host=serenity"
         | 
| 289 | 
            +
                assert @backend.complete.select { |command| command == "let_explode_host" }.size() > 0
         | 
| 290 | 
            +
              end
         | 
| 291 | 
            +
             | 
| 292 | 
            +
              def test_context_handling
         | 
| 293 | 
            +
                # context values should be usable by commands
         | 
| 294 | 
            +
                @backend.process_input "switch_host new_host=serenity"
         | 
| 295 | 
            +
                #@backend.context['host'] = 'serenity'
         | 
| 296 | 
            +
                @backend.process_input "say_hello"
         | 
| 297 | 
            +
                assert_received [ "executed 'say_hello' successfully : hello from serenity" ]
         | 
| 298 | 
            +
              end
         | 
| 299 | 
            +
             | 
| 300 | 
            +
              def test_command_setting_context
         | 
| 301 | 
            +
                @backend.process_input "switch_host new_host=moon"
         | 
| 302 | 
            +
                @backend.process_input "say_hello"
         | 
| 303 | 
            +
                assert_received [ "executed 'switch_host' successfully : hostmoon",
         | 
| 304 | 
            +
                                  "executed 'say_hello' successfully : hello from moon" ]
         | 
| 305 | 
            +
              end
         | 
| 306 | 
            +
             | 
| 270 307 |  | 
| 271 308 | 
             
            end
         | 
    
        data/test/setup_test_registry.rb
    CHANGED
    
    | @@ -112,4 +112,40 @@ broker.register_command command2 | |
| 112 112 |  | 
| 113 113 | 
             
            p broker.get_command("build_a_table")
         | 
| 114 114 |  | 
| 115 | 
            +
             | 
| 116 | 
            +
            switch_host = RHCP::Command.new("switch_host", "modifies the context",
         | 
| 117 | 
            +
              lambda { |request, response|
         | 
| 118 | 
            +
                response.set_context({'host' => request.get_param_value('new_host')})
         | 
| 119 | 
            +
              }
         | 
| 120 | 
            +
            )
         | 
| 121 | 
            +
            switch_host.add_param(RHCP::CommandParam.new("new_host", "the new host name",
         | 
| 122 | 
            +
                {
         | 
| 123 | 
            +
                  :mandatory => true,
         | 
| 124 | 
            +
                  :is_default_param => true,
         | 
| 125 | 
            +
                }
         | 
| 126 | 
            +
            ))
         | 
| 127 | 
            +
            broker.register_command switch_host
         | 
| 128 | 
            +
             | 
| 129 | 
            +
            host_command = RHCP::Command.new("say_hello", "uses context",
         | 
| 130 | 
            +
              lambda { |request, response|
         | 
| 131 | 
            +
                "hello from " + request.get_param_value('the_host')
         | 
| 132 | 
            +
              }
         | 
| 133 | 
            +
            )
         | 
| 134 | 
            +
            host_command.add_param(RHCP::CommandParam.new("the_host", "the host name (should be taken from context)",
         | 
| 135 | 
            +
                {
         | 
| 136 | 
            +
                  :mandatory => true,
         | 
| 137 | 
            +
                  :is_default_param => true,
         | 
| 138 | 
            +
                  :autofill_context_key => 'host'
         | 
| 139 | 
            +
                }
         | 
| 140 | 
            +
            ))
         | 
| 141 | 
            +
            broker.register_command host_command
         | 
| 142 | 
            +
             | 
| 143 | 
            +
            context_command = RHCP::Command.new("let_explode_host", "available only in host context",
         | 
| 144 | 
            +
              lambda { |request, response|
         | 
| 145 | 
            +
                "kaboom."
         | 
| 146 | 
            +
              }
         | 
| 147 | 
            +
            )
         | 
| 148 | 
            +
            context_command.enabled_through_context_keys = ['host']
         | 
| 149 | 
            +
            broker.register_command context_command
         | 
| 150 | 
            +
             | 
| 115 151 | 
             
            $broker = broker
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,13 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: rhcp_shell
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
               | 
| 4 | 
            +
              hash: 1
         | 
| 5 | 
            +
              prerelease: false
         | 
| 6 | 
            +
              segments: 
         | 
| 7 | 
            +
              - 0
         | 
| 8 | 
            +
              - 2
         | 
| 9 | 
            +
              - 11
         | 
| 10 | 
            +
              version: 0.2.11
         | 
| 5 11 | 
             
            platform: ruby
         | 
| 6 12 | 
             
            authors: 
         | 
| 7 13 | 
             
            - Philipp Traeder
         | 
| @@ -9,19 +15,25 @@ autorequire: | |
| 9 15 | 
             
            bindir: bin
         | 
| 10 16 | 
             
            cert_chain: []
         | 
| 11 17 |  | 
| 12 | 
            -
            date:  | 
| 18 | 
            +
            date: 2011-07-26 00:00:00 +00:00
         | 
| 13 19 | 
             
            default_executable: 
         | 
| 14 20 | 
             
            dependencies: 
         | 
| 15 21 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 16 22 | 
             
              name: rhcp
         | 
| 17 | 
            -
               | 
| 18 | 
            -
               | 
| 19 | 
            -
             | 
| 23 | 
            +
              prerelease: false
         | 
| 24 | 
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 25 | 
            +
                none: false
         | 
| 20 26 | 
             
                requirements: 
         | 
| 21 27 | 
             
                - - ">="
         | 
| 22 28 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 29 | 
            +
                    hash: 9
         | 
| 30 | 
            +
                    segments: 
         | 
| 31 | 
            +
                    - 0
         | 
| 32 | 
            +
                    - 1
         | 
| 33 | 
            +
                    - 9
         | 
| 23 34 | 
             
                    version: 0.1.9
         | 
| 24 | 
            -
             | 
| 35 | 
            +
              type: :runtime
         | 
| 36 | 
            +
              version_requirements: *id001
         | 
| 25 37 | 
             
            description: 
         | 
| 26 38 | 
             
            email: philipp at hitchhackers.net
         | 
| 27 39 | 
             
            executables: 
         | 
| @@ -31,39 +43,55 @@ extensions: [] | |
| 31 43 | 
             
            extra_rdoc_files: []
         | 
| 32 44 |  | 
| 33 45 | 
             
            files: 
         | 
| 46 | 
            +
            - bin/rhcp_shell.log
         | 
| 34 47 | 
             
            - bin/rhcp_shell
         | 
| 48 | 
            +
            - lib/util/colorize.rb
         | 
| 35 49 | 
             
            - lib/shell_backend.rb
         | 
| 50 | 
            +
            - lib/version.rb
         | 
| 51 | 
            +
            - lib/rhcp_shell_backend.rb
         | 
| 36 52 | 
             
            - lib/base_shell.rb
         | 
| 53 | 
            +
            - lib/display_types/table.rb
         | 
| 37 54 | 
             
            - lib/test.log
         | 
| 38 | 
            -
            - lib/ | 
| 39 | 
            -
            - lib/ | 
| 40 | 
            -
            -  | 
| 55 | 
            +
            - lib/local_commands/context.rb
         | 
| 56 | 
            +
            - lib/local_commands/set_prompt.rb
         | 
| 57 | 
            +
            - lib/local_commands/help.rb
         | 
| 58 | 
            +
            - lib/local_commands/exit.rb
         | 
| 59 | 
            +
            - lib/local_commands/detail.rb
         | 
| 41 60 | 
             
            - test/setup_test_registry.rb
         | 
| 61 | 
            +
            - test/rhcp_shell_backend_test.rb
         | 
| 42 62 | 
             
            has_rdoc: true
         | 
| 43 63 | 
             
            homepage: http://rubyforge.org/projects/rhcp
         | 
| 64 | 
            +
            licenses: []
         | 
| 65 | 
            +
             | 
| 44 66 | 
             
            post_install_message: 
         | 
| 45 67 | 
             
            rdoc_options: []
         | 
| 46 68 |  | 
| 47 69 | 
             
            require_paths: 
         | 
| 48 70 | 
             
            - lib
         | 
| 49 71 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 72 | 
            +
              none: false
         | 
| 50 73 | 
             
              requirements: 
         | 
| 51 74 | 
             
              - - ">="
         | 
| 52 75 | 
             
                - !ruby/object:Gem::Version 
         | 
| 76 | 
            +
                  hash: 3
         | 
| 77 | 
            +
                  segments: 
         | 
| 78 | 
            +
                  - 0
         | 
| 53 79 | 
             
                  version: "0"
         | 
| 54 | 
            -
              version: 
         | 
| 55 80 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 81 | 
            +
              none: false
         | 
| 56 82 | 
             
              requirements: 
         | 
| 57 83 | 
             
              - - ">="
         | 
| 58 84 | 
             
                - !ruby/object:Gem::Version 
         | 
| 85 | 
            +
                  hash: 3
         | 
| 86 | 
            +
                  segments: 
         | 
| 87 | 
            +
                  - 0
         | 
| 59 88 | 
             
                  version: "0"
         | 
| 60 | 
            -
              version: 
         | 
| 61 89 | 
             
            requirements: []
         | 
| 62 90 |  | 
| 63 91 | 
             
            rubyforge_project: rhcp
         | 
| 64 | 
            -
            rubygems_version: 1.3. | 
| 92 | 
            +
            rubygems_version: 1.3.7
         | 
| 65 93 | 
             
            signing_key: 
         | 
| 66 | 
            -
            specification_version:  | 
| 94 | 
            +
            specification_version: 3
         | 
| 67 95 | 
             
            summary: RHCP is a protocol designed for building up a command-metadata-based communication infrastructure making it easier for application developers to export commands in applications to generic clients - this is the generic shell for it.
         | 
| 68 96 | 
             
            test_files: []
         | 
| 69 97 |  |