class Bosh::Cli::Runner
Attributes
args[R]
@return [Array]
options[R]
@return [Hash]
Public Class Methods
new(args, options = {})
click to toggle source
@param [Array] args
# File lib/cli/runner.rb, line 20 def initialize(args, options = {}) @args = args @options = options.dup banner = 'Usage: bosh [<options>] <command> [<args>]' @option_parser = OptionParser.new(banner) Config.colorize = nil if ENV.has_key?('BOSH_COLOR') && ENV['BOSH_COLOR'] == 'false' Config.colorize = false end Config.output ||= STDOUT parse_global_options end
run(args)
click to toggle source
@param [Array] args
# File lib/cli/runner.rb, line 15 def self.run(args) new(args).run end
Public Instance Methods
add_shortcuts()
click to toggle source
# File lib/cli/runner.rb, line 230 def add_shortcuts { 'st' => 'status', 'props' => 'properties', 'cck' => 'cloudcheck' }.each do |short, long| @parse_tree[short] = @parse_tree[long] end end
build_parse_tree()
click to toggle source
# File lib/cli/runner.rb, line 215 def build_parse_tree @parse_tree = ParseTreeNode.new Config.commands.each_value do |command| p = @parse_tree n_kw = command.keywords.size command.keywords.each_with_index do |kw, i| p[kw] ||= ParseTreeNode.new p = p[kw] p.command = command if i == n_kw - 1 end end end
find_completions(words, node = @parse_tree, index = 0)
click to toggle source
Finds command completions in the parse tree @param [Array] words Completion prefix @param [Bosh::Cli::ParseTreeNode] node Current parse tree node
# File lib/cli/runner.rb, line 87 def find_completions(words, node = @parse_tree, index = 0) word = words[index] # exact match and not on the last word if node[word] && words.length != index find_completions(words, node[word], index + 1) # exact match at the last word elsif node[word] node[word].values # find all partial matches else node.keys.grep(/^#{word}/) end end
get_gem_plugins()
click to toggle source
# File lib/cli/runner.rb, line 201 def get_gem_plugins Gem::Specification.latest_specs(true).map { |spec| spec.matches_for_glob(plugins_glob) }.flatten.uniq rescue err('Cannot load plugins, '.make_yellow + "please run `gem update --system` to ".make_yellow + 'update your RubyGems'.make_yellow) end
load_gem_plugins()
click to toggle source
# File lib/cli/runner.rb, line 183 def load_gem_plugins get_gem_plugins.each do |plugin_path| original_commands = Config.commands.size begin next unless require_plugin plugin_path rescue Exception => e err("Failed to load plugin #{plugin_path}: #{e.message}".make_red) end if Config.commands =~ original_commands say(("File #{plugin_path} has been loaded as plugin but it didn't " + "contain any commands.\nMake sure this plugin is updated to be " + 'compatible with BOSH CLI 1.0.').columnize(80).make_yellow) end end end
load_local_plugins()
click to toggle source
# File lib/cli/runner.rb, line 176 def load_local_plugins Dir.glob(File.join('lib', plugins_glob)).each do |file| say("WARNING: loading local plugin: #{file}") require_plugin(file) end end
load_plugins()
click to toggle source
Discover and load CLI plugins from all available gems @return [void]
# File lib/cli/runner.rb, line 171 def load_plugins load_local_plugins load_gem_plugins end
parse_global_options()
click to toggle source
# File lib/cli/runner.rb, line 104 def parse_global_options # -v is reserved for verbose but having 'bosh -v' is handy, # hence the little hack if @args.size == 1 && (@args[0] == '-v' || @args[0] == '--version') @args = %w(version) return end opts = @option_parser config_desc = 'Override configuration file. Also can be overridden ' + 'by BOSH_CONFIG environment variable. Defaults to ' + '$HOME/.bosh_config. Override precedence is command-' + 'line option, then environment variable, then home directory.' opts.on('-c', '--config FILE', config_desc) do |file| @options[:config] = file end opts.on('--parallel MAX', 'Sets the max number of parallel downloads') do |max| Config.max_parallel_downloads = Integer(max) end opts.on('--[no-]color', 'Toggle colorized output') do |v| Config.colorize = v end opts.on('-v', '--verbose', 'Show additional output') do @options[:verbose] = true end opts.on('-q', '--quiet', 'Suppress all output') do Config.output = nil end opts.on('-n', '--non-interactive', "Don't ask for user input") do @options[:non_interactive] = true end opts.on('-N', '--no-track', "Return Task ID and don't track") do @options[:no_track] = true end opts.on('-P', '--poll INTERVAL', 'Director task polling interval') do |interval| @options[:poll_interval] = Integer(interval) end opts.on('-t', '--target URL', 'Override target') do |target| @options[:target] = target end opts.on('-u', '--user USER', 'Override username') do |user| @options[:username] = user end opts.on('-p', '--password PASSWORD', 'Override password') do |pass| @options[:password] = pass end opts.on('-d', '--deployment FILE', 'Override deployment') do |file| @options[:deployment] = file end opts.on('-h', '--help', 'here you go') do @args << 'help' end opts.on('--ca-cert FILE', 'Override CA certificate') do |file| @options[:ca_cert] = file end @args = @option_parser.order!(@args) end
plugins_glob()
click to toggle source
# File lib/cli/runner.rb, line 166 def plugins_glob; 'bosh/cli/commands/*.rb' ; end
require_plugin(file)
click to toggle source
# File lib/cli/runner.rb, line 211 def require_plugin(file) require File.absolute_path(file) end
run(exit_on_success=true)
click to toggle source
Find and run CLI command @return [void]
# File lib/cli/runner.rb, line 38 def run(exit_on_success=true) Config.interactive = !@options[:non_interactive] Config.poll_interval = @options[:poll_interval] load_plugins build_parse_tree add_shortcuts @args = %w(help) if @args.empty? command = search_parse_tree(@parse_tree) if command.nil? && Config.interactive command = try_alias end if command.nil? err("Unknown command: #{@args.join(' ')}") end command.runner = self begin exit_code, info = command.run(@args, @options) exit(exit_code) if exit_on_success || exit_code != 0 [exit_code, info] rescue OptionParser::ParseError => e say_err(e.message) nl say_err("Usage: bosh #{command.usage_with_params.columnize(60, 7)}") nl if command.has_options? say(command.options_summary.indent(7)) end exit(1) end rescue OptionParser::ParseError => e say_err(e.message) say_err(@option_parser.to_s) exit(1) rescue Bosh::Cli::CliError => e say_err(e.message) nl exit(e.exit_code) end
search_parse_tree(node)
click to toggle source
# File lib/cli/runner.rb, line 244 def search_parse_tree(node) return nil if node.nil? arg = @args.shift longer_command = search_parse_tree(node[arg]) if longer_command.nil? @args.unshift(arg) if arg # backtrack if needed node.command else longer_command end end
try_alias()
click to toggle source
# File lib/cli/runner.rb, line 258 def try_alias # Tries to find best match among aliases (possibly multiple words), # then unwinds it onto the remaining args and searches parse tree again. # Not the most effective algorithm but does the job. config = Bosh::Cli::Config.new(@options[:config]) candidate = [] best_match = nil save_args = @args.dup while (arg = @args.shift) candidate << arg resolved = config.resolve_alias(:cli, candidate.join(' ')) if best_match && resolved.nil? @args.unshift(arg) break end best_match = resolved end if best_match.nil? @args = save_args return end best_match.split(/\s+/).reverse.each do |keyword| @args.unshift(keyword) end search_parse_tree(@parse_tree) end
usage()
click to toggle source
# File lib/cli/runner.rb, line 240 def usage @option_parser.to_s end
Private Instance Methods
say_err(message)
click to toggle source
# File lib/cli/runner.rb, line 291 def say_err(message) $stderr << message.make_red end