rbfind 2.3 → 2.7

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: 0655e863af78b2081d7306e8823694ef7ad5c48625dbdd9c7f0f75fb8a85d4d7
4
- data.tar.gz: 0ef05d8082c2487d7079176ea8373f31e392d41eb1dd269555c47832ff313689
3
+ metadata.gz: b57d2e44d4df6453083635d22ab01c92ea5b54fed8c121a313ac351048f16b51
4
+ data.tar.gz: 20518a97f6e446de75b6397a0e725a9f1c93d5c61f93743072a2b60e322c75a5
5
5
  SHA512:
6
- metadata.gz: 915e2359d8bb0c7814c682f8247e71eb7db8742a8095c2cdbb44194252df0ba2636602443ca916055a3f260cece8de837118c565c76ca2bfb470dd2409749a94
7
- data.tar.gz: f72fdc455e7ac5eba31060f3c96176f47985f7a4f41fd55d089dc78d7b713838365c5b949f537b7089b223829e63ac5ed64935af9a80a90639e31aa7ade67474
6
+ metadata.gz: 6ad6d7f05ad3de24d717dc7d274ea5dc75fd5ee81640c1de03bef875727a5f33ed80846ad7445a990ac925734a1dbed66312bac0686bcbb7d16bd1d33ae2d710
7
+ data.tar.gz: 9b97002d3fd98ffd891d5d10b6fc60087a18f2a2b828a0a0099554fa2f50fe0e562a3cd4a062602e9210508d389b733974ddeb9442e0636083cc4e98a8740777
data/bin/rbfind CHANGED
@@ -33,13 +33,18 @@ module RbFind
33
33
  [ %w(--depth -d), nil, "yield directory after its contents"],
34
34
  [ %w(--maxdepth -m), :num, "maxium step depth"],
35
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"],
36
+ [ %w(--nosort -U), nil, "unsorted"],
37
+ [ %w(--sort-by -s), :str, "sort expression"],
38
+ [ %w(--reverse -R), nil, "reverse the sort"],
39
+ [ %w(--time -t), nil, "sort by time, newest first"],
40
+ [ %w(--size -S), nil, "sort by size, largest first"],
41
+ [ %w(--dirs -F), nil, "sort directories before files"],
39
42
  [ %w(--require -r), :rb, "require library"],
40
43
  [ %w(--puts-path -p), nil, "do 'puts path/cpath' on true block"],
41
44
  [ %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)"],
45
+ [ %w(--long -Q), nil, "alternate long format on true block"],
46
+ [ %w(--ino -J), nil, "show inodes and number of hard links"],
47
+ [ %w(--wider -+), nil, "widen fields in long output format"],
43
48
  [ %w(--slash -/), nil, "append a slash to directory names"],
44
49
  [ %w(--lines -l), :blk, "surround block by 'lines { |$_,$.| ... }'"],
45
50
  [ %w(--reallines -L), :blk, "same as -l but stop at any null character"],
@@ -48,14 +53,15 @@ module RbFind
48
53
  [ %w(--binary -b), nil, "grep even binary files"],
49
54
  [ %w(--no-vcs -C), nil, "prune version control dirs (CVS/.svn/.git)"],
50
55
  [ %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"],
56
+ [ %w(--skip -k), :rgx, "filenames to skip"],
57
+ [ %w(--demand -D), :rgx, "skip all filenames but these"],
53
58
  [ %w(--ext -e), :lst, "skip all filename extensions but these"],
54
59
  [ %w(--visible -I), nil, "skip all hidden (starting with .dot)"],
60
+ [ %w(--all -a), nil, "all, including hidden (starting with .dot)"],
55
61
  [ %w(--nodirs -N), nil, "skip directories"],
56
62
  [ %w(--begin -B), :blk, "eval block before begin"],
57
63
  [ %w(--end -E), :blk, "eval block after end"],
58
- [ %w(--file -f), :blk, "read block expression from file"],
64
+ [ %w(--file -f), :nam, "read block expression from file"],
59
65
  [ %w(--encoding -K), :str, "encoding extern[:intern] (same as ruby -E)"],
60
66
  ]
