Sha256: fd50df4a968544f012f1d3d85c98471d33ef8d050778bbe123b8faf859fd656c

Contents?: true

Size: 1.63 KB

Versions: 6

Compression:

Stored size: 1.63 KB

Contents

require 'pty'

module Buildbox
  class Command
    class Result < Struct.new(:output, :exit_status)
    end

    def self.run(command, options = {}, &block)
      new(command, options).run(&block)
    end

    def initialize(command, options = {})
      @command       = command
      @directory     = options[:directory] || "."
      @read_interval = options[:read_interval] || 5
    end

    def run(&block)
      output = ""
      read_io, write_io, pid = nil

      # spawn the process in a pseudo terminal so colors out outputted
      read_io, write_io, pid = PTY.spawn("cd #{expanded_directory} && #{@command}")

      # we don't need to write to the spawned io
      write_io.close

      loop do
        fds, = IO.select([read_io], nil, nil, read_interval)
        if fds
          # should have some data to read
          begin
            chunk         = read_io.read_nonblock(10240)
            cleaned_chunk = UTF8.clean(chunk)

            output << chunk
            yield cleaned_chunk if block_given?
          rescue Errno::EAGAIN, Errno::EWOULDBLOCK
            # do select again
          rescue EOFError, Errno::EIO # EOFError from OSX, EIO is raised by ubuntu
            break
          end
        end
        # if fds are empty, timeout expired - run another iteration
      end

      # we're done reading, yay!
      read_io.close

      # just wait until its finally finished closing
      Process.waitpid(pid)

      # the final result!
      Result.new(output.chomp, $?.exitstatus)
    end

    private

    def expanded_directory
      File.expand_path(@directory)
    end

    def read_interval
      @read_interval
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
buildbox-0.2.2 lib/buildbox/command.rb
buildbox-0.2.1 lib/buildbox/command.rb
buildbox-0.2 lib/buildbox/command.rb
buildbox-0.1.4 lib/buildbox/command.rb
buildbox-0.1.1 lib/buildbox/command.rb
buildbox-0.1 lib/buildbox/command.rb