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 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
- else
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
@@ -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
- @thread.join
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,9 @@
1
+ def add_exit_command(broker)
2
+ broker.register_command RHCP::Command.new("exit", "closes the shell",
3
+ lambda { |req,res|
4
+ puts "Have a nice day"
5
+ #self.process_ctrl_c
6
+ Kernel.exit(0)
7
+ }
8
+ )
9
+ 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
@@ -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
- @command_broker = RHCP::DispatchingBroker.new()
29
- @command_broker.add_broker(command_broker)
30
- @command_broker.add_broker(local_broker)
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.register_command RHCP::Command.new("exit", "closes the shell",
39
- lambda { |req,res|
40
- puts "Have a nice day"
41
- Kernel.exit(0)
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
- @collected_params = Hash.new
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.params.select { |name,param| param.mandatory }.map { |k,v| v }
179
- @missing_params = mandatory_params.select { |p| ! @collected_params.include? p.name }
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 (x..y)
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
- lookup_values = @current_param.get_lookup_values()
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
- processed_param_values = pre_process_param_value(new_value)
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
- #processed_param_values = [ new_value ]
167
+
243
168
  processed_param_values.each do |value|
244
- # TODO we need to pass a value array here, and we should include the already selected param values
245
- @current_param.check_param_is_valid([ value ])
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
- @collected_params[@current_param.name] = Array.new if @collected_params[@current_param.name] == nil
249
- @collected_params[@current_param.name] << value
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 = @command_broker.get_command(@command_selected.name)
274
- request = RHCP::Request.new(command, @collected_params)
275
- response = command.execute_request(request)
276
- @last_response = response # we might want to access this response in further commands
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
- $logger.debug "result hints: #{command.result_hints}"
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
- # TODO make sure that the response really holds the correct data types and that we've got at least one column
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
- puts "could not execute '#{@command_selected.name}' : #{response.error_text}"
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
- puts "got an error : #{$!}"
387
- raise
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
- if (@command_selected) then
397
- # we're in parameter processing mode - so check which parameter
398
- # we've got now and switch modes if necessary
399
-
400
- # we might have been waiting for multiple param values - check if the user finished
401
- # adding values by selecting an empty string as value
402
- if (@current_param.allows_multiple_values and command_line == "") then
403
- $logger.debug "finished multiple parameter input mode for param #{@current_param.name}"
404
- @missing_params.shift
405
- execute_command_if_possible
406
- else
407
- accepted_params = add_parameter_value(command_line)
408
- if accepted_params
409
- # stop asking for more values if
410
- # a) the parameter does not allow more than one value
411
- # b) the user entered a wildcard parameter that has been expanded to multiple values
412
- if (! @current_param.allows_multiple_values or accepted_params.length > 1) then
413
- $logger.debug "finished parameter input mode for param #{@current_param.name}"
414
- @missing_params.shift
415
- execute_command_if_possible
416
- else
417
- $logger.debug "param '#{@current_param.name}' expects multiple values...deferring mode switching"
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
- end
421
- else
422
- # we're waiting for the user to enter a command
423
- # we might have a command with params
424
- command, *params = command_line.split
425
- $logger.debug "got command '#{command}' (params: #{params})"
426
-
427
- # remember what the user specified so far
428
- begin
429
- @command_selected = @command_broker.get_command(command)
430
- #if (@command_selected != nil) then
431
- $logger.debug "command_selected: #{@command_selected}"
432
-
433
- # apply the preset param values to this new command
434
- # TODO reactivate parameter presets
435
- # @command_broker.get_global_parameter_presets().each do |name, values|
436
- # # check if the selected command needs this param
437
- # @current_param = @command_broker.get_param(command, name)
438
- # if @current_param and not @current_param.ignore_global_presets then
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
- $logger.info "ignoring param '#{value}' because there's no default param"
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
- end
465
-
466
- if key then
467
- begin
468
- @current_param = @command_selected.get_param(key)
469
- add_parameter_value(value)
470
- rescue RHCP::RhcpException => ex
471
- puts ex.to_s
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 "collection completion values for '#{word}'"
330
+ $logger.debug "collecting completion values for '#{word}'"
331
+
332
+ Thread.current['broker'] = @command_broker
490
333
 
491
334
  if (@command_selected) then
492
- # TODO include partial_value here?
493
- props = @command_selected.params[@current_param.name].get_lookup_values()
494
- #props = @command_broker.get_lookup_values(@command_selected.name, @current_param.name)
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 = @command_broker.get_command_list.values.map{|command| command.name}.sort
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
- @prompt = "#{string ? string + " " : ""}$ "
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
@@ -4,8 +4,8 @@ module RhcpShell #:nodoc:
4
4
  include Singleton
5
5
 
6
6
  MAJOR = 0
7
- MINOR = 0
8
- TINY = 9
7
+ MINOR = 2
8
+ TINY = 11
9
9
 
10
10
  def Version.to_s
11
11
  [ MAJOR, MINOR, TINY ].join(".")
@@ -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 this beforehand
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
- def test_wildcard_ranges
179
- @backend.process_input "echo input=string01..05"
180
- assert_received [ "executed 'echo' successfully : string01 string02 string03 string04 string05" ]
181
-
182
- @backend.process_input "echo input=string17..20"
183
- assert_received [ "executed 'echo' successfully : string17 string18 string19 string20" ]
184
- end
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>, ingredient=<value2>, ..."
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
@@ -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
- version: 0.0.9
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: 2009-10-15 00:00:00 +02:00
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
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
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
- version:
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/rhcp_shell_backend.rb
39
- - lib/version.rb
40
- - test/rhcp_shell_backend_test.rb
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.1
92
+ rubygems_version: 1.3.7
65
93
  signing_key:
66
- specification_version: 2
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