# class Chef::ChefFS::FilePattern

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

### Attributes

pattern[R]

The pattern string.

### Public Class Methods

new(pattern) click to toggle source

Initialize a new FilePattern with the pattern string.

Raises `ArgumentError` if empty file pattern is specified

    # File lib/chef/chef_fs/file_pattern.rb, line 50
    def initialize(pattern)
      @pattern = pattern
    end

relative_to(dir, pattern) click to toggle source

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 `..`

    # 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

### Public Instance Methods

could_match_children?(path) click to toggle source

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

    # 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) click to toggle source

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`.

    # 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() click to toggle source

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'

    # 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() click to toggle source

Tell whether this pattern matches absolute, or relative paths

    # File lib/chef/chef_fs/file_pattern.rb, line 142
    def is_absolute
      calculate
      @is_absolute
    end

match?(path) click to toggle source

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

    # 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() click to toggle source

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.

    # File lib/chef/chef_fs/file_pattern.rb, line 136
    def normalized_pattern
      calculate
      @normalized_pattern
    end

to_s() click to toggle source

Returns the string pattern

    # File lib/chef/chef_fs/file_pattern.rb, line 159
    def to_s
      pattern
    end