Class: Command::FileArgument

Inherits:
Argument show all
Defined in:
lib/command-set/arguments.rb

Overview

File access. Completes paths, validates file options.

Constant Summary collapse

Defaults =
{ 
  :prune_patterns => [/^\./],
  :dirs => [ENV['PWD']],
  :acceptor => proc do |path|
    return (File.exists?(path) and not File.directory?(path))
  end
}

Instance Attribute Summary

Attributes inherited from Argument

#name, #value

Instance Method Summary collapse

Methods inherited from Argument

#check_present, #consume, #consume_hash, #match_terms, #omittable?, #parse, register, #required?

Constructor Details

#initialize(name, options = {}) ⇒ FileArgument

You create a FileArgument either with an optional hash of options, or a block that evaluates whether or not a path is acceptable.

The default options hash looks like:

:prune_patterns => [/^./], #regexs of paths to eliminate from

#completion

:dirs => [ENV], #essentially the PATH env variable :acceptor => proc do |path| #Is a good path?

return (File.exists?(path) and not File.directory?(path))

end #The default wants existent non-dirs



192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/command-set/arguments.rb', line 192

def initialize(name, options={})
  super(name)
  options ||= {}
  if Hash === options
    @options = Defaults.merge(options)
    @acceptor = @options[:acceptor]
  elsif Proc === options
    @options = Defaults.dup
    @acceptor = proc &options
  else
    raise "File argument needs hash or proc!"
  end
end

Instance Method Details

#complete(prefix, subject) ⇒ Object



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/command-set/arguments.rb', line 210

def complete(prefix, subject)
  list = []
  search_path = @options[:dirs].dup
  match = %r{^#{Regexp.escape(prefix)}.*}
  infix = "" 

  if( not (m = %r{^#{fs}([^#{fs}]*)$}.match(prefix)).nil? )
  infix = fs
  search_path = [fs]
  match = %r{^#{m[1]}.*}
  elsif( not (m = %r{^#{fs}(.*#{fs})([^#{fs}]*)$}.match(prefix)).nil? )
  infix = "/#{m[1]}"
  match = /^#{m[2]}.*/
  search_path = [infix]
  elsif( %r{#{fs}$} =~ prefix )
  infix = prefix
  search_path.map! {|path| File.join(path, prefix)}
  match = /.*/
  elsif( %r{#{fs}} =~ prefix )
  infix = File.dirname(prefix) + "#{fs}"
  search_path.map! {|path| File.join(path, infix)}
  match = %r{^#{Regexp.escape(File.basename(prefix))}.*}
  end

  search_path.each do |dir|
  begin 
    Dir.foreach(dir) do |path|
 catch(:bad_path) do
   next unless match =~ path

   @options[:prune_patterns].each do |pat|
    if pat =~ path
throw :bad_path 
    end
   end

   candidate = File.join(dir,path)
   if(File.file?(candidate))
    throw :bad_path unless @acceptor[candidate]
   end

   if(File.directory?(candidate))
    path += fs
   end

   list << infix + path
 end
    end
  rescue Errno::ENOENT
    next
  end
  end

  if(list.length == 1 && list[0] =~ %r{#{fs}$})
  list << list[0] + "."
  end

  list
end

#fsObject



206
207
208
# File 'lib/command-set/arguments.rb', line 206

def fs
  File::Separator
end

#validate(term, subject) ⇒ Object



270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/command-set/arguments.rb', line 270

def validate(term, subject)
  if(%r{^#{fs}} =~ term)
  return @acceptor[term]
  end

  @options[:dirs].each do |dir|
  path = File.join(dir, term)
  if(File.exists?(path))
    return @acceptor[path]
  end
  end

  return @acceptor[File.join(@options[:dirs].first, term)]
end