rhcp_shell 0.0.9 → 0.2.11

Sign up to get free protection for your applications and to get access to all the features.
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