Skip to content

Instantly share code, notes, and snippets.

@mateusz-fiolka
Created August 28, 2018 14:26
Show Gist options
  • Save mateusz-fiolka/a56ba3bd59b2d8054c26d2d04984acdf to your computer and use it in GitHub Desktop.
Save mateusz-fiolka/a56ba3bd59b2d8054c26d2d04984acdf to your computer and use it in GitHub Desktop.
Convox cli wrapper, work in progress
#!/usr/bin/ruby
require "readline"
require "open3"
require "yaml"
require "thread"
def fetch_racks
racks = `convox racks`
if $?.exitstatus != 0 ; then
throw "Could not fetch racks"
end
return racks.split("\n")
.drop(1)
.map { |line| line.split(/\s/).first }
end
def fetch_apps_for(rack)
apps = `convox apps --rack #{rack}`
if $?.exitstatus != 0 ; then
throw "Could not fetch apps for rack #{rack}"
end
return apps.split("\n")
.drop(1)
.map { |line| line.split(/\s/).first }
end
def fetch_apps
return Hash[fetch_racks.map { |rack| [rack, fetch_apps_for(rack)] } ]
end
def get_apps
# todo: refresh from time to time
cache_file_path = "#{Dir.home}/.convox-shell-apps-cache"
if File.exists?(cache_file_path) then
return YAML::load(File.read(cache_file_path))
end
apps = fetch_apps
File.write(cache_file_path, YAML::dump(apps))
return apps
end
def parse_command_names
help_commands = `convox help`
if $?.exitstatus != 0 ; then
throw "Could not read convox help options"
end
return help_commands.split("\n")
.map { |line| line.split(/\s{2,}/)[0].sub('convox ', '') }
end
def parse_command_options(command_name)
command_help = `convox #{command_name} --help`
if $?.exitstatus != 0 ; then
throw "Could not read convox help command for command #{command_name}"
end
return command_help.split("\n")
.select { |line| line.match /^\s+\-\-\w/ }
.map { |line| line.sub(/\s+\-\-/, '').split("\s").first }
end
def parse_commands_with_options
parse_command_names
.map { |command_name| [ command_name, parse_command_options(command_name) ] }
end
def get_commands_with_options
# todo: refresh on cli version change
cache_file_path = "#{Dir.home}/.convox-shell-commands-cache"
if File.exists?(cache_file_path) then
return YAML::load(File.read(cache_file_path))
end
apps = parse_commands_with_options
File.write(cache_file_path, YAML::dump(apps))
return apps
end
def setup_completion(apps, commands_with_options)
end
apps = get_apps
commands_with_options = get_commands_with_options.to_s
setup_completion(apps, commands_with_options)
loop do
line = ""
begin
line = Readline.readline("> ", true)
rescue Interrupt => e
break
end
begin
cmd = "convox #{line}"
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
{ :out => stdout, :err => stderr }.each do |key, stream|
Thread.new do
until (raw_line = stream.gets).nil? do
puts raw_line
end
end
end
status = wait_thr.value.exitstatus
puts "Command exited with status: #{status}"
end
rescue Interrupt => e
puts "Command interrupted"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment