class IOStreams::Paths::Matcher
Implement fnmatch logic for any path iterator
Constants
- MATCH_START_CHARS
Characters indicating that pattern matching is required
Attributes
flags[R]
path[R]
pattern[R]
Public Class Methods
new(path, pattern, case_sensitive: false, hidden: false)
click to toggle source
If the supplied pattern contains sub-directories without wildcards, navigate down to that directory first before applying wildcard lookups from that point on.
Examples: If the current path is “/path/work”
"a/b/c/**/*" => "/path/work/a/b/c" "a/b/c?/**/*" => "/path/work/a/b" "**/*" => "/path/work"
Note: Absolute paths in the pattern are not supported.
# File lib/io_streams/paths/matcher.rb, line 19 def initialize(path, pattern, case_sensitive: false, hidden: false) extract_optimized_path(path, pattern) @flags = ::File::FNM_EXTGLOB | ::File::FNM_PATHNAME @flags |= ::File::FNM_CASEFOLD unless case_sensitive @flags |= ::File::FNM_DOTMATCH if hidden end
Public Instance Methods
match?(file_name)
click to toggle source
Returns whether the relative `file_name` matches
# File lib/io_streams/paths/matcher.rb, line 28 def match?(file_name) relative_file_name = file_name.sub(path.to_s, "").sub(%r{\A/}, "") ::File.fnmatch?(pattern, relative_file_name, flags) end
recursive?()
click to toggle source
Whether this pattern includes a recursive match. I.e. Includes `**` anywhere in the path
# File lib/io_streams/paths/matcher.rb, line 35 def recursive? @recursive ||= pattern.nil? ? false : pattern.include?("**") end
Private Instance Methods
extract_optimized_path(path, pattern)
click to toggle source
# File lib/io_streams/paths/matcher.rb, line 41 def extract_optimized_path(path, pattern) elements = pattern.split("/") index = elements.find_index { |e| e.match(MATCH_START_CHARS) } if index.nil? # No index means it has no pattern. @path = path.nil? ? IOStreams.path(pattern) : path.join(pattern) @pattern = nil elsif index.zero? # Cannot optimize path since the very first entry contains a wildcard @path = path || IOStreams.path @pattern = pattern else new_path = elements[0..index - 1].join("/") @path = path.nil? ? IOStreams.path(new_path) : path.join(new_path) @pattern = elements[index..-1].join("/") end end