class Ratch::Shell
Shell
Prompt class¶ ↑
Ratch
Shell
object provides a limited file system shell in code. It is similar to having a shell prompt available to you in Ruby.
NOTE: We have used the term trace in place of verbose for command line options. Even though Ruby itself uses the term verbose with respect to FileUtils, the term is commonly used for command specific needs, so we want to leave it open for such cases.
Public Class Methods
New Shell
object.
Shell.new(:noop=>true) Shell.new('..', :quiet=>true)
# File lib/ratch/shell.rb, line 28 def initialize(*args) path, opts = parse_arguments(*args) opts.rekey!(&:to_sym) set_options(opts) if path.empty? path = Dir.pwd else path = File.join(*path) end raise FileNotFound, "#{path}" unless ::File.exist?(path) raise FileNotFound, "#{path}" unless ::File.directory?(path) @_work = Pathname.new(path).expand_path end
Public Instance Methods
Join paths. TODO: Should this return a new directory object? Or should it change directories?
# File lib/ratch/shell.rb, line 290 def /(path) #@_work += dir # did not work, why? @_work = dir(localize(path)) self end
Two Shell’s are equal if they have the same working path.
# File lib/ratch/shell.rb, line 98 def ==(other) return false unless other.is_a?(self.class) return false unless work == other.work true end
# File lib/ratch/shell.rb, line 414 def absolute?(path) ; FileTest.absolute?(path) ; end
An intergrated glob like method that takes a set of include globs, exclude globs and ignore globs to produce a collection of paths.
Ignore_globs differ from exclude_globs in that they match by the basename of the path rather than the whole pathname.
# File lib/ratch/shell.rb, line 615 def amass(include_globs, exclude_globs=[], ignore_globs=[]) locally do fileutils.amass(include_globs, exclude_globs, ignore_globs) end end
Append to file.
# File lib/ratch/shell.rb, line 379 def append(path, text) $stderr.puts "append #{path}" if trace? File.open(localize(path), 'a'){ |f| f << text } unless noop? end
# File lib/ratch/shell.rb, line 735 def apply_naming_policy(name, ext) naming_policy.each do |policy| case policy.to_s when /^low/, /^down/ name = name.downcase when /^up/ name = name.upcase when /^cap/ name = name.capitalize when /^ext/ name = name + ".#{ext}" end end name end
Returns a Batch
of file patterns
.
# File lib/ratch/shell.rb, line 172 def batch(*patterns) Batch.new patterns.map{|pattern| localize(pattern)} end
Returns a Batch
of file patterns
, without any exclusions.
# File lib/ratch/shell.rb, line 177 def batch_all(*patterns) Batch.all patterns.map{|pattern| localize(pattern)} end
# File lib/ratch/shell.rb, line 402 def blockdev?(path) ; FileTest.blockdev?(localize(path)) ; end
Change working directory.
TODO: Make thread safe.
# File lib/ratch/shell.rb, line 339 def cd(path, &block) if block work_old = @_work begin @_work = dir(localize(path)) locally(&block) #mutex.synchronize do # Dir.chdir(@_work){ block.call } #end ensure @_work = work_old end else @_work = dir(localize(path)) end end
# File lib/ratch/shell.rb, line 395 def chardev?(path) ; FileTest.chardev?(localize(path)) ; end
# File lib/ratch/shell.rb, line 570 def chmod(mode, list, options={}) list = localize(list) fileutils.chmod(mode, list, options) end
# File lib/ratch/shell.rb, line 575 def chmod_r(mode, list, options={}) list = localize(list) fileutils.chmod_r(mode, list, options) end
alias_method :chmod_R, :chmod_r
# File lib/ratch/shell.rb, line 581 def chown(user, group, list, options={}) list = localize(list) fileutils.chown(user, group, list, options) end
# File lib/ratch/shell.rb, line 586 def chown_r(user, group, list, options={}) list = localize(list) fileutils.chown_r(user, group, list, options) end
Same as identical?
# File lib/ratch/shell.rb, line 475 def cmp(a,b) fileutils.compare_file(a,b) end
cp(list, dir, options={})
# File lib/ratch/shell.rb, line 521 def cp(src, dest, options={}) src = localize(src) dest = localize(dest) fileutils.cp(src, dest, options) end
cp_r
(list, dir, options={})
# File lib/ratch/shell.rb, line 529 def cp_r(src, dest, options={}) src = localize(src) dest = localize(dest) fileutils.cp_r(src, dest, options) end
# File lib/ratch/shell.rb, line 200 def dir(path) #Directory.new(name) path = localize(path) raise FileNotFound unless File.directory?(path) Pathname.new(path) end
Returns list of directories.
# File lib/ratch/shell.rb, line 233 def directories pathnames.select{ |f| f.directory? } end
# File lib/ratch/shell.rb, line 392 def directory?(path) ; FileTest.directory?(localize(path)) ; end
Lists directory entries.
# File lib/ratch/shell.rb, line 215 def directory_entries entries.select{ |d| d.directory? } end
def force? ; @_force ; end
# File lib/ratch/shell.rb, line 92 def dryrun? ; noop? && trace? ; end
Lists all entries.
# File lib/ratch/shell.rb, line 208 def entries work.entries end
# File lib/ratch/shell.rb, line 409 def executable?(path) ; FileTest.executable?(localize(path)) ; end
# File lib/ratch/shell.rb, line 417 def executable_real?(path) ; FileTest.executable_real?(localize(path)) ; end
# File lib/ratch/shell.rb, line 396 def exist?(path) ; FileTest.exist?(localize(path)) ; end
# File lib/ratch/shell.rb, line 397 def exists?(path) ; FileTest.exists?(localize(path)) ; end
# File lib/ratch/shell.rb, line 188 def file(path) #FileObject[name] path = localize(path) raise FileNotFound unless File.file?(path) Pathname.new(path) end
# File lib/ratch/shell.rb, line 400 def file?(path) ; FileTest.file?(localize(path)) ; end
Lists file entries.
# File lib/ratch/shell.rb, line 223 def file_entries entries.select{ |f| f.file? } end
Returns list of files.
# File lib/ratch/shell.rb, line 240 def files pathnames.select{ |f| f.file? } end
Glob pattern. Returns matches as strings.
# File lib/ratch/shell.rb, line 245 def glob(*patterns, &block) opts = (::Integer===patterns.last ? patterns.pop : 0) matches = [] locally do matches = patterns.map{ |pattern| ::Dir.glob(pattern, opts) }.flatten end if block_given? matches.each(&block) else matches end end
# File lib/ratch/shell.rb, line 403 def grpowned?(path) ; FileTest.grpowned?(localize(path)) ; end
Current home path.
# File lib/ratch/shell.rb, line 143 def home(*args) dir(File.expand_path('~'), *args) end
# File lib/ratch/shell.rb, line 420 def identical?(path, other) FileTest.identical?(localize(path), localize(other)) end
# File lib/ratch/shell.rb, line 564 def install(src, dest, mode, options={}) src = localize(src) dest = localize(dest) fileutils.install(src, dest, mode, options) end
ln(list, destdir, options={})
# File lib/ratch/shell.rb, line 499 def ln(old, new, options={}) old = localize(old) new = localize(new) fileutils.ln(old, new, options) end
ln_s
(list, destdir, options={})
# File lib/ratch/shell.rb, line 507 def ln_s(old, new, options={}) old = localize(old) new = localize(new) fileutils.ln_s(old, new, options) end
# File lib/ratch/shell.rb, line 514 def ln_sf(old, new, options={}) old = localize(old) new = localize(new) fileutils.ln_sf(old, new, options) end
Returns a path local to the current working path.
# File lib/ratch/shell.rb, line 687 def localize(local_path) # some path arguments are optional return local_path unless local_path # case local_path when Array local_path.collect do |lp| if absolute?(lp) lp else File.expand_path(File.join(work.to_s, lp)) end end else # do not localize an absolute path return local_path if absolute?(local_path) File.expand_path(File.join(work.to_s, local_path)) #(work + local_path).expand_path.to_s end end
Change directory to the shell’s work directory, process the block
and then return to user directory.
# File lib/ratch/shell.rb, line 710 def locally(&block) if work.to_s == Dir.pwd block.call else mutex.synchronize do #work.chdir(&block) Dir.chdir(work, &block) end end end
# File lib/ratch/shell.rb, line 480 def mkdir(dir, options={}) dir = localize(dir) fileutils.mkdir(dir, options) end
# File lib/ratch/shell.rb, line 485 def mkdir_p(dir, options={}) dir = localize(dir) unless File.directory?(dir) fileutils.mkdir_p(dir, options) end end
# File lib/ratch/shell.rb, line 268 def multiglob_r(*args, &blk) Dir.multiglob_r(*args, &blk) end
mv(list, dir, options={})
# File lib/ratch/shell.rb, line 536 def mv(src, dest, options={}) src = localize(src) dest = localize(dest) fileutils.mv(src, dest, options) end
# File lib/ratch/shell.rb, line 725 def naming_policy(*policies) if policies.empty? @naming_policy ||= ['down', 'ext'] else @naming_policy = policies end end
# File lib/ratch/shell.rb, line 89 def noop? ; @_noop ; end
# File lib/ratch/shell.rb, line 622 def outofdate?(path, *sources) #fileutils.outofdate?(localize(path), localize(sources)) # DIDN'T WORK, why? locally do fileutils.outofdate?(path, sources.flatten) end end
# File lib/ratch/shell.rb, line 407 def owned?(path) ; FileTest.owned?(localize(path)) ; end
Return a new prompt with the same location. NOTE: Use #dup or #clone ?
def new ; Shell.new(work)
; end
# File lib/ratch/shell.rb, line 160 def parent dir('..') end
# File lib/ratch/shell.rb, line 182 def path(path) Pathname.new(localize(path)) end
Likes entries but omits ‘.’ and ‘..’ paths.
# File lib/ratch/shell.rb, line 228 def pathnames work.entries - %w{. ..}.map{|f|Pathname.new(f)} end
# File lib/ratch/shell.rb, line 399 def pipe?(path) ; FileTest.pipe?(localize(path)) ; end
Present working directory.
# File lib/ratch/shell.rb, line 470 def pwd work.to_s end
Opertaton mode. This can be :noop, :verbose or :dryrun. The later is the same as the first two combined.
def mode(opts=nil)
return @mode unless opts opts.each do |key, val| next unless val case key when :noop @mode = (@mode == :verbose ? :dryrun : :noop) when :verbose @mode = (@mode == :noop ? :dryrun : :verbose) when :dryrun @mode = :dryrun end end
end
# File lib/ratch/shell.rb, line 87 def quiet? ; @_quiet ; end
Read file.
# File lib/ratch/shell.rb, line 368 def read(path) File.read(localize(path)) end
# File lib/ratch/shell.rb, line 394 def readable?(path) ; FileTest.readable?(localize(path)) ; end
# File lib/ratch/shell.rb, line 418 def readable_real?(path) ; FileTest.readable_real?(localize(path)) ; end
# File lib/ratch/shell.rb, line 413 def relative?(path) ; FileTest.relative?(path) ; end
# File lib/ratch/shell.rb, line 543 def rm(list, options={}) list = localize(list) fileutils.rm(list, options) end
# File lib/ratch/shell.rb, line 554 def rm_f(list, options={}) list = localize(list) fileutils.rm_f(list, options) end
# File lib/ratch/shell.rb, line 549 def rm_r(list, options={}) list = localize(list) fileutils.rm_r(list, options) end
# File lib/ratch/shell.rb, line 559 def rm_rf(list, options={}) list = localize(list) fileutils.rm_rf(list, options) end
# File lib/ratch/shell.rb, line 493 def rmdir(dir, options={}) dir = localize(dir) fileutils.rmdir(dir, options) end
Root location.
# File lib/ratch/shell.rb, line 138 def root(*args) dir('/', *args) end
# File lib/ratch/shell.rb, line 411 def safe?(path) ; FileTest.safe?(localize(path)) ; end
# File lib/ratch/shell.rb, line 404 def setgid?(path) ; FileTest.setgid?(localize(path)) ; end
# File lib/ratch/shell.rb, line 405 def setuid?(path) ; FileTest.setuid?(localize(path)) ; end
Shell
runner.
# File lib/ratch/shell.rb, line 307 def sh(cmd) #puts "--> system call: #{cmd}" if trace? puts cmd if trace? return true if noop? #locally do if quiet? silently{ system(cmd) } else system(cmd) end #end end
# File lib/ratch/shell.rb, line 390 def size(path) ; FileTest.size(localize(path)) ; end
# File lib/ratch/shell.rb, line 391 def size?(path) ; FileTest.size?(localize(path)) ; end
# File lib/ratch/shell.rb, line 406 def socket?(path) ; FileTest.socket?(localize(path)) ; end
TODO: should this have SOURCE diectory?
stage(directory, source_dir, files)
# File lib/ratch/shell.rb, line 601 def stage(stage_dir, files) #dir = localize(directory) #files = localize(files) locally do fileutils.stage(stage_dir, work, files) end end
# File lib/ratch/shell.rb, line 401 def sticky?(path) ; FileTest.sticky?(localize(path)) ; end
# File lib/ratch/shell.rb, line 393 def symlink?(path) ; FileTest.symlink?(localize(path)) ; end
TODO: Tie this into the System
class.
# File lib/ratch/shell.rb, line 300 def system(cmd) locally do super(cmd) end end
String
representation is work directory path.
# File lib/ratch/shell.rb, line 95 def to_s ; work.to_s ; end
alias_method :chown_R, :chown_r
# File lib/ratch/shell.rb, line 592 def touch(list, options={}) list = localize(list) fileutils.touch(list, options) end
# File lib/ratch/shell.rb, line 88 def trace? ; @_trace ; end
# File lib/ratch/shell.rb, line 647 def uptodate?(path, *sources) locally do fileutils.uptodate?(path, sources.flatten) end end
Current working path.
# File lib/ratch/shell.rb, line 148 def work(*args) return @_work if args.empty? return dir(@_work, *args) end
# File lib/ratch/shell.rb, line 408 def writable?(path) ; FileTest.writable?(localize(path)) ; end
# File lib/ratch/shell.rb, line 416 def writable_real?(path) ; FileTest.writable_real?(localize(path)) ; end
Write file.
# File lib/ratch/shell.rb, line 373 def write(path, text) $stderr.puts "write #{path}" if trace? File.open(localize(path), 'w'){ |f| f << text } unless noop? end
# File lib/ratch/shell.rb, line 398 def zero?(path) ; FileTest.zero?(localize(path)) ; end
Private Instance Methods
Returns FileUtils module based on mode.
# File lib/ratch/shell.rb, line 754 def fileutils if dryrun? ::FileUtils::DryRun elsif noop? ::FileUtils::Noop elsif trace? ::FileUtils::Verbose else ::FileUtils end end
# File lib/ratch/shell.rb, line 64 def mutex @mutex ||= Mutex.new end
# File lib/ratch/shell.rb, line 50 def parse_arguments(*args) opts = (Hash===args.last ? args.pop : {}) return args, opts end
# File lib/ratch/shell.rb, line 56 def set_options(opts) @_quiet = opts[:quiet] @_noop = opts[:noop] || opts[:dryrun] @_trace = opts[:trace] || opts[:dryrun] #@_force = opts[:force] end
This may be used by script commands to allow for per command noop and trace options. Global options have precedence.
# File lib/ratch/shell.rb, line 768 def util_options(options) noop = noop? || options[:noop] || options[:dryrun] trace = trace? || options[:trace] || options[:dryrun] return noop, trace end