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



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

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("  %-18s %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



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

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.



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

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.



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

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
66
67
# 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::DocoptLanguageError => e
    abort "mangled command description:\n#{e.message}"
  rescue Docopt::Exit => e
    abort e.message
  end
end

#parse_opts(o) ⇒ Object



69
70
71
# File 'lib/wavefront-cli/controller.rb', line 69

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

#run_command(hook) ⇒ Object



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

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



133
134
135
# File 'lib/wavefront-cli/controller.rb', line 133

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