rbfind 2.4 → 2.8.1

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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rbfind +54 -19
  3. data/lib/rbfind.rb +127 -101
  4. data/lib/rbfind/humansiz.rb +16 -5
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc576c9c24d5acd2c31b95e55bfd40b306c1510060c06c2a5d00140c1fca77dd
4
- data.tar.gz: e2a95604bf31b4290d71b0c93da8bff1cde417407cf6c22c79872cf4132c6de3
3
+ metadata.gz: eb4aa5b122fc89b6358e4da1e8df29ec7942e04e826f51d9a0f8816cdc718156
4
+ data.tar.gz: 7d31b7146665a01a6fe8229751a2b6d866ff36fc4779de79ba766391f2ab4d4e
5
5
  SHA512:
6
- metadata.gz: 671c10d123f2a025f4ee3b0f0b08cbe2a74ef830a0b8f56cd7485470c68051902db9ace56b00a5f479d36ceefb802d133ddd43aa5cc025286a49405ce4860e79
7
- data.tar.gz: 39a4b9cd0565455b010228a68fefd7d021e81953cdd23c150555a83fef577a342282f42b6476c6f1e97287d9e99b659349284eae55244fbfff01edf40a2d724c
6
+ metadata.gz: a07828435433ee962a54d2d9447fa5fcd171a3e1c8bcc28ecc338fcabc5a8e89dd753cbc2b9938e5e9dc5fba186be681555ead5a198bba924ba3b75d4ca52696
7
+ data.tar.gz: 238e1a4a07b9fbe4e7b33b9eb3ee438d52057ab81f735ed30672ef9123e144c9cac4d4c8f75c6f9b2107079233f75b4268da8770e7910ce2f9d07956b16931f5
data/bin/rbfind CHANGED
@@ -32,14 +32,20 @@ module RbFind
32
32
  [ %w(--colored -c), nil, "force color on -p or default output"],
33
33
  [ %w(--depth -d), nil, "yield directory after its contents"],
34
34
  [ %w(--maxdepth -m), :num, "maxium step depth"],
35
+ [ %w(--anydepth -M), nil, "no maxium step depth"],
35
36
  [ %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"],
37
+ [ %w(--nosort -U), nil, "unsorted"],
38
+ [ %w(--sort-by -s), :str, "sort expression"],
39
+ [ %w(--reverse -R), nil, "reverse the sort"],
40
+ [ %w(--time -t), nil, "sort by time, newest first"],
41
+ [ %w(--size -S), nil, "sort by size, largest first"],
42
+ [ %w(--dirs -F), nil, "sort directories before files"],
39
43
  [ %w(--require -r), :rb, "require library"],
40
44
  [ %w(--puts-path -p), nil, "do 'puts path/cpath' on true block"],
41
45
  [ %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)"],
46
+ [ %w(--long -Q), nil, "alternate long format on true block"],
47
+ [ %w(--ino -J), nil, "show inodes and number of hard links"],
48
+ [ %w(--wider -+), nil, "widen fields in long output format"],
43
49
  [ %w(--slash -/), nil, "append a slash to directory names"],
44
50
  [ %w(--lines -l), :blk, "surround block by 'lines { |$_,$.| ... }'"],
45
51
  [ %w(--reallines -L), :blk, "same as -l but stop at any null character"],
@@ -48,14 +54,15 @@ module RbFind
48
54
  [ %w(--binary -b), nil, "grep even binary files"],
49
55
  [ %w(--no-vcs -C), nil, "prune version control dirs (CVS/.svn/.git)"],
50
56
  [ %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"],
57
+ [ %w(--skip -k), :rgx, "filenames to skip"],
58
+ [ %w(--demand -D), :rgx, "skip all filenames but these"],
53
59
  [ %w(--ext -e), :lst, "skip all filename extensions but these"],
54
60
  [ %w(--visible -I), nil, "skip all hidden (starting with .dot)"],
61
+ [ %w(--all -a), nil, "all, including hidden (starting with .dot)"],
55
62
  [ %w(--nodirs -N), nil, "skip directories"],
56
63
  [ %w(--begin -B), :blk, "eval block before begin"],
57
64
  [ %w(--end -E), :blk, "eval block after end"],
58
- [ %w(--file -f), :blk, "read block expression from file"],
65
+ [ %w(--file -f), :nam, "read block expression from file"],
59
66
  [ %w(--encoding -K), :str, "encoding extern[:intern] (same as ruby -E)"],
60
67
  ]
61
68
 
@@ -79,14 +86,20 @@ module RbFind
79
86
  when '--colored' then @color = true
80
87
  when '--depth' then @params[ :depth_first] = true
81
88
  when '--maxdepth' then @params[ :max_depth] = arg.to_i
89
+ when '--anydepth' then @params[ :max_depth] = nil
82
90
  when '--follow' then @params[ :follow] = true
83
91
  when '--nosort' then @params[ :sort] = false
84
- when '--sort-by' then @params[ :sort] = instance_eval "proc { |n| #{arg} }"
92
+ when '--sort-by' then @params[ :sort] = instance_eval "proc { #{arg} }"
93
+ when '--time' then @params[ :sort] = proc { mtime } ; @params[ :reverse] = true
94
+ when '--size' then @params[ :sort] = proc { size } ; @params[ :reverse] = true
95
+ when '--dirs' then @params[ :dirs] = true
85
96
  when '--reverse' then @params[ :reverse] = true
86
97
  when '--require' then require arg
87
98
  when '--puts-path' then @puts = true
88
- when '--ls-l' then @puts = true ; @wd = 6
89
- when '--wider' then @wd = @wd ? @wd.succ : 4
99
+ when '--ls-l' then @puts = :ls ; @wds = 6 ; @wd = 6
100
+ when '--long' then @puts = :alt ; @wds = 7 ; @wd = 4
101
+ when '--ino' then @puts = :ino ; @wds = 8 ; @wd = 2
102
+ when '--wider' then @wd and @wd += 2.succ ; @wds and @wds += @puts != :ls ? 4 : 3
90
103
  when '--slash' then @slash = true
91
104
  when '--lines' then @lines = :plain ; @block = arg
92
105
  when '--reallines' then @lines = :plain ; @real = true ; @block = arg
@@ -99,6 +112,7 @@ module RbFind
99
112
  when '--demand' then @demand = arg
100
113
  when '--ext' then @ext = arg
101
114
  when '--visible' then @visible = true
115
+ when '--all' then @visible = false
102
116
  when '--nodirs' then @nodirs = true
103
117
  when '--begin' then @blkbegin = arg
104
118
  when '--end' then @blkend = arg
@@ -150,11 +164,17 @@ module RbFind
150
164
  end
151
165
  if @puts then
152
166
  @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}"
