Class: Shell::CommandProcessor
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/shell/command-processor.rb |
Overview
Constant Summary
-
NoDelegateMethods =
# File 'lib/shell/command-processor.rb', line 33m
Class Method Summary
-
.alias_command(alias, command, *options) ⇒ self
Creates a command alias at the given
alias
for the givencommand
, passing anyoptions
along with it. -
.alias_map
Returns a list of aliased commands.
-
.def_system_command(command, path) ⇒ Shell::SystemCommand
Defines a command, registering
path
as a::Shell
method for the givencommand
. - .initialize
-
.install_builtin_commands
Delegates File methods into
::Shell
, including the following commands: -
.install_system_commands(prefix = "sys_")
Defines all commands in the default_system_path as
::Shell
method, all with givenprefix
appended to their names. - .method_added(id)
- .new(shell) ⇒ CommandProcessor constructor
-
.run_config
include run file.
-
.unalias_command(alias) ⇒ self
Unaliases the given
alias
command. -
.undef_system_command(command) ⇒ self
Undefines a command.
- .add_delegate_command_to_shell(id) Internal use only
-
.def_builtin_commands(delegation_class, command_specs)
Internal use only
Delegates File and FileTest methods into
::Shell
, including the following commands:
Instance Method Summary
-
#[](command, file1, file2 = nil)
Alias for #test.
- #append(to, filter)
-
#cat(*filename) ⇒ Cat
Returns a
Cat
object, for the givenfilenames
- #concat(*jobs) ⇒ Concat
-
#echo(*strings) ⇒ Echo
Returns a
Echo
object, for the givenstrings
-
#expand_path(path)
#expand_path(path).
-
#find_system_command(command)
private functions.
-
#foreach(path, record_separator) ⇒ Enumerator
See
IO.foreach
whenpath
is a file. -
#glob(pattern) ⇒ Glob
def sort(*filenames).
-
#mkdir(path)
Same as
Dir.mkdir
, except multiple directories are allowed. -
#notify(*opts)
%pwd, %cwd -> @pwd.
-
#open(path, mode, permissions) ⇒ Enumerator
See
IO.open
whenpath
is a file. -
#out(device)
Calls
device.print
on the result passing the block to #transact -
#rehash
Clears the command hash table.
-
#rmdir(path)
Same as
Dir.rmdir
, except multiple directories are allowed. -
#system(command, *options) ⇒ SystemCommand
Executes the given
command
with theoptions
parameter. -
#tee(file) ⇒ Tee
Returns a
Tee
filter object, with the givenfile
command. -
#test(command, file1, file2) ⇒ Boolean
(also: #[])
Tests if the given
command
exists infile1
, or optionallyfile2
. -
#top_level_test
See #test
-
#transact
Executes a block as self.
-
#unlink(path)
See
IO.unlink
whenpath
is a file. - #check_point (also: #finish_all_jobs) Internal use only
-
#finish_all_jobs
Internal use only
Alias for #check_point.
Constructor Details
.new(shell) ⇒ CommandProcessor
# File 'lib/shell/command-processor.rb', line 69
def initialize(shell) @shell = shell @system_commands = {} end
Class Method Details
.add_delegate_command_to_shell(id)
# File 'lib/shell/command-processor.rb', line 579
def self.add_delegate_command_to_shell(id) # :nodoc: id = id.intern if id.kind_of?(String) name = id.id2name if Shell.method_defined?(id) Shell.notify "warn: override definition of Shell##{name}." Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n" Shell.module_eval "alias #{name}_org #{name}" end Shell.notify "method added: Shell##{name}.", Shell.debug? Shell.module_eval(%Q[def #{name}(*args, &block) begin @command_processor.__send__(:#{name}, *args, &block) rescue Exception $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` $@.delete_if{|s| /^\\(eval\\):/ =~ s} raise end end], __FILE__, __LINE__) if Shell::Filter.method_defined?(id) Shell.notify "warn: override definition of Shell::Filter##{name}." Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org." Filter.module_eval "alias #{name}_org #{name}" end Shell.notify "method added: Shell::Filter##{name}.", Shell.debug? Filter.module_eval(%Q[def #{name}(*args, &block) begin self | @shell.__send__(:#{name}, *args, &block) rescue Exception $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` $@.delete_if{|s| /^\\(eval\\):/ =~ s} raise end end], __FILE__, __LINE__) end
.alias_command(alias, command, *options) ⇒ self
# File 'lib/shell/command-processor.rb', line 439
def self.alias_command(ali, command, *opts) ali = ali.id2name if ali.kind_of?(Symbol) command = command.id2name if command.kind_of?(Symbol) begin if iterator? @alias_map[ali.intern] = proc eval((d = %Q[def #{ali}(*opts) @shell.__send__(:#{command}, *(CommandProcessor.alias_map[:#{ali}].call *opts)) end]), nil, __FILE__, __LINE__ - 1) else args = opts.collect{|opt| '"' + opt + '"'}.join(",") eval((d = %Q[def #{ali}(*opts) @shell.__send__(:#{command}, #{args}, *opts) end]), nil, __FILE__, __LINE__ - 1) end rescue SyntaxError Shell.notify "warn: Can't alias #{ali} command: #{command}." Shell.notify("Definition of #{ali}: ", d) raise end Shell.notify "Define #{ali} command: #{command}.", Shell.debug? Shell.notify("Definition of #{ali}: ", d, Shell.debug.kind_of?(Integer) && Shell.debug > 1) self end
.alias_map
Returns a list of aliased commands
# File 'lib/shell/command-processor.rb', line 427
def self.alias_map @alias_map end
.def_builtin_commands(delegation_class, command_specs)
Delegates File and FileTest methods into ::Shell
, including the following commands:
-
Shell#blockdev?
(file) -
Shell#chardev?
(file) -
Shell#directory?
(file) -
Shell#executable?
(file) -
Shell#executable_real?
(file) -
Shell#exist?
(file)/Shell#exists?(file) -
Shell#file?
(file) -
Shell#grpowned?
(file) -
Shell#owned?
(file) -
Shell#pipe?
(file) -
Shell#readable?
(file) -
Shell#readable_real?
(file) -
Shell#setgid?
(file) -
Shell#setuid?
(file) -
Shell#size
(file)/Shell#size?(file) -
Shell#socket?
(file) -
Shell#sticky?
(file) -
Shell#symlink?
(file) -
Shell#writable?
(file) -
Shell#writable_real?
(file) -
Shell#zero?
(file) -
Shell#syscopy
(filename_from, filename_to) -
Shell#copy
(filename_from, filename_to) -
Shell#move
(filename_from, filename_to) -
Shell#compare
(filename_from, filename_to) -
Shell#safe_unlink
(*filenames) -
Shell#makedirs
(*filenames) -
Shell#install
(filename_from, filename_to, mode)
And also, there are some aliases for convenience:
-
Shell#cmp <-
Shell#compare
-
Shell#mv <-
Shell#move
-
Shell#cp <-
Shell#copy
-
Shell#rm_f <-
Shell#safe_unlink
-
Shell#mkpath <-
Shell#makedirs
# File 'lib/shell/command-processor.rb', line 520
def self.def_builtin_commands(delegation_class, command_specs) for meth, args in command_specs arg_str = args.collect{|arg| arg.downcase}.join(", ") call_arg_str = args.collect{ |arg| case arg when /^(FILENAME.*)$/ format("expand_path(%s)", $1.downcase) when /^(\*FILENAME.*)$/ # \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ") $1.downcase + '.collect{|fn| expand_path(fn)}' else arg end }.join(", ") d = %Q[def #{meth}(#{arg_str}) #{delegation_class}.#{meth}(#{call_arg_str}) end] Shell.notify "Define #{meth}(#{arg_str})", Shell.debug? Shell.notify("Definition of #{meth}: ", d, Shell.debug.kind_of?(Integer) && Shell.debug > 1) eval d end end
.def_system_command(command, path) ⇒ Shell::SystemCommand
# File 'lib/shell/command-processor.rb', line 400
def self.def_system_command(command, path = command) begin eval((d = %Q[def #{command}(*opts) SystemCommand.new(@shell, '#{path}', *opts) end]), nil, __FILE__, __LINE__ - 1) rescue SyntaxError Shell.notify "warn: Can't define #{command} path: #{path}." end Shell.notify "Define #{command} path: #{path}.", Shell.debug? Shell.notify("Definition of #{command}: ", d, Shell.debug.kind_of?(Integer) && Shell.debug > 1) end
.initialize
[ GitHub ]# File 'lib/shell/command-processor.rb', line 38
def self.initialize install_builtin_commands # define CommandProcessor#methods to Shell#methods and Filter#methods for m in CommandProcessor.instance_methods(false) - NoDelegateMethods add_delegate_command_to_shell(m) end def self.method_added(id) add_delegate_command_to_shell(id) end end
.install_builtin_commands
Delegates File methods into ::Shell
, including the following commands:
-
Shell#atime
(file) -
Shell#basename
(file, *opt) -
Shell#chmod
(mode, *files) -
Shell#chown
(owner, group, *file) -
Shell#ctime
(file) -
Shell#delete
(*file) -
Shell#dirname
(file) -
Shell#ftype
(file) -
Shell#join
(*file) -
Shell#link
(file_from, file_to) -
Shell#lstat
(file) -
Shell#mtime
(file) -
Shell#readlink
(file) -
Shell#rename
(file_from, file_to) -
Shell#split
(file) -
Shell#stat
(file) -
Shell#symlink
(file_from, file_to) -
Shell#truncate
(file, length) -
Shell#utime
(atime, mtime, *file)
# File 'lib/shell/command-processor.rb', line 637
def self.install_builtin_commands # method related File. # (exclude open/foreach/unlink) normal_delegation_file_methods = [ ["atime", ["FILENAME"]], ["basename", ["fn", "*opts"]], ["chmod", ["mode", "*FILENAMES"]], ["chown", ["owner", "group", "*FILENAME"]], ["ctime", ["FILENAMES"]], ["delete", ["*FILENAMES"]], ["dirname", ["FILENAME"]], ["ftype", ["FILENAME"]], ["join", ["*items"]], ["link", ["FILENAME_O", "FILENAME_N"]], ["lstat", ["FILENAME"]], ["mtime", ["FILENAME"]], ["readlink", ["FILENAME"]], ["rename", ["FILENAME_FROM", "FILENAME_TO"]], ["split", ["pathname"]], ["stat", ["FILENAME"]], ["symlink", ["FILENAME_O", "FILENAME_N"]], ["truncate", ["FILENAME", "length"]], ["utime", ["atime", "mtime", "*FILENAMES"]]] def_builtin_commands(File, normal_delegation_file_methods) alias_method :rm, :delete # method related FileTest def_builtin_commands(FileTest, FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]}) end
.install_system_commands(prefix = "sys_")
Defines all commands in the Shell.default_system_path as ::Shell
method, all with given prefix
appended to their names.
Any invalid character names are converted to _
, and errors are passed to Shell.notify.
Methods already defined are skipped.
# File 'lib/shell/command-processor.rb', line 555
def self.install_system_commands(pre = "sys_") defined_meth = {} for m in Shell.methods defined_meth[m] = true end sh = Shell.new for path in Shell.default_system_path next unless sh.directory? path sh.cd path sh.foreach do |cn| if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn) command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1') begin def_system_command(command, sh. (cn)) rescue Shell.notify "warn: Can't define #{command} path: #{cn}" end defined_meth[command] = command end end end end
.method_added(id)
[ GitHub ]# File 'lib/shell/command-processor.rb', line 47
def self.method_added(id) add_delegate_command_to_shell(id) end
.run_config
include run file.
# File 'lib/shell/command-processor.rb', line 55
def self.run_config rc = "~/.rb_shell" begin load File. (rc) if ENV.key?("HOME") rescue LoadError, Errno::ENOENT rescue print "load error: #{rc}\n" print $!.class, ": ", $!, "\n" for err in $@[0, $@.size - 2] print "\t", err, "\n" end end end
.unalias_command(alias) ⇒ self
Unaliases the given alias
command.
# File 'lib/shell/command-processor.rb', line 472
def self.unalias_command(ali) ali = ali.id2name if ali.kind_of?(Symbol) @alias_map.delete ali.intern undef_system_command(ali) end
.undef_system_command(command) ⇒ self
Undefines a command
Instance Method Details
#[](command, file1, file2 = nil)
Alias for #test.
# File 'lib/shell/command-processor.rb', line 195
alias [] test
#append(to, filter)
[ GitHub ]#cat(*filename) ⇒ Cat
Returns a Cat
object, for the given filenames
#check_point Also known as: #finish_all_jobs
# File 'lib/shell/command-processor.rb', line 263
def check_point # :nodoc: @shell.process_controller.wait_all_jobs_execution end
#concat(*jobs) ⇒ Concat
Returns a Concat
object, for the given Shell#jobs
#echo(*strings) ⇒ Echo
Returns a Echo
object, for the given strings
#expand_path(path)
#expand_path
(path)
path: String
return: String
returns the absolute path for <path>
# File 'lib/shell/command-processor.rb', line 80
def (path) @shell. (path) end
#find_system_command(command)
private functions
# File 'lib/shell/command-processor.rb', line 359
def find_system_command(command) return command if /^\// =~ command case path = @system_commands[command] when String if exists?(path) return path else Shell.Fail Error::CommandNotFound, command end when false Shell.Fail Error::CommandNotFound, command end for p in @shell.system_path path = join(p, command) begin st = File.stat(path) rescue SystemCallError next else next unless st.executable? and !st.directory? @system_commands[command] = path return path end end @system_commands[command] = false Shell.Fail Error::CommandNotFound, command end
#finish_all_jobs
Alias for #check_point.
# File 'lib/shell/command-processor.rb', line 266
alias finish_all_jobs check_point # :nodoc:
#foreach(path, record_separator) ⇒ Enumerator
#foreach(path, record_separator)
Enumerator
#foreach(path, record_separator)
See IO.foreach
when path
is a file.
See Dir.foreach
when path
is a directory.
# File 'lib/shell/command-processor.rb', line 92
def foreach(path = nil, *rs) path = "." unless path path = (path) if File.directory?(path) Dir.foreach(path){|fn| yield fn} else IO.foreach(path, *rs){|l| yield l} end end
#glob(pattern) ⇒ Glob
def sort(*filenames)
Sort.new(self, *filenames)
end
Returns a Glob
filter object, with the given pattern
object
#mkdir(path)
Same as Dir.mkdir
, except multiple directories are allowed.
# File 'lib/shell/command-processor.rb', line 201
def mkdir(*path) @shell.check_point notify("mkdir #{path.join(' ')}") perm = nil if path.last.kind_of?(Integer) perm = path.pop end for dir in path d = (dir) if perm Dir.mkdir(d, perm) else Dir.mkdir(d) end File.chmod(d, 0666 & ~@shell.umask) if @shell.umask end Void.new(@shell) end
#notify(*opts)
%pwd, %cwd -> @pwd
#open(path, mode, permissions) ⇒ Enumerator
#open(path, mode, permissions)
Enumerator
#open(path, mode, permissions)
See IO.open
when path
is a file.
See Dir.open
when path
is a directory.
# File 'lib/shell/command-processor.rb', line 111
def open(path, mode = nil, perm = 0666, &b) path = (path) if File.directory?(path) Dir.open(path, &b) else if @shell.umask f = File.open(path, mode, perm) File.chmod(perm & ~@shell.umask, path) if block_given? f.each(&b) end f else File.open(path, mode, perm, &b) end end end
#out(device)
Calls device.print
on the result passing the block to #transact
# File 'lib/shell/command-processor.rb', line 288
def out(dev = STDOUT, &block) dev.print transact(&block) end
#rehash
Clears the command hash table.
# File 'lib/shell/command-processor.rb', line 259
def rehash @system_commands = {} end
#rmdir(path)
Same as Dir.rmdir
, except multiple directories are allowed.
#system(command, *options) ⇒ SystemCommand
Executes the given command
with the options
parameter.
Example:
print sh.system("ls", "-l")
sh.system("ls", "-l") | sh.head > STDOUT
# File 'lib/shell/command-processor.rb', line 244
def system(command, *opts) if opts.empty? if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/ return SystemCommand.new(@shell, find_system_command("sh"), "-c", command) else command, *opts = command.split(/\s+/) end end SystemCommand.new(@shell, find_system_command(command), *opts) end
#tee(file) ⇒ Tee
Returns a Tee
filter object, with the given file
command
#test(command, file1, file2) ⇒ Boolean
#[](command, file1, file2) ⇒ Boolean
Also known as: #[]
Boolean
#[](command, file1, file2) ⇒ Boolean
Tests if the given command
exists in file1
, or optionally file2
.
Example:
sh[?e, "foo"]
sh[:e, "foo"]
sh["e", "foo"]
sh[:exists?, "foo"]
sh["exists?", "foo"]
# File 'lib/shell/command-processor.rb', line 163
def test(command, file1, file2=nil) file1 = (file1) file2 = (file2) if file2 command = command.id2name if command.kind_of?(Symbol) case command when Integer if file2 top_level_test(command, file1, file2) else top_level_test(command, file1) end when String if command.size == 1 if file2 top_level_test(command, file1, file2) else top_level_test(command, file1) end else unless FileTest.methods(false).include?(command.to_sym) raise "unsupported command: #{ command }" end if file2 FileTest.send(command, file1, file2) else FileTest.send(command, file1) end end end end
#top_level_test
See #test
# File 'lib/shell/command-processor.rb', line 149
alias top_level_test test
#transact
# File 'lib/shell/command-processor.rb', line 275
def transact(&block) begin @shell.instance_eval(&block) ensure check_point end end
#unlink(path)
See IO.unlink
when path
is a file.
See Dir.unlink
when path
is a directory.
# File 'lib/shell/command-processor.rb', line 136
def unlink(path) @shell.check_point path = (path) if File.directory?(path) Dir.unlink(path) else IO.unlink(path) end Void.new(@shell) end