Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Handle ctrl-c and ctrl-d in rails console

Change-Id: I1fe7f501aa11b47c99d4f56c3a13b756bde2780d
  • Loading branch information...
commit 1f3d1f3e23576b358973cb8d021834800f213338 1 parent 6c08b76
Jennifer Hickey authored
30 lib/cli/console_helper.rb
@@ -105,29 +105,31 @@ def telnet_client(port)
105 105 end
106 106
107 107 def readline_with_history(prompt)
108   - line = Readline.readline(prompt, true)
109   - return '' if line.nil?
110   - #Don't keep blank or repeat commands in history
111   - if line =~ /^\s*$/ or Readline::HISTORY.to_a[-2] == line
112   - Readline::HISTORY.pop
113   - end
  108 + line = Readline::readline(prompt)
  109 + return nil if line == nil || line == 'quit' || line == 'exit'
  110 + Readline::HISTORY.push(line) if not line =~ /^\s*$/ and Readline::HISTORY.to_a[-1] != line
114 111 line
115 112 end
116 113
117 114 def run_console(prompt)
118   - while(cmd = readline_with_history(prompt))
119   - if(cmd == "exit" || cmd == "quit")
120   - #TimeoutError expected, as exit doesn't return anything
121   - @telnet_client.cmd("String"=>cmd,"Timeout"=>1) rescue TimeoutError
122   - close_console
  115 + prev = trap("INT") { |x| exit_console; prev.call(x); exit }
  116 + prev = trap("TERM") { |x| exit_console; prev.call(x); exit }
  117 + loop do
  118 + cmd = readline_with_history(prompt)
  119 + if(cmd == nil)
  120 + exit_console
123 121 break
124 122 end
125   - if !cmd.empty?
126   - prompt = send_console_command_display_results(cmd, prompt)
127   - end
  123 + prompt = send_console_command_display_results(cmd, prompt)
128 124 end
129 125 end
130 126
  127 + def exit_console
  128 + #TimeoutError expected, as exit doesn't return anything
  129 + @telnet_client.cmd("String"=>"exit","Timeout"=>1) rescue TimeoutError
  130 + close_console
  131 + end
  132 +
131 133 def send_console_command_display_results(cmd, prompt)
132 134 begin
133 135 lines = send_console_command cmd
47 spec/unit/console_helper_spec.rb
@@ -69,7 +69,7 @@
69 69 it 'should start console and process a command if authentication succeeds' do
70 70 @client.should_receive(:app_files).with("foo", '/app/cf-rails-console/.consoleaccess', '0').and_return(IO.read(spec_asset('console_access.txt')))
71 71 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("Switch to inspect mode\nirb():001:0> ")
72   - exit_console "irb():001:0> "
  72 + verify_console_exit "irb():001:0> "
73 73 start_local_console(3344,'foo')
74 74 end
75 75
@@ -101,7 +101,7 @@
101 101 @client.should_receive(:app_files).with("foo", '/app/cf-rails-console/.consoleaccess', '0').and_return(IO.read(spec_asset('console_access.txt')))
102 102 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_raise(TimeoutError)
103 103 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("Switch to inspect mode\nirb():001:0> ")
104   - exit_console "irb():001:0> "
  104 + verify_console_exit "irb():001:0> "
105 105 start_local_console(3344,'foo')
106 106 end
107 107
@@ -110,32 +110,35 @@
110 110 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_raise(EOFError)
111 111 @telnet_client.should_receive(:close)
112 112 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("irb():001:0> ")
113   - exit_console "irb():001:0> "
  113 + verify_console_exit "irb():001:0> "
114 114 start_local_console(3344,'foo')
115 115 end
116 116
117 117 it 'should operate console interactively' do
118 118 @client.should_receive(:app_files).with("foo", '/app/cf-rails-console/.consoleaccess', '0').and_return(IO.read(spec_asset('console_access.txt')))
119 119 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("irb():001:0> ")
120   - Readline.should_receive(:readline).with("irb():001:0> ",true).and_return("puts 'hi'")
  120 + Readline.should_receive(:readline).with("irb():001:0> ").and_return("puts 'hi'")
  121 + Readline::HISTORY.should_receive(:push).with("puts 'hi'")
121 122 @telnet_client.should_receive(:cmd).with("puts 'hi'").and_return("nil" + "\n" + "irb():002:0> ")
122   - exit_console "irb():002:0> "
  123 + verify_console_exit "irb():002:0> "
123 124 start_local_console(3344,'foo')
124 125 end
125 126
126 127 it 'should not crash if command times out' do
127 128 @client.should_receive(:app_files).with("foo", '/app/cf-rails-console/.consoleaccess', '0').and_return(IO.read(spec_asset('console_access.txt')))
128 129 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("irb():001:0> ")
129   - Readline.should_receive(:readline).with("irb():001:0> ",true).and_return("puts 'hi'")
  130 + Readline.should_receive(:readline).with("irb():001:0> ").and_return("puts 'hi'")
  131 + Readline::HISTORY.should_receive(:push).with("puts 'hi'")
130 132 @telnet_client.should_receive(:cmd).with("puts 'hi'").and_raise(TimeoutError)
131   - exit_console "irb():001:0> "
  133 + verify_console_exit "irb():001:0> "
132 134 start_local_console(3344,'foo')
133 135 end
134 136
135 137 it 'should exit with error message if an EOF is received' do
136 138 @client.should_receive(:app_files).with("foo", '/app/cf-rails-console/.consoleaccess', '0').and_return(IO.read(spec_asset('console_access.txt')))
137 139 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("Switch to inspect mode\nirb():001:0> ")
138   - Readline.should_receive(:readline).with("irb():001:0> ",true).and_return("puts 'hi'")
  140 + Readline.should_receive(:readline).with("irb():001:0> ").and_return("puts 'hi'")
  141 + Readline::HISTORY.should_receive(:push).with("puts 'hi'")
139 142 @telnet_client.should_receive(:cmd).with("puts 'hi'").and_raise(EOFError)
140 143 errmsg = nil
141 144 begin
@@ -147,24 +150,24 @@
147 150 "Perhaps the app was stopped or deleted?"
148 151 end
149 152
150   - it 'should not process blank input lines' do
  153 + it 'should not keep blank lines in history' do
151 154 @client.should_receive(:app_files).with("foo", '/app/cf-rails-console/.consoleaccess', '0').and_return(IO.read(spec_asset('console_access.txt')))
152 155 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("irb():001:0> ")
153   - Readline.should_receive(:readline).with("irb():001:0> ",true).and_return("")
154   - Readline::HISTORY.should_receive(:pop)
155   - exit_console "irb():001:0> "
  156 + Readline.should_receive(:readline).with("irb():001:0> ").and_return("")
  157 + Readline::HISTORY.should_not_receive(:push).with("")
  158 + @telnet_client.should_receive(:cmd).with("").and_return("irb():002:0*> ")
  159 + verify_console_exit "irb():002:0*> "
156 160 start_local_console(3344,'foo')
157 161 end
158 162
159 163 it 'should not keep identical commands in history' do
160 164 @client.should_receive(:app_files).with("foo", '/app/cf-rails-console/.consoleaccess', '0').and_return(IO.read(spec_asset('console_access.txt')))
161 165 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("irb():001:0> ")
162   - Readline::HISTORY.should_receive(:to_a).and_return(["puts 'hi'","puts 'hi'"])
  166 + Readline.should_receive(:readline).with("irb():001:0> ").and_return("puts 'hi'")
163 167 Readline::HISTORY.should_receive(:to_a).and_return(["puts 'hi'"])
164   - Readline.should_receive(:readline).with("irb():001:0> ",true).and_return("puts 'hi'")
  168 + Readline::HISTORY.should_not_receive(:push).with("puts 'hi'")
165 169 @telnet_client.should_receive(:cmd).with("puts 'hi'").and_return("nil" + "\n" + "irb():002:0> ")
166   - Readline::HISTORY.should_receive(:pop)
167   - exit_console "irb():002:0> "
  170 + verify_console_exit "irb():002:0> "
168 171 start_local_console(3344,'foo')
169 172 end
170 173
@@ -172,7 +175,7 @@
172 175 @client.should_receive(:app_files).with("foo", '/app/cf-rails-console/.consoleaccess', '0').and_return(IO.read(spec_asset('console_access.txt')))
173 176 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("Switch to inspect mode\nirb():001:0> ")
174 177 @telnet_client.should_receive(:cmd).with({"String"=>"app.\t", "Match"=>/\S*\n$/, "Timeout"=>10}).and_return("to_s,nil?\n")
175   - exit_console "irb():001:0> "
  178 + verify_console_exit "irb():001:0> "
176 179 start_local_console(3344,'foo')
177 180 Readline.completion_proc.yield("app.").should == ["to_s","nil?"]
178 181 end
@@ -181,7 +184,7 @@
181 184 @client.should_receive(:app_files).with("foo", '/app/cf-rails-console/.consoleaccess', '0').and_return(IO.read(spec_asset('console_access.txt')))
182 185 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("irb():001:0> ")
183 186 @telnet_client.should_receive(:cmd).with({"String"=>"app.\t", "Match"=>/\S*\n$/, "Timeout"=>10}).and_return("\n")
184   - exit_console "irb():001:0> "
  187 + verify_console_exit "irb():001:0> "
185 188 start_local_console(3344,'foo')
186 189 Readline.completion_proc.yield("app.").should == []
187 190 end
@@ -190,7 +193,7 @@
190 193 @client.should_receive(:app_files).with("foo", '/app/cf-rails-console/.consoleaccess', '0').and_return(IO.read(spec_asset('console_access.txt')))
191 194 @telnet_client.should_receive(:login).with({"Name"=>"cfuser", "Password"=>"testpw"}).and_return("Switch to inspect mode\nirb():001:0> ")
192 195 @telnet_client.should_receive(:cmd).with({"String"=>"app.\t", "Match"=>/\S*\n$/, "Timeout"=>10}).and_raise(TimeoutError)
193   - exit_console "irb():001:0> "
  196 + verify_console_exit "irb():001:0> "
194 197 start_local_console(3344,'foo')
195 198 Readline.completion_proc.yield("app.").should == []
196 199 end
@@ -202,7 +205,7 @@
202 205 Readline.should_receive(:basic_word_break_characters=).with(" \t\n`><=;|&{(")
203 206 Readline.should_receive(:completion_append_character=).with(nil)
204 207 Readline.should_receive(:completion_proc=)
205   - exit_console "irb():001:0> "
  208 + verify_console_exit "irb():001:0> "
206 209 start_local_console(3344,'foo')
207 210 end
208 211
@@ -217,8 +220,8 @@ def telnet_client(port)
217 220 @telnet_client
218 221 end
219 222
220   - def exit_console(prompt)
221   - Readline.should_receive(:readline).with(prompt,true).and_return("exit")
  223 + def verify_console_exit(prompt)
  224 + Readline.should_receive(:readline).with(prompt).and_return("exit")
222 225 @telnet_client.should_receive(:cmd).with(({"String"=>"exit", "Timeout"=>1})).and_raise(TimeoutError)
223 226 @telnet_client.should_receive(:close)
224 227 end
1  vmc.gemspec
@@ -22,6 +22,7 @@ spec = Gem::Specification.new do |s|
22 22 s.add_dependency "interact", "~> 0.4.0"
23 23 s.add_dependency "addressable", "~> 2.2.6"
24 24 s.add_dependency "uuidtools", "~> 2.1.0"
  25 + s.add_dependency "rb-readline", "~> 0.4.2"
25 26
26 27 s.add_development_dependency "rake"
27 28 s.add_development_dependency "rspec", "~> 1.3.0"

Git Notes

review

Code-Review+2: Alex Suraci <asuraci@vmware.com>
Verified+1: CI Master <cf-ci@rbcon.com>
Submitted-by: Jennifer Hickey <jhickey@vmware.com>
Submitted-at: Mon, 14 May 2012 19:08:40 +0000
Reviewed-on: http://reviews.cloudfoundry.org/5532
Project: vmc
Branch: refs/heads/master

0 comments on commit 1f3d1f3

Please sign in to comment.
Something went wrong with that request. Please try again.