rbfind 1.13 → 2.2

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: 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