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.



21
22
23
24
25
26
27
28
29
30
# File 'lib/wavefront-cli/controller.rb', line 21

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

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



19
20
21
# File 'lib/wavefront-cli/controller.rb', line 19

def args
  @args
end

#cmdsObject (readonly)

Returns the value of attribute cmds.



19
20
21
# File 'lib/wavefront-cli/controller.rb', line 19

def cmds
  @cmds
end

#optsObject (readonly)

Returns the value of attribute opts.



19
20
21
# File 'lib/wavefront-cli/controller.rb', line 19

def opts
  @opts
end

#twObject (readonly)

Returns the value of attribute tw.



19
20
21
# File 'lib/wavefront-cli/controller.rb', line 19

def tw
  @tw
end

#usageObject (readonly)

Returns the value of attribute usage.



19
20
21
# File 'lib/wavefront-cli/controller.rb', line 19

def usage
  @usage
end

Instance Method Details

#conf_filePathname

The default config file path.

Returns:

  • (Pathname)

    where we excpect to find a config file



118
119
120
121
122
123
124
# File 'lib/wavefront-cli/controller.rb', line 118

def conf_file
  if ENV['HOME']
    Pathname.new(ENV['HOME']) + '.wavefront'
  else
    Pathname.new('/etc/wavefront/client.conf')
  end
end

#default_helpObject

What you see when you do ‘wavefront –help’



34
35
36
37
38
39
40
# File 'lib/wavefront-cli/controller.rb', line 34

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("  %-15s %s\n", k, v.description) }
  s.<< "\nUse '#{CMD} <command> --help' for further information.\n"
end

#docopt_hashObject

Make a hash of command descriptions for docopt.



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

def docopt_hash
  cmds.each_with_object(default: default_help) do |(k, v), ret|
    ret[k.to_sym] = v.docopt
  end
end

#import_command(f) ⇒ 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



107
108
109
110
111
112
# File 'lib/wavefront-cli/controller.rb', line 107

def import_command(f)
  return if f.extname != '.rb' || f.basename.to_s == 'base.rb'
  k_name = f.basename.to_s[0..-4]
  require(CMD_DIR + k_name)
  Object.const_get("WavefrontCommand#{k_name.capitalize}").new
end

#load_commandsObject

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



95
96
97
98
99
100
# File 'lib/wavefront-cli/controller.rb', line 95

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

#load_sdk(cmd, opts) ⇒ Object

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



73
74
75
76
77
78
79
80
# File 'lib/wavefront-cli/controller.rb', line 73

def load_sdk(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.'
rescue => e
  p e
end

#parse_argsObject

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



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/wavefront-cli/controller.rb', line 53

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::Exit => e
    abort e.message
  end
end

#parse_opts(o) ⇒ Object



67
68
69
# File 'lib/wavefront-cli/controller.rb', line 67

def parse_opts(o)
  WavefrontCli::OptHandler.new(conf_file, o).opts
end

#run_command(hook) ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'lib/wavefront-cli/controller.rb', line 82

def run_command(hook)
  hook.validate_opts
  hook.run
rescue => e
  $stderr.puts "general error: #{e}"
  $stderr.puts "re-run with '-D' for stack trace." unless opts[:debug]
  $stderr.puts "Backtrace:\n\t#{e.backtrace.join("\n\t")}" if opts[:debug]
  abort
end

#sanitize_keys(h) ⇒ Object

Symbolize, and remove dashes from option keys

return [Hash] h with modified keys

Parameters:

  • h (Hash)

    options hash



131
132
133
# File 'lib/wavefront-cli/controller.rb', line 131

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