Class: Ratch::Shell

Inherits:
Object show all
Defined in:
lib/ratch/shell.rb

Overview

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.

Direct Known Subclasses

Script

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Shell

New Shell object.

Shell.new(:noop=>true)
Shell.new('..', :quiet=>true)

Raises:



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 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

Class Method Details

.[](path) ⇒ Object



776
777
778
# File 'lib/ratch/shell.rb', line 776

def self.[](path)
  new(path)
end

Instance Method Details

#/(path) ⇒ Object Also known as: +

Join paths. TODO: Should this return a new directory object? Or should it change directories?



290
291
292
293
294
# File 'lib/ratch/shell.rb', line 290

def /(path)
  #@_work += dir   # did not work, why?
  @_work = dir(localize(path))
  self
end

#==(other) ⇒ Object

Two Shell’s are equal if they have the same working path.



98
99
100
101
102
# 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

#absolute?(path) ⇒ Boolean

Returns:

  • (Boolean)


414
# File 'lib/ratch/shell.rb', line 414

def absolute?(path)   ; FileTest.absolute?(path)       ; end

#amass(include_globs, exclude_globs = [], ignore_globs = []) ⇒ Object

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.



615
616
617
618
619
# 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(path, text) ⇒ Object

Append to file.



379
380
381
382
# 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

#apply_naming_policy(name, ext) ⇒ Object



735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
# 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

#batch(*patterns) ⇒ Object

Returns a Batch of file patterns.



172
173
174
# File 'lib/ratch/shell.rb', line 172

def batch(*patterns)
  Batch.new patterns.map{|pattern| localize(pattern)}
end

#batch_all(*patterns) ⇒ Object

Returns a Batch of file patterns, without any exclusions.



177
178
179
# File 'lib/ratch/shell.rb', line 177

def batch_all(*patterns)
  Batch.all patterns.map{|pattern| localize(pattern)}
end

#blockdev?(path) ⇒ Boolean

Returns:

  • (Boolean)


402
# File 'lib/ratch/shell.rb', line 402

def blockdev?(path)   ; FileTest.blockdev?(localize(path))  ; end

#cd(path, &block) ⇒ Object Also known as: chdir

Change working directory.

TODO: Make thread safe.



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# 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

#chardev?(path) ⇒ Boolean

Returns:

  • (Boolean)


395
# File 'lib/ratch/shell.rb', line 395

def chardev?(path)    ; FileTest.chardev?(localize(path))   ; end

#chmod(mode, list, options = {}) ⇒ Object



570
571
572
573
# File 'lib/ratch/shell.rb', line 570

def chmod(mode, list, options={})
  list = localize(list)
  fileutils.chmod(mode, list, options)
end

#chmod_r(mode, list, options = {}) ⇒ Object



575
576
577
578
# File 'lib/ratch/shell.rb', line 575

def chmod_r(mode, list, options={})
  list = localize(list)
  fileutils.chmod_r(mode, list, options)
end

#chown(user, group, list, options = {}) ⇒ Object

alias_method :chmod_R, :chmod_r



581
582
583
584
# File 'lib/ratch/shell.rb', line 581

def chown(user, group, list, options={})
  list = localize(list)
  fileutils.chown(user, group, list, options)
end

#chown_r(user, group, list, options = {}) ⇒ Object



586
587
588
589
# 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

#cmp(a, b) ⇒ Object

Same as #identical?



475
476
477
# File 'lib/ratch/shell.rb', line 475

def cmp(a,b)
  fileutils.compare_file(a,b)
end

#cp(src, dest, options = {}) ⇒ Object Also known as: copy

cp(list, dir, options={})



521
522
523
524
525
# 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(src, dest, options = {}) ⇒ Object

cp_r(list, dir, options={})



529
530
531
532
533
# 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

#dir(path) ⇒ Object

Raises:



200
201
202
203
204
205
# 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

#directoriesObject Also known as: dirs, folders

Returns list of directories.



233
234
235
# File 'lib/ratch/shell.rb', line 233

def directories
  pathnames.select{ |f| f.directory? }
end

#directory?(path) ⇒ Boolean

Returns:

  • (Boolean)


392
# File 'lib/ratch/shell.rb', line 392

def directory?(path)  ; FileTest.directory?(localize(path)) ; end

#directory_entriesObject Also known as: dir_entries

