Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seperate module #54

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions lib/cli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
module PryRemote
# Parses arguments and allows to start the client.
class CLI
def initialize(args = ARGV)
params = Slop.parse args, help: true do
banner "#$PROGRAM_NAME [OPTIONS]"

on :s, :server=, "Host of the server (#{DefaultHost})", argument: :optional,
:default => DefaultHost
on :p, :port=, "Port of the server (#{DefaultPort})", argument: :optional,
a: Integer, default: DefaultPort
on :w, :wait, "Wait for the pry server to come up",
default: false
on :r, :persist, "Persist the client to wait for the pry server to come up each time",
default: false
on :c, :capture, "Captures $stdout and $stderr from the server (true)",
default: true
on :f, "Disables loading of .pryrc and its plugins, requires, and command history "
end

exit if params.help?

@host = params[:server]
@port = params[:port]

@wait = params[:wait]
@persist = params[:persist]
@capture = params[:capture]

Pry.initial_session_setup unless params[:f]
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

attr_reader :wait
attr_reader :persist
attr_reader :capture
alias wait? wait
alias persist? persist
alias capture? capture

def run
while true
connect
break unless persist?
end
end

# Connects to the server
#
# @param [IO] input Object holding input for pry-remote
# @param [IO] output Object pry-debug will send its output to
def connect(input = Pry.config.input, output = Pry.config.output)
local_ip = UDPSocket.open { |s| s.connect(@host, 1); s.addr.last }
DRb.start_service "druby://#{local_ip}:0"
client = DRbObject.new(nil, uri)

cleanup(client)

input = IOUndumpedProxy.new(input)
output = IOUndumpedProxy.new(output)

begin
client.input = input
client.output = output
rescue DRb::DRbConnError => ex
if wait? || persist?
sleep 1
retry
else
raise ex
end
end

if capture?
client.stdout = $stdout
client.stderr = $stderr
end

client.thread = Thread.current

sleep
DRb.stop_service
end

# Clean up the client
def cleanup(client)
begin
# The method we are calling here doesn't matter.
# This is a hack to close the connection of DRb.
client.cleanup
rescue DRb::DRbConnError, NoMethodError
end
end
end
end
24 changes: 24 additions & 0 deletions lib/client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module PryRemote
# A client is used to retrieve information from the client program.
class Client
attr_accessor :input, :output, :thread, :stdout, :stderr

def initialize
end

# Waits until both an input and output are set
def wait
sleep 0.01 until input && output && 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
end
25 changes: 25 additions & 0 deletions lib/input_proxy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
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)
case readline_arity
when 1 then input.readline(prompt)
else input.readline
end
end

def completion_proc=(val)
input.completion_proc = val
end

def readline_arity
input.method_missing(:method, :readline).arity
rescue NameError
0
end
end
end
61 changes: 61 additions & 0 deletions lib/io_undumped_proxy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module PryRemote
# Class used to wrap inputs so that they can be sent through DRb.
#
# This is to ensure the input is used locally and not reconstructed on the
# server by DRb.
class IOUndumpedProxy
include DRb::DRbUndumped

def initialize(obj)
@obj = obj
end

def completion_proc=(val)
if @obj.respond_to? :completion_proc=
@obj.completion_proc = val
end
end

def completion_proc
@obj.completion_proc if @obj.respond_to? :completion_proc
end

def readline(prompt)
if Readline == @obj
@obj.readline(prompt, true)
elsif @obj.method(:readline).arity == 1
@obj.readline(prompt)
else
$stdout.print prompt
@obj.readline
end
end

def puts(*lines)
@obj.puts(*lines)
end

def print(*objs)
@obj.print(*objs)
end

def printf(*args)
@obj.printf(*args)
end

def write(data)
@obj.write data
end

def <<(data)
@obj << data
self
end

# Some versions of Pry expect $stdout or its output objects to respond to
# this message.
def tty?
false
end
end
end
Loading