Class: Chef::ChefFS::FilePattern
- Defined in:
- lib/chef/chef_fs/file_pattern.rb
Overview
Represents a glob pattern. This class is designed so that it can match arbitrary strings, and tell you about partial matches.
Examples:
-
a*z
-
Matches
abcz
-
Does not match
ab/cd/ez
-
Does not match
xabcz
-
-
a**z
-
Matches
abcz
-
Matches
ab/cd/ez
-
Special characters supported:
-
/
(and\
on Windows) - directory separators -
*
- match zero or more characters (but not directory separators) -
*\*
- match zero or more characters, including directory separators -
?
- match exactly one character (not a directory separator)
Only on Unix:
-
[abc0-9]
- match one of the included characters -
\<character>
- escape character: match the given character
Instance Attribute Summary collapse
-
#pattern ⇒ Object
readonly
The pattern string.
Class Method Summary collapse
-
.relative_to(dir, pattern) ⇒ Object
Given a relative file pattern and a directory, makes a new file pattern starting with the directory.
Instance Method Summary collapse
-
#could_match_children?(path) ⇒ Boolean
Reports whether this pattern could match children of
path
. -
#exact_child_name_under(path) ⇒ Object
Returns the immediate child of a path that would be matched if this FilePattern was applied.
-
#exact_path ⇒ Object
If this pattern represents an exact path, returns the exact path.
-
#initialize(pattern) ⇒ FilePattern
constructor
Initialize a new FilePattern with the pattern string.
-
#is_absolute ⇒ Object
Tell whether this pattern matches absolute, or relative paths.
-
#match?(path) ⇒ Boolean
Returns <tt>true+ if this pattern matches the path, <tt>false+ otherwise.
-
#normalized_pattern ⇒ Object
Returns the normalized version of the pattern, with / as the directory separator, and “.” and “..” removed.
-
#to_s ⇒ Object
Returns the string pattern.
Constructor Details
#initialize(pattern) ⇒ FilePattern
Initialize a new FilePattern with the pattern string.
Raises ArgumentError
if empty file pattern is specified
50 51 52 |
# File 'lib/chef/chef_fs/file_pattern.rb', line 50 def initialize(pattern) @pattern = pattern end |
Instance Attribute Details
#pattern ⇒ Object (readonly)
The pattern string.
55 56 57 |
# File 'lib/chef/chef_fs/file_pattern.rb', line 55 def pattern @pattern end |
Class Method Details
.relative_to(dir, pattern) ⇒ Object
Given a relative file pattern and a directory, makes a new file pattern starting with the directory.
FilePattern.relative_to('/usr/local', 'bin/*grok') == FilePattern.new('/usr/local/bin/*grok')
BUG: this does not support patterns starting with ..
169 170 171 172 |
# File 'lib/chef/chef_fs/file_pattern.rb', line 169 def self.relative_to(dir, pattern) return FilePattern.new(pattern) if pattern =~ /^#{Chef::ChefFS::PathUtils::regexp_path_separator}/ FilePattern.new(Chef::ChefFS::PathUtils::join(dir, pattern)) end |
Instance Method Details
#could_match_children?(path) ⇒ Boolean
Reports whether this pattern could match children of path
. If the pattern doesn’t match the path up to this point or if it matches and doesn’t allow further children, this will return false
.
Attributes
-
path
- a path to check
Examples
abc/def.could_match_children?('abc') == true
abc.could_match_children?('abc') == false
abc/def.could_match_children?('x') == false
a**z.could_match_children?('ab/cd') == true
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/chef/chef_fs/file_pattern.rb', line 72 def could_match_children?(path) return false if path == '' # Empty string is not a path argument_is_absolute = !!(path =~ /^#{Chef::ChefFS::PathUtils::regexp_path_separator}/) return false if is_absolute != argument_is_absolute path = path[1,path.length-1] if argument_is_absolute path_parts = Chef::ChefFS::PathUtils::split(path) # If the pattern is shorter than the path (or same size), children will be larger than the pattern, and will not match. return false if regexp_parts.length <= path_parts.length && !has_double_star # If the path doesn't match up to this point, children won't match either. return false if path_parts.zip(regexp_parts).any? { |part,regexp| !regexp.nil? && !regexp.match(part) } # Otherwise, it's possible we could match: the path matches to this point, and the pattern is longer than the path. # TODO There is one edge case where the double star comes after some characters like abc**def--we could check whether the next # bit of path starts with abc in that case. return true end |
#exact_child_name_under(path) ⇒ Object
Returns the immediate child of a path that would be matched if this FilePattern was applied. If more than one child could match, this method returns nil.
Attributes
-
path
- The path to look for an exact child name under.
Returns
The next directory in the pattern under the given path. If the directory part could match more than one child, it returns nil
.
Examples
abc/def.exact_child_name_under('abc') == 'def'
abc/def/ghi.exact_child_name_under('abc') == 'def'
abc/*/ghi.exact_child_name_under('abc') == nil
abc/*/ghi.exact_child_name_under('abc/def') == 'ghi'
abc/**/ghi.exact_child_name_under('abc/def') == nil
This method assumes could_match_children?(path) is true
.
113 114 115 116 117 118 |
# File 'lib/chef/chef_fs/file_pattern.rb', line 113 def exact_child_name_under(path) path = path[1,path.length-1] if !!(path =~ /^#{Chef::ChefFS::PathUtils::regexp_path_separator}/) dirs_in_path = Chef::ChefFS::PathUtils::split(path).length return nil if exact_parts.length <= dirs_in_path return exact_parts[dirs_in_path] end |
#exact_path ⇒ Object
If this pattern represents an exact path, returns the exact path.
abc/def.exact_path == 'abc/def'
abc/*def.exact_path == 'abc/def'
abc/x\\yz.exact_path == 'abc/xyz'
125 126 127 128 129 |
# File 'lib/chef/chef_fs/file_pattern.rb', line 125 def exact_path return nil if has_double_star || exact_parts.any? { |part| part.nil? } result = Chef::ChefFS::PathUtils::join(*exact_parts) is_absolute ? Chef::ChefFS::PathUtils::join('', result) : result end |
#is_absolute ⇒ Object
Tell whether this pattern matches absolute, or relative paths
142 143 144 145 |
# File 'lib/chef/chef_fs/file_pattern.rb', line 142 def is_absolute calculate @is_absolute end |
#match?(path) ⇒ Boolean
Returns <tt>true+ if this pattern matches the path, <tt>false+ otherwise.
abc/*/def.match?('abc/foo/def') == true
abc/*/def.match?('abc/foo') == false
151 152 153 154 155 156 |
# File 'lib/chef/chef_fs/file_pattern.rb', line 151 def match?(path) argument_is_absolute = !!(path =~ /^#{Chef::ChefFS::PathUtils::regexp_path_separator}/) return false if is_absolute != argument_is_absolute path = path[1,path.length-1] if argument_is_absolute !!regexp.match(path) end |
#normalized_pattern ⇒ Object
Returns the normalized version of the pattern, with / as the directory separator, and “.” and “..” removed.
This does not presently change things like b to b, but in the future it might.
136 137 138 139 |
# File 'lib/chef/chef_fs/file_pattern.rb', line 136 def normalized_pattern calculate @normalized_pattern end |
#to_s ⇒ Object
Returns the string pattern
159 160 161 |
# File 'lib/chef/chef_fs/file_pattern.rb', line 159 def to_s pattern end |