chitin / lib / chitin / commands / runnable.rb

module Chitin
  module Runnable

    def initialize
      set_in  STDIN
      set_out STDOUT
      set_err STDERR
    end

    def <(io)
      case io
      when IO, File
        self[:set_in, io]
      when String, FileObject
        f = File.open io.to_s, 'r'
        self[:set_in, f]
        f.close
      else
        raise "Unknown piping type: #{io.class}"
      end
  
      self
    end

    def >(io)
      case io
      when IO, File
        self[:set_out, io]
      when String, FileObject
        f = File.open io.to_s, 'w'
        self[:set_out, f]
        f.close
      else
        raise "Unknown piping type: #{io.class}"
      end
  
      self
    end

    def >>(io)
      case io
      when IO, File
        self[:set_out, io]
      when String, FileObject
        f = File.open io.to_s, 'a'
        self[:set_out, f]
        f.close
      else
        raise "Unknown piping type: #{io.class}"
      end
  
      self
    end

    def ^(io)
      case io
      when IO, File
        self[:set_err, io]
      when String, FileObject
        f = File.open io.to_s, 'w'
        self[:set_err, f]
        f.close
      else
        raise "Unknown piping type: #{io.class}"
      end
  
      self
    end

    # access private methods
    def [](*args)
      if method(args.first)
        method(args.first).call *args[1..-1]
      else
        raise NoMethodError.new("undefined method" +
                                "`#{args.first}' for #{self}:#{self.class}")
      end
    end

    def bg!; @bg = true; self; end
    def bg?; @bg; end
    def fg?; !@bg; end

    def |(other); Pipe.new self, other; end
    alias_method :<=>, :|

    private

    attr_accessor :bg
    attr_accessor :in
    attr_accessor :out
    attr_accessor :err
  
    # I'm pretty sure this would induce a memory leak if Ruby
    # weren't GCed. Suggestions are appreciated.
    def set_in(other)
      r, w = IO.pipe
      w.close
      self[:in=, r]
      self[:in].reopen other
    end
  
    # I'm pretty sure this would induce a memory leak if Ruby
    # weren't GCed. Suggestions are appreciated.
    def set_out(other)
      r, w = IO.pipe
      r.close
      self[:out=, w]
      self[:out].reopen other
    end
  
    # I'm pretty sure this would induce a memory leak if Ruby
    # weren't GCed. Suggestions are appreciated.
    def set_err(other)
      r, w = IO.pipe
      r.close
      self[:err=, w]
      self[:err].reopen other
    end
  
    # if one of the following is nil, bad things happen. this is deliberate.
    # is it wise? that's an exercise left to the reader.
    def close_all
      self[:in].close
      self[:out].close
      self[:err].close
    end

    # These methods need to be implemented by those including this module
    def returning; raise "Not Yet Implemented"; end
    def wait; raise "Not Yet Implemented"; end
    def reset; raise "Not Yet Implemented"; end
    def run; raise "Not Yet Implemented"; end

    # Generally the same as +run+, except for the ruby commands.
    # they return real ruby that can be given back to the user.
    def raw_run
      run
    end

    def secure_run
      verify_permissions
      run
    end

    def secure_raw_run
      verify_permissions
      raw_run
    end

    def verify_permissions(name=self.name)
      # find the manifest file
      manifest = Manifest.find name
      # ask user to confirm permissions
      confirmed_perms = manifest.confirm_permissions name
      # take the requested permissions
      #   implement the restrictions according to PinkTrace
      Sandbox.secure confirmed_perms
    end

    def name; raise "Not Yet Implemented"; end
  end
end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.