Module: FakeFS::Globber

Extended by:
Globber
Included in:
Globber
Defined in:
lib/fakefs/globber.rb

Overview

Handles globbing for FakeFS.

Instance Method Summary collapse

Instance Method Details

#expand(pattern) ⇒ Object



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
# File 'lib/fakefs/globber.rb', line 6

def expand(pattern)
  pattern = pattern.to_s

  return [pattern] if pattern[0] != '{' || pattern[-1] != '}'

  part = ''
  result = []

  each_char_with_levels pattern, '{', '}' do |chr, level|
    case level
    when 0
      case chr
      when '{' # rubocop:disable Lint/EmptyWhen
        # noop
      else
        part << chr
      end
    when 1
      case chr
      when ','
        result << part
        part = ''
      when '}' # rubocop:disable Lint/EmptyWhen
        # noop
      else
        part << chr
      end
    else
      part << chr
    end
  end

  result << part

  result
end

#path_components(pattern) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/fakefs/globber.rb', line 43

def path_components(pattern)
  pattern = pattern.to_s

  part = ''
  result = []

  each_char_with_levels pattern, '{', '}' do |chr, level|
    if level == 0 && chr == File::SEPARATOR
      result << part
      part = ''
    else
      part << chr
    end
  end

  result << part

  drop_root(result).reject(&:empty?)
end

#regexp(pattern, find_flags = 0, gave_char_class = false) ⇒ Object



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
# File 'lib/fakefs/globber.rb', line 63

def regexp(pattern, find_flags = 0, gave_char_class = false)
  pattern = pattern.to_s

  regex_body =
    pattern
    .gsub('.', '\.')
    .gsub('+') { '\+' }
    .gsub('?', '.')
    .gsub('*', '.*')
    .gsub('(', '\(')
    .gsub(')', '\)')
    .gsub('$', '\$')

  # unless we're expecting character class contructs in regexes, escape all brackets
  # since if we're expecting them, the string should already be properly escaped
  unless gave_char_class
    regex_body = regex_body.gsub('[', '\[').gsub(']', '\]')
  end

  # This matches nested braces and attempts to do something correct most of the time
  # There are known issues (i.e. {,*,*/*}) that cannot be resolved with out a total
  # refactoring
  loop do
    break unless regex_body.gsub!(/(?<re>\{(?:(?>[^{}]+)|\g<re>)*\})/) do
      "(#{Regexp.last_match[1][1..-2].gsub(',', '|')})"
    end
  end

  # if we are matching dot files/directories, add that to the regex
  if find_flags == File::FNM_DOTMATCH
    regex_body = "(\.)?" + regex_body
  end

  regex_body = regex_body.gsub(/\A\./, '(?!\.).')
  /\A#{regex_body}\Z/
end