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