Module: RackConsole::AppHelpers
- Includes:
- ExprHelpers
- Defined in:
- lib/rack_console/app_helpers.rb
Defined Under Namespace
Classes: MockMethod
Constant Summary collapse
- DUMMY_SOURCE_LOCATION =
[ "".freeze, 0 ].freeze
Instance Method Summary collapse
- #ansi2html(ansi) ⇒ Object
- #capture_stdio! ⇒ Object
- #console! ⇒ Object
- #const_get_safe(m, name) ⇒ Object
- #css_dir ⇒ Object
- #e(text) ⇒ Object
- #evaluate_expr! ⇒ Object
- #evaluate_method! ⇒ Object
- #evaluate_methods! ⇒ Object
- #evaluate_module! ⇒ Object
- #file_line_to_href(name, lineno = nil) ⇒ Object
- #file_name_tag(str) ⇒ Object
- #find_template(views, name, engine, &block) ⇒ Object
- #format_as_terminal(str) ⇒ Object
- #format_backtrace(line) ⇒ Object
- #format_method(m, kind, owner = nil) ⇒ Object
- #format_methods(name) ⇒ Object
- #format_module(obj) ⇒ Object
- #format_object(obj, inline = false) ⇒ Object
- #format_other(obj, inline = false) ⇒ Object
- #format_source_location(source_location, meth = nil, kind = nil, owner = nil) ⇒ Object
- #h(text) ⇒ Object
- #has_console_access? ⇒ Boolean
- #has_file_access?(file) ⇒ Boolean
- #href_to_file_line(path) ⇒ Object
- #instance_method_names(owner) ⇒ Object
- #layout ⇒ Object
- #limit_string(text, len) ⇒ Object
- #literal_tag(str) ⇒ Object
- #locals ⇒ Object
- #match_pred(value, m = nil) ⇒ Object
- #method_href(m, kind, owner = nil) ⇒ Object
- #method_name_tag(str) ⇒ Object
- #methods_for_module(owner, name_p = nil, kind_p = nil, file_p = nil, seen = { }, to_methods = nil) ⇒ Object
- #methods_matching(params) ⇒ Object
- #methods_within_file(file) ⇒ Object
- #module_name_tag(str) ⇒ Object
- #prepare_file! ⇒ Object
- #result_capture! ⇒ Object
- #safe_format(obj) ⇒ Object
- #safe_format_structured(obj) ⇒ Object
- #safe_pp(obj) ⇒ Object
- #server_info ⇒ Object
- #singleton_method_names(owner) ⇒ Object
- #sort_methods!(methods) ⇒ Object
- #sort_methods_by_source_location!(methods) ⇒ Object
- #source_file(source_location) ⇒ Object
- #source_file_methods_href(file) ⇒ Object
- #url_root(url) ⇒ Object
- #wrap_line(str, width = 80) ⇒ Object
- #wrap_lines(str, width = 80) ⇒ Object
Methods included from ExprHelpers
#expr_for_Module, #expr_for_method, #expr_for_object, #expr_for_object!
Instance Method Details
#ansi2html(ansi) ⇒ Object
466 467 468 |
# File 'lib/rack_console/app_helpers.rb', line 466 def ansi2html ansi Ansi2Html.new.convert(ansi, '') end |
#capture_stdio! ⇒ Object
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/rack_console/app_helpers.rb', line 107 def capture_stdio! @captured_stdio = true _stdin, _stdout, _stderr = $stdin, $stdout, $stderr $stdin, $stdout, $stderr = @stdin, @stdout, @stderr begin yield ensure $stdin, $stdout, $stderr = _stdin, _stdout, _stderr end end |
#console! ⇒ Object
46 47 48 49 50 51 52 |
# File 'lib/rack_console/app_helpers.rb', line 46 def console! if has_console_access? haml :console, locals: locals, layout: layout else raise "not authorized" end end |
#const_get_safe(m, name) ⇒ Object
187 188 189 190 191 |
# File 'lib/rack_console/app_helpers.rb', line 187 def const_get_safe m, name m.const_get(name) rescue Object "ERROR: #{$!.inspect}" end |
#css_dir ⇒ Object
40 41 42 |
# File 'lib/rack_console/app_helpers.rb', line 40 def css_dir config[:css_dir] end |
#e(text) ⇒ Object
342 343 344 |
# File 'lib/rack_console/app_helpers.rb', line 342 def e(text) Rack::Utils.escape(text.to_s) end |
#evaluate_expr! ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rack_console/app_helpers.rb', line 54 def evaluate_expr! return if @result_evaled result_capture! do @stdin = StringIO.new('') @stdout = StringIO.new('') @stderr = StringIO.new('') @result_ok = false @expr = (params[:expr] || '').strip unless @expr.blank? @result_evaled = true Timeout.timeout(config[:eval_timeout] || 120) do capture_stdio! do expr_str = "begin; #{@expr} \n; end" @result = eval(expr_str) @result_ok = true end end end end end |
#evaluate_method! ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/rack_console/app_helpers.rb', line 85 def evaluate_method! evaluate_expr! @show_stdio = @show_result = false if @result_ok && @result.is_a?(Module) result_capture! do @module = @result @method_name = params[:name] @method_kind = params[:kind].to_s =~ /i/ ? :instance_method : :method @method = @module.send(@method_kind, @method_name) rescue nil unless @method @method = @module.send(:method, @method_name) @method_kind = :method end @method_source_location = @method.source_location @method_source = @method_source_location && SourceFile.new(@method_source_location).load!.narrow_to_block! @result = @method @is_method = true expr_for_object! @method, @module, @method_kind end end end |
#evaluate_methods! ⇒ Object
118 119 120 121 122 123 |
# File 'lib/rack_console/app_helpers.rb', line 118 def evaluate_methods! @methods = nil result_capture! do @methods = methods_matching(params) end end |
#evaluate_module! ⇒ Object
75 76 77 78 79 80 81 82 83 |
# File 'lib/rack_console/app_helpers.rb', line 75 def evaluate_module! evaluate_expr! @show_stdio = @show_result = false if @result_ok && @result.is_a?(Module) result_capture! do @module = @result end end end |
#file_line_to_href(name, lineno = nil) ⇒ Object
314 315 316 317 318 319 320 |
# File 'lib/rack_console/app_helpers.rb', line 314 def file_line_to_href name, lineno = nil link = name.sub(%r{^/}, '-') link = link.split('/').map{|s| e s}.join('/') link = url_root("/file/#{link}") link << ":#{lineno}\##{lineno - 2}" if lineno link end |
#file_name_tag(str) ⇒ Object
387 388 389 |
# File 'lib/rack_console/app_helpers.rb', line 387 def file_name_tag str %Q{<span class="file_name">#{str}</span>} end |
#find_template(views, name, engine, &block) ⇒ Object
32 33 34 35 36 37 38 |
# File 'lib/rack_console/app_helpers.rb', line 32 def find_template(views, name, engine, &block) views = config[:views] || views Array(views).each do |v| v = config[:views_default] if v == :default super(v, name, engine, &block) end end |
#format_as_terminal(str) ⇒ Object
457 458 459 460 461 462 463 464 |
# File 'lib/rack_console/app_helpers.rb', line 457 def format_as_terminal str str &&= str.to_s.force_encoding('UTF-8') if str.blank? %Q{<span class="none">NONE</span>} else ansi2html(str) end end |
#format_backtrace(line) ⇒ Object
403 404 405 406 407 408 409 410 411 412 |
# File 'lib/rack_console/app_helpers.rb', line 403 def format_backtrace line line = line.to_s html = if line =~ /^(.*):(\d+):(in .*)$/ && File.exist?($1) "#{format_source_location([$1, $2.to_i])}:#{h $3}" else file_name_tag(h line) end %Q{<span class="backtrace">#{html}</span>} end |
#format_method(m, kind, owner = nil) ⇒ Object
369 370 371 372 373 374 375 |
# File 'lib/rack_console/app_helpers.rb', line 369 def format_method m, kind, owner = nil owner ||= m.owner source_location = m.source_location source_location &&= source_location * ":" href = method_href(m, kind, owner) "<a href='#{href}' title='#{source_location}' class='method_name'>#{method_name_tag(h(m.name))}</a>" end |
#format_methods(name) ⇒ Object
382 383 384 385 |
# File 'lib/rack_console/app_helpers.rb', line 382 def format_methods name href = url_root("/methods/*/*/#{e name}") "<a href='#{href}' title='Other methods named #{h name.inspect}' class='method_name'>#{method_name_tag(h(name))}</a>" end |
#format_module(obj) ⇒ Object
354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
# File 'lib/rack_console/app_helpers.rb', line 354 def format_module obj return module_name_tag(h(obj.inspect)) unless obj && obj.name path = obj.name.to_s.split('::') result = '' name = ''; pre = '' path.each do | n | name << n href = url_root("/module/#{name}") result << "<a href='#{href}' class='module_name'>#{module_name_tag("#{pre}#{h n}")}</a>" name << '::' pre = '::' end module_name_tag(result) end |
#format_object(obj, inline = false) ⇒ Object
170 171 172 173 174 175 176 177 |
# File 'lib/rack_console/app_helpers.rb', line 170 def format_object obj, inline = false case obj when Module format_module obj else format_other obj, inline end end |
#format_other(obj, inline = false) ⇒ Object
179 180 181 182 183 184 185 |
# File 'lib/rack_console/app_helpers.rb', line 179 def format_other obj, inline = false if inline literal_tag(h(limit_string(safe_format(obj), 80))) else safe_format_structured(obj) end end |
#format_source_location(source_location, meth = nil, kind = nil, owner = nil) ⇒ Object
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/rack_console/app_helpers.rb', line 193 def format_source_location source_location, meth = nil, kind = nil, owner = nil file, line = source_location if file "<a href='#{file_line_to_href file, line}' class='file_name'>#{file_name_tag("#{file}:#{line}")}</a>" else if meth # Assume meth is Ruby Core and link to rdocs on ruby-doc.org. name = meth.name owner ||= meth.owner owner_name = (owner.name || '').gsub('::', '/') kind ||= (owner.instance_method(name) rescue nil) ? :i : :c a_name = name.to_s.gsub(/([^a-z0-9_])/i){|m| "-%X" % [ m.ord ]} a_name.sub!(/^-/, '') a_name = "method-#{kind}-#{a_name}" ruby_core_link = "http://www.ruby-doc.org/core-#{RUBY_VERSION}/#{owner_name}.html\##{a_name}" "<a href='#{ruby_core_link}' class='ruby_core_doc'>#{h ruby_core_link}</a>" else "NONE" end end end |
#h(text) ⇒ Object
338 339 340 |
# File 'lib/rack_console/app_helpers.rb', line 338 def h(text) Rack::Utils.escape_html(text.to_s) end |
#has_console_access? ⇒ Boolean
12 13 14 |
# File 'lib/rack_console/app_helpers.rb', line 12 def has_console_access? true end |
#has_file_access?(file) ⇒ Boolean
16 17 18 |
# File 'lib/rack_console/app_helpers.rb', line 16 def has_file_access? file ! ! (file != '(eval)' && $".include?(file)) end |
#href_to_file_line(path) ⇒ Object
322 323 324 325 326 327 |
# File 'lib/rack_console/app_helpers.rb', line 322 def href_to_file_line path path.to_s =~ /^([^:]+)(:([^:]+))?/ file, line = $1, $3 file.sub!(/^-/, '/') [ file, line && line.to_i ] end |
#instance_method_names(owner) ⇒ Object
280 281 282 283 284 285 |
# File 'lib/rack_console/app_helpers.rb', line 280 def instance_method_names owner ( owner.instance_methods(false) | owner.private_instance_methods(false) | owner.protected_instance_methods(false) ).sort end |
#layout ⇒ Object
28 29 30 |
# File 'lib/rack_console/app_helpers.rb', line 28 def layout config[:layout] || :layout end |
#limit_string(text, len) ⇒ Object
346 347 348 349 350 351 352 |
# File 'lib/rack_console/app_helpers.rb', line 346 def limit_string(text, len) text = text.to_s if text.size > len text = text[0 .. len] + ' ...' end text end |
#literal_tag(str) ⇒ Object
399 400 401 |
# File 'lib/rack_console/app_helpers.rb', line 399 def literal_tag str %Q{<span class="literal">#{str}</span>} end |
#locals ⇒ Object
24 25 26 |
# File 'lib/rack_console/app_helpers.rb', line 24 def locals @locals ||= { } end |
#match_pred(value, m = nil) ⇒ Object
232 233 234 235 236 237 238 239 |
# File 'lib/rack_console/app_helpers.rb', line 232 def match_pred value, m = nil if value != nil && value != '*' && value != '' value = value.send(m) if m else value = nil end value end |
#method_href(m, kind, owner = nil) ⇒ Object
377 378 379 380 |
# File 'lib/rack_console/app_helpers.rb', line 377 def method_href m, kind, owner = nil owner ||= m.owner href = url_root("/method/#{owner.name}/#{e kind.to_s}/#{e m.name}") end |
#method_name_tag(str) ⇒ Object
395 396 397 |
# File 'lib/rack_console/app_helpers.rb', line 395 def method_name_tag str %Q{<span class="method_name">#{str}</span>} end |
#methods_for_module(owner, name_p = nil, kind_p = nil, file_p = nil, seen = { }, to_methods = nil) ⇒ Object
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/rack_console/app_helpers.rb', line 241 def methods_for_module owner, name_p = nil, kind_p = nil, file_p = nil, seen = { }, to_methods = nil methods = to_methods || [ ] kind = :i unless kind_p && kind_p != kind instance_method_names(owner).each do | name | next if name_p && name_p != (name = name.to_sym) if meth = (owner.instance_method(name) rescue nil) and key = [ owner, kind, name ] and ! seen[key] seen[key] = true if file_p f = meth.source_location and f = f.first next if f != file_p end methods << MockMethod.new(meth, name, kind, owner) end end end kind = :c unless kind_p && kind_p != kind singleton_method_names(owner).each do | name | next if name_p && name_p != (name = name.to_sym) if meth = (owner.singleton_method(name) rescue nil) and key = [ owner, kind, name ] and ! seen[key] seen[key] = true if file_p f = meth.source_location and f = f.first next if f != file_p end methods << MockMethod.new(meth, name, kind, owner) end end end sort_methods! methods unless to_methods methods end |
#methods_matching(params) ⇒ Object
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/rack_console/app_helpers.rb', line 215 def methods_matching params name_p = match_pred(params[:name], :to_sym) kind_p = match_pred(params[:kind], :to_sym) owner_p = match_pred(params[:owner]) file_p = match_pred(params[:file]) methods = [ ] seen = { } ObjectSpace.each_object(::Module) do | owner | next unless (owner.name rescue nil) next if owner_p && owner_p != owner.name methods_for_module(owner, name_p, kind_p, file_p, seen, methods) end sort_methods! methods methods end |
#methods_within_file(file) ⇒ Object
291 292 293 294 |
# File 'lib/rack_console/app_helpers.rb', line 291 def methods_within_file file methods = methods_matching(file: file) sort_methods_by_source_location! methods end |
#module_name_tag(str) ⇒ Object
391 392 393 |
# File 'lib/rack_console/app_helpers.rb', line 391 def module_name_tag str %Q{<span class="module_name">#{str}</span>} end |
#prepare_file! ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/rack_console/app_helpers.rb', line 125 def prepare_file! path = params[:splat][0] file, line = href_to_file_line(path) result_capture! do unless has_file_access? file content_type 'text/plain' return "NOT A LOADABLE FILE" end @source_file = SourceFile.new([ file, line ]).load! end end |
#result_capture! ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/rack_console/app_helpers.rb', line 137 def result_capture! @result_ok = false result = yield @result_ok = true result rescue @error = $! @error_description = @error.inspect ensure @result_extended = @result.singleton_class.included_modules rescue nil @result_class = @result.class.name if @is_module = Module === @result @module = @result @ancestors = @module.ancestors.drop(1) if @is_class = @module.is_a?(Class) @superclass = @module.superclass @subclasses = @module.subclasses.sort_by{|c| c.name || ''} end @constants = @module.constants(false).sort.map{|n| [ n, const_get_safe(@module, n) ]} @methods = methods_for_module(@module) end end |
#safe_format(obj) ⇒ Object
446 447 448 |
# File 'lib/rack_console/app_helpers.rb', line 446 def safe_format obj safe_pp(obj) end |
#safe_format_structured(obj) ⇒ Object
432 433 434 435 436 437 438 439 440 441 442 443 444 |
# File 'lib/rack_console/app_helpers.rb', line 432 def safe_format_structured obj begin if config[:awesome_print] && defined?(::AwesomePrint) ansi = obj.ai(indent: 2, html: false, index: false) ansi2html(ansi) else '<pre>' << wrap_lines(safe_pp(obj)) << '</pre>' end rescue STDERR.puts " #{$!.inspect}: falling back to #inspect for #{obj.class}\n #{$!.backtrace * "\n "}" '<pre>' << wrap_lines(obj.inspect) << '</pre>' end end |
#safe_pp(obj) ⇒ Object
450 451 452 453 454 455 |
# File 'lib/rack_console/app_helpers.rb', line 450 def safe_pp obj ::PP.pp(obj, '') rescue STDERR.puts " #{$!.inspect}: falling back to #inspect for #{obj.class}\n #{$!.backtrace * "\n "}" obj.inspect end |
#server_info ⇒ Object
160 161 162 163 164 165 166 167 168 |
# File 'lib/rack_console/app_helpers.rb', line 160 def server_info thr = Thread.current (config[:server_info] || { }).merge( host: Socket.gethostname, pid: Process.pid, ppid: Process.ppid, thread: thr[:name] || thr.object_id, ) end |
#singleton_method_names(owner) ⇒ Object
287 288 289 |
# File 'lib/rack_console/app_helpers.rb', line 287 def singleton_method_names owner owner.singleton_methods(false) end |
#sort_methods!(methods) ⇒ Object
276 277 278 |
# File 'lib/rack_console/app_helpers.rb', line 276 def sort_methods! methods methods.sort_by!{|x| [ x.owner.to_s, x.kind, x.name ]} end |
#sort_methods_by_source_location!(methods) ⇒ Object
296 297 298 |
# File 'lib/rack_console/app_helpers.rb', line 296 def sort_methods_by_source_location! methods methods.sort_by!{|x| x.source_location || DUMMY_SOURCE_LOCATION } end |
#source_file(source_location) ⇒ Object
334 335 336 |
# File 'lib/rack_console/app_helpers.rb', line 334 def source_file source_location source_location && SourceFile.new(source_location).load! end |
#source_file_methods_href(file) ⇒ Object
329 330 331 332 |
# File 'lib/rack_console/app_helpers.rb', line 329 def source_file_methods_href file link = file.sub(%r{^/}, '-') link = url_root("/methods/file/#{link}") end |
#url_root(url) ⇒ Object
20 21 22 |
# File 'lib/rack_console/app_helpers.rb', line 20 def url_root url "#{config[:url_root_prefix]}#{url}" end |
#wrap_line(str, width = 80) ⇒ Object
420 421 422 423 424 425 426 427 428 429 430 |
# File 'lib/rack_console/app_helpers.rb', line 420 def wrap_line str, width = 80 str = str.to_s out = '' pos = 0 while pos < str.size out << h(str[pos, width]) pos += width out << " \u21B5\n" if pos < str.size end out end |
#wrap_lines(str, width = 80) ⇒ Object
414 415 416 417 418 |
# File 'lib/rack_console/app_helpers.rb', line 414 def wrap_lines str, width = 80 str.to_s.split("\n").map do | line | wrap_line line, width end * "\n" end |