61
67
 
@@ -81,12 +87,17 @@ module RbFind
81
87
  when '--maxdepth' then @params[ :max_depth] = arg.to_i
82
88
  when '--follow' then @params[ :follow] = true
83
89
  when '--nosort' then @params[ :sort] = false
84
- when '--sort-by' then @params[ :sort] = instance_eval "proc { |n| #{arg} }"
90
+ when '--sort-by' then @params[ :sort] = instance_eval "proc { #{arg} }"
91
+ when '--time' then @params[ :sort] = proc { mtime } ; @params[ :reverse] = true
92
+ when '--size' then @params[ :sort] = proc { size } ; @params[ :reverse] = true
93
+ when '--dirs' then @params[ :dirs] = true
85
94
  when '--reverse' then @params[ :reverse] = true
86
95
  when '--require' then require arg
87
96
  when '--puts-path' then @puts = true
88
- when '--ls-l' then @puts = true ; @wd = 6
89
- when '--wider' then @wd = @wd ? @wd.succ : 4
97
+ when '--ls-l' then @puts = :ls ; @wds = 6 ; @wd = 6
98
+ when '--long' then @puts = :alt ; @wds = 7 ; @wd = 4
99
+ when '--ino' then @puts = :ino ; @wds = 8 ; @wd = 2
100
+ when '--wider' then @wd and @wd += 2.succ ; @wds and @wds += @puts != :ls ? 4 : 3
90
101
  when '--slash' then @slash = true
91
102
  when '--lines' then @lines = :plain ; @block = arg
92
103
  when '--reallines' then @lines = :plain ; @real = true ; @block = arg
@@ -99,6 +110,7 @@ module RbFind
99
110
  when '--demand' then @demand = arg
100
111
  when '--ext' then @ext = arg
101
112
  when '--visible' then @visible = true
113
+ when '--all' then @visible = false
102
114
  when '--nodirs' then @nodirs = true
103
115
  when '--begin' then @blkbegin = arg
104
116
  when '--end' then @blkend = arg
@@ -142,7 +154,7 @@ module RbFind
142
154
  @binary or @block = "not binary? and (#@block)"
143
155
 
144
156
  else
145
- @block ||= if @args.last and not (File.exists? @args.last) then
157
+ @block ||= if @args.last and not (File.lstat @args.last rescue false) then
146
158
  @args.pop.dup
147
159
  else
148
160
  @puts ||= true
@@ -150,11 +162,17 @@ module RbFind
150
162
  end
151
163
  if @puts then
152
164
  @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}"
165
+ @block << case @puts
166
+ when :ls then
167
+ "spcsep stype+modes, user.w#@wd, group.w#@wd, size.w#@wds, " +
168
+ "mtime.lsish, #{opath} + #{co ? 'carrow' : 'arrow'}.to_s"
169
+ when :alt then
170
+ "spcsep stype+modes, user!.w#@wd, group!.w#@wd, size.w_#@wds, " +
171
+ "mtime.long, #{opath} + #{co ? 'carrow' : 'arrow'}.to_s"
172
+ when :ino then
173
+ "spcsep ino.w#@wds, nlink.w#@wd, #{opath}"
174
+ else
175
+ "puts #{opath}"
158
176
  end
159
177
  end
160
178
 
@@ -246,7 +264,7 @@ module RbFind
246
264
  $ rbfind -d -m3 -- /mnt/data
247
265
  $ rbfind 'filesize > 10.MiB and colsep size.to_hib, path'
248
266
 
249
- $ rbfind -S "name =~ /^\.*/ ; $'.downcase"
267
+ $ rbfind -U "name =~ /^\.*/ ; $'.downcase"
250
268
  $ rbfind -B '$s=0' -E 'puts $s.to_h' 'filesize {|s|$s+=s}'
251
269
  $ rbfind 'puts path if ext == ".rb"'
