Class | Shell::CommandProcessor |
In: |
lib/shell/command-processor.rb
|
Parent: | Object |
NoDelegateMethods | = | ["initialize", "expand_path"] | initialize of Shell and related classes. |
# File lib/shell/command-processor.rb, line 500 500: def self.add_delegate_command_to_shell(id) 501: id = id.intern if id.kind_of?(String) 502: name = id.id2name 503: if Shell.method_defined?(id) 504: Shell.notify "warn: override definnition of Shell##{name}." 505: Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n" 506: Shell.module_eval "alias #{name}_org #{name}" 507: end 508: Shell.notify "method added: Shell##{name}.", Shell.debug? 509: Shell.module_eval(%Q[def #{name}(*args, &block) 510: begin 511: @command_processor.__send__(:#{name}, *args, &block) 512: rescue Exception 513: $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` 514: $@.delete_if{|s| /^\\(eval\\):/ =~ s} 515: raise 516: end 517: end], __FILE__, __LINE__) 518: 519: if Shell::Filter.method_defined?(id) 520: Shell.notify "warn: override definnition of Shell::Filter##{name}." 521: Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org." 522: Filter.module_eval "alias #{name}_org #{name}" 523: end 524: Shell.notify "method added: Shell::Filter##{name}.", Shell.debug? 525: Filter.module_eval(%Q[def #{name}(*args, &block) 526: begin 527: self | @shell.__send__(:#{name}, *args, &block) 528: rescue Exception 529: $@.delete_if{|s| /:in `__getobj__'$/ =~ s} #` 530: $@.delete_if{|s| /^\\(eval\\):/ =~ s} 531: raise 532: end 533: end], __FILE__, __LINE__) 534: end
# File lib/shell/command-processor.rb, line 391 391: def self.alias_command(ali, command, *opts, &block) 392: ali = ali.id2name if ali.kind_of?(Symbol) 393: command = command.id2name if command.kind_of?(Symbol) 394: begin 395: if iterator? 396: @alias_map[ali.intern] = proc 397: 398: eval((d = %Q[def #{ali}(*opts) 399: @shell.__send__(:#{command}, 400: *(CommandProcessor.alias_map[:#{ali}].call *opts)) 401: end]), nil, __FILE__, __LINE__ - 1) 402: 403: else 404: args = opts.collect{|opt| '"' + opt + '"'}.join(",") 405: eval((d = %Q[def #{ali}(*opts) 406: @shell.__send__(:#{command}, #{args}, *opts) 407: end]), nil, __FILE__, __LINE__ - 1) 408: end 409: rescue SyntaxError 410: Shell.notify "warn: Can't alias #{ali} command: #{command}." 411: Shell.notify("Definition of #{ali}: ", d) 412: raise 413: end 414: Shell.notify "Define #{ali} command: #{command}.", Shell.debug? 415: Shell.notify("Definition of #{ali}: ", d, 416: Shell.debug.kind_of?(Integer) && Shell.debug > 1) 417: self 418: end
CommandProcessor.def_builtin_commands(delegation_class, command_specs)
delegation_class: Class or Module command_specs: [[command_name, [argument,...]],...] command_name: String arguments: String FILENAME?? -> expand_path(filename??) *FILENAME?? -> filename??.collect{|f|expand_path(f)}.join(", ") define command_name(argument,...) as delegation_class.command_name(argument,...)
# File lib/shell/command-processor.rb, line 437 437: def self.def_builtin_commands(delegation_class, command_specs) 438: for meth, args in command_specs 439: arg_str = args.collect{|arg| arg.downcase}.join(", ") 440: call_arg_str = args.collect{ 441: |arg| 442: case arg 443: when /^(FILENAME.*)$/ 444: format("expand_path(%s)", $1.downcase) 445: when /^(\*FILENAME.*)$/ 446: # \*FILENAME* -> filenames.collect{|fn| expand_path(fn)}.join(", ") 447: $1.downcase + '.collect{|fn| expand_path(fn)}' 448: else 449: arg 450: end 451: }.join(", ") 452: d = %Q[def #{meth}(#{arg_str}) 453: #{delegation_class}.#{meth}(#{call_arg_str}) 454: end] 455: Shell.notify "Define #{meth}(#{arg_str})", Shell.debug? 456: Shell.notify("Definition of #{meth}: ", d, 457: Shell.debug.kind_of?(Integer) && Shell.debug > 1) 458: eval d 459: end 460: end
CommandProcessor.def_system_command(command, path)
command: String path: String define 'command()' method as method.
# File lib/shell/command-processor.rb, line 361 361: def self.def_system_command(command, path = command) 362: begin 363: eval((d = %Q[def #{command}(*opts) 364: SystemCommand.new(@shell, '#{path}', *opts) 365: end]), nil, __FILE__, __LINE__ - 1) 366: rescue SyntaxError 367: Shell.notify "warn: Can't define #{command} path: #{path}." 368: end 369: Shell.notify "Define #{command} path: #{path}.", Shell.debug? 370: Shell.notify("Definition of #{command}: ", d, 371: Shell.debug.kind_of?(Integer) && Shell.debug > 1) 372: end
# File lib/shell/command-processor.rb, line 30 30: def self.initialize 31: 32: install_builtin_commands 33: 34: # define CommandProccessor#methods to Shell#methods and Filter#methods 35: for m in CommandProcessor.instance_methods(false) - NoDelegateMethods 36: add_delegate_command_to_shell(m) 37: end 38: 39: def self.method_added(id) 40: add_delegate_command_to_shell(id) 41: end 42: end
define default builtin commands
# File lib/shell/command-processor.rb, line 539 539: def self.install_builtin_commands 540: # method related File. 541: # (exclude open/foreach/unlink) 542: normal_delegation_file_methods = [ 543: ["atime", ["FILENAME"]], 544: ["basename", ["fn", "*opts"]], 545: ["chmod", ["mode", "*FILENAMES"]], 546: ["chown", ["owner", "group", "*FILENAME"]], 547: ["ctime", ["FILENAMES"]], 548: ["delete", ["*FILENAMES"]], 549: ["dirname", ["FILENAME"]], 550: ["ftype", ["FILENAME"]], 551: ["join", ["*items"]], 552: ["link", ["FILENAME_O", "FILENAME_N"]], 553: ["lstat", ["FILENAME"]], 554: ["mtime", ["FILENAME"]], 555: ["readlink", ["FILENAME"]], 556: ["rename", ["FILENAME_FROM", "FILENAME_TO"]], 557: # ["size", ["FILENAME"]], 558: ["split", ["pathname"]], 559: ["stat", ["FILENAME"]], 560: ["symlink", ["FILENAME_O", "FILENAME_N"]], 561: ["truncate", ["FILENAME", "length"]], 562: ["utime", ["atime", "mtime", "*FILENAMES"]]] 563: 564: def_builtin_commands(File, normal_delegation_file_methods) 565: alias_method :rm, :delete 566: 567: # method related FileTest 568: def_builtin_commands(FileTest, 569: FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]}) 570: 571: # method related ftools 572: normal_delegation_ftools_methods = [ 573: ["syscopy", ["FILENAME_FROM", "FILENAME_TO"]], 574: ["copy", ["FILENAME_FROM", "FILENAME_TO"]], 575: ["move", ["FILENAME_FROM", "FILENAME_TO"]], 576: ["compare", ["FILENAME_FROM", "FILENAME_TO"]], 577: ["safe_unlink", ["*FILENAMES"]], 578: ["makedirs", ["*FILENAMES"]], 579: # ["chmod", ["mode", "*FILENAMES"]], 580: ["install", ["FILENAME_FROM", "FILENAME_TO", "mode"]], 581: ] 582: def_builtin_commands(File, 583: normal_delegation_ftools_methods) 584: alias_method :cmp, :compare 585: alias_method :mv, :move 586: alias_method :cp, :copy 587: alias_method :rm_f, :safe_unlink 588: alias_method :mkpath, :makedirs 589: end
CommandProcessor.install_system_commands(pre)
pre: String - command name prefix
defines every command which belongs in default_system_path via CommandProcessor.command(). It doesn‘t define already defined methods twice. By default, "pre_" is prefixes to each method name. Characters that may not be used in a method name are all converted to ‘_’. Definition errors are just ignored.
# File lib/shell/command-processor.rb, line 471 471: def self.install_system_commands(pre = "sys_") 472: defined_meth = {} 473: for m in Shell.methods 474: defined_meth[m] = true 475: end 476: sh = Shell.new 477: for path in Shell.default_system_path 478: next unless sh.directory? path 479: sh.cd path 480: sh.foreach do 481: |cn| 482: if !defined_meth[pre + cn] && sh.file?(cn) && sh.executable?(cn) 483: command = (pre + cn).gsub(/\W/, "_").sub(/^([0-9])/, '_\1') 484: begin 485: def_system_command(command, sh.expand_path(cn)) 486: rescue 487: Shell.notify "warn: Can't define #{command} path: #{cn}" 488: end 489: defined_meth[command] = command 490: end 491: end 492: end 493: end
# File lib/shell/command-processor.rb, line 39 39: def self.method_added(id) 40: add_delegate_command_to_shell(id) 41: end
# File lib/shell/command-processor.rb, line 60 60: def initialize(shell) 61: @shell = shell 62: @system_commands = {} 63: end
include run file.
# File lib/shell/command-processor.rb, line 47 47: def self.run_config 48: begin 49: load File.expand_path("~/.rb_shell") if ENV.key?("HOME") 50: rescue LoadError, Errno::ENOENT 51: rescue 52: print "load error: #{rc}\n" 53: print $!.class, ": ", $!, "\n" 54: for err in $@[0, $@.size - 2] 55: print "\t", err, "\n" 56: end 57: end 58: end
# File lib/shell/command-processor.rb, line 420 420: def self.unalias_command(ali) 421: ali = ali.id2name if ali.kind_of?(Symbol) 422: @alias_map.delete ali.intern 423: undef_system_command(ali) 424: end
# File lib/shell/command-processor.rb, line 374 374: def self.undef_system_command(command) 375: command = command.id2name if command.kind_of?(Symbol) 376: remove_method(command) 377: Shell.module_eval{remove_method(command)} 378: Filter.module_eval{remove_method(command)} 379: self 380: end
# File lib/shell/command-processor.rb, line 281 281: def append(to, filter) 282: case to 283: when String 284: AppendFile.new(@shell, to, filter) 285: when IO 286: AppendIO.new(@shell, to, filter) 287: else 288: Shell.Fail Error::CantApplyMethod, "append", to.class 289: end 290: end
# File lib/shell/command-processor.rb, line 269 269: def cat(*filenames) 270: Cat.new(@shell, *filenames) 271: end
ProcessCommand#transact
# File lib/shell/command-processor.rb, line 245 245: def check_point 246: @shell.process_controller.wait_all_jobs_execution 247: end
# File lib/shell/command-processor.rb, line 296 296: def concat(*jobs) 297: Concat.new(@shell, *jobs) 298: end
# File lib/shell/command-processor.rb, line 265 265: def echo(*strings) 266: Echo.new(@shell, *strings) 267: end
CommandProcessor#expand_path(path)
path: String return: String returns the absolute path for <path>
# File lib/shell/command-processor.rb, line 71 71: def expand_path(path) 72: @shell.expand_path(path) 73: end
# File lib/shell/command-processor.rb, line 331 331: def find_system_command(command) 332: return command if /^\// =~ command 333: case path = @system_commands[command] 334: when String 335: if exists?(path) 336: return path 337: else 338: Shell.Fail Error::CommandNotFound, command 339: end 340: when false 341: Shell.Fail Error::CommandNotFound, command 342: end 343: 344: for p in @shell.system_path 345: path = join(p, command) 346: if FileTest.exists?(path) 347: @system_commands[command] = path 348: return path 349: end 350: end 351: @system_commands[command] = false 352: Shell.Fail Error::CommandNotFound, command 353: end
File related commands Shell#foreach Shell#open Shell#unlink Shell#test
-
CommandProcessor#foreach(path, rs)
path: String rs: String - record separator iterator Same as: File#foreach (when path is file) Dir#foreach (when path is directory) path is relative to pwd
# File lib/shell/command-processor.rb, line 93 93: def foreach(path = nil, *rs) 94: path = "." unless path 95: path = expand_path(path) 96: 97: if File.directory?(path) 98: Dir.foreach(path){|fn| yield fn} 99: else 100: IO.foreach(path, *rs){|l| yield l} 101: end 102: end
def sort(*filenames)
Sort.new(self, *filenames)
end
# File lib/shell/command-processor.rb, line 277 277: def glob(pattern) 278: Glob.new(@shell, pattern) 279: end
%pwd, %cwd -> @pwd
# File lib/shell/command-processor.rb, line 301 301: def notify(*opts, &block) 302: Thread.exclusive do 303: Shell.notify(*opts) {|mes| 304: yield mes if iterator? 305: 306: mes.gsub!("%pwd", "#{@cwd}") 307: mes.gsub!("%cwd", "#{@cwd}") 308: } 309: end 310: end
CommandProcessor#open(path, mode)
path: String mode: String return: File or Dir Same as: File#open (when path is file) Dir#open (when path is directory) mode has an effect only when path is a file
# File lib/shell/command-processor.rb, line 114 114: def open(path, mode) 115: path = expand_path(path) 116: if File.directory?(path) 117: Dir.open(path) 118: else 119: effect_umask do 120: File.open(path, mode) 121: end 122: end 123: end
internal commands
# File lib/shell/command-processor.rb, line 261 261: def out(dev = STDOUT, &block) 262: dev.print transact(&block) 263: end
ProcessCommand#rehash
clear command hash table.
# File lib/shell/command-processor.rb, line 238 238: def rehash 239: @system_commands = {} 240: end
path: String same as Dir.rmdir()
# File lib/shell/command-processor.rb, line 207 207: def rmdir(*path) 208: for dir in path 209: Dir.rmdir(expand_path(dir)) 210: end 211: end
CommandProcessor#system(command, *opts)
command: String opts: String return: SystemCommand Same as system() function example: print sh.system("ls", "-l") sh.system("ls", "-l") | sh.head > STDOUT
# File lib/shell/command-processor.rb, line 223 223: def system(command, *opts) 224: if opts.empty? 225: if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/ 226: return SystemCommand.new(@shell, find_system_command("sh"), "-c", command) 227: else 228: command, *opts = command.split(/\s+/) 229: end 230: end 231: SystemCommand.new(@shell, find_system_command(command), *opts) 232: end
# File lib/shell/command-processor.rb, line 292 292: def tee(file) 293: Tee.new(@shell, file) 294: end
CommandProcessor#test(command, file1, file2) CommandProcessor#[command, file1, file2]
command: char or String or Symbol file1: String file2: String(optional) return: Boolean same as: test() (when command is char or length 1 string or symbol) FileTest.command (others) example: sh[?e, "foo"] sh[:e, "foo"] sh["e", "foo"] sh[:exists?, "foo"] sh["exists?", "foo"]
# File lib/shell/command-processor.rb, line 158 158: def test(command, file1, file2=nil) 159: file1 = expand_path(file1) 160: file2 = expand_path(file2) if file2 161: command = command.id2name if command.kind_of?(Symbol) 162: 163: case command 164: when Integer 165: top_level_test(command, file1, file2) 166: when String 167: if command.size == 1 168: if file2 169: top_level_test(command, file1, file2) 170: else 171: top_level_test(command, file1) 172: end 173: else 174: if file2 175: FileTest.send(command, file1, file2) 176: else 177: FileTest.send(command, file1) 178: end 179: end 180: end 181: end
# File lib/shell/command-processor.rb, line 250 250: def transact(&block) 251: begin 252: @shell.instance_eval(&block) 253: ensure 254: check_point 255: end 256: end
same as: Dir#unlink (when path is directory) File#unlink (when path is file)
# File lib/shell/command-processor.rb, line 132 132: def unlink(path) 133: path = expand_path(path) 134: if File.directory?(path) 135: Dir.unlink(path) 136: else 137: IO.unlink(path) 138: end 139: end