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
27
28
# File 'lib/utils/finder.rb', line 13

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

Instance Attribute Details

#outputObject (readonly)

Returns the value of attribute output.



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

def output
  @output
end

#pathsObject (readonly)

Returns the value of attribute paths.



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

def paths
  @paths
end

Instance Method Details

#ascii_file?(stat, path) ⇒ Boolean

Returns:

  • (Boolean)


34
35
36
# File 'lib/utils/finder.rb', line 34

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

#attempt_match?(path) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/utils/finder.rb', line 38

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

#searchObject



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
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/utils/finder.rb', line 53

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(file)
      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 << file[current...b]
          marked_file << red(file[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 = file[0...match.begin(0)] <<
          red(file[match.begin(0)...match.end(0)]) <<
          file[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)
  if !@args['e'] && @output && !@output.empty?
    yield @output if block_given?
  end
  self
end