Class: Utils::Finder

Inherits:
Object show all
Includes:
Term::ANSIColor, Tins::Find, Patterns
Defined in:
lib/utils/finder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Finder

Returns a new instance of Finder.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/utils/finder.rb', line 13

def initialize(opts = {})
  @args  = opts[:args] || {}
  @roots = discover_roots(opts[:roots])
  @config = opts[:config] || Utils::ConfigFile.new
  pattern_opts = opts.subhash(:pattern) | {
    :cset  => @args[?a],
    :icase => @args.fetch('i', true),
  }
  @binary = @args[?b]
  @pattern = @args[?r] ?
    RegexpPattern.new(pattern_opts) :
    FuzzyPattern.new(pattern_opts)
  @paths  = []
end

Instance Attribute Details

#outputObject (readonly)

Returns the value of attribute output.



30
31
32
# File 'lib/utils/finder.rb', line 30

def output
  @output
end

#pathsObject (readonly)

Returns the value of attribute paths.



28
29
30
# File 'lib/utils/finder.rb', line 28

def paths
  @paths
end

Instance Method Details

#ascii_file?(stat, path) ⇒ Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/utils/finder.rb', line 32

def ascii_file?(stat, path)
  stat.file? && (@binary || stat.size == 0 || File.ascii?(path))
end

#attempt_match?(path) ⇒ Boolean

Returns:

  • (Boolean)


36
37
38
39
40
41
42
43
# File 'lib/utils/finder.rb', line 36

def attempt_match?(path)
  stat = path.stat
  stat.symlink? and stat = path.lstat
  stat.directory? || ascii_file?(stat, path)
rescue SystemCallError => e
  warn "Caught #{e.class}: #{e}"
  nil
end

#searchObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/utils/finder.rb', line 45

def search
  paths = []
  suffixes = @args[?I].ask_and_send(:split, /[\s,]+/).to_a
  find(*(@roots + [ { :suffix => suffixes } ])) do |filename|
    begin
      bn, s = filename.pathname.basename, filename.stat
      if !s || s.directory? && @config.discover.prune?(bn)
        @args[?v] and warn "Pruning #{filename.inspect}."
        prune
      end
      if s.file? && @config.discover.skip?(bn)
        @args[?v] and warn "Skipping #{filename.inspect}."
        next
      end
      paths << filename
    end
  end
  paths.uniq!
  paths.map! { |p| a = File.split(p) ; a.unshift(p) ; a }
  paths = paths.map! do |path, dir, file|
    if do_match = attempt_match?(path) and @args[?v]
      warn "Attempt match of #{path.inspect}"
    end
    if do_match and match = @pattern.match(path)
      if FuzzyPattern === @pattern
        current = 0
        marked_file = ''
        score, e = 0, 0
        for i in 1...(match.size)
          match[i] or next
          b = match.begin(i)
          marked_file << path[current...b]
          marked_file << red(path[b, 1])
          score += (b - e)
          e = match.end(i)
          current = b + 1
        end
        marked_file << match.post_match
        [ score, file.size, path, File.join(dir, marked_file) ]
      else
        marked_file = path[0...match.begin(0)] <<
          red(path[match.begin(0)...match.end(0)]) <<
          path[match.end(0)..-1]
        [ 0, file.size, path, File.join(dir, marked_file) ]
      end
    end
  end
  paths.compact!
  @paths, @output = paths.sort.transpose.values_at(-2, -1)
  self
end