rbfind 1.11 → 2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b687941a0ed418599c3f32451afdf5bcaba86f7df68286396409f48446ca740
4
- data.tar.gz: e513a7092e68bae9f88fa83c8be96dcd58b52ef7baf425a7fa49814858e1888a
3
+ metadata.gz: 8ccb45a241d65a9dadc83c1ba5a72515f2165d18bf84564e15fad687010221a8
4
+ data.tar.gz: aef115794fdd548ba799413611e39964eca2c9ce9dc10d7ee355e95c52af1ff9
5
5
  SHA512:
6
- metadata.gz: 1eafac28ac55651614b926b83fa129087891ca43a14ec1c3217f522799d0e722a8b7381257a04355f1dd497cb62f63823f577fe3a01d878848cd0c834e751a03
7
- data.tar.gz: 0a87bc6a2be21912f2015e5b7f540c6b941df33224ac30f9be33783f2d6108092b862137403b360c4f9816d11e2086b03ae757528871029d3a50221cb45f1e7c
6
+ metadata.gz: 95c622fbc6cadf9b86eafa357c1a3dadbdb9ca8df85a83569e2855254c38bc219c11fc4e6a2c59dbeb730ff0f7e6b3133e8e5827158821c8d7ad9d6e3b03be04
7
+ data.tar.gz: f7d5151eb5402104aa7cedc31e932ec9471b0d73df230a1b7943c664ba3d2be98c8bf340624c9c6779330776eefea64241b0cdf449dd61d5ecea70c8625dd4a2
data/bin/rbfind CHANGED
@@ -5,137 +5,421 @@
5
5
  #
6
6
 
7
7
  require "rbfind"
8
+ require "rbfind/humansiz"
9
+ require "English"
10
+ require 'getoptlong'
8
11
 
9
- PROGRAM = <<EOT
10
- rbfind #{RbFind::VERSION} -- A find tool using Ruby
11
12
 
