Module: SearchUp

Defined in:
lib/search_up.rb,
lib/search_up/version.rb

Constant Summary collapse

VERSION =
"1.0.2"

Class Method Summary collapse

Class Method Details

.search(start_at, pattern, stop_at: nil, find_one: false, &predicate) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/search_up.rb', line 5

def self.search(start_at, pattern, stop_at: nil, find_one: false, &predicate)
  raise "start_at must be a String" unless start_at.is_a?(String)
  raise "pattern must be a String or a Regexp" \
    unless pattern.is_a?(String) || pattern.is_a?(Regexp)

  raise "stop_at must be nil or a String" \
    unless stop_at.nil? || stop_at.is_a?(String)

  find_one = !!find_one

  ret = []

  start_directory = File.expand_path(start_at)
  stop_directory = stop_at.nil? ? nil : File.expand_path(stop_at)

  previous = nil
  current = start_directory
  until current.nil? || current == previous
    candidates =
      if pattern.is_a?(String)
        Dir[File.join(current, pattern)]
      else
        Dir[File.join(current, "*")].grep(pattern)
      end

    candidates.select!(&predicate) unless predicate.nil?

    return candidates.first if find_one && !candidates.first.nil?

    ret << candidates

    previous = current
    current = File.expand_path("..", previous)

    break if current == stop_directory
  end

  # implicit; we can't get here in the find_one path unless we haven't found one
  find_one ? nil : ret.flatten
end