rbfind 1.13 → 2.0.1

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