252
270
  $ rbfind -p 'ext == ".rb"'
@@ -345,7 +363,7 @@ module RbFind
345
363
 
346
364
  def show
347
365
  puts "arguments:"
348
- @args.each { |a| puts_val a }.any? or puts_val "(none)"
366
+ @args.each { |a| puts_val a }.any? or puts_val "(none)"
349
367
  puts "parameters:"
350
368
  @params.each { |k,v| puts_val k, "=", v }.any? or puts_val "(none)"
351
369
  puts "block:"
@@ -447,8 +465,9 @@ class Integer
447
465
  # convenient formatting, right justification
448
466
  def method_missing sym, *args
449
467
  case sym.to_s # .to_s for Ruby 1.8
450
- when /\Aw_?(\d+)/ then "%#{$1}d" % self
451
- else super
468
+ when /\Aw(\d+)/ then "%#{$1}d" % self
469
+ when /\Aw_(\d+)/ then to_g.rjust $1.to_i
470
+ else super
452
471
  end
453
472
  end
454
473
  end
@@ -483,6 +502,20 @@ class NilClass
483
502
  end
484
503
  end
485
504
 
505
+ class TrueClass
506
+ def <=> oth
507
+ oth == true ? 0 : oth == false ? 1 : nil
508
+ end
509
+ include Enumerable
510
+ end
511
+
512
+ class FalseClass
513
+ def <=> oth
514
+ oth == false ? 0 : oth == true ? -1 : nil
515
+ end
516
+ include Enumerable
517
+ end
518
+
486
519
  class Proc
487
520
  def to_s
488
521
  "#<%s:0x%08x>" % [ self.class, object_id]
data/lib/rbfind.rb CHANGED
@@ -8,7 +8,7 @@ require "rbfind/csv"
8
8
 
9
9
  module RbFind
10
10
 
11
- VERSION = "2.3".freeze
11
+ VERSION = "2.7".freeze
12
12
 
13
13
  =begin rdoc
14
14
 
@@ -241,7 +241,7 @@ Reverse sort:
241
241
 
242
242
  Sort without case sensitivity and preceding dot:
243
243
 
