Skip to content
Browse files

Initial import

  • Loading branch information...
0 parents commit 0c797d89ab3a329e401246a5456e12436d061703 @Mon-Ouie committed Sep 11, 2011
Showing with 201 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +58 −0 README.md
  3. +4 −0 bin/pry-remote
  4. +113 −0 lib/pry-remote.rb
  5. +25 −0 pry-remote.gemspec
1 .gitignore
@@ -0,0 +1 @@
+*.gem
58 README.md
@@ -0,0 +1,58 @@
+# What is it?
+
+A way to start Pry remotely and to connect to it using DRb. This allows to
+access the state of the running program from anywhere.
+
+# Installation
+
+ gem install pry-remote
+
+# Usage
+
+Here's a program starting pry-remote:
+
+ require 'pry-remote'
+
+ class Foo
+ def initialize(x, y)
+ binding.remote_pry
+ end
+ end
+
+ Foo.new 10, 20
+
+Running it will prompt you with a message telling you Pry is waiting for a
+program to connect itself to it:
+
+ [pry-remote] Waiting for client on drb://localhost:9876
+
+You can then connect yourself using ``pry-remote``:
+
+ $ pry-remote
+ From: example.rb @ line 7 in Foo#initialize:
+ 2:
+ 3: require 'pry-remote'
+ 4:
+ 5: class Foo
+ 6: def initialize(x, y)
+ => 7: binding.remote_pry
+ 8: end
+ 9: end
+ 10:
+ 11: Foo.new 10, 20
+ pry(#<Foo:0x00000000d9b5e8>):1> self
+ => #<Foo:0x1efb3b0>
+ pry(#<Foo:0x00000001efb3b0>):2> ls -l
+ Local variables: [
+ [0] :_,
+ [1] :_dir_,
+ [2] :_file_,
+ [3] :_ex_,
+ [4] :_pry_,
+ [5] :_out_,
+ [6] :_in_,
+ [7] :x,
+ [8] :y
+ ]
+ pry(#<Foo:0x00000001efb3b0>):3> ^D
+
4 bin/pry-remote
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+
+require 'pry-remote'
+PryRemote::CLI.new.run
113 lib/pry-remote.rb
@@ -0,0 +1,113 @@
+require 'pry'
+require 'slop'
+require 'drb'
+require 'readline'
+
+module PryRemote
+ # A class to represent an input object created from DRb. This is used because
+ # Pry checks for arity to know if a prompt should be passed to the object.
+ #
+ # @attr [#readline] input Object to proxy
+ InputProxy = Struct.new :input do
+ # Reads a line from the input
+ def readline(prompt)
+ input.readline(prompt)
+ end
+ end
+
+ # A client is used to retrieve information from the client program.
+ Client = Struct.new :input, :output, :thread do
+ def initialize
+ super nil, nil, nil
+ end
+
+ # Waits until both an input and output are set
+ def wait
+ sleep 0.01 until input and output and thread
+ end
+
+ # Tells the client the session is terminated
+ def kill
+ thread.run
+ end
+
+ # @return [InputProxy] Proxy for the input
+ def input_proxy
+ InputProxy.new input
+ end
+ end
+
+ # Parses arguments and allows to start the client.
+ class CLI
+ def initialize(args = ARGV)
+ params = Slop.parse args, :help => true do
+ banner "#$PROGRAM_NAME [-h HOST] [-p PORT]"
+
+ on :h, :host, "Host of the server (localhost)", true,
+ :default => "localhost"
+ on :p, :port, "Port of the server (9876)", true, :as => Integer,
+ :default => 9876
+ end
+
+ @host = params[:host]
+ @port = params[:port]
+ end
+
+ # @return [String] Host of the server
+ attr_reader :host
+
+ # @return [Integer] Port of the server
+ attr_reader :port
+
+ # @return [String] URI for DRb
+ def uri
+ "druby://#{host}:#{port}"
+ end
+
+ # Connects to the server
+ def run
+ DRb.start_service
+ client = DRbObject.new(nil, uri)
+
+ # Passing Readline to DRb won't actually make it use our readline
+ # object. Instead, it will use the server-side readilne. Therefore, we
+ # create a simple proxy here.
+
+ input = Object.new
+ def input.readline(prompt)
+ Readline.readline(prompt, true)
+ end
+
+ client.input = input
+ client.output = $stdout
+ client.thread = Thread.current
+
+ sleep
+ DRb.stop_service
+ end
+ end
+end
+
+class Object
+ # Starts a remote Pry session
+ #
+ # @param [String] host Host of the server
+ # @param [Integer] port Port of the server
+ def remote_pry(host = "localhost", port = 9876)
+ uri = "druby://#{host}:#{port}"
+
+ client = PryRemote::Client.new
+ DRb.start_service uri, client
+
+ puts "[pry-remote] Waiting for client on #{uri}"
+ client.wait
+
+ puts "[pry-remote] Client received, starting remote sesion"
+ Pry.start(self, :input => client.input_proxy, :output => client.output)
+
+ puts "[pry-remote] Remote sesion terminated"
+ client.kill
+
+ DRb.stop_service
+ end
+end
25 pry-remote.gemspec
@@ -0,0 +1,25 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = "pry-remote"
+
+ s.version = "0.0.1"
+
+ s.summary = "Connect to Pry remotely"
+ s.description = "Connect to Pry remotely using DRb"
+ s.homepage = "http://github.com/Mon-Ouie/pry-remote"
+
+ s.email = "mon.ouie@gmail.com"
+ s.authors = ["Mon ouie"]
+
+ s.files |= Dir["lib/**/*.rb"]
+ s.files |= Dir["*.md"]
+
+ s.require_paths = ["lib"]
+
+ s.add_dependency "slop", "~> 2.1"
+ s.add_dependency "pry", "~> 0.9"
+
+ s.executables = ["pry-remote"]
+end

0 comments on commit 0c797d8

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