Class: WavefrontCliController
- Inherits:
-
Object
- Object
- WavefrontCliController
- Includes:
- WavefrontCli::Constants
- Defined in:
- lib/wavefront-cli/controller.rb
Overview
Dynamically generate a CLI interface from files which describe each subcomand.
Constant Summary
Constants included from WavefrontCli::Constants
WavefrontCli::Constants::ALL_PAGE_SIZE, WavefrontCli::Constants::DEFAULT_CONFIG, WavefrontCli::Constants::DEFAULT_OPTS, WavefrontCli::Constants::EVENT_STATE_DIR, WavefrontCli::Constants::HUMAN_TIME_FORMAT, WavefrontCli::Constants::HUMAN_TIME_FORMAT_MS, WavefrontCli::Constants::SEARCH_SPLIT
Instance Attribute Summary collapse
-
#args ⇒ Object
readonly
Returns the value of attribute args.
-
#cmds ⇒ Object
readonly
Returns the value of attribute cmds.
-
#opts ⇒ Object
readonly
Returns the value of attribute opts.
-
#tw ⇒ Object
readonly
Returns the value of attribute tw.
-
#usage ⇒ Object
readonly
Returns the value of attribute usage.
Instance Method Summary collapse
-
#backtrace_message(err) ⇒ Object
rubocop:enable Metrics/MethodLength rubocop:enable Metrics/AbcSize.
-
#cli_class(cmd, opts) ⇒ Object
Get the CLI class we need to run the command we’ve been given.
-
#default_help ⇒ String
What you see when you do ‘wf –help’ rubocop:disable Metrics/MethodLength.
-
#docopt_hash ⇒ Hash
Command descriptions for docopt.
- #handle_missing_credentials(error) ⇒ Object
-
#import_command(path) ⇒ Object
Load a command description from a file.
-
#initialize(args) ⇒ WavefrontCliController
constructor
A new instance of WavefrontCliController.
- #load_cli_class(cmd, opts) ⇒ Object
-
#load_commands ⇒ Hash
Each command is defined in its own file.
-
#parse_args ⇒ Object
Parse the input.
-
#parse_cmd(cmd) ⇒ Object
Parse a command.
- #parse_opts(options) ⇒ Object
-
#run_command(cli_class_obj) ⇒ Object
rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize.
-
#sanitize_keys(options) ⇒ Object
Symbolize, and remove dashes from option keys.
Constructor Details
#initialize(args) ⇒ WavefrontCliController
Returns a new instance of WavefrontCliController.
32 33 34 35 36 37 38 39 40 |
# File 'lib/wavefront-cli/controller.rb', line 32 def initialize(args) @args = args @cmds = load_commands @usage = docopt_hash cmd, opts = parse_args @opts = parse_opts(opts) cli_class_obj = cli_class(cmd, @opts) run_command(cli_class_obj) end |
Instance Attribute Details
#args ⇒ Object (readonly)
Returns the value of attribute args.
28 29 30 |
# File 'lib/wavefront-cli/controller.rb', line 28 def args @args end |
#cmds ⇒ Object (readonly)
Returns the value of attribute cmds.
28 29 30 |
# File 'lib/wavefront-cli/controller.rb', line 28 def cmds @cmds end |
#opts ⇒ Object (readonly)
Returns the value of attribute opts.
28 29 30 |
# File 'lib/wavefront-cli/controller.rb', line 28 def opts @opts end |
#tw ⇒ Object (readonly)
Returns the value of attribute tw.
28 29 30 |
# File 'lib/wavefront-cli/controller.rb', line 28 def tw @tw end |
#usage ⇒ Object (readonly)
Returns the value of attribute usage.
28 29 30 |
# File 'lib/wavefront-cli/controller.rb', line 28 def usage @usage end |
Instance Method Details
#backtrace_message(err) ⇒ Object
rubocop:enable Metrics/MethodLength rubocop:enable Metrics/AbcSize
183 184 185 186 187 188 189 |
# File 'lib/wavefront-cli/controller.rb', line 183 def (err) if opts[:debug] warn "Backtrace:\n\t#{err.backtrace.join("\n\t")}" else puts "Re-run command with '-D' for backtrace." end end |
#cli_class(cmd, opts) ⇒ Object
Get the CLI class we need to run the command we’ve been given.
109 110 111 112 113 114 115 116 117 |
# File 'lib/wavefront-cli/controller.rb', line 109 def cli_class(cmd, opts) load_cli_class(cmd, opts) rescue WavefrontCli::Exception::UnhandledCommand abort 'Fatal error. Unsupported command. Please open a Github issue.' rescue WavefrontCli::Exception::InvalidInput => e abort "Invalid input. #{e.}" rescue RuntimeError => e abort "Unable to run command. #{e.}." end |
#default_help ⇒ String
What you see when you do ‘wf –help’ rubocop:disable Metrics/MethodLength
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/wavefront-cli/controller.rb', line 46 def default_help s = ['Wavefront CLI', '', 'Usage:', " #{CMD} command [options]", " #{CMD} --version", " #{CMD} --help", '', 'Commands:', ''] cmds.sort.each do |k, v| s.<< format(' %-18<command>s %<desc>s', command: k, desc: v.description) end s.<< '' s.<< "Use '#{CMD} <command> --help' for further information." s.join("\n") end |
#docopt_hash ⇒ Hash
Returns command descriptions for docopt.
71 72 73 74 75 |
# File 'lib/wavefront-cli/controller.rb', line 71 def docopt_hash cmds.each_with_object(default: default_help) do |(k, v), ret| ret[k.to_sym] = v.docopt end end |
#handle_missing_credentials(error) ⇒ Object
193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/wavefront-cli/controller.rb', line 193 def handle_missing_credentials(error) if DEFAULT_CONFIG.exist? && DEFAULT_CONFIG.file? abort "Credential error. #{error.}" else puts 'No credentials supplied on the command line or via ' \ 'environment variables, and no configuration file found. ' \ "Please run 'wf config setup' to create configuration." .fold(TW, 0) exit 1 end end |
#import_command(path) ⇒ Object
Load a command description from a file. Each is in its own class
return [Class] new class object defining command.
221 222 223 224 225 226 227 |
# File 'lib/wavefront-cli/controller.rb', line 221 def import_command(path) return if path.extname != '.rb' || path.basename.to_s == 'base.rb' k_name = path.basename.to_s[0..-4] require(CMD_DIR + k_name) Object.const_get("WavefrontCommand#{k_name.capitalize}").new end |
#load_cli_class(cmd, opts) ⇒ Object
119 120 121 122 |
# File 'lib/wavefront-cli/controller.rb', line 119 def load_cli_class(cmd, opts) require_relative File.join('.', cmds[cmd].sdk_file) Object.const_get('WavefrontCli').const_get(cmds[cmd].sdk_class).new(opts) end |
#load_commands ⇒ Hash
Each command is defined in its own file. Dynamically load all those commands.
209 210 211 212 213 214 |
# File 'lib/wavefront-cli/controller.rb', line 209 def load_commands CMD_DIR.children.each_with_object({}) do |f, ret| k = import_command(f) ret[k.word.to_sym] = k if k end end |
#parse_args ⇒ Object
Parse the input. The first Docopt.docopt handles the default options, the second works on the command.
80 81 82 83 84 85 86 87 |
# File 'lib/wavefront-cli/controller.rb', line 80 def parse_args Docopt.docopt(usage[:default], version: WF_CLI_VERSION, argv: args) rescue Docopt::Exit => e cmd = args.empty? ? nil : args.first.to_sym abort e. unless usage.key?(cmd) parse_cmd(cmd) end |
#parse_cmd(cmd) ⇒ Object
Parse a command.
92 93 94 95 96 97 98 |
# File 'lib/wavefront-cli/controller.rb', line 92 def parse_cmd(cmd) [cmd, sanitize_keys(Docopt.docopt(usage[cmd], argv: args))] rescue Docopt::DocoptLanguageError => e abort "Mangled command description:\n#{e.}" rescue Docopt::Exit => e abort e. end |
#parse_opts(options) ⇒ Object
100 101 102 |
# File 'lib/wavefront-cli/controller.rb', line 100 def parse_opts() WavefrontCli::OptHandler.new().opts end |
#run_command(cli_class_obj) ⇒ Object
rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/wavefront-cli/controller.rb', line 126 def run_command(cli_class_obj) cli_class_obj.validate_opts cli_class_obj.run rescue Interrupt abort "\nOperation aborted at user request." rescue WavefrontCli::Exception::ConfigFileNotFound => e abort "Configuration file #{e}' not found." rescue WavefrontCli::Exception::CredentialError => e handle_missing_credentials(e) rescue WavefrontCli::Exception::MandatoryValue abort 'A value must be supplied.' rescue Wavefront::Exception::InvalidPermission => e abort "'#{e}' is not a valid privilege." rescue Wavefront::Exception::InvalidUserGroupId => e abort "'#{e}' is not a valid user group id." rescue WavefrontCli::Exception::InvalidValue => e abort "Invalid value for #{e}." rescue WavefrontCli::Exception::ProfileExists => e abort "Profile '#{e}' already exists." rescue WavefrontCli::Exception::ProfileNotFound => e abort "Profile '#{e}' not found." rescue WavefrontCli::Exception::FileNotFound abort 'File not found.' rescue WavefrontCli::Exception::InsufficientData => e abort "Insufficient data. #{e.}" rescue WavefrontCli::Exception::InvalidQuery => e abort "Invalid query. API message: '#{e.}'." rescue WavefrontCli::Exception::SystemError => e abort "Host system error. #{e.}" rescue WavefrontCli::Exception::UnparseableInput => e abort "Cannot parse input. #{e.}" rescue WavefrontCli::Exception::UnparseableSearchPattern abort 'Searches require a key, a value, and a match operator.' rescue WavefrontCli::Exception::UnsupportedFileFormat abort 'Unsupported file format.' rescue WavefrontCli::Exception::UnsupportedOperation => e abort "Unsupported operation.\n#{e.}" rescue WavefrontCli::Exception::UnsupportedOutput => e abort e. rescue WavefrontCli::Exception::UnsupportedNoop abort 'Multiple API call operations cannot be performed as no-ops.' rescue WavefrontCli::Exception::UserGroupNotFound => e abort "Cannot find user group '#{e.}'." rescue Wavefront::Exception::UnsupportedWriter => e abort "Unsupported writer '#{e.}'." rescue WavefrontCli::Exception::UserError => e abort "User error: #{e.}." rescue WavefrontCli::Exception::ImpossibleSearch abort 'Search on non-existent key. Please use a top-level field.' rescue StandardError => e warn "general error: #{e}" (e) abort end |
#sanitize_keys(options) ⇒ Object
Symbolize, and remove dashes from option keys
return [Hash] h with modified keys
234 235 236 237 238 |
# File 'lib/wavefront-cli/controller.rb', line 234 def sanitize_keys() .each_with_object({}) do |(k, v), r| r[k.to_s.delete('-').to_sym] = v end end |