Class: WavefrontCliController

Inherits:
Object
  • Object
show all
Defined in:
lib/wavefront-cli/controller.rb

Overview

Dynamically generate a CLI interface from files which describe each subcomand.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ WavefrontCliController

Returns a new instance of WavefrontCliController.



27
28
29
30
31
32
33
34
35
36
# File 'lib/wavefront-cli/controller.rb', line 27

def initialize(args)
  @args = args
  @cmds = load_commands
  @usage = docopt_hash
  cmd, opts = parse_args
  @opts = parse_opts(opts)
  pp @opts if @opts[:debug]
  cli_class_obj = load_cli_class(cmd, @opts)
  run_command(cli_class_obj)
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



25
26
27
# File 'lib/wavefront-cli/controller.rb', line 25

def args
  @args
end

#cmdsObject (readonly)

Returns the value of attribute cmds.



25
26
27
# File 'lib/wavefront-cli/controller.rb', line 25

def cmds
  @cmds
end

#optsObject (readonly)

Returns the value of attribute opts.



25
26
27
# File 'lib/wavefront-cli/controller.rb', line 25

def opts
  @opts
end

#twObject (readonly)

Returns the value of attribute tw.



25
26
27
# File 'lib/wavefront-cli/controller.rb', line 25

def tw
  @tw
end

#usageObject (readonly)

Returns the value of attribute usage.



25
26
27
# File 'lib/wavefront-cli/controller.rb', line 25

def usage
  @usage
end

Instance Method Details

#default_helpString

What you see when you do ‘wf –help’

Returns:



41
42
43
44
45
46
47
# File 'lib/wavefront-cli/controller.rb', line 41

def default_help
  s = "Wavefront CLI\n\nUsage:\n  #{CMD} command [options]\n" \
      "  #{CMD} --version\n  #{CMD} --help\n\nCommands:\n"

  cmds.sort.each { |k, v| s.<< format("  %-18s %s\n", k, v.description) }
  s.<< "\nUse '#{CMD} <command> --help' for further information.\n"
end

#docopt_hashHash

Returns command descriptions for docopt.

Returns:

  • (Hash)

    command descriptions for docopt.



51
52
53
54
55
# File 'lib/wavefront-cli/controller.rb', line 51

def docopt_hash
  cmds.each_with_object(default: default_help) do |(k, v), ret|
    ret[k.to_sym] = v.docopt
  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.

Parameters:

  • f (Pathname)

    path of file to load



150
151
152
153
154
155
# File 'lib/wavefront-cli/controller.rb', line 150

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

Get the CLI class we need to run the command we’ve been given.

rubocop:disable Metrics/AbcSize

Parameters:

Returns:

  • WavefrontCli::cmd



88
89
90
91
92
93
94
95
96
97
# File 'lib/wavefront-cli/controller.rb', line 88

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)
rescue WavefrontCli::Exception::UnhandledCommand
  abort 'Fatal error. Unsupported command. Please open a Github issue.'
rescue WavefrontCli::Exception::InvalidInput => e
  abort "Invalid input. #{e.message}"
rescue RuntimeError => e
  abort "Unable to run command. #{e.message}."
end

#load_commandsHash

Each command is defined in its own file. Dynamically load all those commands.

Returns:

  • (Hash)

    :command => CommandClass



138
139
140
141
142
143
# File 'lib/wavefront-cli/controller.rb', line 138

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_argsObject

Parse the input. The first Docopt.docopt handles the default options, the second works on the command.

rubocop:disable Metrics/AbcSize



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/wavefront-cli/controller.rb', line 61

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.message unless usage.keys.include?(cmd)

  begin
    [cmd, sanitize_keys(Docopt.docopt(usage[cmd], argv: args))]
  rescue Docopt::DocoptLanguageError => e
    abort "mangled command description:\n#{e.message}"
  rescue Docopt::Exit => e
    abort e.message
  end
end

#parse_opts(options) ⇒ Object

rubocop:enable Metrics/AbcSize



78
79
80
# File 'lib/wavefront-cli/controller.rb', line 78

def parse_opts(options)
  WavefrontCli::OptHandler.new(options).opts
end

#run_command(cli_class_obj) ⇒ Object

rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/wavefront-cli/controller.rb', line 102

def run_command(cli_class_obj)
  cli_class_obj.validate_opts
  cli_class_obj.run
rescue WavefrontCli::Exception::CredentialError => e
  abort "Credential error. #{e.message}"
rescue WavefrontCli::Exception::UnsupportedOutput => e
  abort e.message
rescue WavefrontCli::Exception::InsufficientData => e
  abort "Insufficient data. #{e.message}"
rescue WavefrontCli::Exception::UnsupportedFileFormat
  abort 'Unsupported file format.'
rescue WavefrontCli::Exception::UnparseableInput => e
  abort "Cannot parse input. #{e.message}"
rescue WavefrontCli::Exception::FileNotFound
  abort 'File not found.'
rescue WavefrontCli::Exception::UnparseableInput
  abort 'Cannot parse input.'
rescue WavefrontCli::Exception::SystemError => e
  abort "Host system error. #{e.message}"
rescue WavefrontCli::Exception::UnsupportedOperation => e
  abort "Unsupported operation.\n#{e.message}"
rescue Wavefront::Exception::UnsupportedWriter => e
  abort "Unsupported writer '#{e.message}'."
rescue StandardError => e
  warn "general error: #{e}"
  warn "re-run with '-D' for stack trace." unless opts[:debug]
  warn "Backtrace:\n\t#{e.backtrace.join("\n\t")}" if opts[:debug]
  abort
end

#sanitize_keys(options) ⇒ Object

Symbolize, and remove dashes from option keys

return [Hash] h with modified keys

Parameters:

  • h (Hash)

    options hash



162
163
164
165
166
# File 'lib/wavefront-cli/controller.rb', line 162

def sanitize_keys(options)
  options.each_with_object({}) do |(k, v), r|
    r[k.to_s.delete('-').to_sym] = v
  end
end