12
- Author: Bertram Scharpf <software@bertram-scharpf.de>
13
- License: BSD
14
- EOT
13
+ module RbFind
14
+
15
+ class Application
16
+
17
+ PROGRAM = <<~EOT
18
+ rbfind #{RbFind::VERSION} -- A find tool using Ruby
19
+
20
+ Author: Bertram Scharpf <software@bertram-scharpf.de>
21
+ License: BSD
22
+ EOT
23
+
24
+ OPTIONS = [
25
+ # options arg description
26
+ [ %w(--help -h), nil, "print this help"],
27
+ [ %w(--examples -X), nil, "print this help and examples"],
28
+ [ %w(--version -V), nil, "print version information"],
29
+ [ %w(--verbose -v), nil, "standard Ruby error reports"],
30
+ [ %w(--show -o), nil, "just show Ruby block built from options"],
31
+ [ %w(--bw -w), nil, "black and white on -p or default output"],
32
+ [ %w(--colored -c), nil, "force color on -p or default output"],
33
+ [ %w(--depth -d), nil, "yield directory after its contents"],
34
+ [ %w(--maxdepth -m), :num, "maxium step depth"],
35
+ [ %w(--follow -y), nil, "follow symbolic links"],
36
+ [ %w(--nosort -S), nil, "unsorted"],
37
+ [ %w(--sort-by -s), :str, "sort expression ('n' is name)"],
38
+ [ %w(--reverse -R), :str, "reverse sort"],
39
+ [ %w(--require -r), :rb, "require library"],
40
+ [ %w(--puts-path -p), nil, "do 'puts path/cpath' on true block"],
41
+ [ %w(--ls-l -P), nil, "do 'ls -l' style output on true block"],
42
+ [ %w(--wider -+), nil, "widen fields in long output format (--ls-l)"],
43
+ [ %w(--slash -/), nil, "append a slash to directory names"],
44
+ [ %w(--lines -l), :blk, "surround block by 'lines { |$_,$.| ... }'"],
45
+ [ %w(--reallines -L), :blk, "same as -l but stop at any null character"],
46
+ [ %w(--grep -g), :blk, "grep files (implies -pL)"],
47
+ [ %w(--igrep -G), :blk, "case insensitive grep"],
48
+ [ %w(--binary -b), nil, "grep even binary files"],
49
+ [ %w(--no-vcs -C), nil, "prune version control dirs (CVS/.svn/.git)"],
50
+ [ %w(--no-swap -W), nil, "ignore Vim swapfiles"],
51
+ [ %w(--skip -k), :lst, "filenames to skip"],
52
+ [ %w(--demand -D), :lst, "skip all filenames but these"],
53
+ [ %w(--ext -e), :lst, "skip all filename extensions but these"],
54
+ [ %w(--visible -I), nil, "skip all hidden (starting with .dot)"],
55
+ [ %w(--nodirs -N), nil, "skip directories"],
56
+ [ %w(--begin -B), :blk, "eval block before begin"],
57
+ [ %w(--end -E), :blk, "eval block after end"],
58
+ [ %w(--file -f), :blk, "read block expression from file"],
59
+ [ %w(--encoding -K), :str, "encoding extern[:intern] (same as ruby -E)"],
60
+ ]
61
+
62
+ def initialize
63
+ @params = {}
64
+ envopts = ENV[ "RBFIND_OPTIONS"]
65
+ $*.unshift *envopts.split if envopts
66
+ opts = GetoptLong.new *OPTIONS.map { |(long,short),arg,|
67
+ [long,short,(arg ? GetoptLong::REQUIRED_ARGUMENT : GetoptLong::NO_ARGUMENT)]
68
+ }
69
+ opts.ordering = GetoptLong::PERMUTE
70
+ opts.quiet = true
71
+ opts.each do |opt,arg|
72
+ case opt
73
+ when '--help' then usage ; exit
74
+ when '--version' then puts PROGRAM ; exit
75
+ when '--examples' then usage_examples ; exit
76
+ when '--verbose' then @verbose = true
77
+ when '--show' then @show = true
78
+ when '--bw' then @color = false
79
+ when '--colored' then @color = true
80
+ when '--depth' then @params[ :depth_first] = true
81
+ when '--maxdepth' then @params[ :max_depth] = arg.to_i
82
+ when '--follow' then @params[ :follow] = true
83
+ when '--nosort' then @params[ :sort] = false
84
+ when '--sort-by' then @params[ :sort] = instance_eval "proc { |n| #{arg} }"
85
+ when '--reverse' then @params[ :reverse] = true
86
+ when '--require' then require arg
87
+ when '--puts-path' then @puts = true
88
+ when '--ls-l' then @puts = true ; @wd = 6
89
+ when '--wider' then @wd = @wd ? @wd.succ : 4
90
+ when '--slash' then @slash = true
91
+ when '--lines' then @lines = :plain ; @block = arg
92
+ when '--reallines' then @lines = :plain ; @real = true ; @block = arg
93
+ when '--grep' then @lines = :grep ; @block = arg
94
+ when '--igrep' then @lines = :grep ; @icase = true ; @block = arg
95
+ when '--binary' then @binary = true
96
+ when '--no-vcs' then @vcs = true
97
+ when '--no-swap' then @vim = true
98
+ when '--skip' then @skip = arg
99
+ when '--demand' then @demand = arg
100
+ when '--ext' then @ext = arg
101
+ when '--visible' then @visible = true
102
+ when '--nodirs' then @nodirs = true
103
+ when '--begin' then @blkbegin = arg
104
+ when '--end' then @blkend = arg
105
+ when '--file' then @block = File.read arg
106
+ when '--encoding' then e, i = arg.split ":" ; set_encoding e, i
107
+ end
108
+ end
109
+ @args = $*.dup
110
+ if @args.empty? and not $stdin.tty? then
111
+ $stdin.each_line { |l|
112
+ l.chomp!
113
+ @args.push l
114
+ }
115
+ end
116
+ build_block
117
+ rescue GetoptLong::InvalidOption
118
+ $stderr.puts $!
119
+ $stderr.puts
120
+ usage
121
+ exit 9
122
+ rescue
123
+ $stderr.puts $!
124
+ exit 8
125
+ end
15
126
 
127
+ def build_block
128
+ co = color_on $stdout
129
+ opath = co ? "cpath" : "path"
130
+ @slash and opath << "!"
131
+ case @lines
132
+ when :plain then
133
+ @puts and @block = "( #@block ) and colsep #{opath}, num, line"
134
+ @real and @block = "break if ~/\0/o ; #@block"
135
+ @block = "lines { |line,num| #@block }"
136
+
137
+ when :grep then
138
+ re = Regexp.new @block, @icase && Regexp::IGNORECASE
139
+ @block = "grep %r#{re.inspect}"
140
+ @block << ", true" if co
141
+ @block << " ; $stdout.flush" unless $stdout.tty?
142
+ @binary or @block = "not binary? and (#@block)"
16
143
 
17
- require 'getoptlong'
144
+ else
145
+ @block ||= if @args.last and not (File.exists? @args.last) then
146
+ @args.pop.dup
147
+ else
148
+ @puts ||= true
149
+ "true"
150
+ end
151
+ if @puts then
152
+ @block = "( #@block ) and "
153
+ @block << if @wd then
154
+ "spcsep stype+modes, user.w#@wd, group.w#@wd, size.w#@wd, " +
155
+ "mtime.lsish, #{opath} + #{co ? 'carrow' : 'arrow'}.to_s"
156
+ else
157
+ "puts #{opath}"
158
+ end
159
+ end
18
160
 
