Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

instead of a simple ruby evaluator, enlighten is now a ruby-debug cli…

…ent gui
  • Loading branch information...
commit 5e2ca8d54c1af3a9ba25c4f6cf6b99b258cb83aa 1 parent 34b80c1
@ryanb authored
View
2  config.ru
@@ -0,0 +1,2 @@
+require File.expand_path("../lib/enlighten_app", __FILE__)
+run Rack::Static.new(Enlighten::Application.new, :urls => ["/javascripts", "/stylesheets"], :root => File.expand_path("../lib/enlighten/public", __FILE__))
View
45 lib/enlighten.rb
@@ -1,44 +1 @@
-require "erb"
-require "rack"
-
-class Enlighten
- def initialize(app)
- @external_app = app
- @enlighten_app = Application.new
- @static_app = Rack::Static.new(@enlighten_app, :urls => ["/enlighten/javascripts", "/enlighten/stylesheets"], :root => public_path)
- end
-
- def call(env)
- request = Rack::Request.new(env)
- if (request.path =~ /^\/enlighten/)
- @static_app.call(env)
- else
- begin
- @external_app.call(env)
- rescue Exception => exception
- app = handle_exception(exception)
- if app
- app.call(env)
- else
- raise exception
- end
- end
- end
- end
-
- def handle_exception(exception)
- if exception.kind_of?(Trigger)
- @enlighten_app.trigger = exception
- @enlighten_app
- elsif exception.respond_to?(:original_exception)
- handle_exception(exception.original_exception)
- end
- end
-
- def public_path
- File.expand_path(File.dirname(__FILE__) + "/enlighten/public")
- end
-end
-
-require "enlighten/trigger"
-require "enlighten/application"
+# TODO here we should help frameworks (Rails) start and open enlighten app
View
95 lib/enlighten/application.rb
@@ -1,35 +1,66 @@
-class Enlighten::Application
- attr_accessor :trigger
-
- def initialize
- @trigger = trigger
- end
-
- def call(env)
- request = Rack::Request.new(env)
- case request.path
- when /^\/enlighten\/execute/ then execute(request.params["prompt"])
- else render("index.html")
+module Enlighten
+ class Application
+ attr_accessor :socket
+
+ def call(env)
+ request = Rack::Request.new(env)
+ case request.path
+ when "/" then render_index
+ when /^\/debugger\/(.+)/ then call_debugger($1, request.params)
+ else [404, {"Content-Type" => "text/plain"}, ["Not Found"]]
+ end
+ end
+
+ def call_debugger(command, params)
+ @socket.puts command + " " + params["code"]
+ respond_with(socket_response)
+ end
+
+ def render_index
+ connect_to_debugger
+ render("index.html")
+ end
+
+ def render(view_file)
+ respond_with(erb(view_file))
+ end
+
+ def respond_with(content)
+ [200, {"Content-Type" => "text/html"}, [content]]
+ end
+
+ def erb(view_file)
+ ERB.new(File.read("#{view_path}/#{view_file}.erb")).result(binding)
+ end
+
+ def view_path
+ File.expand_path(File.dirname(__FILE__) + "/views/")
+ end
+
+ def connect_to_debugger
+ if @socket.nil?
+ @socket = TCPSocket.new("localhost", 8989)
+ socket_response # get to first prompt
+ end
+ rescue Errno::ECONNREFUSED => e
+ @socket = nil
+ end
+
+ def socket_response
+ continue = true
+ response = []
+ while continue && line = @socket.gets
+ print line
+ case line
+ when /^PROMPT (.*)$/
+ continue = false
+ when /^CONFIRM (.*)$/
+ socket.puts "y"
+ else
+ response << line
+ end
+ end
+ response.join
end
- end
-
- def render(view_file)
- respond_with(erb(view_file))
- end
-
- def respond_with(content)
- [200, {}, [content]]
- end
-
- def execute(command)
- respond_with(eval(command.to_s, @trigger.binding_of_caller).inspect)
- end
-
- def erb(view_file)
- ERB.new(File.read("#{view_path}/#{view_file}.erb")).result(binding)
- end
-
- def view_path
- File.expand_path(File.dirname(__FILE__) + "/views/")
end
end
View
2  ...public/enlighten/javascripts/enlighten.js → ...enlighten/public/javascripts/enlighten.js
@@ -1,7 +1,7 @@
$(function() {
$("#console").submit(function() {
$.post(this.action, $(this).serialize(), function(result) {
- $("#prompt_section").before("<div>&gt;&gt; " + $("#prompt").val() + "<br />" + "=&gt; " + result + "</div>");
+ $("#prompt_section").before("<pre>&gt;&gt; " + $("#prompt").val() + "<br />" + "=&gt; " + result + "</pre>");
$("#prompt").val("");
});
return false;
View
0  ...enlighten/javascripts/jquery-1.4.2.min.js → ...en/public/javascripts/jquery-1.4.2.min.js
File renamed without changes
View
0  ...ublic/enlighten/stylesheets/enlighten.css → ...nlighten/public/stylesheets/enlighten.css
File renamed without changes
View
21 lib/enlighten/trigger.rb
@@ -1,21 +0,0 @@
-class Enlighten::Trigger < Exception
- attr_reader :binding_of_caller
-
- # From: http://stackoverflow.com/questions/106920/how-can-i-get-source-and-variable-values-in-ruby-tracebacks
- def initialize
- expected_file, expected_line = caller(1).first.split(':')[0,2]
- expected_line = expected_line.to_i
- return_count = 5
-
- set_trace_func(proc do |event, file, line, id, binding, kls|
- if file == expected_file && line == expected_line
- @binding_of_caller = binding
- set_trace_func(nil)
- end
-
- if event == :return
- set_trace_func(nil) if (return_count -= 1) <= 0
- end
- end)
- end
-end
View
11 lib/enlighten/views/index.html.erb
@@ -2,13 +2,13 @@
<html>
<head>
<title>Enlighten</title>
- <script src="/enlighten/javascripts/jquery-1.4.2.min.js" type="text/javascript" charset="utf-8"></script>
- <script src="/enlighten/javascripts/enlighten.js" type="text/javascript" charset="utf-8"></script>
- <link rel="stylesheet" href="/enlighten/stylesheets/enlighten.css" type="text/css" charset="utf-8" />
+ <script src="/javascripts/jquery-1.4.2.min.js" type="text/javascript" charset="utf-8"></script>
+ <script src="/javascripts/enlighten.js" type="text/javascript" charset="utf-8"></script>
+ <link rel="stylesheet" href="/stylesheets/enlighten.css" type="text/css" charset="utf-8" />
</head>
<body>
- <% if @trigger %>
- <form id="console" action="/enlighten/execute" method="post">
+ <% if @socket %>
+ <form id="console" action="/execute" method="post">
<div id="prompt_section">
&gt;&gt;
<input type="text" name="prompt" value="" id="prompt" />
@@ -17,6 +17,7 @@
</form>
<% else %>
<p>Not yet enlightened.</p>
+ <p>Unable to establish a connection to the ruby-debug server. Make sure a "debugger" statement has been triggered and try again.</p>
<% end %>
</body>
</html>
View
4 lib/enlighten_app.rb
@@ -0,0 +1,4 @@
+require "erb"
+require "rack"
+
+require "enlighten/application"
View
33 spec/enlighten/application_spec.rb
@@ -6,29 +6,30 @@
@request = Rack::MockRequest.new(@app)
end
- it "should render an HTML view" do
- @request.get("/enlighten").body.should include("<html")
+ it "should say not yet enlightened when socket connection fails" do
+ stub(TCPSocket).new("localhost", 8989) { raise Errno::ECONNREFUSED }
+ @request.get("/").body.should include("Not yet enlightened")
end
- it "should say not yet enlightened" do
- @request.get("/enlighten").body.should include("Not yet enlightened")
- end
-
- describe "with trigger" do
+ describe "/" do
before(:each) do
- begin
- raise Enlighten::Trigger.new
- rescue Enlighten::Trigger => e
- @app.trigger = e
- end
+ @app.socket = MockDebuggerSocket.new
+ @response = @request.get("/")
end
- it "should show text area" do
- @request.get("/enlighten").body.should include("<input")
+ it "should render an HTML view" do
+ @response.body.should include("<html")
end
- it "should" do
- @request.post("/enlighten/execute", :params => {"prompt" => "self.class.name"}).body.should == self.class.name.inspect
+ it "should include text input" do
+ @response.body.should include("<input")
end
end
+
+ it "/debugger/eval should evaluate and return response" do
+ @app.socket = MockDebuggerSocket.new
+ mock(@app.socket).puts("eval chunky")
+ @app.socket.buffer << "bacon"
+ @request.get("/debugger/eval?code=chunky").body.should == "bacon\n"
+ end
end
View
16 spec/enlighten/trigger_spec.rb
@@ -1,16 +0,0 @@
-require "spec_helper"
-
-describe Enlighten::Trigger do
- def trigger
- something = "foo"
- raise Enlighten::Trigger
- end
-
- it "should contain caller's binding" do
- begin
- trigger
- rescue Enlighten::Trigger => e
- eval("something", e.binding_of_caller).should == "foo"
- end
- end
-end
View
60 spec/enlighten_spec.rb
@@ -1,60 +0,0 @@
-require "spec_helper"
-
-class WrapperException < Exception
- attr_accessor :original_exception
- def initialize(original_exception)
- @original_exception = original_exception
- end
-end
-
-describe Enlighten do
- before(:each) do
- @app = nil
- @middleware = Enlighten.new(proc { |e| @app.call(e) })
- @request = Rack::MockRequest.new(@middleware)
- end
-
- describe "simple app" do
- before(:each) do
- @app = proc { |e| [200, {}, ["hello"]] }
- end
-
- it "should pass normal requests through without modification" do
- @request.get("/foobar").body.should == "hello"
- @request.get("/foobar/enlighten").body.should == "hello"
- end
-
- it "should not pass enlighten requests through to application" do
- @request.get("/enlighten").body.should_not == "hello"
- @request.get("/enlighten/foo").body.should_not == "hello"
- end
- end
-
- it "with trigger should rescue from exception and return a successful response" do
- @app = proc { |e| raise Enlighten::Trigger }
- @request.get("/foobar").status.should == 200
- end
-
- it "with trigger in wrapper should rescue from exception and return a successful response" do
- @app = proc { |e| raise WrapperException.new(Enlighten::Trigger.new) }
- @request.get("/foobar").status.should == 200
- end
-
- it "with normal exception should not rescue from the exception" do
- @app = proc { |e| raise "normal exception" }
- lambda { @request.get("/foobar") }.should raise_error(RuntimeError)
- end
-
- it "with normal exception in wrapper should not rescue from the exception" do
- @app = proc { |e| raise WrapperException.new(Exception.new) }
- lambda { @request.get("/foobar") }.should raise_error(WrapperException)
- end
-
- it "should return static files in enlighten path" do
- @request.get("/enlighten/javascripts/jquery-1.4.2.min.js").body.should include("jQuery")
- end
-
- it "should pass to application for other paths" do
- @request.get("/enlighten.js").status.should == 200
- end
-end
View
17 spec/spec_helper.rb
@@ -1,7 +1,22 @@
require "rubygems"
require "spec"
-require "enlighten"
+require "enlighten_app"
Spec::Runner.configure do |config|
config.mock_with :rr
end
+
+class MockDebuggerSocket
+ attr_reader :buffer
+
+ def initialize
+ @buffer = []
+ end
+
+ def puts(content)
+ end
+
+ def gets
+ (@buffer.shift || "PROMPT (rdb:1) ") + "\n"
+ end
+end
View
11 test_debugger.rb
@@ -0,0 +1,11 @@
+# Simple script to start a debugger for testing
+require "rubygems"
+require "ruby-debug"
+Debugger.wait_connection = true
+Debugger.start_remote
+
+before = true
+puts "before"
+debugger
+after = true
+puts "after"
Please sign in to comment.
Something went wrong with that request. Please try again.