167
+ @block << case @puts
168
+ when :ls then
169
+ "spcsep stype+modes, user.w#@wd, group.w#@wd, size.w#@wds, " +
170
+ "mtime.lsish, #{opath} + #{co ? 'carrow' : 'arrow'}.to_s"
171
+ when :alt then
172
+ "spcsep stype+modes, user!.w#@wd, group!.w#@wd, size.w_#@wds, " +
173
+ "mtime.long, #{opath} + #{co ? 'carrow' : 'arrow'}.to_s"
174
+ when :ino then
175
+ "spcsep ino.w#@wds, nlink.w#@wd, #{opath}"
176
+ else
177
+ "puts #{opath}"
158
178
  end
159
179
  end
160
180
 
@@ -246,7 +266,7 @@ module RbFind
246
266
  $ rbfind -d -m3 -- /mnt/data
247
267
  $ rbfind 'filesize > 10.MiB and colsep size.to_hib, path'
248
268
 
249
- $ rbfind -S "name =~ /^\.*/ ; $'.downcase"
269
+ $ rbfind -U "name =~ /^\.*/ ; $'.downcase"
250
270
  $ rbfind -B '$s=0' -E 'puts $s.to_h' 'filesize {|s|$s+=s}'
251
271
  $ rbfind 'puts path if ext == ".rb"'
252
272
  $ rbfind -p 'ext == ".rb"'
@@ -345,7 +365,7 @@ module RbFind
345
365
 
346
366
  def show
347
367
  puts "arguments:"
348
- @args.each { |a| puts_val a }.any? or puts_val "(none)"
368
+ @args.each { |a| puts_val a }.any? or puts_val "(none)"
349
369
  puts "parameters:"
350
370
  @params.each { |k,v| puts_val k, "=", v }.any? or puts_val "(none)"
351
371
  puts "block:"
@@ -447,8 +467,9 @@ class Integer
447
467
  # convenient formatting, right justification
448
468
  def method_missing sym, *args
449
469
  case sym.to_s # .to_s for Ruby 1.8
450
- when /\Aw_?(\d+)/ then "%#{$1}d" % self
451
- else super
470
+ when /\Aw(\d+)/ then "%#{$1}d" % self
471
+ when /\Aw_(\d+)/ then to_g.rjust $1.to_i
472
+ else super
452
473
  end
453
474
  end
454
475
  end
@@ -483,6 +504,20 @@ class NilClass
483
504
  end
484
505
  end
485
506
 
507
+ class TrueClass
508
+ def <=> oth
509
+ oth == true ? 0 : oth == false ? 1 : nil
510
+ end
511
+ include Enumerable
512
+ end
513
+
514
+ class FalseClass
515
+ def <=> oth
516
+ oth == false ? 0 : oth == true ? -1 : nil
517
+ end
518
+ include Enumerable
519
+ end
520
+
486
521
  class Proc
487
522
  def to_s
488
523
  "#<%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.4".freeze
11
+ VERSION = "2.8.1".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,119 @@ 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, 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
302
  args.each { |base|
309
- handle_error do
310
- File.lstat base rescue raise "`#{base}` doesn't exist."
311
- visit_depth base
312
- end
303
+ e = Entry.new base, self
304
+ enter e if handle_error do e.stat end
313
305
  }
314
306
  end
315
- ensure
316
- @levels = @depth = nil
317
307
  end
318
308
 
319
- private
309
+ attr_reader :start, :count
310
+ attr_reader :depth
311
+ attr_reader :current
320
312
 
321
- def join_path
322
- (File.join @levels).freeze
323
- end
313
+ private
324
314
 
325
- def visit filename
315
+ def step_depth
326
316
  @depth += 1
327
- visit_depth filename
317
+ yield
328
318
  ensure
329
319
  @depth -= 1
330
320
  end
331
321
 
332
- def visit_depth filename
333
- @levels.push filename.dup.freeze
334
- p_, @path = @path, join_path
335
- if @depth_first then
322
+ def enter elem
323
+ c_, @current = @current, elem
324
+ @count += 1
325
+ if @params.depth_first then
336
326
  enter_dir
337
- call_block or raise "#{self.class}: prune doesn't work with :depth_first."
327
+ begin
328
+ call_block
329
+ rescue Prune
330
+ handle_error do
331
+ raise "#{self.class}: prune with :depth_first is pointless."
332
+ end
333
+ end
338
334
  else
339
- call_block and enter_dir
335
+ begin
336
+ call_block
337
+ enter_dir if @current.path
338
+ rescue Prune
339
+ end
340
340
  end
341
- @count += 1
342
341
  ensure
343
- @path = p_
344
- @levels.pop
342
+ @current = c_
345
343
  end
346
344
 
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
345
+ def visit_dir dir
346
+ return if @params.max_depth and @params.max_depth <= @depth
347
+ list = (Dir.new dir).children.map { |f| Entry.new f, self }
348
+ @params.sort.call list
349
+ list.reverse! if @params.reverse
350
+ if @params.dirs then
351
+ list = list.partition { |e| e.rstat.directory? rescue nil }
352
+ list.reverse! if @params.depth_first
353
+ list.flatten!
358
354
  end
359
- handle_error do
360
- visit_dir @path
355
+ step_depth do
356
+ list.each { |e| enter e }
361
357
  end
362
358
  end
363
359
 
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
360
+ def enter_dir
361
+ return unless @current.stat.directory? || (@params.follow &&
362
+ @current.symlink? && @current.rstat.directory?)
363
+ handle_error do
364
+ @current.cyclic? and
365
+ raise "Cyclic recursion in #{@current.path}"
366
+ visit_dir @current.path
367
+ end
370
368
  end
371
369
 
372
370
  def call_block
373
- e = Entry.new @levels.last, @path, self
374
371
  handle_error do
375
- $_, $. = e.name, count
376
372
  begin
377
- e.instance_eval &@block
373
+ $_, $. = @current.name, @count
374
+ @current.instance_eval &@params.block
378
375
  rescue Done
379
376
  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
377
  end
399
- rescue Prune
400
378
  end
401
379
 
402
380
  def handle_error
403
381
  yield
404
382
  rescue
405
- case @error
406
- when Proc then @error.call
407
- when String then instance_eval @error
383
+ case @params.error
384
+ when Proc then @params.error.call
385
+ when String then instance_eval @params.error
408
386
  else raise
409
387
  end
410
388
  nil
@@ -417,21 +395,35 @@ Sort without case sensitivity and preceding dot:
417
395
 
