Skip to content

Instantly share code, notes, and snippets.

@narutaro
Last active September 11, 2020 00:54
Show Gist options
  • Save narutaro/713e528a323e618b0d824473e19b0b14 to your computer and use it in GitHub Desktop.
Save narutaro/713e528a323e618b0d824473e19b0b14 to your computer and use it in GitHub Desktop.
class version
require "readline"
require "yaml"
require "json"
class CLI
attr_accessor :command_tree
def initialize(swagger_json)
# TODO: json might be broken
if swagger_json.nil?
puts "Usage: #{$0} <json_file>"
exit
end
@command_tree = create_command_tree(swagger_json)["paths"]
end
# array_of_hash to hash
def format_params(array_of_parameters)
return {} if array_of_parameters.nil?
h = {}
array_of_parameters.each{|hash|
#h[hash["name"]] = { "in" => hash['in'], "description" => hash['description'], "schema" => hash['schema']}
h[hash["name"]] = {}
}
h
end
def create_command_tree(swagger_json)
swagger_hash = File.open(ARGV[0]) do |j|
JSON.load(j)
end
paths = swagger_hash.select{|k, v| k == "paths"}
command_tree = paths.each{|k1, v1| # k1 = paths
v1.each{|k2, v2| # k2 = /cab
v2.map{|k3, v3| # k3 = get
v2[k3] = format_params(v3["parameters"])
}
}
}
command_tree
end
def parse_command(array_of_commands, command_tree)
#return "command too short" if array_of_commands.size < 3
result = array_of_commands.all?{|command|
if command_tree.has_key?(command)
command_tree = command_tree[command]
end
}
"Invalid command" if !result
end
def get_current_option(command_tree, line_buffer)
current_option = command_tree.keys
commands = line_buffer.split
commands.each_with_index{|command, i|
# Don't go down to the lower level(and return current_option) in case current command matches two candidates such as "pet" and "petGroup"
return current_option if i == commands.size-1 and !line_buffer.end_with?("\s")
# Go down
if command_tree.has_key?(command)
if command_tree[command].nil? # invalid command or key at leaf
current_option = []
else
command_tree = command_tree[command]
current_option = command_tree.keys
end
end
}
current_option
end
end
cli = CLI.new(ARGV[0])
command_tree = cli.command_tree
# Evaluate the proc when pressing <tab>
comp = proc do |input|
cli.get_current_option(command_tree, Readline.line_buffer).select { |name| name.to_s.start_with?(input) }
end
Readline.completion_proc = comp
Readline.completion_append_character = " "
while input = Readline.readline("〉", true)
break if input == "q"
p Readline.line_buffer.split if !input.empty?
p cli.parse_command(Readline.line_buffer.split, command_tree)
# p command_tree
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment