skylight 0.0.7 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/bin/skylight +5 -0
  3. data/lib/skylight.rb +2 -0
  4. data/lib/skylight/cli.rb +84 -0
  5. data/lib/skylight/config.rb +53 -6
  6. data/lib/skylight/instrumenter.rb +4 -1
  7. data/lib/skylight/json_proto.rb +0 -3
  8. data/lib/skylight/middleware.rb +1 -0
  9. data/lib/skylight/normalize.rb +30 -5
  10. data/lib/skylight/normalize/process_action.rb +1 -1
  11. data/lib/skylight/normalize/render_collection.rb +2 -6
  12. data/lib/skylight/normalize/render_partial.rb +2 -5
  13. data/lib/skylight/normalize/render_template.rb +2 -5
  14. data/lib/skylight/normalize/sql.rb +2 -4
  15. data/lib/skylight/railtie.rb +30 -33
  16. data/lib/skylight/sanity_checker.rb +73 -0
  17. data/lib/skylight/subscriber.rb +1 -15
  18. data/lib/skylight/trace.rb +30 -5
  19. data/lib/skylight/util/http.rb +97 -0
  20. data/lib/skylight/vendor/highline.rb +1012 -0
  21. data/lib/skylight/vendor/highline/color_scheme.rb +134 -0
  22. data/lib/skylight/vendor/highline/compatibility.rb +16 -0
  23. data/lib/skylight/vendor/highline/import.rb +41 -0
  24. data/lib/skylight/vendor/highline/menu.rb +398 -0
  25. data/lib/skylight/vendor/highline/question.rb +475 -0
  26. data/lib/skylight/vendor/highline/simulate.rb +48 -0
  27. data/lib/skylight/vendor/highline/string_extensions.rb +131 -0
  28. data/lib/skylight/vendor/highline/style.rb +181 -0
  29. data/lib/skylight/vendor/highline/system_extensions.rb +218 -0
  30. data/lib/skylight/vendor/thor.rb +473 -0
  31. data/lib/skylight/vendor/thor/actions.rb +318 -0
  32. data/lib/skylight/vendor/thor/actions/create_file.rb +105 -0
  33. data/lib/skylight/vendor/thor/actions/create_link.rb +60 -0
  34. data/lib/skylight/vendor/thor/actions/directory.rb +119 -0
  35. data/lib/skylight/vendor/thor/actions/empty_directory.rb +137 -0
  36. data/lib/skylight/vendor/thor/actions/file_manipulation.rb +314 -0
  37. data/lib/skylight/vendor/thor/actions/inject_into_file.rb +109 -0
  38. data/lib/skylight/vendor/thor/base.rb +652 -0
  39. data/lib/skylight/vendor/thor/command.rb +136 -0
  40. data/lib/skylight/vendor/thor/core_ext/hash_with_indifferent_access.rb +80 -0
  41. data/lib/skylight/vendor/thor/core_ext/io_binary_read.rb +12 -0
  42. data/lib/skylight/vendor/thor/core_ext/ordered_hash.rb +100 -0
  43. data/lib/skylight/vendor/thor/error.rb +28 -0
  44. data/lib/skylight/vendor/thor/group.rb +282 -0
  45. data/lib/skylight/vendor/thor/invocation.rb +172 -0
  46. data/lib/skylight/vendor/thor/parser.rb +4 -0
  47. data/lib/skylight/vendor/thor/parser/argument.rb +74 -0
  48. data/lib/skylight/vendor/thor/parser/arguments.rb +171 -0
  49. data/lib/skylight/vendor/thor/parser/option.rb +121 -0
  50. data/lib/skylight/vendor/thor/parser/options.rb +218 -0
  51. data/lib/skylight/vendor/thor/rake_compat.rb +72 -0
  52. data/lib/skylight/vendor/thor/runner.rb +322 -0
  53. data/lib/skylight/vendor/thor/shell.rb +88 -0
  54. data/lib/skylight/vendor/thor/shell/basic.rb +393 -0
  55. data/lib/skylight/vendor/thor/shell/color.rb +148 -0
  56. data/lib/skylight/vendor/thor/shell/html.rb +127 -0
  57. data/lib/skylight/vendor/thor/util.rb +270 -0
  58. data/lib/skylight/vendor/thor/version.rb +3 -0
  59. data/lib/skylight/version.rb +1 -1
  60. data/lib/skylight/worker.rb +3 -58
  61. metadata +56 -18
@@ -0,0 +1,48 @@
1
+ # simulate.rb
2
+ #
3
+ # Created by Andy Rossmeissl on 2012-04-29.
4
+ # Copyright 2005 Gray Productions. All rights reserved.
5
+ #
6
+ # This is Free Software. See LICENSE and COPYING for details.
7
+ #
8
+ # adapted from https://gist.github.com/194554
9
+ class HighLine
10
+
11
+ # Simulates Highline input for use in tests.
12
+ class Simulate
13
+
14
+ # Creates a simulator with an array of Strings as a script
15
+ def initialize(strings)
16
+ @strings = strings
17
+ end
18
+
19
+ # Simulate StringIO#gets by shifting a string off of the script
20
+ def gets
21
+ @strings.shift
22
+ end
23
+
24
+ # Simulate StringIO#getbyte by shifting a single character off of the next line of the script
25
+ def getbyte
26
+ line = gets
27
+ if line.length > 0
28
+ char = line.slice! 0
29
+ @strings.unshift line
30
+ char
31
+ end
32
+ end
33
+
34
+ # The simulator handles its own EOF
35
+ def eof?
36
+ false
37
+ end
38
+
39
+ # A wrapper method that temporarily replaces the Highline instance in $terminal with an instance of this object for the duration of the block
40
+ def self.with(*strings)
41
+ @input = $terminal.instance_variable_get :@input
42
+ $terminal.instance_variable_set :@input, new(strings)
43
+ yield
44
+ ensure
45
+ $terminal.instance_variable_set :@input, @input
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,131 @@
1
+ # Extensions for class String
2
+ #
3
+ # HighLine::String is a subclass of String with convenience methods added for colorization.
4
+ #
5
+ # Available convenience methods include:
6
+ # * 'color' method e.g. highline_string.color(:bright_blue, :underline)
7
+ # * colors e.g. highline_string.magenta
8
+ # * RGB colors e.g. highline_string.rgb_ff6000
9
+ # or highline_string.rgb(255,96,0)
10
+ # * background colors e.g. highline_string.on_magenta
11
+ # * RGB background colors e.g. highline_string.on_rgb_ff6000
12
+ # or highline_string.on_rgb(255,96,0)
13
+ # * styles e.g. highline_string.underline
14
+ #
15
+ # Additionally, convenience methods can be chained, for instance the following are equivalent:
16
+ # highline_string.bright_blue.blink.underline
17
+ # highline_string.color(:bright_blue, :blink, :underline)
18
+ # HighLine.color(highline_string, :bright_blue, :blink, :underline)
19
+ #
20
+ # For those less squeamish about possible conflicts, the same convenience methods can be
21
+ # added to the built-in String class, as follows:
22
+ #
23
+ # require 'highline'
24
+ # Highline.colorize_strings
25
+
26
+ class HighLine
27
+ def self.String(s)
28
+ HighLine::String.new(s)
29
+ end
30
+
31
+ module StringExtensions
32
+ def self.included(base)
33
+ HighLine::COLORS.each do |color|
34
+ base.class_eval <<-END
35
+ if public_instance_methods.map { |m| m.to_s }.
36
+ include? "#{color.downcase}"
37
+ undef :#{color.downcase}
38
+ end
39
+ def #{color.downcase}
40
+ color(:#{color.downcase})
41
+ end
42
+ END
43
+ base.class_eval <<-END
44
+ if public_instance_methods.map { |m| m.to_s }.
45
+ include? "on_#{color.downcase}"
46
+ undef :on_#{color.downcase}
47
+ end
48
+ def on_#{color.downcase}
49
+ on(:#{color.downcase})
50
+ end
51
+ END
52
+ HighLine::STYLES.each do |style|
53
+ base.class_eval <<-END
54
+ if public_instance_methods.map { |m| m.to_s }.
55
+ include? "#{style.downcase}"
56
+ undef :#{style.downcase}
57
+ end
58
+ def #{style.downcase}
59
+ color(:#{style.downcase})
60
+ end
61
+ END
62
+ end
63
+ end
64
+
65
+ base.class_eval do
66
+ if public_instance_methods.map { |m| m.to_s }.include? "color"
67
+ undef :color
68
+ end
69
+ if public_instance_methods.map { |m| m.to_s }.include? "foreground"
70
+ undef :foreground
71
+ end
72
+ def color(*args)
73
+ self.class.new(HighLine.color(self, *args))
74
+ end
75
+ alias_method :foreground, :color
76
+
77
+ if public_instance_methods.map { |m| m.to_s }.include? "on"
78
+ undef :on
79
+ end
80
+ def on(arg)
81
+ color(('on_' + arg.to_s).to_sym)
82
+ end
83
+
84
+ if public_instance_methods.map { |m| m.to_s }.include? "uncolor"
85
+ undef :uncolor
86
+ end
87
+ def uncolor
88
+ self.class.new(HighLine.uncolor(self))
89
+ end
90
+
91
+ if public_instance_methods.map { |m| m.to_s }.include? "rgb"
92
+ undef :rgb
93
+ end
94
+ def rgb(*colors)
95
+ color_code = colors.map{|color| color.is_a?(Numeric) ? '%02x'%color : color.to_s}.join
96
+ raise "Bad RGB color #{colors.inspect}" unless color_code =~ /^[a-fA-F0-9]{6}/
97
+ color("rgb_#{color_code}".to_sym)
98
+ end
99
+
100
+ if public_instance_methods.map { |m| m.to_s }.include? "on_rgb"
101
+ undef :on_rgb
102
+ end
103
+ def on_rgb(*colors)
104
+ color_code = colors.map{|color| color.is_a?(Numeric) ? '%02x'%color : color.to_s}.join
105
+ raise "Bad RGB color #{colors.inspect}" unless color_code =~ /^[a-fA-F0-9]{6}/
106
+ color("on_rgb_#{color_code}".to_sym)
107
+ end
108
+
109
+ if public_instance_methods.map { |m| m.to_s }.include? "method_missing"
110
+ undef :method_missing
111
+ end
112
+ # TODO Chain existing method_missing
113
+ def method_missing(method, *args, &blk)
114
+ if method.to_s =~ /^(on_)?rgb_([0-9a-fA-F]{6})$/
115
+ color(method)
116
+ else
117
+ raise NoMethodError, "undefined method `#{method}' for #<#{self.class}:#{'%#x'%self.object_id}>"
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ class HighLine::String < ::String
125
+ include StringExtensions
126
+ end
127
+
128
+ def self.colorize_strings
129
+ ::String.send(:include, StringExtensions)
130
+ end
131
+ end
@@ -0,0 +1,181 @@
1
+ # color_scheme.rb
2
+ #
3
+ # Created by Richard LeBer on 2011-06-27.
4
+ # Copyright 2011. All rights reserved
5
+ #
6
+ # This is Free Software. See LICENSE and COPYING for details
7
+
8
+ class HighLine
9
+
10
+ def self.Style(*args)
11
+ args = args.compact.flatten
12
+ if args.size==1
13
+ arg = args.first
14
+ if arg.is_a?(Style)
15
+ Style.list[arg.name] || Style.index(arg)
16
+ elsif arg.is_a?(::String) && arg =~ /^\e\[/ # arg is a code
17
+ if styles = Style.code_index[arg]
18
+ styles.first
19
+ else
20
+ Style.new(:code=>arg)
21
+ end
22
+ elsif style = Style.list[arg]
23
+ style
24
+ elsif HighLine.color_scheme && HighLine.color_scheme[arg]
25
+ HighLine.color_scheme[arg]
26
+ elsif arg.is_a?(Hash)
27
+ Style.new(arg)
28
+ elsif arg.to_s.downcase =~ /^rgb_([a-f0-9]{6})$/
29
+ Style.rgb($1)
30
+ elsif arg.to_s.downcase =~ /^on_rgb_([a-f0-9]{6})$/
31
+ Style.rgb($1).on
32
+ else
33
+ raise NameError, "#{arg.inspect} is not a defined Style"
34
+ end
35
+ else
36
+ name = args
37
+ Style.list[name] || Style.new(:list=>args)
38
+ end
39
+ end
40
+
41
+ class Style
42
+
43
+ def self.index(style)
44
+ if style.name
45
+ @@styles ||= {}
46
+ @@styles[style.name] = style
47
+ end
48
+ if !style.list
49
+ @@code_index ||= {}
50
+ @@code_index[style.code] ||= []
51
+ @@code_index[style.code].reject!{|indexed_style| indexed_style.name == style.name}
52
+ @@code_index[style.code] << style
53
+ end
54
+ style
55
+ end
56
+
57
+ def self.rgb_hex(*colors)
58
+ colors.map do |color|
59
+ color.is_a?(Numeric) ? '%02x'%color : color.to_s
60
+ end.join
61
+ end
62
+
63
+ def self.rgb_parts(hex)
64
+ hex.scan(/../).map{|part| part.to_i(16)}
65
+ end
66
+
67
+ def self.rgb(*colors)
68
+ hex = rgb_hex(*colors)
69
+ name = ('rgb_' + hex).to_sym
70
+ if style = list[name]
71
+ style
72
+ else
73
+ parts = rgb_parts(hex)
74
+ new(:name=>name, :code=>"\e[38;5;#{rgb_number(parts)}m", :rgb=>parts)
75
+ end
76
+ end
77
+
78
+ def self.rgb_number(*parts)
79
+ parts = parts.flatten
80
+ 16 + parts.inject(0) {|kode, part| kode*6 + (part/256.0*6.0).floor}
81
+ end
82
+
83
+ def self.ansi_rgb_to_hex(ansi_number)
84
+ raise "Invalid ANSI rgb code #{ansi_number}" unless (16..231).include?(ansi_number)
85
+ parts = (ansi_number-16).to_s(6).rjust(3,'0').scan(/./).map{|d| (d.to_i*255.0/6.0).ceil}
86
+ rgb_hex(*parts)
87
+ end
88
+
89
+ def self.list
90
+ @@styles ||= {}
91
+ end
92
+
93
+ def self.code_index
94
+ @@code_index ||= {}
95
+ end
96
+
97
+ def self.uncolor(string)
98
+ string.gsub(/\e\[\d+(;\d+)*m/, '')
99
+ end
100
+
101
+ attr_reader :name, :list
102
+ attr_accessor :rgb, :builtin
103
+
104
+ # Single color/styles have :name, :code, :rgb (possibly), :builtin
105
+ # Compound styles have :name, :list, :builtin
106
+ def initialize(defn = {})
107
+ @definition = defn
108
+ @name = defn[:name]
109
+ @code = defn[:code]
110
+ @rgb = defn[:rgb]
111
+ @list = defn[:list]
112
+ @builtin = defn[:builtin]
113
+ if @rgb
114
+ hex = self.class.rgb_hex(@rgb)
115
+ @name ||= 'rgb_' + hex
116
+ elsif @list
117
+ @name ||= @list
118
+ end
119
+ self.class.index self unless defn[:no_index]
120
+ end
121
+
122
+ def dup
123
+ self.class.new(@definition)
124
+ end
125
+
126
+ def to_hash
127
+ @definition
128
+ end
129
+
130
+ def color(string)
131
+ code + string + HighLine::CLEAR
132
+ end
133
+
134
+ def code
135
+ if @list
136
+ @list.map{|element| HighLine.Style(element).code}.join
137
+ else
138
+ @code
139
+ end
140
+ end
141
+
142
+ def red
143
+ @rgb && @rgb[0]
144
+ end
145
+
146
+ def green
147
+ @rgb && @rgb[1]
148
+ end
149
+
150
+ def blue
151
+ @rgb && @rgb[2]
152
+ end
153
+
154
+ def variant(new_name, options={})
155
+ raise "Cannot create a variant of a style list (#{inspect})" if @list
156
+ new_code = options[:code] || code
157
+ if options[:increment]
158
+ raise "Unexpected code in #{inspect}" unless new_code =~ /^(.*?)(\d+)(.*)/
159
+ new_code = $1 + ($2.to_i + options[:increment]).to_s + $3
160
+ end
161
+ new_rgb = options[:rgb] || @rgb
162
+ self.class.new(self.to_hash.merge(:name=>new_name, :code=>new_code, :rgb=>new_rgb))
163
+ end
164
+
165
+ def on
166
+ new_name = ('on_'+@name.to_s).to_sym
167
+ self.class.list[new_name] ||= variant(new_name, :increment=>10)
168
+ end
169
+
170
+ def bright
171
+ raise "Cannot create a bright variant of a style list (#{inspect})" if @list
172
+ new_name = ('bright_'+@name.to_s).to_sym
173
+ if style = self.class.list[new_name]
174
+ style
175
+ else
176
+ new_rgb = @rgb == [0,0,0] ? [128, 128, 128] : @rgb.map {|color| color==0 ? 0 : [color+128,255].min }
177
+ variant(new_name, :increment=>60, :rgb=>new_rgb)
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,218 @@
1
+ # system_extensions.rb
2
+ #
3
+ # Created by James Edward Gray II on 2006-06-14.
4
+ # Copyright 2006 Gray Productions. All rights reserved.
5
+ #
6
+ # This is Free Software. See LICENSE and COPYING for details.
7
+
8
+ require "highline/compatibility"
9
+
10
+ class HighLine
11
+ module SystemExtensions
12
+ JRUBY = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
13
+
14
+ if JRUBY
15
+ def initialize_system_extensions
16
+ require 'java'
17
+ if JRUBY_VERSION =~ /^1.7/
18
+ java_import 'jline.console.ConsoleReader'
19
+
20
+ @java_console = ConsoleReader.new(@input.to_inputstream, @output.to_outputstream)
21
+ @java_console.set_history_enabled(false)
22
+ @java_console.set_bell_enabled(true)
23
+ @java_console.set_pagination_enabled(false)
24
+ @java_terminal = @java_console.getTerminal
25
+ elsif JRUBY_VERSION =~ /^1.6/
26
+ java_import 'java.io.OutputStreamWriter'
27
+ java_import 'java.nio.channels.Channels'
28
+ java_import 'jline.ConsoleReader'
29
+ java_import 'jline.Terminal'
30
+
31
+ @java_input = Channels.newInputStream(@input.to_channel)
32
+ @java_output = OutputStreamWriter.new(Channels.newOutputStream(@output.to_channel))
33
+ @java_terminal = Terminal.getTerminal
34
+ @java_console = ConsoleReader.new(@java_input, @java_output)
35
+ @java_console.setUseHistory(false)
36
+ @java_console.setBellEnabled(true)
37
+ @java_console.setUsePagination(false)
38
+ end
39
+ end
40
+ end
41
+
42
+ extend self
43
+
44
+ #
45
+ # This section builds character reading and terminal size functions
46
+ # to suit the proper platform we're running on. Be warned: Here be
47
+ # dragons!
48
+ #
49
+ if RUBY_PLATFORM =~ /mswin(?!ce)|mingw|bccwin/i
50
+ begin
51
+ require "fiddle"
52
+
53
+ module WinAPI
54
+ include Fiddle
55
+ Handle = RUBY_VERSION >= "2.0.0" ? Fiddle::Handle : DL::Handle
56
+ Kernel32 = Handle.new("kernel32")
57
+ Crt = Handle.new("msvcrt") rescue Handle.new("crtdll")
58
+
59
+ def self._getch
60
+ @@_m_getch ||= Function.new(Crt["_getch"], [], TYPE_INT)
61
+ @@_m_getch.call
62
+ end
63
+
64
+ def self.GetStdHandle(handle_type)
65
+ @@get_std_handle ||= Function.new(Kernel32["GetStdHandle"], [-TYPE_INT], -TYPE_INT)
66
+ @@get_std_handle.call(handle_type)
67
+ end
68
+
69
+ def self.GetConsoleScreenBufferInfo(cons_handle, lp_buffer)
70
+ @@get_console_screen_buffer_info ||=
71
+ Function.new(Kernel32["GetConsoleScreenBufferInfo"], [TYPE_LONG, TYPE_VOIDP], TYPE_INT)
72
+ @@get_console_screen_buffer_info.call(cons_handle, lp_buffer)
73
+ end
74
+ end
75
+ rescue LoadError
76
+ require "dl/import"
77
+
78
+ module WinAPI
79
+ extend DL::Importer rescue DL::Importable
80
+ begin
81
+ dlload "msvcrt", "kernel32"
82
+ rescue DL::DLError
83
+ dlload "crtdll", "kernel32"
84
+ end
85
+ extern "unsigned long _getch()"
86
+ extern "unsigned long GetConsoleScreenBufferInfo(unsigned long, void*)"
87
+ extern "unsigned long GetStdHandle(unsigned long)"
88
+ end
89
+ end
90
+
91
+ CHARACTER_MODE = "Win32API" # For Debugging purposes only.
92
+
93
+ #
94
+ # Windows savvy getc().
95
+ #
96
+ # *WARNING*: This method ignores <tt>input</tt> and reads one
97
+ # character from +STDIN+!
98
+ #
99
+ def get_character( input = STDIN )
100
+ WinAPI._getch
101
+ end
102
+
103
+ # We do not define a raw_no_echo_mode for Windows as _getch turns off echo
104
+ def raw_no_echo_mode
105
+ end
106
+
107
+ def restore_mode
108
+ end
109
+
110
+ # A Windows savvy method to fetch the console columns, and rows.
111
+ def terminal_size
112
+ format = 'SSSSSssssSS'
113
+ buf = ([0] * format.size).pack(format)
114
+ stdout_handle = WinAPI.GetStdHandle(0xFFFFFFF5)
115
+
116
+ WinAPI.GetConsoleScreenBufferInfo(stdout_handle, buf)
117
+ _, _, _, _, _,
118
+ left, top, right, bottom, _, _ = buf.unpack(format)
119
+ return right - left + 1, bottom - top + 1
120
+ end
121
+ else # If we're not on Windows try...
122
+ begin
123
+ require "termios" # Unix, first choice termios.
124
+
125
+ CHARACTER_MODE = "termios" # For Debugging purposes only.
126
+
127
+ def raw_no_echo_mode
128
+ @state = Termios.getattr(@input)
129
+ new_settings = @state.dup
130
+ new_settings.c_lflag &= ~(Termios::ECHO | Termios::ICANON)
131
+ new_settings.c_cc[Termios::VMIN] = 1
132
+ Termios.setattr(@input, Termios::TCSANOW, new_settings)
133
+ end
134
+
135
+ def restore_mode
136
+ Termios.setattr(@input, Termios::TCSANOW, @state)
137
+ end
138
+ rescue LoadError # If our first choice fails, try using JLine
139
+ if JRUBY # if we are on JRuby. JLine is bundled with JRuby.
140
+ CHARACTER_MODE = "jline" # For Debugging purposes only.
141
+
142
+ def terminal_size
143
+ [ @java_terminal.getTerminalWidth, @java_terminal.getTerminalHeight ]
144
+ end
145
+
146
+ def raw_no_echo_mode
147
+ @state = @java_console.getEchoCharacter
148
+ @java_console.setEchoCharacter 0
149
+ end
150
+
151
+ def restore_mode
152
+ @java_console.setEchoCharacter @state
153
+ end
154
+ else # If we are not on JRuby, try ncurses
155
+ begin
156
+ require 'ffi-ncurses'
157
+ CHARACTER_MODE = "ncurses" # For Debugging purposes only.
158
+
159
+ def raw_no_echo_mode
160
+ FFI::NCurses.initscr
161
+ FFI::NCurses.cbreak
162
+ end
163
+
164
+ def restore_mode
165
+ FFI::NCurses.endwin
166
+ end
167
+
168
+ #
169
+ # A ncurses savvy method to fetch the console columns, and rows.
170
+ #
171
+ def terminal_size
172
+ size = [80, 40]
173
+ FFI::NCurses.initscr
174
+ begin
175
+ size = FFI::NCurses.getmaxyx(stdscr).reverse
176
+ ensure
177
+ FFI::NCurses.endwin
178
+ end
179
+ size
180
+ end
181
+ rescue LoadError # Finally, if all else fails, use stty
182
+ # *WARNING*: This requires the external "stty" program!
183
+ CHARACTER_MODE = "stty" # For Debugging purposes only.
184
+
185
+ def raw_no_echo_mode
186
+ @state = `stty -g`
187
+ system "stty raw -echo -icanon isig"
188
+ end
189
+
190
+ def restore_mode
191
+ system "stty #{@state}"
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ # For termios and stty
198
+ if not method_defined?(:terminal_size)
199
+ # A Unix savvy method using stty to fetch the console columns, and rows.
200
+ # ... stty does not work in JRuby
201
+ def terminal_size
202
+ if /solaris/ =~ RUBY_PLATFORM and
203
+ `stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/
204
+ [$2, $1].map { |c| x.to_i }
205
+ else
206
+ `stty size`.split.map { |x| x.to_i }.reverse
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ if not method_defined?(:get_character)
213
+ def get_character( input = STDIN )
214
+ input.getbyte
215
+ end
216
+ end
217
+ end
218
+ end