Lists directory entries.



215
216
217
# File 'lib/ratch/shell.rb', line 215

def directory_entries
  entries.select{ |d| d.directory? }
end

#dryrun?Boolean

def force? ; @_force ; end

Returns:

  • (Boolean)


92
# File 'lib/ratch/shell.rb', line 92

def dryrun?  ; noop? && trace? ; end

#entriesObject

Lists all entries.



208
209
210
# File 'lib/ratch/shell.rb', line 208

def entries
  work.entries
end

#eql?(other) ⇒ Boolean

Same as #== except that #noop? must also be the same.

Returns:

  • (Boolean)


105
106
107
108
109
110
# File 'lib/ratch/shell.rb', line 105

def eql?(other)
  return false unless other.is_a?(self.class)
  return false unless work == other.work
  return false unless noop?  == other.noop?
  true
end

#executable?(path) ⇒ Boolean

Returns:

  • (Boolean)


409
# File 'lib/ratch/shell.rb', line 409

def executable?(path) ; FileTest.executable?(localize(path))  ; end

#executable_real?(path) ⇒ Boolean

Returns:

  • (Boolean)


417
# File 'lib/ratch/shell.rb', line 417

def executable_real?(path) ; FileTest.executable_real?(localize(path)) ; end

#exist?(path) ⇒ Boolean

Returns:

  • (Boolean)


396
# File 'lib/ratch/shell.rb', line 396

def exist?(path)      ; FileTest.exist?(localize(path))     ; end

#exists?(path) ⇒ Boolean

Returns:

  • (Boolean)


397
# File 'lib/ratch/shell.rb', line 397

def exists?(path)     ; FileTest.exists?(localize(path))    ; end

#file(path) ⇒ Object

Raises:



188
189
190
191
192
193
# 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?(path) ⇒ Boolean

Returns:

  • (Boolean)


400
# File 'lib/ratch/shell.rb', line 400

def file?(path)       ; FileTest.file?(localize(path))      ; end

#file_entriesObject

Lists file entries.



223
224
225
# File 'lib/ratch/shell.rb', line 223

def file_entries
  entries.select{ |f| f.file? }
end

#filesObject

Returns list of files.



240
241
242
# File 'lib/ratch/shell.rb', line 240

def files
  pathnames.select{ |f| f.file? }
end

#glob(*patterns, &block) ⇒ Object

Glob pattern. Returns matches as strings.



245
246
247
248
249
250
251
252
253
254
255
256
# 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

#grpowned?(path) ⇒ Boolean

Returns:

  • (Boolean)


403
# File 'lib/ratch/shell.rb', line 403

def grpowned?(path)   ; FileTest.grpowned?(localize(path))  ; end

#home(*args) ⇒ Object

Current home path.



143
144
145
# File 'lib/ratch/shell.rb', line 143

def home(*args)
  dir(File.expand_path('~'), *args)
end

#identical?(path, other) ⇒ Boolean Also known as: compare_file

Returns:

  • (Boolean)


420
421
422
# File 'lib/ratch/shell.rb', line 420

def identical?(path, other)
  FileTest.identical?(localize(path), localize(other))
end

#install(src, dest, mode, options = {}) ⇒ Object



564
565
566
567
568
# 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(old, new, options = {}) ⇒ Object Also known as: link

ln(list, destdir, options={})



499
500
501
502
503
# 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(old, new, options = {}) ⇒ Object Also known as: symlink

ln_s(list, destdir, options={})



507
508
509
510
511
# 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

#ln_sf(old, new, options = {}) ⇒ Object



514
515
516
517
518
# 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

#localize(local_path) ⇒ Object

Returns a path local to the current working path.



687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
# 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

#locally(&block) ⇒ Object

Change directory to the shell’s work directory, process the block and then return to user directory.



710
711
712
713
714
715
716
717
718
719
# 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

#mkdir(dir, options = {}) ⇒ Object



480
481
482
483
# File 'lib/ratch/shell.rb', line 480

def mkdir(dir, options={})
  dir = localize(dir)
  fileutils.mkdir(dir, options)
end

#mkdir_p(dir, options = {}) ⇒ Object Also known as: mkpath



485
486
487
488
489
490
# 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

#multiglob(*args, &blk) ⇒ Object

TODO: Ultimately merge #glob and #multiglob.