244
- s = proc { |x| x =~ /^\.?/ ; $'.downcase }
244
+ s = proc { name =~ /^\.?/ ; $'.downcase }
245
245
  RbFind.run sort: s do
246
246
  puts path
247
247
  end
@@ -270,141 +270,121 @@ Sort without case sensitivity and preceding dot:
270
270
 
271
271
  private
272
272
 
273
- def initialize max_depth: nil, depth_first: nil, follow: nil,
274
- sort: true, reverse: false, error: nil, &block
275
- @max_depth = max_depth
276
- @depth_first = depth_first
277
- @follow = follow
278
- @sort = sort_parser sort, reverse
279
- @error = error
280
- @block = block
281
-
282
- ostat = $stdout.stat
283
- @ostat = ostat if ostat.file?
284
-
285
- @wd, @start, @count = Dir.getwd, Time.now, 0
286
- end
273
+ Params = Struct.new :max_depth, :depth_first, :follow,
274
+ :sort, :dirs, :reverse, :error, :block
287
275
 
288
- def sort_parser st, rev
289
- r = case st
290
- when Proc then proc { |l| l.sort_by! &st }
291
- when nil, false, nil, "" then proc { }
292
- else proc { |l| l.sort! }
276
+ def initialize max_depth: nil, depth_first: nil, follow: nil,
277
+ sort: true, dirs: false, reverse: false, error: nil, &block
278
+ @params = Params.new max_depth&.nonzero?, depth_first, follow,
279
+ (sort_parser sort), dirs, reverse, error, block
280
+ @start = Time.instance_eval { @start = Time.now }
281
+ Time.instance_eval { @start = Time.now }
282
+ @count, @depth = 0, 0
283
+ end
284
+
285
+ def sort_parser st
286
+ case st
287
+ when Proc then proc { |l| l.sort_by! { |e| e.instance_eval &st } }
288
+ when String then proc { |l| l.sort_by! { |e| e.instance_eval st } }
289
+ when nil, false then proc { }
290
+ else proc { |l| l.sort_by! { |e| e.name } }
293
291
  end
294
- rev ? proc { |l| r.call l ; l.reverse! } : r
295
292
  end
296
293
 
297
294
  public
298
295
 
299
- attr_reader :wd, :start, :count, :depth
300
-
301
296
  def run *args
302
- @levels, @depth = [], 0
303
297
  args.flatten!
304
298
  args.compact!
305
299
  if args.empty? then
306
300
  visit_dir Dir::CUR_DIR
307
301
  else
308
- args.each { |base|
309
- handle_error do
310
- File.exists? base or raise "`#{base}` doesn't exist."
311
- visit_depth base
312
- end
313
- }
302
+ step_depth do
303
+ args.each { |base|
304
+ e = Entry.new base, self
305
+ enter e if handle_error do e.stat end
306
+ }
307
+ end
314
308
  end
315
- ensure
316
- @levels = @depth = nil
317
309
  end
318
310
 
319
- private
311
+ attr_reader :start, :count
312
+ attr_reader :depth
313
+ attr_reader :current
320
314
 
321
- def join_path
322
- (File.join @levels).freeze
323
- end
315
+ private
324
316
 
325
- def visit filename
317
+ def step_depth
326
318
  @depth += 1
327
- visit_depth filename
319
+ yield
328
320
  ensure
329
321
  @depth -= 1
330
322
  end
331
323
 
332
- def visit_depth filename
333
- @levels.push filename.dup.freeze
334
- p_, @path = @path, join_path
335
- if @depth_first then
324
+ def enter elem
325
+ c_, @current = @current, elem
326
+ @count += 1
327
+ if @params.depth_first then
336
328
  enter_dir
337
- call_block or raise "#{self.class}: prune doesn't work with :depth_first."
329
+ begin
330
+ call_block
331
+ rescue Prune
332
+ handle_error do
333
+ raise "#{self.class}: prune with :depth_first is pointless."
334
+ end
335
+ end
338
336
  else
339
- call_block and enter_dir
337
+ begin
338
+ call_block
339
+ enter_dir if @current.path
340
+ rescue Prune
341
+ end
340
342
  end
341
- @count += 1
342
343
  ensure
343
- @path = p_
344
- @levels.pop
344
+ @current = c_
345
345
  end
346
346
 
347
- def enter_dir
348
- return unless File.directory? @path
349
- if File.symlink? @path then
350
- return unless @follow and handle_error do
351
- d = @path.dup
352
- while d != Dir::CUR_DIR do
353
- d, = File.split d
354
- raise "cyclic recursion in #@path" if File.identical? d, @path
355
- end
356
- true
357
- end
347
+ def visit_dir dir
348
+ return if @params.max_depth and @params.max_depth == @depth
349
+ list = (Dir.new dir).children.map { |f| Entry.new f, self }
350
+ @params.sort.call list
351
+ list.reverse! if @params.reverse
352
+ if @params.dirs then
353
+ list = list.partition { |e| e.rstat.directory? rescue nil }
354
+ list.reverse! if @params.depth_first
355
+ list.flatten!
358
356
  end
359
- handle_error do
360
- visit_dir @path
357
+ step_depth do
358
+ list.each { |e| enter e }
361
359
  end
362
360
  end
363
361
 
364
- def visit_dir dir
365
- return if @max_depth and @max_depth == @depth
366
- list = (Dir.new dir).children
367
- @sort.call list
368
- list.each { |f| visit f }
369
- ensure
362
+ def enter_dir
363
+ return unless @current.stat.directory? || (@params.follow &&
364
+ @current.symlink? && @current.rstat.directory?)
365
+ handle_error do
366
+ @current.cyclic? and
367
+ raise "Cyclic recursion in #{@current.path}"
368
+ visit_dir @current.path
369
+ end
370
370
  end
371
371
 
372
372
  def call_block
373
- e = Entry.new @levels.last, @path, self
374
373
  handle_error do
375
- $_, $. = e.name, count
376
374
  begin
377
- e.instance_eval &@block
375
+ $_, $. = @current.name, @count
376
+ @current.instance_eval &@params.block
378
377
  rescue Done
379
378
  end
380
- if !(e.name.equal? @levels.last) && e.name != @levels.last then
381
- if e.name then
382
- e.name == (File.basename e.name) or
383
- raise "#{self.class}: rename to `#{e.name}' may not be a path."
384
- e.name.freeze
385
- @levels.pop
386
- @levels.push e.name
387
- p, @path = @path, join_path
388
- File.rename p, @path
389
- else
390
- if e.dir? then
391
- Dir.rmdir @path
392
- else
393
- File.unlink @path
394
- end
395
- end
396
- end
397
- true
398
379
  end
399
- rescue Prune
400
380
  end
401
381
 
402
382
  def handle_error
403
383
  yield
404
384
  rescue
405
- case @error
406
- when Proc then @error.call
407
- when String then instance_eval @error
385
+ case @params.error
386
+ when Proc then @params.error.call
387
+ when String then instance_eval @params.error
408
388
  else raise
409
389
  end
410
390
  nil
@@ -417,21 +397,35 @@ Sort without case sensitivity and preceding dot:
417
397
 
418
398
  attr_reader :path, :name
419
399
 
420
- def initialize name, path, walk
421
- @name, @path, @walk = name, path, walk
400
+ def initialize filename, walk
401
+ @walk = walk
402
+ @prev, @name = walk.current, filename.dup.freeze
403
+ @path = join_path @name
422
404
  end
423
405
 
406
+ protected
407
+ attr_reader :prev
408
+ private
409
+ def join_path name
410
+ @prev ? (File.join @prev.path, name).freeze : name
411
+ end
412
+ def reset
413
+ @fullpath = @stat = @rstat = @ostat = @colors = nil
414
+ end
415
+ public
416
+
417
+ def count ; @walk.count ; end
424
418
  def depth ; @walk.depth ; end
425
419
  def now ; @walk.start ; end
426
420
 
427
- def fullpath ; @fullpath ||= File.absolute_path @path, @walk.wd ; end
421
+ def fullpath ; @fullpath ||= File.absolute_path @path ; end
428
422
 
429
423
  def stat ; @stat ||= File.lstat @path ; end
430
424
  def rstat ; @rstat ||= File.stat @path ; end
431
425
 
432
426
 
433
427
  private
434
- def append_slash s ; (File.directory? s) ? (File.join s, "") : s ; end
428
+ def append_slash s ; directory? ? (File.join s, "") : s ; end
435
429
  public
436
430
 
437
431
  def path! ; append_slash path ; end
@@ -461,7 +455,23 @@ Sort without case sensitivity and preceding dot:
461
455
  end
462
456
  public
463
457
 
464
- def dir? ; stat.directory? ; end
458
+ def directory? ; stat.directory? ; end
459
+ alias dir? directory?
460
+
461
+ def symlink? ; stat.symlink? ; end
462
+
463
+ def cyclic?
464
+ e = self
465
+ loop do
466
+ e = e.prev
467
+ e or break
468
+ if File.identical? e.path, @path then
469
+ return true
470
+ end
471
+ end
472
+ false
473
+ end
474
+
465
475
 
466
476
  def aage ; @walk.start - stat.atime ; end
467
477
  def mage ; @walk.start - stat.mtime ; end
@@ -516,10 +526,10 @@ Sort without case sensitivity and preceding dot:
516
526
  end
517
527
 
518
528
 
519
- def readlink ; File.readlink @path if stat.symlink? ; end
529
+ def readlink ; File.readlink @path if symlink? ; end
520
530
 
521
531
  def broken_link?
522
- return unless stat.symlink?
532
+ return unless symlink?
523
533
  rstat
524
534
  false
525
535
  rescue
@@ -529,7 +539,7 @@ Sort without case sensitivity and preceding dot:
529
539
 
530
540
  ARROW = " -> "
531
541
  def arrow
532
- ARROW + (File.readlink @path) if stat.symlink?
542
+ ARROW + (File.readlink @path) if symlink?
533
543
  end
534
544
 
535
545
 
@@ -552,7 +562,11 @@ Sort without case sensitivity and preceding dot:
552
562
  # Check whether a directory contains an entry.
553
563
  #
554
564
  def contains? name
555
- File.exists? File.join @path, name
565
+ p = File.join @path, name
566
+ File.lstat p
567
+ true
568
+ rescue
569
+ false
556
570
  end
557
571
 
558
572
  # :call-seq:
@@ -580,7 +594,8 @@ Sort without case sensitivity and preceding dot:
580
594
  # nothing will be done.
581
595
  #
582
596
  def open &block
583
- @ostat and @ostat.identical? @path and
597
+ @ostat ||= $stdout.stat
598
+ @ostat.identical? @path and
584
599
  raise "Refusing to open output file."
585
600
  File.open @path, &block if file?
586
601
  end
@@ -690,10 +705,27 @@ Sort without case sensitivity and preceding dot:
690
705
  include Csv
691
706
 
692
707
 
693
- def rename newname ; @name = newname ; end
708
+ def rename newname
709
+ @name = newname
710
+ newname == (File.basename newname) or
711
+ raise "Rename to `#{newname}' may not be a path."
712
+ p = join_path newname
713
+ (File.exist? p) and raise "Rename to `#{p}` would overwrite."
714
+ File.rename @path, p
715
+ @name, @path = newname.dup.freeze, p
716
+ reset
717
+ end
694
718
  alias mv rename
695
719
 
696
- def rm ; @name = nil ; end
720
+ def rm
721
+ if directory? then
722
+ Dir.rmdir @path
723
+ else
724
+ File.unlink @path
725
+ end
726
+ @name = @path = nil
727
+ reset
728
+ end
697
729
 
698
730
 
699
731
  def cname ; color name ; end
@@ -5,7 +5,7 @@
5
5
 
6
6
  =begin rdoc
7
7
 
8
- Human readable sizes, times, and modes.
8
+ Human readable sizes and times.
9
9
 
10
10
  Examples:
11
11
 
@@ -136,12 +136,23 @@ class Time
136
136
  # file.stat.mtime.lsish #=> " 1. Apr 2008 "
137
137
  #
138
138
  def lsish
139
- strftime "#{PERC_DAY}. %b " +
140
- (year == Time.now.year ? "%H:%M:%S" : "%Y ")
139
+ strftime "%e. %b " + (year == Time.start.year ? "%H:%M:%S" : "%Y ")
141
140
  end
142
141
 
143
- # Windows has no "%e".
144
- PERC_DAY = Time.now.strftime("%e") =~ /\d/ ? "%e" : "%d" # :nodoc:
142
+ def long
143
+ s = Time.start
144
+ if year == s.year && month == s.month && day == s.day then
145
+ strftime "==%H:%M:%S"
146
+ else
147
+ strftime "%Y-%m-%d"
148
+ end
149
+ end
150
+
151
+ class <<self
152
+ def start
153
+ @start ||= Time.now
154
+ end
155
+ end
145
156
 
146
157
  end
147
158
 
data/lib/rbfind/table.rb CHANGED
@@ -42,7 +42,11 @@ module RbFind
42
42
  @rows.empty?
43
43
  end
44
44
 
45
- def output head: false
45
+ def output head: false, ifempty: nil
46
+ if empty? and ifempty then
47
+ puts ifempty
48
+ return
49
+ end
46
50
  make_lines head: head do |l| puts l end
47
51
  end
48
52
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbfind
3
3
  version: !ruby/object:Gem::Version
4
- version: '2.3'
4
+ version: '2.7'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bertram Scharpf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-24 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  A replacement for the standard UNIX command find.