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



206
207
208
209
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
# File 'lib/command-set/arguments.rb', line 206

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

  if( not (m = %r{^/([^/]*)$}.match(prefix)).nil? )
	infix = "/"
	search_path = ["/"]
	match = /^#{m[1]}.*/
  elsif( not (m = %r{^/(.*/)([^/]*)$}.match(prefix)).nil? )
	infix = "/#{m[1]}"
	match = /^#{m[2]}.*/
	search_path = [infix]
  elsif( %r{/$} =~ prefix )
	infix = prefix
	search_path.map! {|path| File.join(path, prefix)}
	match = /.*/
  elsif( %r{/} =~ prefix )
	infix = File.dirname(prefix) + "/"
	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 += "/"
   end

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

  if(list.length == 1 && list[0] =~ /\/$/)
	list << list[0] + "."
  end

  list
end

#validate(term, subject) ⇒ Object



266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/command-set/arguments.rb', line 266

def validate(term, subject)
  if(%r{^/} =~ 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