|
|
|
@ -1,17 +1,21 @@
|
|
|
|
|
#!/usr/bin/env ruby |
|
|
|
|
|
|
|
|
|
require "base64" |
|
|
|
|
require "io/console" |
|
|
|
|
require "optparse" |
|
|
|
|
require "socket" |
|
|
|
|
|
|
|
|
|
usage_output = "USAGE:\n github-fast-env SCRIPT_PATH [options]" |
|
|
|
|
|
|
|
|
|
$options = {:verbose => false} |
|
|
|
|
$options = {:verbose => false, :interactive => false} |
|
|
|
|
OptionParser.new do |options| |
|
|
|
|
options.banner = usage_output |
|
|
|
|
options.on("-v", "--verbose", "Show verbose output") do |
|
|
|
|
$options[:verbose] = true |
|
|
|
|
end |
|
|
|
|
options.on("-i", "--interactive", "Run an interactive session using a pseudoterminal") do |
|
|
|
|
$options[:interactive] = true |
|
|
|
|
end |
|
|
|
|
end.parse! |
|
|
|
|
|
|
|
|
|
if not ARGV or ARGV.empty? |
|
|
|
@ -34,9 +38,13 @@ control_socket_path = "/tmp/github-fast-envd.sock"
|
|
|
|
|
|
|
|
|
|
$control_socket = UNIXSocket.new(control_socket_path) |
|
|
|
|
|
|
|
|
|
$original_stdin = $stdin.dup |
|
|
|
|
$original_stdout = $stdout.dup |
|
|
|
|
$origianl_stderr = $stderr.dup |
|
|
|
|
|
|
|
|
|
def log(level, message) |
|
|
|
|
if level == "error" or $options[:verbose] |
|
|
|
|
$stderr.puts "[github-fast-env] #{level}: #{message}" |
|
|
|
|
$origianl_stderr.puts "[github-fast-env] #{level}: #{message}" |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
@ -89,7 +97,12 @@ end
|
|
|
|
|
log "info", "connected to control socket" |
|
|
|
|
|
|
|
|
|
encoded_script_path = Base64.encode64(script_path).delete("\n") |
|
|
|
|
$control_socket.puts "new v1 named-pipes #{encoded_script_path}" |
|
|
|
|
|
|
|
|
|
if $options[:interactive] |
|
|
|
|
$control_socket.puts "new v1 pseudoterminal #{encoded_script_path}" |
|
|
|
|
else |
|
|
|
|
$control_socket.puts "new v1 named-pipes #{encoded_script_path}" |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
pipes = {"stdin" => nil, "stdout" => nil, "stderr" => nil} |
|
|
|
|
|
|
|
|
@ -115,10 +128,27 @@ while true
|
|
|
|
|
pipes["stderr"] = File::open("#{pipe_base_path}.stderr", "r") |
|
|
|
|
pipes["stderr"].sync = true |
|
|
|
|
|
|
|
|
|
read_ios = [$control_socket, $stdin, pipes["stdout"], pipes["stderr"]] |
|
|
|
|
|
|
|
|
|
log "info", "connected via named pipes" |
|
|
|
|
elsif command == "pseudoterminal" |
|
|
|
|
log "error", "not yet implemented" |
|
|
|
|
exit 1 |
|
|
|
|
if arguments.empty? |
|
|
|
|
log "error", "malformed response" |
|
|
|
|
exit 1 |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
pseudoterminal_path = Base64.decode64(arguments[0]) |
|
|
|
|
|
|
|
|
|
log "info", "connecting to pseudoterminal at #{pseudoterminal_path}" |
|
|
|
|
|
|
|
|
|
pseudoterminal_io = File::open(pseudoterminal_path, File::RDWR | File::NOCTTY) |
|
|
|
|
|
|
|
|
|
pipes["stdin"] = pseudoterminal_io |
|
|
|
|
pipes["stdout"] = pseudoterminal_io |
|
|
|
|
|
|
|
|
|
read_ios = [$control_socket, $stdin, pipes["stdout"]] |
|
|
|
|
|
|
|
|
|
log "info", "connected via pseudoterminal" |
|
|
|
|
else |
|
|
|
|
log "error", "malformed response" |
|
|
|
|
exit 1 |
|
|
|
@ -128,8 +158,6 @@ end
|
|
|
|
|
log "info", "ready" |
|
|
|
|
$control_socket.puts "ready" |
|
|
|
|
|
|
|
|
|
read_ios = [$control_socket, $stdin, pipes["stdout"], pipes["stderr"]] |
|
|
|
|
|
|
|
|
|
exit_code = "unknown" |
|
|
|
|
|
|
|
|
|
while read_ios.include?($control_socket) or read_ios.include?(pipes["stdout"]) or read_ios.include?(pipes["stderr"]) |
|
|
|
@ -165,7 +193,7 @@ while read_ios.include?($control_socket) or read_ios.include?(pipes["stdout"]) o
|
|
|
|
|
log "warn", "received input from unknown stream" |
|
|
|
|
end |
|
|
|
|
rescue EOFError |
|
|
|
|
log "trace", "closing stream" |
|
|
|
|
log "trace", "closing stream #{ready_read_io}" |
|
|
|
|
ready_read_io.close |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|