Class: Command::FileArgument

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

Overview

File access. Completes paths, validates file options. 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], #works 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

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

Instance Method Summary collapse

Methods inherited from Argument

#check_present, #consume, #consume_hash, #initialize, #match_terms, #names, #omittable?, #parse, register, #required?, #subject_requirements

Constructor Details

This class inherits a constructor from Command::Argument

Instance Method Details

#basis(subject = nil) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/command-set/arguments.rb', line 218

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

#complete(terms, prefix, subject) ⇒ Object



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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/command-set/arguments.rb', line 236

def complete(terms, prefix, subject)
  list = []
  options = basis(subject)
  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 options[:acceptor].call(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



232
233
234
# File 'lib/command-set/arguments.rb', line 232

def fs
  File::Separator
end

#validate(term, subject) ⇒ Object



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/command-set/arguments.rb', line 297

def validate(term, subject)
  options = basis(subject)
  acceptor = options[:acceptor]
  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