418
396
  attr_reader :path, :name
419
397
 
420
- def initialize name, path, walk
421
- @name, @path, @walk = name, path, walk
398
+ def initialize filename, walk
399
+ @walk = walk
400
+ @prev, @name = walk.current, filename.dup.freeze
401
+ @path = join_path @name
402
+ end
403
+
404
+ protected
405
+ attr_reader :prev
406
+ private
407
+ def join_path name
408
+ @prev ? (File.join @prev.path, name).freeze : name
422
409
  end
410
+ def reset
411
+ @fullpath = @stat = @rstat = @ostat = @colors = nil
412
+ end
413
+ public
423
414
 
415
+ def count ; @walk.count ; end
424
416
  def depth ; @walk.depth ; end
425
417
  def now ; @walk.start ; end
426
418
 
427
- def fullpath ; @fullpath ||= File.absolute_path @path, @walk.wd ; end
419
+ def fullpath ; @fullpath ||= File.absolute_path @path ; end
428
420
 
429
421
  def stat ; @stat ||= File.lstat @path ; end
430
422
  def rstat ; @rstat ||= File.stat @path ; end
431
423
 
432
424
 
433
425
  private
434
- def append_slash s ; (File.directory? s) ? (File.join s, "") : s ; end
426
+ def append_slash s ; directory? ? (File.join s, "") : s ; end
435
427
  public
436
428
 
437
429
  def path! ; append_slash path ; end
@@ -461,7 +453,23 @@ Sort without case sensitivity and preceding dot:
461
453
  end
462
454
  public
463
455
 
464
- def dir? ; stat.directory? ; end
456
+ def directory? ; stat.directory? ; end
457
+ alias dir? directory?
458
+
459
+ def symlink? ; stat.symlink? ; end
460
+
461
+ def cyclic?
462
+ e = self
463
+ loop do
464
+ e = e.prev
465
+ e or break
466
+ if File.identical? e.path, @path then
467
+ return true
468
+ end
469
+ end
470
+ false
471
+ end
472
+
465
473
 
466
474
  def aage ; @walk.start - stat.atime ; end
467
475
  def mage ; @walk.start - stat.mtime ; end
@@ -516,10 +524,10 @@ Sort without case sensitivity and preceding dot:
516
524
  end
517
525
 
518
526
 
519
- def readlink ; File.readlink @path if stat.symlink? ; end
527
+ def readlink ; File.readlink @path if symlink? ; end
520
528
 
521
529
  def broken_link?
522
- return unless stat.symlink?
530
+ return unless symlink?
523
531
  rstat
524
532
  false
525
533
  rescue
@@ -529,7 +537,7 @@ Sort without case sensitivity and preceding dot:
529
537
 
530
538
  ARROW = " -> "
531
539
  def arrow
532
- ARROW + (File.readlink @path) if stat.symlink?
540
+ ARROW + (File.readlink @path) if symlink?
533
541
  end
534
542
 
535
543
 
@@ -584,7 +592,8 @@ Sort without case sensitivity and preceding dot:
584
592
  # nothing will be done.
585
593
  #
586
594
  def open &block
587
- @ostat and @ostat.identical? @path and
595
+ @ostat ||= $stdout.stat
596
+ @ostat.identical? @path and
588
597
  raise "Refusing to open output file."
589
598
  File.open @path, &block if file?
590
599
  end
@@ -694,10 +703,27 @@ Sort without case sensitivity and preceding dot:
694
703
  include Csv
695
704
 
696
705
 
697
- def rename newname ; @name = newname ; end
706
+ def rename newname
707
+ @name = newname
708
+ newname == (File.basename newname) or
709
+ raise "Rename to `#{newname}' may not be a path."
710
+ p = join_path newname
711
+ (File.exist? p) and raise "Rename to `#{p}` would overwrite."
712
+ File.rename @path, p
713
+ @name, @path = newname.dup.freeze, p
714
+ reset
715
+ end
698
716
  alias mv rename
699
717
 
700
- def rm ; @name = nil ; end
718
+ def rm
719
+ if directory? then
720
+ Dir.rmdir @path
721
+ else
722
+ File.unlink @path
723
+ end
724
+ @name = @path = nil
725
+ reset
726
+ end
701
727
 
702
728
 
703
729
  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
 
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.4'
4
+ version: 2.8.1
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-11-07 00:00:00.000000000 Z
11
+ date: 2021-03-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  A replacement for the standard UNIX command find.