pry-remote-em 0.7.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +140 -0
- data/README.md +347 -63
- data/bin/pry-remote-em +40 -21
- data/bin/pry-remote-em-broker +28 -0
- data/lib/pry-remote-em.rb +23 -12
- data/lib/pry-remote-em/broker.rb +85 -63
- data/lib/pry-remote-em/client.rb +75 -130
- data/lib/pry-remote-em/client/broker.rb +6 -3
- data/lib/pry-remote-em/client/generic.rb +7 -6
- data/lib/pry-remote-em/client/interactive_menu.rb +171 -0
- data/lib/pry-remote-em/client/keyboard.rb +11 -15
- data/lib/pry-remote-em/client/proxy.rb +3 -2
- data/lib/pry-remote-em/proto.rb +58 -77
- data/lib/pry-remote-em/sandbox.rb +47 -0
- data/lib/pry-remote-em/server.rb +156 -75
- data/lib/pry-remote-em/server/shell_cmd.rb +1 -1
- data/lib/pry-remote-em/version.rb +1 -1
- metadata +52 -42
@@ -0,0 +1,47 @@
|
|
1
|
+
module PryRemoteEm
|
2
|
+
# See Readme for Sandbox using guide
|
3
|
+
class Sandbox
|
4
|
+
@@last_errors = []
|
5
|
+
|
6
|
+
attr_accessor :pry, :server
|
7
|
+
|
8
|
+
%w[puts putc print p pp].each do |method|
|
9
|
+
define_method method do |*arguments|
|
10
|
+
pry.output.puts(*arguments)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
'sandbox'
|
16
|
+
end
|
17
|
+
|
18
|
+
def any_errors?
|
19
|
+
last_errors.any?
|
20
|
+
end
|
21
|
+
|
22
|
+
def last_error
|
23
|
+
last_errors.last
|
24
|
+
end
|
25
|
+
|
26
|
+
def last_errors
|
27
|
+
@@last_errors
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.add_error(exception, source_binding = nil)
|
31
|
+
unless exception.kind_of?(Exception) && exception.backtrace && (source_binding.nil? || source_binding.kind_of?(Binding))
|
32
|
+
raise ArgumentError, 'exception with backtrace and optional binding expected'
|
33
|
+
end
|
34
|
+
|
35
|
+
return if @@last_errors.include?(exception)
|
36
|
+
|
37
|
+
exception.define_singleton_method(:source_binding) { source_binding } if source_binding
|
38
|
+
|
39
|
+
@@last_errors.push(exception)
|
40
|
+
|
41
|
+
maximum_errors = ENV['PRYEMSANDBOXERRORS'].nil? || ENV['PRYEMSANDBOXERRORS'].empty? ? MAXIMUM_ERRORS_IN_SANDBOX : ENV['PRYEMSANDBOXERRORS'].to_i
|
42
|
+
@@last_errors.shift if @@last_errors.size > maximum_errors
|
43
|
+
end
|
44
|
+
|
45
|
+
Pry.config.prompt_safe_objects.push(self)
|
46
|
+
end
|
47
|
+
end
|
data/lib/pry-remote-em/server.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'pry'
|
2
|
+
require 'socket'
|
2
3
|
require 'logger'
|
4
|
+
require 'securerandom'
|
3
5
|
require 'pry-remote-em'
|
4
6
|
require 'pry-remote-em/broker'
|
5
7
|
require 'pry-remote-em/server/shell_cmd'
|
8
|
+
require 'pry-remote-em/sandbox'
|
6
9
|
|
7
10
|
# How it works with Pry
|
8
11
|
#
|
@@ -34,7 +37,7 @@ require 'pry-remote-em/server/shell_cmd'
|
|
34
37
|
# http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/
|
35
38
|
module PryRemoteEm
|
36
39
|
class << self
|
37
|
-
# Local PryRemoteEm EM signatures
|
40
|
+
# Local PryRemoteEm servers, including EM signatures, indexed by id. Each
|
38
41
|
# signature can be used with high level EM methods like EM.stop_server or
|
39
42
|
# EM.get_sockname. If a server has been stopped EM.get_sockname will return
|
40
43
|
# nil for that server's signature.
|
@@ -44,21 +47,23 @@ module PryRemoteEm
|
|
44
47
|
|
45
48
|
# Safely stop one or more PryRemoteEm servers and remove them from the list
|
46
49
|
# of servers.
|
47
|
-
# @param [String] id url or name
|
48
|
-
|
49
|
-
|
50
|
-
|
50
|
+
# @param [String, nil] argument id, url or name, use `nil` to stop them all
|
51
|
+
# @return [Hash] stopped servers if they were
|
52
|
+
def stop_server(argument = nil)
|
53
|
+
servers_to_stop = if argument
|
54
|
+
servers.select do |id, description|
|
55
|
+
argument == id || description[:urls].include?(argument) || argument == description[:name]
|
56
|
+
end
|
57
|
+
else
|
58
|
+
servers
|
59
|
+
end
|
60
|
+
|
61
|
+
servers_to_stop.each do |id, description|
|
62
|
+
EM.stop_server(description[:server]) if EM.get_sockname(description[:server])
|
51
63
|
Broker.unregister(id)
|
52
64
|
servers.delete(id)
|
53
|
-
return Array(id)
|
54
|
-
end
|
55
|
-
servers.select{ |i, (sig, name)| name == id }.map do |i, (sig, name)|
|
56
|
-
EM.stop_server(sig) if EM.get_sockname(sig)
|
57
|
-
Broker.unregister(i)
|
58
|
-
servers.delete(i)
|
59
|
-
i
|
60
65
|
end
|
61
|
-
end
|
66
|
+
end
|
62
67
|
end
|
63
68
|
|
64
69
|
module Server
|
@@ -66,51 +71,41 @@ module PryRemoteEm
|
|
66
71
|
|
67
72
|
class << self
|
68
73
|
# Start a pry-remote-em server
|
69
|
-
# @param [
|
70
|
-
# @
|
71
|
-
# @
|
72
|
-
# @
|
73
|
-
# @option
|
74
|
-
# @option
|
75
|
-
# @option
|
76
|
-
# @option
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
name = Pry.view_clip(name)
|
105
|
-
PryRemoteEm.servers[url] = [server, name]
|
106
|
-
(opts[:logger] || ::Logger.new(STDERR)).info("[pry-remote-em] listening for connections on #{url}")
|
107
|
-
Broker.run(opts[:broker_host] || ENV['PRYEMBROKER'] || DEF_BROKERHOST, opts[:broker_port] || ENV['PRYEMBROKERPORT'] || DEF_BROKERPORT, opts) do |broker|
|
108
|
-
broker.register(url, name)
|
109
|
-
rereg = EM::PeriodicTimer.new(15) do
|
110
|
-
EM.get_sockname(server) ? broker.register(url, name) : nil #rereg.cancel
|
111
|
-
end
|
112
|
-
end # broker
|
113
|
-
url
|
74
|
+
# @param [Hash] options
|
75
|
+
# @option options [Object] :target Object to bind Pry session, default - PryRemoteEm::Sandbox instance
|
76
|
+
# @option options [String] :host The IP-address to listen on, default - 127.0.0.1 (same as PRYEMHOST environment variable)
|
77
|
+
# @option options [Fixnum, String, Symbol] :port The port to listen on - if :auto or 'auto' the next available port will be taken, default - 6463 (same as PRYEMPORT environment variable)
|
78
|
+
# @option options [String] :id Server's UUID, will be generated automatically unless you pass it explicitly
|
79
|
+
# @option options [Boolean] :tls require SSL encryption, default - false
|
80
|
+
# @option options [Logger] :logger Logger for Pry Server, default - STDERR
|
81
|
+
# @option options [Proc, Object] :auth require user authentication - see README
|
82
|
+
# @option options [Boolean] :allow_shell_cmds Allow shell commands or not, default - true
|
83
|
+
# @option options [Integer, Symbol] :port_fail set to :auto to search for available port in range from given port to port + 100, or pass explicit integer to use instaed of 100, default - 1
|
84
|
+
# @option options [String] :name Server name to show in broker list, default - object's inspect (same as PRYEMNAME environment variable)
|
85
|
+
# @option options [String] :external_url External URL to connect behind firewall, NAT, Docket etc. in form "pryem://my.host:6463", default - use given host and port and expand it to all interfaces in case of 0.0.0.0 (same as PRYEMURL environment variable)
|
86
|
+
# @option options [Integer] :heartbeat_interval Interval to send heartbeats and updated details to broker, default - 15 (same as PRYEMHBSEND environment variable)
|
87
|
+
# @option options [Boolean] :remote_broker Connect to remote broker instead of starting local one, default - false (same as PRYEMREMOTEBROKER environment variable)
|
88
|
+
# @option options [String] :broker_host Broker host to connect to, default - localhost
|
89
|
+
# @option options [String] :broker_port Broker port to connect to, default - 6462
|
90
|
+
# @option options [Hash] :details Optional details to pass to broker and show in table (should consist of string/symbol keys and simple serializable values)
|
91
|
+
def run(options = {}, &block)
|
92
|
+
description = options.dup
|
93
|
+
description[:target] ||= PryRemoteEm::Sandbox.new
|
94
|
+
description[:host] ||= ENV['PRYEMHOST'].nil? || ENV['PRYEMHOST'].empty? ? DEFAULT_SERVER_HOST : ENV['PRYEMHOST']
|
95
|
+
determine_port_and_tries(description)
|
96
|
+
determine_name(description)
|
97
|
+
description[:id] ||= SecureRandom.uuid
|
98
|
+
description[:logger] ||= ::Logger.new(STDERR)
|
99
|
+
description[:external_url] ||= ENV['PRYEMURL'] || "#{description[:tls] ? 'pryems' : 'pryem'}://#{description[:host]}:#{description[:port]}/"
|
100
|
+
description[:details] ||= {}
|
101
|
+
description[:allow_shell_cmds] = true if description[:allow_shell_cmds].nil?
|
102
|
+
description[:heartbeat_interval] ||= ENV['PRYEMHBSEND'].nil? || ENV['PRYEMHBSEND'].empty? ? HEARTBEAT_SEND_INTERVAL : ENV['PRYEMHBSEND']
|
103
|
+
description[:urls] = expand_url(description[:external_url])
|
104
|
+
description[:server] = start_server(description, &block)
|
105
|
+
description[:logger].info("[pry-remote-em] listening for connections on #{description[:external_url]}")
|
106
|
+
PryRemoteEm.servers[description[:id]] = description
|
107
|
+
register_in_broker(description)
|
108
|
+
return description
|
114
109
|
end
|
115
110
|
|
116
111
|
# The list of pry-remote-em connections for a given object, or the list of all pry-remote-em
|
@@ -130,10 +125,84 @@ module PryRemoteEm
|
|
130
125
|
def unregister(obj, peer)
|
131
126
|
peers(obj).tap {|plist| true while plist.delete(peer) }
|
132
127
|
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def determine_port_and_tries(description)
|
132
|
+
description[:port] ||= ENV['PRYEMPORT'].nil? || ENV['PRYEMPORT'].empty? ? DEFAULT_SERVER_PORT : ENV['PRYEMPORT']
|
133
|
+
description[:port] = :auto if description[:port] == 'auto'
|
134
|
+
description[:port] = description[:port].to_i if description[:port].kind_of?(String)
|
135
|
+
description[:tries] = [description[:port], description[:port_fail]].include?(:auto) ? 100 : description[:port_fail] || 1
|
136
|
+
description[:port] = DEFAULT_SERVER_PORT if description[:port] == :auto
|
137
|
+
# TODO raise a useful exception not RuntimeError
|
138
|
+
raise "root permission required for port below 1024 (#{port})" if description[:port] < 1024 && Process.euid != 0
|
139
|
+
end
|
140
|
+
|
141
|
+
def determine_name(description)
|
142
|
+
description[:name] ||= ENV['PRYEMNAME']
|
143
|
+
if description[:name].nil?
|
144
|
+
object = description[:target]
|
145
|
+
inner_object = object.kind_of?(Binding) ? object.send(:eval, 'self') : object
|
146
|
+
description[:name] = Pry.view_clip(inner_object)
|
147
|
+
else
|
148
|
+
description[:custom_name] = true
|
149
|
+
end
|
150
|
+
description[:name] = description[:name].first(57) + '...' if description[:name].size > 60
|
151
|
+
end
|
152
|
+
|
153
|
+
def expand_url(url)
|
154
|
+
return Array(url) if (uri = URI.parse(url)).host != '0.0.0.0'
|
155
|
+
Socket.ip_address_list.select(&:ipv4?).map(&:ip_address).map do |ip|
|
156
|
+
uri.clone.tap { |uri_copy| uri_copy.host = ip }.to_s
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def start_server(description, &block)
|
161
|
+
EM.start_server(description[:host], description[:port], PryRemoteEm::Server, description) do |pre|
|
162
|
+
Fiber.new do
|
163
|
+
begin
|
164
|
+
yield pre if block_given?
|
165
|
+
Pry.hooks.add_hook :when_started, pre do |target, options, pry|
|
166
|
+
pry.pager = false
|
167
|
+
pry.config.prompt_name = description[:name] + ' ' if description[:custom_name]
|
168
|
+
if description[:target].is_a? PryRemoteEm::Sandbox
|
169
|
+
description[:target].pry = pry
|
170
|
+
description[:target].server = description
|
171
|
+
pry.last_exception = description[:target].last_error if description[:target].any_errors?
|
172
|
+
end
|
173
|
+
description[:pry] = pry
|
174
|
+
end
|
175
|
+
Pry.start(description[:target], input: pre, output: pre)
|
176
|
+
ensure
|
177
|
+
pre.close_connection
|
178
|
+
Pry.hooks.delete_hook :when_started, pre
|
179
|
+
end
|
180
|
+
end.resume
|
181
|
+
end
|
182
|
+
rescue => error
|
183
|
+
if error.message.include?('port is in use') && description[:tries] > 1
|
184
|
+
description[:tries] -= 1
|
185
|
+
description[:port] += 1
|
186
|
+
retry
|
187
|
+
end
|
188
|
+
raise "can't bind to #{description[:host]}:#{description[:port]} - #{error}"
|
189
|
+
end
|
190
|
+
|
191
|
+
def register_in_broker(description)
|
192
|
+
broker_description = { id: description[:id], urls: description[:urls], name: description[:name], details: description[:details] }
|
193
|
+
broker_options = { tls: description[:tls], remote_broker: description[:remote_broker], logger: description[:logger] }
|
194
|
+
Broker.run(description[:broker_host], description[:broker_port], broker_options) do |broker|
|
195
|
+
broker.register(broker_description)
|
196
|
+
|
197
|
+
rereg = EM::PeriodicTimer.new(description[:heartbeat_interval]) do
|
198
|
+
EM.get_sockname(description[:server]) ? broker.register(broker_description) : nil #rereg.cancel
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
133
202
|
end # class << self
|
134
203
|
|
135
|
-
def initialize(
|
136
|
-
@obj =
|
204
|
+
def initialize(opts = {})
|
205
|
+
@obj = opts[:target]
|
137
206
|
@opts = opts
|
138
207
|
@allow_shell_cmds = opts[:allow_shell_cmds]
|
139
208
|
@log = opts[:logger] || ::Logger.new(STDERR)
|
@@ -162,7 +231,7 @@ module PryRemoteEm
|
|
162
231
|
return fail("auth handler must take two arguments not (#{a.method(:call).arity})") unless a.method(:call).arity == 2
|
163
232
|
@auth = a
|
164
233
|
else
|
165
|
-
return error(
|
234
|
+
return error('auth handler objects must respond to :call, or :[]') unless a.respond_to?(:[])
|
166
235
|
@auth = lambda {|u,p| a[u] && a[u] == p }
|
167
236
|
end
|
168
237
|
end
|
@@ -174,10 +243,9 @@ module PryRemoteEm
|
|
174
243
|
|
175
244
|
def post_init
|
176
245
|
@lines = []
|
177
|
-
Pry.config.pager, @old_pager = false, Pry.config.pager
|
178
246
|
@auth_required = @auth
|
179
|
-
port, ip = Socket.unpack_sockaddr_in(get_peername)
|
180
|
-
@log.info("[pry-remote-em] received client connection from #{ip}:#{port}")
|
247
|
+
@port, @ip = Socket.unpack_sockaddr_in(get_peername)
|
248
|
+
@log.info("[pry-remote-em] received client connection from #{@ip}:#{@port}")
|
181
249
|
# TODO include first level prompt in banner
|
182
250
|
send_banner("PryRemoteEm #{VERSION} #{@opts[:tls] ? 'pryems' : 'pryem'}")
|
183
251
|
@log.info("#{url} PryRemoteEm #{VERSION} #{@opts[:tls] ? 'pryems' : 'pryem'}")
|
@@ -197,22 +265,36 @@ module PryRemoteEm
|
|
197
265
|
|
198
266
|
def peer_ip
|
199
267
|
return @peer_ip if @peer_ip
|
200
|
-
return
|
268
|
+
return '' if get_peername.nil?
|
201
269
|
@peer_port, @peer_ip = Socket.unpack_sockaddr_in(get_peername)
|
202
270
|
@peer_ip
|
203
271
|
end
|
204
272
|
|
205
273
|
def peer_port
|
206
274
|
return @peer_port if @peer_port
|
207
|
-
return
|
275
|
+
return '' if get_peername.nil?
|
208
276
|
@peer_port, @peer_ip = Socket.unpack_sockaddr_in(get_peername)
|
209
277
|
@peer_port
|
210
278
|
end
|
211
279
|
|
280
|
+
def receive_clear_buffer
|
281
|
+
@opts[:pry].eval_string.replace('')
|
282
|
+
@last_prompt = @opts[:pry].select_prompt
|
283
|
+
send_last_prompt
|
284
|
+
end
|
285
|
+
|
212
286
|
def receive_raw(d)
|
213
287
|
return if require_auth
|
214
|
-
|
215
|
-
|
288
|
+
|
289
|
+
return send_last_prompt if d.nil?
|
290
|
+
|
291
|
+
if d.empty?
|
292
|
+
@lines.push('')
|
293
|
+
else
|
294
|
+
lines = d.split("\n")
|
295
|
+
@lines.push(*lines)
|
296
|
+
end
|
297
|
+
|
216
298
|
if @waiting
|
217
299
|
f, @waiting = @waiting, nil
|
218
300
|
f.resume(@lines.shift)
|
@@ -236,7 +318,7 @@ module PryRemoteEm
|
|
236
318
|
else
|
237
319
|
auth_fail(user, peer_ip)
|
238
320
|
if @auth_tries <= 0
|
239
|
-
msg =
|
321
|
+
msg = 'max authentication attempts reached'
|
240
322
|
send_auth(msg)
|
241
323
|
@log.debug("[pry-remote-em] #{msg} (#{peer_ip}:#{peer_port})")
|
242
324
|
return close_connection_after_writing
|
@@ -278,7 +360,7 @@ module PryRemoteEm
|
|
278
360
|
|
279
361
|
def receive_shell_sig(type)
|
280
362
|
return if require_auth
|
281
|
-
type == :
|
363
|
+
@shell_cmd.close_connection if type == :int
|
282
364
|
end
|
283
365
|
|
284
366
|
def receive_unknown(j)
|
@@ -301,9 +383,8 @@ module PryRemoteEm
|
|
301
383
|
end
|
302
384
|
|
303
385
|
def unbind
|
304
|
-
Pry.config.pager = @old_pager
|
305
386
|
PryRemoteEm::Server.unregister(@obj, self)
|
306
|
-
@log.debug("[pry-remote-em] remote session terminated (#{
|
387
|
+
@log.debug("[pry-remote-em] remote session terminated (#{@ip}:#{@port})")
|
307
388
|
end
|
308
389
|
|
309
390
|
def peers(all = false)
|
@@ -324,13 +405,13 @@ module PryRemoteEm
|
|
324
405
|
# Sends a chat message to the client.
|
325
406
|
def send_message(msg, from = nil)
|
326
407
|
msg = "#{msg} (@#{from})" unless from.nil?
|
327
|
-
@auth_required ?
|
408
|
+
@auth_required ? (after_auth {send_msg(msg)}) : send_msg(msg)
|
328
409
|
end
|
329
410
|
#
|
330
411
|
# Sends a chat message to the client.
|
331
412
|
def send_bmessage(msg, from = nil)
|
332
413
|
msg = "#{msg} (@#{from})" unless from.nil?
|
333
|
-
@auth_required ?
|
414
|
+
@auth_required ? (after_auth {send_msg_bcast(msg)}) : send_msg_bcast(msg)
|
334
415
|
end
|
335
416
|
|
336
417
|
# Callbacks for events on the server
|
@@ -390,7 +471,7 @@ module PryRemoteEm
|
|
390
471
|
end
|
391
472
|
alias :write :print
|
392
473
|
|
393
|
-
def puts(data =
|
474
|
+
def puts(data = '')
|
394
475
|
s = data.to_s
|
395
476
|
print(s[0] == "\n" ? s : s + "\n")
|
396
477
|
end
|
metadata
CHANGED
@@ -1,124 +1,134 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pry-remote-em
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Caleb Crane
|
8
|
+
- Xanders
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-08-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
17
|
requirements:
|
19
|
-
- -
|
18
|
+
- - "~>"
|
20
19
|
- !ruby/object:Gem::Version
|
21
|
-
version: '
|
20
|
+
version: '1'
|
22
21
|
type: :runtime
|
23
22
|
prerelease: false
|
24
23
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
24
|
requirements:
|
27
|
-
- -
|
25
|
+
- - "~>"
|
28
26
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
27
|
+
version: '1'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: msgpack
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1'
|
30
42
|
- !ruby/object:Gem::Dependency
|
31
43
|
name: pry
|
32
44
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
45
|
requirements:
|
35
|
-
- - ~>
|
46
|
+
- - "~>"
|
36
47
|
- !ruby/object:Gem::Version
|
37
|
-
version: '0.
|
48
|
+
version: '0.11'
|
38
49
|
type: :runtime
|
39
50
|
prerelease: false
|
40
51
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
52
|
requirements:
|
43
|
-
- - ~>
|
53
|
+
- - "~>"
|
44
54
|
- !ruby/object:Gem::Version
|
45
|
-
version: '0.
|
55
|
+
version: '0.11'
|
46
56
|
- !ruby/object:Gem::Dependency
|
47
57
|
name: ruby-termios
|
48
58
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
59
|
requirements:
|
51
|
-
- - ~>
|
60
|
+
- - "~>"
|
52
61
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0
|
54
|
-
type: :
|
62
|
+
version: '1.0'
|
63
|
+
type: :runtime
|
55
64
|
prerelease: false
|
56
65
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
66
|
requirements:
|
59
|
-
- - ~>
|
67
|
+
- - "~>"
|
60
68
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0
|
69
|
+
version: '1.0'
|
62
70
|
- !ruby/object:Gem::Dependency
|
63
71
|
name: highline
|
64
72
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
73
|
requirements:
|
67
|
-
- -
|
74
|
+
- - "~>"
|
68
75
|
- !ruby/object:Gem::Version
|
69
|
-
version: '0'
|
76
|
+
version: '2.0'
|
70
77
|
type: :runtime
|
71
78
|
prerelease: false
|
72
79
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
80
|
requirements:
|
75
|
-
- -
|
81
|
+
- - "~>"
|
76
82
|
- !ruby/object:Gem::Version
|
77
|
-
version: '0'
|
83
|
+
version: '2.0'
|
78
84
|
description: Connect to Pry remotely using EventMachine with tab-completion, paging,
|
79
85
|
user auth and SSL
|
80
86
|
email: pry-remote-em@simulacre.org
|
81
87
|
executables:
|
82
88
|
- pry-remote-em
|
89
|
+
- pry-remote-em-broker
|
83
90
|
extensions: []
|
84
91
|
extra_rdoc_files: []
|
85
92
|
files:
|
93
|
+
- CHANGELOG.md
|
94
|
+
- README.md
|
95
|
+
- bin/pry-remote-em
|
96
|
+
- bin/pry-remote-em-broker
|
97
|
+
- lib/pry-remote-em.rb
|
86
98
|
- lib/pry-remote-em/broker.rb
|
99
|
+
- lib/pry-remote-em/client.rb
|
87
100
|
- lib/pry-remote-em/client/broker.rb
|
88
101
|
- lib/pry-remote-em/client/generic.rb
|
102
|
+
- lib/pry-remote-em/client/interactive_menu.rb
|
89
103
|
- lib/pry-remote-em/client/keyboard.rb
|
90
104
|
- lib/pry-remote-em/client/proxy.rb
|
91
|
-
- lib/pry-remote-em/client.rb
|
92
105
|
- lib/pry-remote-em/proto.rb
|
93
|
-
- lib/pry-remote-em/
|
106
|
+
- lib/pry-remote-em/sandbox.rb
|
94
107
|
- lib/pry-remote-em/server.rb
|
108
|
+
- lib/pry-remote-em/server/shell_cmd.rb
|
95
109
|
- lib/pry-remote-em/version.rb
|
96
|
-
|
97
|
-
|
98
|
-
-
|
99
|
-
|
100
|
-
licenses: []
|
110
|
+
homepage: https://github.com/gruis/pry-remote-em
|
111
|
+
licenses:
|
112
|
+
- Nonstandard
|
113
|
+
metadata: {}
|
101
114
|
post_install_message:
|
102
115
|
rdoc_options: []
|
103
116
|
require_paths:
|
104
117
|
- lib
|
105
118
|
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
119
|
requirements:
|
108
|
-
- -
|
120
|
+
- - ">="
|
109
121
|
- !ruby/object:Gem::Version
|
110
122
|
version: '0'
|
111
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
-
none: false
|
113
124
|
requirements:
|
114
|
-
- -
|
125
|
+
- - ">="
|
115
126
|
- !ruby/object:Gem::Version
|
116
127
|
version: '0'
|
117
128
|
requirements: []
|
118
129
|
rubyforge_project:
|
119
|
-
rubygems_version:
|
130
|
+
rubygems_version: 2.6.13
|
120
131
|
signing_key:
|
121
|
-
specification_version:
|
132
|
+
specification_version: 4
|
122
133
|
summary: Connect to Pry remotely using EventMachine
|
123
134
|
test_files: []
|
124
|
-
has_rdoc:
|