Class: Mxup::ExecRunner

Inherits:
Object
  • Object
show all
Defined in:
lib/mxup/exec_runner.rb

Overview

Implements ‘mxup exec`: send a command to a pane, block until it finishes, print its output, and exit with its return code. The three interesting parts are:

1. Resolving a logical window name to a real tmux pane target.
2. Using `tmux wait-for -S <marker>` so we know the command finished.
3. Capturing both the output (tmux capture-pane) and the exit code
   (written to a temp file by the wrapped command).

Instance Method Summary collapse

Constructor Details

#initialize(config, resolver:, dry_run: false, out: nil, err: nil, exiter: ->(n) { exit(n) }) ⇒ ExecRunner

Returns a new instance of ExecRunner.



18
19
20
21
22
23
24
25
26
27
# File 'lib/mxup/exec_runner.rb', line 18

def initialize(config, resolver:, dry_run: false,
               out: nil, err: nil, exiter: ->(n) { exit(n) })
  @config       = config
  @session      = config.session
  @resolver     = resolver
  @dry_run      = dry_run
  @out_override = out
  @err_override = err
  @exit         = exiter
end

Instance Method Details

#errObject



33
34
35
# File 'lib/mxup/exec_runner.rb', line 33

def err
  @err_override || $stderr
end

#outObject



29
30
31
# File 'lib/mxup/exec_runner.rb', line 29

def out
  @out_override || $stdout
end

#run(target_spec, command, lines: 50, timeout: nil, force: false, quiet: false) ⇒ Object

target_spec may be:

"session:window"      — session must match config
"window"              — logical name from config, or a raw tmux window
"window.pane_index"   — raw tmux pane address


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/mxup/exec_runner.rb', line 41

def run(target_spec, command, lines: 50, timeout: nil, force: false, quiet: false)
  abort "Session #{@session} is not running." unless Tmux.has_session?(@session)
  abort 'mxup exec: command is required.' if command.nil? || command.strip.empty?

  window_part = strip_session_prefix(target_spec)
  resolved    = resolve_target(window_part)
  abort "Target '#{window_part}' not found in session '#{@session}'." unless resolved

  full_target = "#{@session}:#{resolved}"
  refuse_if_busy(resolved, full_target) unless force

  if @dry_run
    out.puts "[dry-run] Would exec on #{full_target}: #{command}"
    return 0
  end

  send_and_wait(full_target, command, lines: lines, timeout: timeout, quiet: quiet)
end