module Folio require 'folio/xdg' # = Prompt class # # A Folio Shell object provides a limited file system shell in code. # class Shell # New Shell object. def initialize(*path) opts = (Hash===path.last ? path.pop : {}) mode(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 = Directory.new(path) 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 # String representation is work directory path. def to_s ; work.to_s ; end # Present working directory as a Directory object. attr :work # Home location. def home ; file('~') ; end # Root location. def root ; file('/') ; end # Return a new prompt with the same location. # NOTE: Use #dup or #clone ? #def new ; Prompt.new(work) ; end # Get the FileObject for the given file name. # # TODO: Should there be methods like this for each # type, and raise an error if not the right type? # def file(name) FileObject[name] end alias_method :[], :file # Join paths. def +(fname) @work =+ fname end alias_method :/, :+ # Lists all entries. def entries work.entries end alias_method :ls, :entries # Lists directory entries. def directory_entries work.directory_entries end # Lists directory entries. def document_entries work.document_entries end # Returns Enumerator of files objects. def files ; work.files ; end # Returns Enumerator of directories. def documents ; work.documents ; end # Returns Enumerator of documents. def directories ; work.directories ; end # Glob pattern. def glob(*patterns) opts = (::Integer===patterns.last ? patterns.pop : 0) pattern = localize(pattern) ::Dir.glob(pattern, opts).each{ |f| FileObject[f] } end # Chage working directory. def cd(dir, &block) #dir = localize(dir) if block @work.cd(dir, &block) else @work += dir end end ############# # FileUtils # ############# # def mkdir(dir, options) dir = localize(dir) fileutils.mkdir(dir, options) end def mkdir_p(dir, options) dir = localize(dir) fileutils.mkdir_p(dir, options) end def rmdir(dir, options) dir = localize(dir) fileutils.rmdir(dir, options) end # ln(list, destdir, options) def ln(old, new, options) old = localize(old) new = localize(new) fileutils.ln(old, new, options) end # ln_s(list, destdir, options) def ln_s(old, new, options) old = localize(old) new = localize(new) fileutils.ln_s(old, new, options) end def ln_sf(old, new, options) old = localize(old) new = localize(new) fileutils.ln_sf(old, new, options) end # cp(list, dir, options) def cp(src, dest, options) src = localize(src) dest = localize(dest) fileutils.cp(src, dest, options) end # cp_r(list, dir, options) def cp_r(src, dest, options) src = localize(src) dest = localize(dest) fileutils.cp_r(src, dest, options) end # mv(list, dir, options) def mv(src, dest, options) src = localize(src) dest = localize(dest) fileutils.mv(src, dest, options) end def rm(list, options) list = localize(list) fileutils.rm(list, options) end def rm_r(list, options) list = localize(list) fileutils.rm_f(list, options) end def rm_rf(list, options) list = localize(list) fileutils.rm_rf(list, options) end def install(src, dest, mode, options) src = localize(src) dest = localize(dest) fileutils.install(src, dest, mode, options) end def chmod(mode, list, options) list = localize(list) fileutils.chmod(mode, list, options) end def chmod_r(mode, list, options) list = localize(list) fileutils.chmod_r(mode, list, options) end #alias_method :chmod_R, :chmod_r def chown(user, group, list, options) list = localize(list) fileutils.chown(user, group, list, options) end def chown_r(user, group, list, options) list = localize(list) fileutils.chown_r(user, group, list, options) end #alias_method :chown_R, :chown_r def touch(list, options) list = localize(list) fileutils.touch(list, options) end ################# # XDG locations # ################# # Look up a config file. def config(path) file(XDG.xdg_config_file(path)) end # Look up a data file. def data(path) file(XDG.xdg_data_file(path)) end # Look up a cache file. def cache(path) file(XDG.xdg_cache_file(path)) end # Return a enumertor of system config directories. def root_config() #_directories XDG.xdg_config_dirs.to_enum(:each){ |f| file(f) } end # Return a enumertor of system data directories. def root_data() #_directories XDG.xdg_data_dirs.to_enum(:each){ |f| file(f) } end # Return the home config directory. def home_config file(XDG.xdg_config_home) end # Return the home data directory. def home_data file(XDG.xdg_data_home) end # Return the home cache directory. def home_cache file(XDG.xdg_cache_home) end # Return the home config directory. def work_config file(XDG.xdg_config_work) end # Return the home data directory. def work_data file(XDG.xdg_data_work) end # Return the home cache directory. def work_cache file(XDG.xdg_cache_work) end private def localize(local_path) case local_path when Array local_path.collect{ |lp| File.expand_path(File.join(path, lp)) } else File.expand_path(File.join(path, local_path)) end end # Returns FileUtils module based on mode. def fileutils return ::FileUtils unless @mode case @mode when :dryrun ::FileUtils::DryRun when :noop ::FileUtils::Noop when :verbose ::FileUtils::Verbose else ::FileUtils end end public#class def self.[](path) new(path) end end end # Could the prompt act as a delegate to file objects? # If we did this then the file prompt could actually "cd" into a file. # =begin :nodoc: def initialize(path) @path = path = ::File.join(*path) raise FileNotFound unless ::File.exist?(path) if ::File.blockdev?(path) or chardev?(path) @delegate = Device.new(path) elsif ::File.link?(path) @delegate = Link.new(path) elsif ::File.directory?(path) @delegate = Directory.new(path) else @delegate = Document.new(path) end end def delete @delegate.delete @delegate = nil end =end #++