Module: Ace::Core::Atoms::GlobExpander
- Defined in:
- lib/ace/core/atoms/glob_expander.rb
Overview
Pure glob pattern expansion and file matching functions
Class Method Summary collapse
-
.expand(pattern, base_dir: Dir.pwd, flags: 0) ⇒ Array<String>
Expand glob pattern to file paths.
-
.expand_multiple(patterns, base_dir: Dir.pwd, flags: 0) ⇒ Array<String>
Expand multiple glob patterns.
-
.expand_with_exclusions(pattern, exclude: [], base_dir: Dir.pwd) ⇒ Array<String>
Expand pattern with exclusions.
-
.filter_excluded(paths, exclude_patterns, flags: File::FNM_PATHNAME) ⇒ Array<String>
Filter paths by exclusion patterns.
-
.find_files(pattern, base_dir: Dir.pwd, max_depth: nil) ⇒ Array<String>
Find files recursively with pattern.
-
.glob_pattern?(pattern) ⇒ Boolean
Check if pattern is a glob pattern.
-
.matches?(path, patterns, flags: File::FNM_PATHNAME) ⇒ Boolean
Check if path matches any of the patterns.
-
.normalize_separators(path) ⇒ String
Normalize path separators for current OS.
-
.to_regex(pattern) ⇒ Regexp
Convert glob pattern to regex.
Class Method Details
.expand(pattern, base_dir: Dir.pwd, flags: 0) ⇒ Array<String>
Expand glob pattern to file paths
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/ace/core/atoms/glob_expander.rb', line 17 def (pattern, base_dir: Dir.pwd, flags: 0) return [] if pattern.nil? || pattern.empty? # Ensure base_dir is absolute base_dir = File.(base_dir) # Handle absolute patterns if pattern.start_with?("/") Dir.glob(pattern, flags).sort else # Make pattern relative to base_dir full_pattern = File.join(base_dir, pattern) Dir.glob(full_pattern, flags).map do |path| # Return relative paths from base_dir Pathname.new(path).relative_path_from(Pathname.new(base_dir)).to_s rescue ArgumentError # If we can't make it relative, return absolute path end.sort end rescue [] end |
.expand_multiple(patterns, base_dir: Dir.pwd, flags: 0) ⇒ Array<String>
Expand multiple glob patterns
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/ace/core/atoms/glob_expander.rb', line 46 def (patterns, base_dir: Dir.pwd, flags: 0) return [] if patterns.nil? || patterns.empty? patterns = Array(patterns) results = [] patterns.each do |pattern| results.concat((pattern, base_dir: base_dir, flags: flags)) end results.uniq.sort end |
.expand_with_exclusions(pattern, exclude: [], base_dir: Dir.pwd) ⇒ Array<String>
Expand pattern with exclusions
91 92 93 94 95 96 |
# File 'lib/ace/core/atoms/glob_expander.rb', line 91 def (pattern, exclude: [], base_dir: Dir.pwd) = (pattern, base_dir: base_dir) return if exclude.nil? || exclude.empty? filter_excluded(, exclude) end |
.filter_excluded(paths, exclude_patterns, flags: File::FNM_PATHNAME) ⇒ Array<String>
Filter paths by exclusion patterns
78 79 80 81 82 83 84 |
# File 'lib/ace/core/atoms/glob_expander.rb', line 78 def filter_excluded(paths, exclude_patterns, flags: File::FNM_PATHNAME) return paths if paths.nil? || exclude_patterns.nil? || exclude_patterns.empty? paths.reject do |path| matches?(path, exclude_patterns, flags: flags) end end |
.find_files(pattern, base_dir: Dir.pwd, max_depth: nil) ⇒ Array<String>
Find files recursively with pattern
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/ace/core/atoms/glob_expander.rb', line 103 def find_files(pattern, base_dir: Dir.pwd, max_depth: nil) return [] if pattern.nil? base_dir = File.(base_dir) results = [] # Build the glob pattern based on depth if max_depth.nil? glob_pattern = File.join(base_dir, "**", pattern) else # Build pattern with limited depth depth_pattern = (0..max_depth).map do |depth| parts = ["*"] * depth File.join(base_dir, *parts, pattern) end depth_pattern.each do |p| results.concat(Dir.glob(p)) end return results.map do |path| Pathname.new(path).relative_path_from(Pathname.new(base_dir)).to_s rescue ArgumentError path end.uniq.sort end Dir.glob(glob_pattern).map do |path| Pathname.new(path).relative_path_from(Pathname.new(base_dir)).to_s rescue ArgumentError path end.sort end |
.glob_pattern?(pattern) ⇒ Boolean
Check if pattern is a glob pattern
140 141 142 143 144 |
# File 'lib/ace/core/atoms/glob_expander.rb', line 140 def glob_pattern?(pattern) return false if pattern.nil? pattern.match?(/[*?\[{]/) end |
.matches?(path, patterns, flags: File::FNM_PATHNAME) ⇒ Boolean
Check if path matches any of the patterns
64 65 66 67 68 69 70 71 |
# File 'lib/ace/core/atoms/glob_expander.rb', line 64 def matches?(path, patterns, flags: File::FNM_PATHNAME) return false if path.nil? || patterns.nil? patterns = Array(patterns) patterns.any? do |pattern| File.fnmatch(pattern, path, flags) end end |
.normalize_separators(path) ⇒ String
Normalize path separators for current OS
149 150 151 152 153 |
# File 'lib/ace/core/atoms/glob_expander.rb', line 149 def normalize_separators(path) return nil if path.nil? path.gsub(/[\\\/]+/, File::SEPARATOR) end |
.to_regex(pattern) ⇒ Regexp
Convert glob pattern to regex
158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/ace/core/atoms/glob_expander.rb', line 158 def to_regex(pattern) return nil if pattern.nil? # Escape special regex characters except glob ones escaped = pattern.gsub(/[.+^$()|\[\]{}\\]/) { |m| "\\#{m}" } # Convert glob patterns to regex regex_pattern = escaped .gsub("**/", ".*/") # ** matches any depth .gsub("*", "[^/]*") # * matches within directory .tr("?", ".") # ? matches single character Regexp.new("^#{regex_pattern}$") end |