utils 0.2.4 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/classify +15 -3
- data/bin/discover +25 -10
- data/bin/edit +16 -9
- data/bin/probe +36 -11
- data/bin/search +87 -8
- data/lib/utils.rb +4 -1
- data/lib/utils/finder.rb +0 -3
- data/lib/utils/grepper.rb +6 -13
- data/lib/utils/irb.rb +78 -182
- data/lib/utils/irb/service.rb +39 -0
- data/lib/utils/line_formatter.rb +162 -103
- data/lib/utils/patterns.rb +2 -0
- data/lib/utils/probe_server.rb +62 -82
- data/lib/utils/version.rb +1 -1
- data/utils.gemspec +12 -12
- data/utils.gemspec +0 -0
- metadata +10 -7
data/lib/utils/irb.rb
CHANGED
@@ -1,30 +1,60 @@
|
|
1
1
|
require 'tins/xt'
|
2
2
|
require 'irb/completion'
|
3
3
|
require 'enumerator'
|
4
|
+
require 'tempfile'
|
4
5
|
require 'pp'
|
5
6
|
require_maybe 'ap'
|
6
7
|
if Readline.respond_to?(:point) && Readline.respond_to?(:line_buffer)
|
7
8
|
require 'pry-editline'
|
8
9
|
end
|
9
10
|
require 'utils'
|
10
|
-
require 'drb'
|
11
11
|
|
12
12
|
$editor = Utils::Editor.new
|
13
13
|
$pager = ENV['PAGER'] || 'less -r'
|
14
14
|
|
15
15
|
module Utils
|
16
16
|
module IRB
|
17
|
+
require 'utils/irb/service'
|
17
18
|
|
18
19
|
module Shell
|
19
20
|
require 'fileutils'
|
20
21
|
include FileUtils
|
21
22
|
include Tins::Find
|
22
23
|
|
24
|
+
def receiver_unless_main(method, &block)
|
25
|
+
receiver_name = method.receiver.to_s
|
26
|
+
if receiver_name != 'main'
|
27
|
+
if block
|
28
|
+
block.(receiver_name)
|
29
|
+
else
|
30
|
+
receiver_name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
private :receiver_unless_main
|
35
|
+
|
23
36
|
# Start _ri_ for +pattern+. If +pattern+ is not string like, call it with
|
24
37
|
# pattern.class.name as argument.
|
25
|
-
def ri(*patterns)
|
26
|
-
patterns.
|
27
|
-
|
38
|
+
def ri(*patterns, doc: 'ri')
|
39
|
+
patterns.empty? and
|
40
|
+
receiver_unless_main(method(__method__)) do |pattern|
|
41
|
+
return ri(pattern, doc: doc)
|
42
|
+
end
|
43
|
+
patterns.map! { |p|
|
44
|
+
case
|
45
|
+
when Module === p
|
46
|
+
p.name
|
47
|
+
when p.respond_to?(:to_str)
|
48
|
+
p.to_str
|
49
|
+
else
|
50
|
+
p.class.name
|
51
|
+
end
|
52
|
+
}
|
53
|
+
system "#{doc} #{patterns.map { |p| "'#{p}'" } * ' ' } | #$pager"
|
54
|
+
end
|
55
|
+
|
56
|
+
def yri(*patterns)
|
57
|
+
ri *patterns, doc: 'yri'
|
28
58
|
end
|
29
59
|
|
30
60
|
# Restart this irb.
|
@@ -32,53 +62,70 @@ module Utils
|
|
32
62
|
exec $0
|
33
63
|
end
|
34
64
|
|
65
|
+
def irb_open(url = nil, &block)
|
66
|
+
case
|
67
|
+
when url
|
68
|
+
system 'open', url
|
69
|
+
when block
|
70
|
+
Tempfile.open('wb') do |t|
|
71
|
+
t.write capture_output(&block)
|
72
|
+
t.rewind
|
73
|
+
system 'open', t.path
|
74
|
+
end
|
75
|
+
when url = receiver_unless_main(method(__method__))
|
76
|
+
irb_open url
|
77
|
+
else
|
78
|
+
raise ArgumentError, 'need an url or block'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
35
82
|
# Start an irb server.
|
36
|
-
def irb_server(
|
37
|
-
Utils::IRB::Service.start(
|
83
|
+
def irb_server(uri = nil)
|
84
|
+
Utils::IRB::Service.start(uri) {}
|
38
85
|
end
|
39
86
|
|
40
87
|
# Connect to an irb server.
|
41
|
-
def irb_connect(
|
42
|
-
Utils::IRB::Service.connect(
|
88
|
+
def irb_connect(uri = nil)
|
89
|
+
Utils::IRB::Service.connect(uri)
|
43
90
|
end
|
44
91
|
|
45
92
|
# TODO: change the API of this stuff
|
46
93
|
|
47
94
|
# Return all instance methods of obj's class.
|
48
|
-
def irb_all_class_instance_methods(obj)
|
95
|
+
def irb_all_class_instance_methods(obj = self)
|
49
96
|
methods = obj.class.instance_methods
|
50
97
|
irb_wrap_methods obj, methods
|
51
98
|
end
|
52
99
|
|
53
100
|
# Return instance methods of obj's class without the inherited/mixed in
|
54
101
|
# methods.
|
55
|
-
def irb_class_instance_methods(obj)
|
102
|
+
def irb_class_instance_methods(obj = self)
|
56
103
|
methods = obj.class.instance_methods(false)
|
57
104
|
irb_wrap_methods obj, methods
|
58
105
|
end
|
59
106
|
|
60
107
|
# Return all instance methods defined in module modul.
|
61
|
-
def irb_all_instance_methods(modul)
|
108
|
+
def irb_all_instance_methods(modul = self)
|
62
109
|
methods = modul.instance_methods
|
63
110
|
irb_wrap_methods modul, methods, true
|
64
111
|
end
|
65
112
|
|
66
113
|
# Return instance methods defined in module modul without the inherited/mixed
|
67
114
|
# in methods.
|
68
|
-
def irb_instance_methods(modul)
|
115
|
+
def irb_instance_methods(modul = self)
|
69
116
|
methods = modul.instance_methods(false)
|
70
117
|
irb_wrap_methods modul, methods, true
|
71
118
|
end
|
72
119
|
|
73
120
|
# Return all methods of obj (including obj's eigenmethods.)
|
74
|
-
def irb_all_methods(obj)
|
121
|
+
def irb_all_methods(obj = self)
|
75
122
|
methods = obj.methods
|
76
123
|
irb_wrap_methods obj, methods
|
77
124
|
end
|
78
125
|
|
79
126
|
# Return instance methods of obj's class without the inherited/mixed in
|
80
127
|
# methods, but including obj's eigenmethods.
|
81
|
-
def irb_methods(obj)
|
128
|
+
def irb_methods(obj = self)
|
82
129
|
methods = obj.class.ancestors[1..-1].inject(obj.methods) do |all, a|
|
83
130
|
all -= a.instance_methods
|
84
131
|
end
|
@@ -86,23 +133,16 @@ module Utils
|
|
86
133
|
end
|
87
134
|
|
88
135
|
# Return all eigen methods of obj.
|
89
|
-
def irb_eigen_methods(obj)
|
136
|
+
def irb_eigen_methods(obj = self)
|
90
137
|
irb_wrap_methods obj, obj.methods(false)
|
91
138
|
end
|
92
139
|
|
93
|
-
def irb_wrap_methods(obj, methods, modul = false)
|
140
|
+
def irb_wrap_methods(obj = self, methods = methods(), modul = false)
|
94
141
|
methods.map do |name|
|
95
142
|
MethodWrapper.new(obj, name, modul) rescue nil
|
96
143
|
end.compact.sort!
|
97
144
|
end
|
98
145
|
|
99
|
-
def irb_clipboard
|
100
|
-
case RUBY_PLATFORM
|
101
|
-
when /darwin/
|
102
|
-
'reattach-to-user-namespace pbcopy'
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
146
|
class WrapperBase
|
107
147
|
include Comparable
|
108
148
|
|
@@ -147,7 +187,7 @@ module Utils
|
|
147
187
|
def initialize(obj, name, modul)
|
148
188
|
super(name)
|
149
189
|
@method = modul ? obj.instance_method(name) : obj.method(name)
|
150
|
-
@description =
|
190
|
+
@description = @method.description(style: :namespace)
|
151
191
|
end
|
152
192
|
|
153
193
|
attr_reader :method
|
@@ -180,12 +220,12 @@ module Utils
|
|
180
220
|
end
|
181
221
|
|
182
222
|
# Return all the constants defined in +modul+.
|
183
|
-
def irb_constants(modul)
|
223
|
+
def irb_constants(modul = self)
|
184
224
|
modul.constants.map { |c| ConstantWrapper.new(modul.const_get(c), c) }.sort
|
185
225
|
end
|
186
226
|
|
187
227
|
# Return all the subclasses of +klass+. TODO implement subclasses w/out rails
|
188
|
-
def irb_subclasses(klass)
|
228
|
+
def irb_subclasses(klass = self)
|
189
229
|
klass.subclasses.map { |c| ConstantWrapper.new(eval(c), c) }.sort
|
190
230
|
end
|
191
231
|
|
@@ -193,76 +233,7 @@ module Utils
|
|
193
233
|
Infinity = 1.0 / 0 # I like to define the infinite.
|
194
234
|
end
|
195
235
|
|
196
|
-
# Output all kinds of information about +obj+. If detailed is given output
|
197
|
-
# details about the methods (+ arity) in inheritance chain of +obj+ as well.
|
198
|
-
# * detailed as 0 output instance methods only of part 0 (the first) of the
|
199
|
-
# chain.
|
200
|
-
# * detailed as 1..2 output instance methods of +obj+ inherited from parts 1
|
201
|
-
# and 2 of the the chain.
|
202
|
-
def irb_info(obj, detailed = nil)
|
203
|
-
if Module === obj
|
204
|
-
modul = obj
|
205
|
-
klassp = Class === modul
|
206
|
-
if klassp
|
207
|
-
begin
|
208
|
-
allocated = modul.allocate
|
209
|
-
rescue TypeError
|
210
|
-
else
|
211
|
-
obj = allocated
|
212
|
-
end
|
213
|
-
end
|
214
|
-
else
|
215
|
-
modul = obj.class
|
216
|
-
end
|
217
|
-
inspected = obj.inspect
|
218
|
-
puts "obj = #{inspected.size > 40 ? inspected[0, 40] + '...' : inspected} is of class #{obj.class}."
|
219
|
-
am = irb_all_methods(obj).size
|
220
|
-
ms = irb_methods(obj).size
|
221
|
-
ems = irb_eigen_methods(obj).size
|
222
|
-
puts "obj: #{am} methods, #{ms} only local#{ems > 0 ? " (#{ems} eigenmethods),": ','} #{am - ms} inherited/mixed in."
|
223
|
-
acim = irb_all_class_instance_methods(obj).size
|
224
|
-
cim = irb_class_instance_methods(obj).size
|
225
|
-
puts "obj: #{acim} instance methods, #{cim} local, #{acim - cim} only inherited/mixed in."
|
226
|
-
if klassp
|
227
|
-
s = modul.superclass
|
228
|
-
puts "Superclass of #{modul}: #{s}"
|
229
|
-
end
|
230
|
-
a = []
|
231
|
-
ec = true
|
232
|
-
begin
|
233
|
-
a << (class << obj; self; end)
|
234
|
-
rescue TypeError
|
235
|
-
ec = false
|
236
|
-
end
|
237
|
-
a.concat modul.ancestors
|
238
|
-
if ec
|
239
|
-
puts "Ancestors of #{modul}: (#{a[0]},) #{a[1..-1].map { |k| "#{k}#{k == s ? '*' : ''}" } * ', '}"
|
240
|
-
else
|
241
|
-
puts "Ancestors of #{modul}: #{a[0..-1].map { |k| "#{k}#{k == s ? '*' : ''}" } * ', '}"
|
242
|
-
end
|
243
|
-
if Class === modul and detailed
|
244
|
-
if detailed.respond_to? :to_int
|
245
|
-
detailed = detailed..detailed
|
246
|
-
end
|
247
|
-
detailed.each do |i|
|
248
|
-
break if i >= a.size
|
249
|
-
k = a[i]
|
250
|
-
puts "#{k}:"
|
251
|
-
puts irb_wrap_methods(obj, k.instance_methods(false)).sort
|
252
|
-
end
|
253
|
-
end
|
254
|
-
nil
|
255
|
-
end
|
256
|
-
|
257
|
-
# Output *all* the irb_info about +obj+. You may need to buy a bigger screen for
|
258
|
-
# this or use:
|
259
|
-
# less { irb_fullinfo object }
|
260
|
-
def irb_fullinfo(obj)
|
261
|
-
irb_info obj, 0..Infinity
|
262
|
-
end
|
263
|
-
|
264
236
|
def capture_output(with_stderr = false)
|
265
|
-
return "missing block" unless block_given?
|
266
237
|
require 'tempfile'
|
267
238
|
begin
|
268
239
|
old_stdout, $stdout = $stdout, Tempfile.new('irb')
|
@@ -319,8 +290,12 @@ module Utils
|
|
319
290
|
end
|
320
291
|
end
|
321
292
|
|
322
|
-
def irb_write(filename, text = nil)
|
323
|
-
|
293
|
+
def irb_write(filename, text = nil, &block)
|
294
|
+
if text.nil? && block
|
295
|
+
File.secure_write filename, nil, 'wb', &block
|
296
|
+
else
|
297
|
+
File.secure_write filename, text, 'wb'
|
298
|
+
end
|
324
299
|
end
|
325
300
|
|
326
301
|
def irb_read(filename, chunk_size = 8_192)
|
@@ -367,6 +342,10 @@ module Utils
|
|
367
342
|
$editor.full?(:edit, *files)
|
368
343
|
end
|
369
344
|
|
345
|
+
def edit
|
346
|
+
$editor.full?(:edit, self)
|
347
|
+
end
|
348
|
+
|
370
349
|
# List contents of directory
|
371
350
|
def ls(*args)
|
372
351
|
puts `ls #{args.map { |x| "'#{x}'" } * ' '}`
|
@@ -388,25 +367,6 @@ module Utils
|
|
388
367
|
end
|
389
368
|
end
|
390
369
|
|
391
|
-
module Module
|
392
|
-
# Start +ri+ for +module#pattern+, trying to find a method matching +pattern+
|
393
|
-
# for all modules in the ancestors chain of this module.
|
394
|
-
def ri(pattern = nil)
|
395
|
-
if pattern
|
396
|
-
pattern = pattern.to_sym.to_s if pattern.respond_to? :to_sym
|
397
|
-
ancestors.each do |a|
|
398
|
-
if method = a.instance_methods(false).find { |m| pattern === m }
|
399
|
-
a = Object if a == Kernel # ri seems to be confused
|
400
|
-
system "ri #{a}##{method} | #{$pager}"
|
401
|
-
end
|
402
|
-
end
|
403
|
-
else
|
404
|
-
system "ri #{self} | #{$pager}"
|
405
|
-
end
|
406
|
-
return
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
370
|
module Regexp
|
411
371
|
# Show the match of this Regexp on the +string+.
|
412
372
|
def show_match(string)
|
@@ -430,59 +390,6 @@ module Utils
|
|
430
390
|
end
|
431
391
|
end
|
432
392
|
|
433
|
-
module Relation
|
434
|
-
def explain
|
435
|
-
connection.select_all("EXPLAIN #{to_sql}")
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
module Service
|
440
|
-
class << self
|
441
|
-
attr_accessor :hostname
|
442
|
-
|
443
|
-
attr_accessor :port
|
444
|
-
|
445
|
-
def start(hostname = nil, port = nil, &block)
|
446
|
-
hostname ||= self.hostname
|
447
|
-
port ||= self.port
|
448
|
-
block ||= proc {}
|
449
|
-
uri = "druby://#{hostname}:#{port}"
|
450
|
-
puts "Starting IRB server listening to #{uri.inspect}."
|
451
|
-
DRb.start_service(uri, eval('irb_current_working_binding', block.binding))
|
452
|
-
end
|
453
|
-
|
454
|
-
def connect(hostname = nil, port = nil)
|
455
|
-
hostname ||= self.hostname
|
456
|
-
port ||= self.port
|
457
|
-
uri = "druby://#{hostname}:#{port}"
|
458
|
-
irb = DRbObject.new_with_uri(uri)
|
459
|
-
Proxy.new(irb)
|
460
|
-
end
|
461
|
-
end
|
462
|
-
|
463
|
-
self.hostname = 'localhost'
|
464
|
-
|
465
|
-
self.port = 6642
|
466
|
-
|
467
|
-
class Proxy
|
468
|
-
def initialize(irb)
|
469
|
-
@irb = irb
|
470
|
-
end
|
471
|
-
|
472
|
-
def eval(code)
|
473
|
-
@irb.conf.workspace.evaluate nil, code
|
474
|
-
end
|
475
|
-
|
476
|
-
def load(filename)
|
477
|
-
unless filename.start_with?('/')
|
478
|
-
filename = File.expand_path filename
|
479
|
-
end
|
480
|
-
@irb.load filename
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
end
|
485
|
-
|
486
393
|
def self.configure
|
487
394
|
::IRB.conf[:SAVE_HISTORY] = 1000
|
488
395
|
if ::IRB.conf[:PROMPT]
|
@@ -501,12 +408,11 @@ end
|
|
501
408
|
|
502
409
|
Utils::IRB.configure
|
503
410
|
|
504
|
-
|
505
411
|
module IRB
|
506
412
|
class Context
|
507
413
|
def init_save_history
|
508
|
-
unless
|
509
|
-
@io.extend
|
414
|
+
unless @io.singleton_class < HistorySavingAbility
|
415
|
+
@io.extend HistorySavingAbility
|
510
416
|
end
|
511
417
|
end
|
512
418
|
|
@@ -568,12 +474,6 @@ module IRB
|
|
568
474
|
end
|
569
475
|
end
|
570
476
|
|
571
|
-
if defined?(ActiveRecord::Relation) && !ActiveRecord::Relation.method_defined?(:examine)
|
572
|
-
class ActiveRecord::Relation
|
573
|
-
include Utils::IRB::Relation
|
574
|
-
end
|
575
|
-
end
|
576
|
-
|
577
477
|
class String
|
578
478
|
include Utils::IRB::String
|
579
479
|
end
|
@@ -582,10 +482,6 @@ class Object
|
|
582
482
|
include Utils::IRB::Shell
|
583
483
|
end
|
584
484
|
|
585
|
-
class Module
|
586
|
-
include Utils::IRB::Module
|
587
|
-
end
|
588
|
-
|
589
485
|
class Regexp
|
590
486
|
include Utils::IRB::Regexp
|
591
487
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'drb'
|
2
|
+
|
3
|
+
module Utils::IRB::Service
|
4
|
+
class << self
|
5
|
+
attr_accessor :hostname
|
6
|
+
|
7
|
+
attr_accessor :port
|
8
|
+
|
9
|
+
def start(uri = nil, &block)
|
10
|
+
uri ||= "druby://localhost:6642"
|
11
|
+
block ||= proc {}
|
12
|
+
puts "Starting IRB server listening to #{uri.inspect}."
|
13
|
+
DRb.start_service(uri, eval('irb_current_working_binding', block.binding))
|
14
|
+
end
|
15
|
+
|
16
|
+
def connect(uri = nil)
|
17
|
+
uri ||= "druby://localhost:6642"
|
18
|
+
irb = DRbObject.new_with_uri(uri)
|
19
|
+
Proxy.new(irb)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Proxy
|
24
|
+
def initialize(irb)
|
25
|
+
@irb = irb
|
26
|
+
end
|
27
|
+
|
28
|
+
def eval(code)
|
29
|
+
@irb.conf.workspace.evaluate nil, code
|
30
|
+
end
|
31
|
+
|
32
|
+
def load(filename)
|
33
|
+
unless filename.start_with?('/')
|
34
|
+
filename = File.expand_path filename
|
35
|
+
end
|
36
|
+
@irb.load filename
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|