Class: Godo::Finder
- Inherits:
-
Object
- Object
- Godo::Finder
- Defined in:
- lib/finder.rb
Class Method Summary collapse
-
.find(query, options) ⇒ Object
Find, if possible, a single project path matching the query string.
Instance Method Summary collapse
- #base_match(paths) ⇒ Object
- #excluded?(path) ⇒ Boolean
- #filtered?(path) ⇒ Boolean
-
#find(query) ⇒ Object
Search for a folder matching the query.
-
#initialize(roots, ignores, max_depth = 0) ⇒ Finder
constructor
Create a Finder which will search under the given root folders, ignoring folders that match any of the specified ‘ignore’ patterns.
- #matches?(path, query) ⇒ Boolean
- #strip_inexact_matches(query, paths) ⇒ Object
Constructor Details
#initialize(roots, ignores, max_depth = 0) ⇒ Finder
Create a Finder which will search under the given root folders, ignoring folders that match any of the specified ‘ignore’ patterns. Searches only max_depth folders below the root paths, searches unlimited depth if not specified.
20 21 22 23 24 |
# File 'lib/finder.rb', line 20 def initialize( roots, ignores, max_depth = 0 ) @roots = roots.map { |root| File.( root ) } @ignores = ignores.map { |ignore| Regexp.compile( "/#{ignore}" ) } @max_depth = max_depth.to_i end |
Class Method Details
Instance Method Details
#base_match(paths) ⇒ Object
110 111 112 113 114 |
# File 'lib/finder.rb', line 110 def base_match( paths ) # Is the first path a prefix for all subsequent-paths path_match = Regexp.compile( "^#{paths.first}" ) paths[1..-1].all? { |path| path.match( path_match ) } end |
#excluded?(path) ⇒ Boolean
95 96 97 98 |
# File 'lib/finder.rb', line 95 def excluded?( path ) ignore = !!@ignores.detect { |ignore| ignore.match( path ) } ignore end |
#filtered?(path) ⇒ Boolean
91 92 93 |
# File 'lib/finder.rb', line 91 def filtered?( path ) !File.directory?( path ) || excluded?( path ) end |
#find(query) ⇒ Object
Search for a folder matching the query.
1) If a single folder is found it is returned.
2) If multiple folders are found then an attempt is made to strip any folders that are not an exact match for the query string.
For example with the query ‘reeplay’ returning the following paths
Paths:
/root/reeplay.it
/root/reeplay.it/reeplay
/root/reeplay.it/reeplay/app
The first path would be stripped because none of it’s components are an exact match for the query term.
3) If there are still multiple folders then the remaining folders are checked to see if they contain the first folder as a base path. If so the first path is returned.
In this case because the second of the two remaining paths has the first as a base path, the first path would be returned.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/finder.rb', line 50 def find( query ) matches = [] @roots.each do |root| # puts "Searching for #{query} in #{root}" Find.find( root ) do |path| if @max_depth > 0 # limit to @max_depth partial_path = path.gsub(root, '') Find.prune if partial_path =~ /\A\.+\Z/ depth = partial_path.split('/').length Find.prune if depth > @max_depth + 1 end if filtered?( path ) Find.prune elsif matches?( path, query ) matches << path end end end if matches.size > 1 matches = strip_inexact_matches( query, matches ) if matches.size > 1 if base_match( matches ) matches[0,1] else matches end else matches end else matches end end |
#matches?(path, query) ⇒ Boolean
87 88 89 |
# File 'lib/finder.rb', line 87 def matches?( path, query ) path.match( query ) end |
#strip_inexact_matches(query, paths) ⇒ Object
100 101 102 103 104 105 106 107 108 |
# File 'lib/finder.rb', line 100 def strip_inexact_matches( query, paths ) # If any of the paths have the query as a complete path component # then strip any paths that don't if paths.any? { |path| path.split( File::SEPARATOR ).any? { |component| query == component } } paths.select { |path| path.split( File::SEPARATOR ).any? { |component| query == component } } else paths end end |