264
265
266
# File 'lib/ratch/shell.rb', line 264

def multiglob(*args, &blk)
  Dir.multiglob(*args, &blk)
end

#multiglob_r(*args, &blk) ⇒ Object



268
269
270
# File 'lib/ratch/shell.rb', line 268

def multiglob_r(*args, &blk)
  Dir.multiglob_r(*args, &blk)
end

#mv(src, dest, options = {}) ⇒ Object Also known as: move

mv(list, dir, options={})



536
537
538
539
540
# File 'lib/ratch/shell.rb', line 536

def mv(src, dest, options={})
  src  = localize(src)
  dest = localize(dest)
  fileutils.mv(src, dest, options)
end

#naming_policy(*policies) ⇒ Object



725
726
727
728
729
730
731
# File 'lib/ratch/shell.rb', line 725

def naming_policy(*policies)
  if policies.empty?
    @naming_policy ||= ['down', 'ext']
  else
    @naming_policy = policies
  end
end

#noop?Boolean

Returns:

  • (Boolean)


89
# File 'lib/ratch/shell.rb', line 89

def noop?    ; @_noop  ; end

#outofdate?(path, *sources) ⇒ Boolean

Returns:

  • (Boolean)


622
623
624
625
626
627
# 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

#owned?(path) ⇒ Boolean

Returns:

  • (Boolean)


407
# File 'lib/ratch/shell.rb', line 407

def owned?(path)      ; FileTest.owned?(localize(path))     ; end

#parentObject

Return a new prompt with the same location. NOTE: Use #dup or #clone ? def new ; Shell.new(work) ; end



160
161
162
# File 'lib/ratch/shell.rb', line 160

def parent
  dir('..')
end

#path(path) ⇒ Object Also known as: pathname



182
183
184
# File 'lib/ratch/shell.rb', line 182

def path(path)
  Pathname.new(localize(path))
end

#pathnamesObject

Likes entries but omits ‘.’ and ‘..’ paths.



228
229
230
# File 'lib/ratch/shell.rb', line 228

def pathnames
  work.entries - %w{. ..}.map{|f|Pathname.new(f)}
end

#pipe?(path) ⇒ Boolean

Returns:

  • (Boolean)


399
# File 'lib/ratch/shell.rb', line 399

def pipe?(path)       ; FileTest.pipe?(localize(path))      ; end

#pwdObject

Present working directory.



470
471
472
# File 'lib/ratch/shell.rb', line 470

def pwd
  work.to_s
end

#quiet?Boolean

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

Returns:

  • (Boolean)


87
# File 'lib/ratch/shell.rb', line 87

def quiet?   ; @_quiet ; end

#read(path) ⇒ Object

Read file.



368
369
370
# File 'lib/ratch/shell.rb', line 368

def read(path)
  File.read(localize(path))
end

#readable?(path) ⇒ Boolean

Returns:

  • (Boolean)


394
# File 'lib/ratch/shell.rb', line 394

def readable?(path)   ; FileTest.readable?(localize(path))  ; end

#readable_real?(path) ⇒ Boolean

Returns:

  • (Boolean)


418
# File 'lib/ratch/shell.rb', line 418

def readable_real?(path)   ; FileTest.readable_real?(localize(path))   ; end

#relative?(path) ⇒ Boolean

Returns:

  • (Boolean)


413
# File 'lib/ratch/shell.rb', line 413

def relative?(path)   ; FileTest.relative?(path)       ; end

#rm(list, options = {}) ⇒ Object Also known as: remove



543
544
545
546
# File 'lib/ratch/shell.rb', line 543

def rm(list, options={})
  list = localize(list)
  fileutils.rm(list, options)
end

#rm_f(list, options = {}) ⇒ Object



554
555
556
557
# File 'lib/ratch/shell.rb', line 554

def rm_f(list, options={})
  list = localize(list)
  fileutils.rm_f(list, options)
end

#rm_r(list, options = {}) ⇒ Object



549
550
551
552
# File 'lib/ratch/shell.rb', line 549

def rm_r(list, options={})
  list = localize(list)
  fileutils.rm_r(list, options)
end

#rm_rf(list, options = {}) ⇒ Object



559
560
561
562
# File 'lib/ratch/shell.rb', line 559

def rm_rf(list, options={})
  list = localize(list)
  fileutils.rm_rf(list, options)
