Class: Yap::Shell::Execution::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/yap/shell/execution/context.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stdin:, stdout:, stderr:) ⇒ Context

Returns a new instance of Context.



30
31
32
33
34
# File 'lib/yap/shell/execution/context.rb', line 30

def initialize(stdin:, stdout:, stderr:)
  @stdin, @stdout, @stderr = stdin, stdout, stderr
  @command_queue = []
  @suspended_execution_contexts = []
end

Class Method Details

.execution_context_for(command) ⇒ Object



26
27
28
# File 'lib/yap/shell/execution/context.rb', line 26

def self.execution_context_for(command)
  @registrations[command.type] || raise("No execution context found for given #{command.type} command: #{command.inspect}")
end

.fire(event, context, *args) ⇒ Object



13
14
15
16
17
# File 'lib/yap/shell/execution/context.rb', line 13

def self.fire(event, context, *args)
  on[event.to_sym].each do |block|
    block.call(context, *args)
  end
end

.on(event = nil, &blk) ⇒ Object



5
6
7
8
9
10
11
# File 'lib/yap/shell/execution/context.rb', line 5

def self.on(event=nil, &blk)
  @on_callbacks ||= Hash.new{ |h,k| h[k] = [] }
  if event
    @on_callbacks[event.to_sym].push blk
  end
  @on_callbacks
end

.register(context, command_type:) ⇒ Object



19
20
21
22
23
24
# File 'lib/yap/shell/execution/context.rb', line 19

def self.register(context, command_type:)
  raise "context cannot be nil" if context.nil?
  @registrations ||= {}
  @registrations[command_type] = context
  true
end

Instance Method Details

#add_command_to_run(command, stdin:, stdout:, stderr:, wait:) ⇒ Object



36
37
38
# File 'lib/yap/shell/execution/context.rb', line 36

def add_command_to_run(command, stdin:, stdout:, stderr:, wait:)
  @command_queue << [command, stdin, stdout, stderr, wait]
end

#clear_commandsObject



40
41
42
# File 'lib/yap/shell/execution/context.rb', line 40

def clear_commands
  @command_queue.clear
end

#execute(world:) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/yap/shell/execution/context.rb', line 44

def execute(world:)
  results = []
  @command_queue.each_with_index do |(command, stdin, stdout, stderr, wait), reversed_i|
    of = @command_queue.length
    i = reversed_i + 1
    stdin  = @stdin  if stdin  == :stdin
    stdout = @stdout if stdout == :stdout
    stderr = @stderr if stderr == :stderr

    execution_context_factory = self.class.execution_context_for(command)
    if execution_context_factory
      execution_context = execution_context_factory.new(
        stdin:  stdin,
        stdout: stdout,
        stderr: stderr,
        world:  world
      )

      @saved_tty_attrs = Termios.tcgetattr(STDIN)
      Treefell['shell'].puts "firing :before_execute for #{command}"
      self.class.fire :before_execute, world, command: command

      begin
        result = execution_context.execute(command:command, n:i, of:of, wait:wait)
      rescue Exception => ex
        raise(ex) if ex.is_a?(SystemExit)

        Treefell['shell'].puts "rescued unexpected error=#{ex} with message=#{ex.message.inspect}"
        puts <<-ERROR.gsub(/^\s*\|/, '')
          |******************************
          |\e[31mWhoops! An unexpected error has occurred\e[0m
          |******************************
          |
          |The error was:
          |  #{ex.message}
          |
          |Backtrace:
          |#{ex.backtrace.join("\n")}
          |
          |Report this to yap-shell on github:
          |   https://github.com/zdennis/yap-shell/issues/new?title=#{URI.escape(ex.message)}
          |
        ERROR
      end

      Treefell['shell'].puts "firing :after_execute for #{command}"
      self.class.fire :after_execute, world, command: command, result: result

      results << process_execution_result(execution_context:execution_context, result:result)
      Termios.tcsetattr(STDIN, Termios::TCSANOW, @saved_tty_attrs)
    end
  end

  clear_commands

  results.last
end