19
- OPTIONS = [
20
- # options arg description
21
- [ %w(--help -h), nil, "print this help"],
22
- [ %w(--examples -X), nil, "print this help and examples"],
23
- [ %w(--version -V), nil, "print version information"],
24
- [ %w(--verbose -v), nil, "standard Ruby error reports"],
25
- [ %w(--show -o), nil, "just show Ruby block built from options"],
26
- [ %w(--bw -w), nil, "black and white on -p or default output"],
27
- [ %w(--colored -c), nil, "force color on -p or default output"],
28
- [ %w(--depth -d), nil, "yield directory after its contents"],
29
- [ %w(--maxdepth -m), :num, "maxium step depth"],
30
- [ %w(--follow -y), nil, "follow symbolic links"],
31
- [ %w(--sort -s), :str, "=reverse/desc/-1,unsorted; default is sorted"],
32
- [ %w(--sort-by -S), :str, "sort expression ('name' is name)"],
33
- [ %w(--require -r), :rb, "require library"],
34
- [ %w(--fileutils -U), nil, "include FileUtils module"],
35
- [ %w(--puts-path -p), nil, "do 'puts path/cpath' on true block"],
36
- [ %w(--ls-l -P), nil, "do 'ls -l' style output on true block"],
37
- [ %w(--wider -+), nil, "widen fields in long output format (--ls-l)"],
38
- [ %w(--slash -/), nil, "append a slash to directory names"],
39
- [ %w(--lines -l), :blk, "surround block by 'lines { |$_,$.| ... }'"],
40
- [ %w(--reallines -L), :blk, "same as -l but stop at any null character"],
41
- [ %w(--grep -g), :blk, "grep files (implies -pL)"],
42
- [ %w(--igrep -G), :blk, "case insensitive grep"],
43
- [ %w(--binary -b), nil, "grep even binary files"],
44
- [ %w(--no-vcs -C), nil, "prune version control dirs (CVS/.svn/.git)"],
45
- [ %w(--no-swap -W), nil, "ignore Vim swapfiles"],
46
- [ %w(--skip -k), :lst, "filenames to skip"],
47
- [ %w(--demand -D), :lst, "skip all filenames but these"],
48
- [ %w(--ext -e), :lst, "skip all filename extensions but these"],
49
- [ %w(--visible -I), nil, "skip all hidden (starting with .dot)"],
50
- [ %w(--nodirs -N), nil, "skip directories"],
51
- [ %w(--begin -B), :blk, "eval block before begin"],
52
- [ %w(--end -E), :blk, "eval block after end"],
53
- [ %w(--file -f), :blk, "read block expression from file"],
54
- [ %w(--encoding -K), :str, "encoding extern[:intern] (same as ruby -E)"],
55
- ]
56
-
57
- def usage
58
- puts <<EOT
59
- Usage:
60
-
61
- rbfind [options] path... 'block'
62
-
63
- EOT
64
- OPTIONS.each { |(long,short),arg,desc|
65
- puts " %-12s %2s %-5s %s" % [long,short,arg.to_s.upcase,desc]
66
- }
67
- puts <<'EOT'
68
-
69
- "--" stops option processing.
70
-
71
- The last argument is a block that will be executed on every found
72
- file object. It may be omitted; then "puts path" is assumed or "cpath"
73
- in case the output is a terminal.
74
-
75
- Default sort order is alphabetical.
76
-
77
- EOT
78
- end
161
+ end
79
162
 
