rbfind 1.13 → 2.2

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: 75ec1222c8e64f36c9927aa96c1c4f2a737d624d142fea22bfce274637074a7b
4
+ data.tar.gz: 6c34e268c249977c6c74dc3bf42d841ea63c2649274742be29918a1c19d592a0
5
5
  SHA512:
6
- metadata.gz: 170d599e93cd82d128f3ea4541b6d4c92f04d21b79e15cd09a7c1de1f18d5a3bf4862b56bfa2ab2ccfb8229eef6e428135591f59f84b6b59266f129bb2e932be
7
- data.tar.gz: 2f3dba6cca4000d736d77f054962bb0265a22414a3db2fc837d97bd2c68d17cb7e8d1c94f30e22725ead2d974fefec34e4acfc46df893a46c3df541c6ffa03aa
6
+ metadata.gz: c71fdaa76238ddae6fcc6b887bf30280f7f48c97e92d324ad5a400f81de8038f4fbe1b10ff931e4cc8f80604d69e71e496a80f99544ff5ba5a37ad0beb1dc2ea
7
+ data.tar.gz: b12aad69797682840b1a75b07b77f5474d5aab8e66b4b536dfe41e538e7f5fee493aaf5ad493db8419454532729600acc037e0936001b193d7911a44ac886f73
data/bin/rbfind CHANGED
@@ -5,137 +5,422 @@
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 broken broken?
373
+ alias dir dir?
374
+ alias binary binary?
375
+ alias bin bin?
376
+ alias vimswap vimswap?
377
+
378
+ def blockdev ; blockdev? ; end
379
+ def chardev ; chardev? ; end
380
+ def directory ; directory? ; end
381
+ def executable ; executable? ; end
382
+ def executable_real ; executable_real? ; end
383
+ def file ; file? ; end
384
+ def grpowned ; grpowned? ; end
385
+ def owned ; owned? ; end
386
+ def pipe ; pipe? ; end
387
+ def readable ; readable? ; end
388
+ def readable_real ; readable_real? ; end
389
+ def setgid ; setgid? ; end
390
+ def setuid ; setuid? ; end
391
+ def socket ; socket? ; end
392
+ def sticky ; sticky? ; end
393
+ def symlink ; symlink? ; end
394
+ def writable ; writable? ; end
395
+ def writable_real ; writable_real? ; end
396
+ def zero ; zero? ; end
397
+
398
+ # convenient digest and time format methods
399
+ alias method_missing_orig method_missing
400
+ def method_missing sym, *args, &block
401
+ case sym.to_s
402
+ when /\Adigest_(.*)/, /\A([a-z]+[0-9]+)\z/ then
403
+ m = $1
404
+ d = begin
405
+ Digest.const_get m.upcase
406
+ rescue NameError
407
+ if m =~ /sha\d\d\d/ then m = "sha2" end
408
+ require "digest/#{m}" and retry
409
+ raise
410
+ end
411
+ e = d.new
412
+ read 0x1000_0000 do |b| e.update b end
413
+ e.hexdigest
414
+ when /\A([amc]time)!\z/ then
415
+ (send $1).strftime "%Y-%m-%d %H:%M:%S %z"
416
+ else
417
+ method_missing_orig sym, *args, &block
418
+ end
419
+ end
420
+
421
+ end
422
+
423
+ end
139
424
 
140
425
 
141
426
  class Time
@@ -176,9 +461,6 @@ class String
176
461
  else super
177
462
  end
178
463
  end
179
- def | width
180
- ljust width
181
- end
182
464
  # conventient date/time construction
183
465
  def time
184
466
  Time.parse self
@@ -201,298 +483,12 @@ class NilClass
201
483
  end
202
484
  end
203
485
 
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
486
+ class Proc
487
+ def to_s
488
+ "#<%s:0x%08x>" % [ self.class, object_id]
210
489
  end
211
490
  end
212
491
 
213
492
 
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
493
+ RbFind::Application.new.run
498
494