end

#rmdir(dir, options = {}) ⇒ Object



493
494
495
496
# File 'lib/ratch/shell.rb', line 493

def rmdir(dir, options={})
  dir = localize(dir)
  fileutils.rmdir(dir, options)
end

#root(*args) ⇒ Object

Root location.



138
139
140
# File 'lib/ratch/shell.rb', line 138

def root(*args)
  dir('/', *args)
end

#safe?(path) ⇒ Boolean

Returns:

  • (Boolean)


411
# File 'lib/ratch/shell.rb', line 411

def safe?(path)       ; FileTest.safe?(localize(path)) ; end

#setgid?(path) ⇒ Boolean

Returns:

  • (Boolean)


404
# File 'lib/ratch/shell.rb', line 404

def setgid?(path)     ; FileTest.setgid?(localize(path))    ; end

#setuid?(path) ⇒ Boolean

Returns:

  • (Boolean)


405
# File 'lib/ratch/shell.rb', line 405

def setuid?(path)     ; FileTest.setuid?(localize(path))    ; end

#sh(cmd) ⇒ Object

Shell runner.



307
308
309
310
311
312
313
314
315
316
317
318
# 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

#size(path) ⇒ Object



390
# File 'lib/ratch/shell.rb', line 390

def size(path)        ; FileTest.size(localize(path))       ; end

#size?(path) ⇒ Boolean

Returns:

  • (Boolean)


391
# File 'lib/ratch/shell.rb', line 391

def size?(path)       ; FileTest.size?(localize(path))      ; end

#socket?(path) ⇒ Boolean

Returns:

  • (Boolean)


406
# File 'lib/ratch/shell.rb', line 406

def socket?(path)     ; FileTest.socket?(localize(path))    ; end

#stage(stage_dir, files) ⇒ Object

TODO: should this have SOURCE diectory?

stage(directory, source_dir, files)


601
602
603
604
605
606
607
# 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

#sticky?(path) ⇒ Boolean

Returns:

  • (Boolean)


401
# File 'lib/ratch/shell.rb', line 401

def sticky?(path)     ; FileTest.sticky?(localize(path))    ; end

#symlink?(path) ⇒ Boolean

Returns:

  • (Boolean)


393
# File 'lib/ratch/shell.rb', line 393

def symlink?(path)    ; FileTest.symlink?(localize(path))   ; end

#system(cmd) ⇒ Object

TODO: Tie this into the System class.



300
301
302
303
304
# File 'lib/ratch/shell.rb', line 300

def system(cmd)
  locally do
    super(cmd)
  end
end

#to_sObject

String representation is work directory path.



95
# File 'lib/ratch/shell.rb', line 95

def to_s ; work.to_s ; end

#touch(list, options = {}) ⇒ Object

alias_method :chown_R, :chown_r



592
593
594
595
# File 'lib/ratch/shell.rb', line 592

def touch(list, options={})
  list = localize(list)
  fileutils.touch(list, options)
end

#trace?Boolean

Returns:

  • (Boolean)


88
# File 'lib/ratch/shell.rb', line 88

def trace?   ; @_trace ; end

#uptodate?(path, *sources) ⇒ Boolean

Returns:

  • (Boolean)


647
648
649
650
651
# File 'lib/ratch/shell.rb', line 647

def uptodate?(path, *sources)
  locally do
    fileutils.uptodate?(path, sources.flatten)
  end
end

#work(*args) ⇒ Object

Current working path.



148
149
150
151
# File 'lib/ratch/shell.rb', line 148

def work(*args)
  return @_work if args.empty?
  return dir(@_work, *args)
end

#writable?(path) ⇒ Boolean

Returns:

  • (Boolean)


408
# File 'lib/ratch/shell.rb', line 408

def writable?(path)   ; FileTest.writable?(localize(path))  ; end

#writable_real?(path) ⇒ Boolean

Returns:

  • (Boolean)


416
# File 'lib/ratch/shell.rb', line 416

def writable_real?(path)   ; FileTest.writable_real?(localize(path))   ; end

#write(path, text) ⇒ Object

Write file.



373
374
375
376
# 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

#zero?(path) ⇒ Boolean

Returns:

  • (Boolean)


398
# File 'lib/ratch/shell.rb', line 398

def zero?(path)       ; FileTest.zero?(localize(path))      ; end