80
- def usage_examples
81
- usage
82
- puts <<'EOT'
83
- Examples:
84
- $ rbfind -p 'file and age < 5.m'
85
- $ rbfind -p 'file and age > 1.d'
86
- $ rbfind -p '(90.d .. 183.d) === age'
87
-
88
- $ rbfind -Cg require
89
- $ rbfind -Cp
90
- $ rbfind 'filesize < 100.kB and grep /require/'
91
- $ rbfind -g 'define\s*ALLOC_N'
92
- $ rbfind myproject -e rb -l '~/require/ and puts $_'
93
-
94
- $ rbfind -pe '.rb c h'
95
- $ rbfind /usr/include -e .h -g EACCES
96
- $ rbfind -d -m3 -- /mnt/data
97
- $ rbfind 'filesize > 10.MiB and colsep size.to_hib, path'
98
-
99
- $ rbfind -S "name =~ /^\.*/ ; $'.downcase"
100
- $ rbfind -B '$s=0' -E 'puts $s.to_h' 'filesize {|s|$s+=s}'
101
- $ rbfind 'puts path if ext == ".rb"'
102
- $ rbfind -p 'ext == ".rb"'
103
- $ rbfind /usr/include -p -D '\.h$' -l '~/EACCES/'
104
- $ rbfind /usr/include -pD 'pg|pq|postgres' dir
105
- $ rbfind 'no_svn ; puts path'
106
- $ rbfind 'prune if name == ".svn" ; puts path'
107
- $ rbfind -p 'prune if name == ".svn"'
108
- $ rbfind myproject 'name[/\.rb$/] and lines { |l,i| l=~/require/ and puts l }'
109
- # rbfind /etc 'lines { |l,| l["192.168."] and (puts path ; break) }'
110
- $ rbfind /etc 'readable? or raise "Access denied: #{path}" ;
111
- > lines { |l,| l["192.168."] and (puts path ; break) }'
112
-
113
- $ rbfind 'col_sep stype+modes, size.w10, path'
114
- $ rbfind 'tab_sep stype+modes, size.w10, path'
115
- $ rbfind 'spc_sep stype+modes, size.to_h, user, group, mtime.lsish, path'
116
- $ rbfind 'spacesep stype+modes, size.to_h, user, group, mtime.lsish, path'
117
- $ rbfind 'spacesep stype+modes, size.to_h, user, group, mtime!, path'
118
- $ rbfind 'spacesep stype+modes, size.to_h, user, group, mtime.i, path'
119
- $ rbfind 'spacesep mtime.u, path'
120
- $ rbfind 'spacesep modes, user.w8, group.w8, size.w8, cpath + carrow.to_s'
121
-
122
- $ rbfind 'spacesep digest_md5, size.w8, path'
123
- $ rbfind 'spacesep digest_sha256, size.w8, path'
124
-
125
- $ rbfind 'rename name.downcase'
126
- $ rbfind 'ext == ".tgz" and rename without_ext+".tar.gz"'
127
-
128
- See the RbFind class documentation or the "rbfind.rb" source file for more
129
- sophisticated examples and for a full list of file examination methods.
130
-
131
- Valid units are 1.s, 1.m, 1.h, 1.d, 1.w for time values and
132
- 1.kB == 1000, 1.kiB == 1024, 1.MB, 1.MiB for file sizes.
133
- EOT
134
- end
163
+ osic = File::ALT_SEPARATOR&&Regexp::IGNORECASE
164
+ if @skip then
165
+ re = Regexp.new @skip, osic
166
+ @block.insert 0, "done if name =~ #{re.inspect} ; "
167
+ end
135
168
 
169
+ if @demand then
170
+ re = Regexp.new @demand, osic
171
+ @block.insert 0, "done unless name =~ #{re.inspect} ; "
172
+ end
136
173
 
