Class: TermUtils::FF::Finder

Inherits:
Object
  • Object
show all
Defined in:
lib/term_utils/ff/finder.rb

Overview

Represents the find method engine.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(paths) ⇒ Finder



127
128
129
130
# File 'lib/term_utils/ff/finder.rb', line 127

def initialize(paths)
  @paths = paths.dup
  @query = FinderQuery.new
end

Instance Attribute Details

#queryObject (readonly)

Returns the value of attribute query.



125
126
127
# File 'lib/term_utils/ff/finder.rb', line 125

def query
  @query
end

Instance Method Details

#enter?(entry) ⇒ Boolean



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/term_utils/ff/finder.rb', line 210

def enter?(entry)
  unless @query.use_stat
    return File.directory?(entry.path)
  end

  return false unless entry.directory?

  @query.each_filter do |f|
    case f[:kind]
    when :enter
      return true if f[:block].call(entry)
    when :skip
      return false if f[:block].call(entry)
    end
  end
  true
end

#execObject



132
133
134
135
136
137
# File 'lib/term_utils/ff/finder.rb', line 132

def exec
  @paths.each_with_object([]) do |path, obj|
    ctx = { entries: obj, basedir: path }
    list_start(ctx)
  end
end

#include?(entry) ⇒ Boolean



228
229
230
231
232
233
234
235
236
237
238
# File 'lib/term_utils/ff/finder.rb', line 228

def include?(entry)
  @query.each_filter do |f|
    case f[:kind]
    when :include
      return true if f[:block].call(entry)
    when :exclude
      return false if f[:block].call(entry)
    end
  end
  true
end

#list(ctx) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/term_utils/ff/finder.rb', line 160

def list(ctx)
  path_parts = ctx.fetch(:path_parts, [])
  absolute_path =
    if path_parts.empty?
      ctx[:basedir]
    else
      "#{ctx[:basedir]}/#{path_parts.join('/')}"
    end
  entries = Dir.entries(absolute_path)
  entries.each do |name|
    next if %w[. ..].include?(name)

    entry = FinderEntry.new.tap do |e|
      e.index = ctx[:entries].length
      e.name = name
      if @query.use_stat
        st = File.stat("#{absolute_path}/#{name}")
        e.kind = st.ftype
        e.uid = st.uid
        e.gid = st.gid
        e.mode = st.mode
        e.size = st.size
      end
      e.path_parts = path_parts.dup + [name]
      e.path = "#{ctx[:basedir]}/#{e.path_parts.join('/')}"
    end
    ctx[:entries] << entry if match?(entry) && include?(entry)
    if enter?(entry)
      list(ctx.merge({ path_parts: entry.path_parts }))
    end
  end
end

#list_start(ctx) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/term_utils/ff/finder.rb', line 139

def list_start(ctx)
  entry = FinderEntry.new.tap do |e|
    e.index = ctx[:entries].length
    e.name = File.basename(ctx[:basedir])
    if @query.use_stat
      st = File.stat(ctx[:basedir])
      e.kind = st.ftype
      e.uid = st.uid
      e.gid = st.gid
      e.mode = st.mode
      e.size = st.size
    end
    e.path_parts = []
    e.path = ctx[:basedir]
  end
  ctx[:entries] << entry if match?(entry) && include?(entry)
  return unless enter?(entry)

  list(ctx)
end

#match?(entry) ⇒ Boolean



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/term_utils/ff/finder.rb', line 193

def match?(entry)
  # (1of2) Depth
  return false if entry.depth < @query.min_depth
  return false if !@query.max_depth.nil? && entry.depth > @query.max_depth

  # (2of2) Entry kind.
  if @query.entry_kind.nil?
    true
  elsif @query.entry_kind.is_a?(String)
    entry.kind == @query.entry_kind
  elsif @query.entry_kind.is_a?(Array)
    @query.entry_kind.include?(entry.kind)
  else
    false
  end
end