137
- require "humansiz"
138
- require "English"
174
+ if @ext then
175
+ re = Regexp.new '\A\.(' +
176
+ @ext.split(/ +|,/).map { |e| e[ /\A\.?(.*)\z/, 1] }.join('|') +
177
+ ')\z', osic
178
+ @block.insert 0, "ext =~ #{re.inspect} or done ; "
179
+ end
180
+
181
+ @visible and @block.insert 0, "visible? or done ; "
182
+
183
+ @nodirs and @block.insert 0, "done if dir? ; "
184
+
185
+ @vcs and @block.insert 0, "no_vcs ; "
186
+ @vim and @block.insert 0, "vimswap? and done ; "
187
+
188
+ @params[ :error] = proc do
189
+ case $!
190
+ when Errno::EPIPE then raise
191
+ when NameError, TypeError then raise
192
+ when ArgumentError then raise
193
+ else show_error $!
194
+ end
195
+ end
196
+ end
197
+
198
+ def run
199
+ if @show then
200
+ show
201
+ else
202
+ execute
203
+ end
204
+ end
205
+
206
+ private
207
+
208
+ def usage
209
+ puts <<~EOT
210
+ Usage:
211
+
212
+ rbfind [options] path... 'block'
213
+
214
+ EOT
215
+ OPTIONS.each { |(long,short),arg,desc|
216
+ puts " %-12s %2s %-5s %s" % [long,short,arg.to_s.upcase,desc]
217
+ }
218
+ puts <<~'EOT'
219
+
220
+ "--" stops option processing.
221
+
222
+ The last argument is a block that will be executed on every found
223
+ file object. It may be omitted; then "puts path" is assumed or "cpath"
224
+ in case the output is a terminal.
225
+
226
+ Default sort order is alphabetical.
227
+ EOT
228
+ end
229
+
230
+ def usage_examples
231
+ usage
232
+ puts <<~'EOT'
233
+ Examples:
234
+ $ rbfind -p 'file and age < 5.m'
235
+ $ rbfind -p 'file and age > 1.d'
236
+ $ rbfind -p '(90.d .. 183.d) === age'
237
+
238
+ $ rbfind -Cg require
239
+ $ rbfind -Cp
240
+ $ rbfind 'filesize < 100.kB and grep /require/'
241
+ $ rbfind -g 'define\s*ALLOC_N'
242
+ $ rbfind myproject -e rb -l '~/require/ and puts $_'
243
+
244
+ $ rbfind -pe '.rb c h'
245
+ $ rbfind /usr/include -e .h -g EACCES
246
+ $ rbfind -d -m3 -- /mnt/data
247
+ $ rbfind 'filesize > 10.MiB and colsep size.to_hib, path'
248
+
249
+ $ rbfind -S "name =~ /^\.*/ ; $'.downcase"
250
+ $ rbfind -B '$s=0' -E 'puts $s.to_h' 'filesize {|s|$s+=s}'
251
+ $ rbfind 'puts path if ext == ".rb"'
252
+ $ rbfind -p 'ext == ".rb"'
253
+ $ rbfind /usr/include -p -D '\.h$' -l '~/EACCES/'
254
+ $ rbfind /usr/include -pD 'pg|pq|postgres' dir
255
+ $ rbfind 'no_svn ; puts path'
256
+ $ rbfind 'prune if name == ".svn" ; puts path'
257
+ $ rbfind -p 'prune if name == ".svn"'
258
+ $ rbfind myproject 'name[/\.rb$/] and lines { |l,i| l=~/require/ and puts l }'
259
+ # rbfind /etc 'lines { |l,| l["192.168."] and (puts path ; break) }'
260
+ $ rbfind /etc 'readable? or raise "Access denied: #{path}" ;
261
+ > lines { |l,| l["192.168."] and (puts path ; break) }'
262
+
263
+ $ rbfind 'col_sep stype+modes, size.w10, path'
264
+ $ rbfind 'tab_sep stype+modes, size.w10, path'
265
+ $ rbfind 'spc_sep stype+modes, size.to_h, user, group, mtime.lsish, path'
266
+ $ rbfind 'p stype+modes, size.to_h, user, group, mtime.lsish, path'
267
+ $ rbfind 'p stype+modes, size.to_h, user, group, mtime!, path'
268
+ $ rbfind 'p stype+modes, size.to_h, user, group, mtime.i, path'
269
+ $ rbfind 'p mtime.u, path'
270
+ $ rbfind 'p modes, user.w8, group.w8, size.w8, cpath + carrow.to_s'
271
+
272
+ $ rbfind 'p digest_md5, size.w8, path'
273
+ $ rbfind 'p digest_sha256, size.w8, path'
274
+
275
+ $ rbfind 'rename name.downcase'
276
+ $ rbfind 'ext == ".tgz" and rename without_ext+".tar.gz"'
277
+
278
+ See the RbFind documentation or the "rbfind.rb" source file for more
279
+ sophisticated examples and for a full list of file examination methods.
280
+
281
+ Valid units are 1.s, 1.m, 1.h, 1.d, 1.w for time values and
282
+ 1.kB == 1000, 1.kiB == 1024, 1.MB, 1.MiB for file sizes.
283
+ EOT
284
+ end
285
+
286
+ def set_encoding extern, intern = nil
287
+ Encoding.default_external = extern if extern and not extern.empty?
288
+ Encoding.default_internal = intern if intern and not intern.empty?
289
+ [ $stdin, $stdout, $stderr].each do |io|
290
+ io.set_encoding extern, intern
291
+ end
292
+ end
293
+
294
+ def color_on stream
295
+ @color.nil? ? !File::ALT_SEPARATOR && stream.tty? : @color
296
+ end
297
+
298
+
299
+ def show_error e
300
+ co = color_on $stderr
301
+ $stderr.puts co ? "\e[31m#{e.class}: \e[1m#{e}\e[m" : "#{e.class}: #{e}"
302
+ end
303
+
304
+ def error_handle
305
+ if @verbose then
306
+ yield
307
+ else
308
+ begin
309
+ yield
310
+ rescue ArgumentError
311
+ show_error $!
312
+ if $!.message[ "invalid byte sequence"] then
313
+ $stderr.puts <<~EOT
314
+ Hint: Try to give a different default encoding by explicitly setting one or
315
+ by changing the locale.
316
+
317
+ $ rbfind -K ascii-8bit ...
318
+ $ LC_ALL="C" rbfind ...
319
+
320
+ Alternatively, you may prefer to scrub the invalid encodings yourself.
321
+
322
+ $ rbfind -P 'name.scrub =~ /Fu.ball/'
323
+
324
+ EOT
325
+ end
326
+ exit 1
327
+ rescue
328
+ show_error $!
329
+ exit 1
330
+ rescue NoMemoryError, ScriptError, SignalException
331
+ show_error $!
332
+ exit 2
333
+ end
334
+ end
335
+ end
336
+
337
+ def execute
338
+ error_handle do
339
+ eval @blkbegin if @blkbegin
340
+ b = @block
341
+ Walk.run *@args, **@params do instance_eval b end
342
+ eval @blkend if @blkend
343
+ end
344
+ end
345
+
346
+ def show
347
+ puts "arguments:"
348
+ @args.each { |a| puts_val a }.any? or puts_val "(none)"
349
+ puts "parameters:"
350
+ @params.each { |k,v| puts_val k, "=", v }.any? or puts_val "(none)"
351
+ puts "block:"
352
+ @block.each_line { |l| puts_val l }
353
+ end
354
+
355
+ INDENT = " "*2
356
+
357
+ def puts_val *args
358
+ l = [ INDENT, *args].join ""
359
+ puts l
360
+ end
361
+
362
+ end
363
+
364
+
365
+ class Entry
366
+
367
+ # Alias the question marks away from all method names because
368
+ # they're a nuisance on the command line.
369
+ alias hidden hidden?
370
+ alias visible visible?
371
+ alias broken_link broken_link?
372
+ alias dir dir?
373
+ alias binary binary?
374
+ alias bin bin?
375
+ alias vimswap vimswap?
376
+
377
+ def blockdev ; blockdev? ; end
378
+ def chardev ; chardev? ; end
379
+ def directory ; directory? ; end
380
+ def executable ; executable? ; end
381
+ def executable_real ; executable_real? ; end
382
+ def file ; file? ; end
383
+ def grpowned ; grpowned? ; end
384
+ def owned ; owned? ; end
385
+ def pipe ; pipe? ; end
386
+ def readable ; readable? ; end
387
+ def readable_real ; readable_real? ; end
388
+ def setgid ; setgid? ; end
389
+ def setuid ; setuid? ; end
390
+ def socket ; socket? ; end
391
+ def sticky ; sticky? ; end
392
+ def symlink ; symlink? ; end
393
+ def writable ; writable? ; end
394
+ def writable_real ; writable_real? ; end
395
+ def zero ; zero? ; end
396
+
397
+ # convenient digest and time format methods
398
+ alias method_missing_orig method_missing
399
+ def method_missing sym, *args, &block
400
+ case sym.to_s
401
+ when /\Adigest_(.*)/, /\A([a-z]+[0-9]+)\z/ then
402
+ m = $1
403
+ d = begin
404
+ Digest.const_get m.upcase
405
+ rescue NameError
406
+ if m =~ /sha\d\d\d/ then m = "sha2" end
407
+ require "digest/#{m}" and retry
408
+ raise
409
+ end
410
+ e = d.new
411
+ read 0x1000_0000 do |b| e.update b end
412
+ e.hexdigest
413
+ when /\A([amc]time)!\z/ then
414
+ (send $1).strftime "%Y-%m-%d %H:%M:%S %z"
415
+ else
416
+ method_missing_orig sym, *args, &block
417
+ end
418
+ end
419
+
420
+ end
421
+
422
+ end
139
423
 
140
424
 
141
425
  class Time
@@ -176,9 +460,6 @@ class String
176
460
  else super
177
461
  end
178
462
  end
179
- def | width
180
- ljust width
181
- end
182
463
  # conventient date/time construction
183
464
  def time
184
465
  Time.parse self
@@ -201,298 +482,12 @@ class NilClass
201
482
  end
202
483
  end
203
484
 
204
-
205
- def set_encoding extern, intern = nil
206
- Encoding.default_external = extern if extern and not extern.empty?
207
- Encoding.default_internal = intern if intern and not intern.empty?
208
- [ $stdin, $stdout, $stderr].each do |io|
209
- io.set_encoding extern, intern
485
+ class Proc
486
+ def to_s
487
+ "#<%s:0x%08x>" % [ self.class, object_id]
210
488
  end
211
489
  end
212
490
 
213
491
 
214
- class RbFindApp < RbFind
215
-
216
- # Alias the question marks away from all method names because
217
- # they're a nuisance on the command line.
218
- alias hidden hidden?
219
- alias visible visible?
220
- alias broken_link broken_link?
221
- alias dir dir?
222
- alias binary binary?
223
- alias bin bin?
224
- alias vimswap vimswap?
225
-
226
- def blockdev ; blockdev? ; end
227
- def chardev ; chardev? ; end
228
- def directory ; directory? ; end
229
- def executable ; executable? ; end
230
- def executable_real ; executable_real? ; end
231
- def file ; file? ; end
232
- def grpowned ; grpowned? ; end
233
- def owned ; owned? ; end
234
- def pipe ; pipe? ; end
235
- def readable ; readable? ; end
236
- def readable_real ; readable_real? ; end
237
- def setgid ; setgid? ; end
238
- def setuid ; setuid? ; end
239
- def socket ; socket? ; end
240
- def sticky ; sticky? ; end
241
- def symlink ; symlink? ; end
242
- def writable ; writable? ; end
243
- def writable_real ; writable_real? ; end
244
- def zero ; zero? ; end
245
-
246
- # convenient digest and time format methods
247
- def method_missing sym, *args, &block
248
- case sym.to_s
249
- when /\Adigest_(.*)/, /\A([a-z]+[0-9]+)\z/ then
250
- m = $1
251
- d = begin
252
- Digest.const_get m.upcase
253
- rescue NameError
254
- if m =~ /sha\d\d\d/ then m = "sha2" end
255
- require "digest/#{m}" and retry
256
- raise
257
- end
258
- e = d.new
259
- read 0x1000_0000 do |b| e.update b end
260
- e.hexdigest
261
- when /\A([amc]time)!\z/ then
262
- (send $1).strftime "%Y-%m-%d %H:%M:%S %z"
263
- else
264
- super
265
- end
266
- end
267
-
268
- def hide_instance_eval
269
- instance_eval yield
270
- end
271
-
272
- end
273
-
274
-
275
- @params = {}
276
-
277
- envopts = ENV[ "RBFIND_OPTIONS"]
278
- $*.unshift *envopts.split if envopts
279
- opts = GetoptLong.new *OPTIONS.map { |(long,short),arg,|
280
- [long,short,(arg ? GetoptLong::REQUIRED_ARGUMENT : GetoptLong::NO_ARGUMENT)]
281
- }
282
- opts.ordering = GetoptLong::PERMUTE
283
- opts.quiet = true
284
- begin
285
- opts.each do |opt,arg|
286
- case opt
287
- when '--help' then usage ; exit
288
- when '--version' then puts PROGRAM ; exit
289
- when '--examples' then usage_examples ; exit
290
- when '--verbose' then @verbose = true
291
- when '--show' then @show = true
292
- when '--bw' then @color = false
293
- when '--colored' then @color = true
294
- when '--depth' then @params[ :depth] = true
295
- when '--maxdepth' then @params[ :max_depth] = arg
296
- when '--follow' then @params[ :follow] = true
297
- when '--sort' then @params[ :sort] = arg
298
- when '--sort-by' then
299
- @params[ :sort] = instance_eval "proc { |name| #{arg} }"
300
- when '--require' then require arg
301
- when '--fileutils' then require "fileutils" ; include FileUtils
302
- when '--puts-path' then @puts = true
303
- when '--ls-l' then @puts = true ; @wd = 6
304
- when '--wider' then @wd = @wd ? @wd.succ : 4
305
- when '--slash' then @slash = true
306
- when '--lines' then @lines = :plain ; @block = arg
307
- when '--reallines' then @lines = :plain ; @real = true ; @block = arg
308
- when '--grep' then @lines = :grep ; @block = arg
309
- when '--igrep' then @lines = :grep ; @icase = true ; @block = arg
310
- when '--binary' then @binary = true
311
- when '--no-vcs' then @vcs = true
312
- when '--no-swap' then @vim = true
313
- when '--skip' then @skip = arg
314
- when '--demand' then @demand = arg
315
- when '--ext' then @ext = arg
316
- when '--visible' then @visible = true
317
- when '--nodirs' then @nodirs = true
318
- when '--begin' then @blkbegin = arg
319
- when '--end' then @blkend = arg
320
- when '--file' then @block = File.read arg
321
- when '--encoding' then e, i = arg.split ":" ; set_encoding e, i
322
- end
323
- end
324
- rescue GetoptLong::InvalidOption
325
- $stderr.puts $!
326
- $stderr.puts
327
- usage
328
- exit 9
329
- rescue
330
- $stderr.puts $!
331
- exit 8
332
- end
333
-
334
- def color_on stream
335
- unless @color.nil? then
336
- @color
337
- else
338
- !File::ALT_SEPARATOR && stream.tty?
339
- end
340
- end
341
-
342
- if color_on $stderr then
343
- def show_error e
344
- $stderr.puts "\e[31m#{e.class}: \e[1m#{e}\e[m"
345
- end
346
- else
347
- def show_error e
348
- $stderr.puts "#{e.class}: #{e}"
349
- end
350
- end
351
-
352
- def error_handle
353
- if @verbose then
354
- yield
355
- else
356
- begin
357
- yield
358
- rescue ArgumentError
359
- show_error $!
360
- if $!.message[ "invalid byte sequence"] then
361
- $stderr.puts <<-EOT
362
- Hint: Try to give a different default encoding by explicitly setting one or
363
- by changing the locale.
364
-
365
- $ rbfind -K ascii-8bit ...
366
- $ LC_ALL="C" rbfind ...
367
-
368
- Alternatively, you may prefer to scrub the invalid encodings yourself.
369
-
370
- $ rbfind -P 'name.scrub =~ /Fu.ball/'
371
-
372
- EOT
373
- end
374
- exit 1
375
- rescue
376
- show_error $!
377
- exit 1
378
- rescue NoMemoryError, ScriptError, SignalException
379
- show_error $!
380
- exit 2
381
- end
382
- end
383
- end
384
-
385
-
386
- error_handle do
387
-
388
- co = color_on $stdout
389
- opath = co ? "cpath" : "path"
390
- @slash and opath << "!"
391
- case @lines
392
- when :plain then
393
- @puts and @block = "( #@block ) and colsep #{opath}, num, line"
394
- @real and @block = "break if ~/\0/o ; #@block"
395
- @block = "lines { |line,num| #@block }"
396
-
397
- when :grep then
398
- RE = Regexp.new @block, @icase && Regexp::IGNORECASE
399
- @block = "grep RE"
400
- @block << ", true" if co
401
- @block << " ; $stdout.flush" unless $stdout.tty?
402
- @binary or @block = "not binary? and (#@block)"
403
-
404
- else
405
- @block ||= if $*.last and not (File.exists? $*.last) then
406
- $*.pop.dup
407
- else
408
- @puts ||= true
409
- "true"
410
- end
411
- if @puts then
412
- @block = "( #@block ) and "
413
- @block << if @wd then
414
- "spcsep stype+modes, user|#@wd, group|#@wd, size.w#@wd, " +
415
- "mtime.lsish, #{opath} + #{co ? 'carrow' : 'arrow'}.to_s"
416
- else
417
- "puts #{opath}"
418
- end
419
- end
420
-
421
- end
422
-
423
- if @skip then
424
- RE_SKIP = Regexp.new @skip, File::ALT_SEPARATOR&&Regexp::IGNORECASE
425
- @block.insert 0, "next if name =~ RE_SKIP ; "
426
- end
427
-
428
- if @demand then
429
- RE_DEMAND = Regexp.new @demand, File::ALT_SEPARATOR&&Regexp::IGNORECASE
430
- @block.insert 0, "next unless name =~ RE_DEMAND ; "
431
- end
432
-
433
- if @ext then
434
- RE_EXT = Regexp.new '\A\.(' +
435
- @ext.split(/ +|,/).map { |e| e[ /\A\.?(.*)\z/, 1] }.join('|') + ')\z',
436
- File::ALT_SEPARATOR&&Regexp::IGNORECASE
437
- @block.insert 0, "ext =~ RE_EXT or next ; "
438
- end
439
-
440
- @visible and @block.insert 0, "visible? or prune ; "
441
-
442
- @nodirs and @block.insert 0, "next if dir? ; "
443
-
444
- @vcs and @block.insert 0, "no_vcs ; "
445
- @vim and @block.insert 0, "vimswap? and next ; "
446
-
447
- args = $*.dup
448
- if args.empty? and not $stdin.tty? then
449
- $stdin.each_line { |l|
450
- l.chomp!
451
- args.push l
452
- }
453
- end
454
-
455
- if @show then
456
- class Proc
457
- def to_s
458
- "#<%s:0x%08x>" % [ self.class, object_id]
459
- end
460
- end
461
- INDENT = " "*2
462
- def puts_val *args
463
- l = [ INDENT, *args].join ""
464
- puts l
465
- end
466
- puts "arguments:"
467
- args.each { |a| puts_val a }.any? or puts_val "(none)"
468
- puts "parameters:"
469
- @params.each { |k,v| puts_val k, "=", v }.any? or puts_val "(none)"
470
- puts "block:"
471
- self.class.constants.grep( /^RE(_[A-Z]+)?$/).each { |re|
472
- v = self.class.const_get re
473
- puts_val re, "=", v
474
- }
475
- puts_val @block
476
- exit
477
- end
478
-
479
- @params[ :error] = proc do
480
- case $!
481
- when Errno::EPIPE then raise
482
- when NameError, TypeError then raise
483
- when ArgumentError then raise
484
- else show_error $!
485
- end
486
- end
487
-
488
- @block = <<-EOT
489
- handle_error do
490
- #@block
491
- end
492
- EOT
493
-
494
- eval @blkbegin if @blkbegin
495
- RbFindApp.open args, @params do |f| f.hide_instance_eval { @block } end
496
- eval @blkend if @blkend
497
- end
492
+ RbFind::Application.new.run
498
493