rzo 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,123 @@
1
+ module Rzo
2
+ ##
3
+ # Mix-in module to handle all option parsing. Options will be accessible from
4
+ # the `opts` method. This module is meant to be included in an App class.
5
+ module OptionParsing
6
+ attr_reader :argv, :env, :opts
7
+
8
+ ##
9
+ # Reset the @opts instance variable by parsing @argv and @env. Operates
10
+ # against duplicate copies of the argument vector avoid side effects.
11
+ #
12
+ # @return [Hash<Symbol, String>] Options hash
13
+ def reset_options!
14
+ @opts = parse_options(argv, env)
15
+ end
16
+
17
+ ##
18
+ # Parse options using the argument vector and the environment hash as
19
+ # input. Option parsing occurs in two phases, first the global options are
20
+ # parsed. These are the options specified before the subcommand. The
21
+ # subcommand, if any, is matched, and subcommand specific options are then
22
+ # parsed from the remainder of the argument vector.
23
+ #
24
+ # @param [Array] argv The argument vector, passed to the option parser.
25
+ #
26
+ # @param [Hash] env The environment hash, passed to the option parser to
27
+ # supply defaults not specified on the command line argument vector.
28
+ #
29
+ # @return [Hash<Symbol, String>] options hash
30
+ def parse_options(argv, env)
31
+ argv_copy = argv.dup
32
+ opts = parse_global_options!(argv_copy, env)
33
+ if subcommand = parse_subcommand!(argv_copy)
34
+ opts[:subcommand] = subcommand
35
+ sub_opts = parse_subcommand_options!(subcommand, argv_copy, env)
36
+ opts.merge!(sub_opts)
37
+ end
38
+ opts
39
+ end
40
+
41
+ ##
42
+ # Parse out the global options, the ones specified between the main
43
+ # executable and the subcommand argument.
44
+ #
45
+ # Modifies argv as a side effect, shifting elements from the array until
46
+ # the first unknown option is found, which is assumed to be the subcommand
47
+ # name.
48
+ #
49
+ # @return [Hash<Symbol, String>] Global options
50
+ # rubocop:disable Metrics/MethodLength
51
+ def parse_global_options!(argv, env)
52
+ semver = Rzo::VERSION
53
+ prog_name = NAME
54
+ Rzo::Trollop.options(argv) do
55
+ stop_on_unknown
56
+ version "#{prog_name} #{semver} (c) 2017 Garrett Honeycutt"
57
+ banner BANNER
58
+ log_msg = 'Log file to write to or keywords '\
59
+ 'STDOUT, STDERR {RZO_LOGTO}'
60
+ opt :logto, log_msg, default: env['RZO_LOGTO'] || 'STDERR'
61
+ opt :syslog, 'Log to syslog', default: false, conflicts: :logto
62
+ opt :verbose, 'Set log level to INFO'
63
+ opt :debug, 'Set log level to DEBUG'
64
+ opt :config, 'Rizzo config file {RZO_CONFIG}',
65
+ default: env['RZO_CONFIG'] || '~/.rizzo.json'
66
+ end
67
+ end
68
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
69
+
70
+ ##
71
+ # Extract the subcommand, if any, from the arguments provided. Modifies
72
+ # argv as a side effect, shifting the subcommand name if it is present.
73
+ #
74
+ # @return [String] The subcommand name, e.g. 'backup' or 'restore', or
75
+ # false if no arguments remain in the argument vector.
76
+ def parse_subcommand!(argv)
77
+ argv.shift || false
78
+ end
79
+
80
+ ##
81
+ # Parse the subcommand options. This method branches out because each
82
+ # subcommand can have quite different options, unlike global options which
83
+ # are consistent across all invocations of the application.
84
+ #
85
+ # Modifies argv as a side effect, shifting all options as things are
86
+ # parsed.
87
+ #
88
+ # @return [Hash<Symbol, String>] Subcommand specific options hash
89
+ # rubocop:disable Metrics/MethodLength
90
+ def parse_subcommand_options!(subcommand, argv, env)
91
+ prog_name = NAME
92
+ case subcommand
93
+ when 'config'
94
+ Rzo::Trollop.options(argv) do
95
+ banner "#{prog_name} #{subcommand} options:"
96
+ opt :output, 'Config output', short: 'o', default: env['RZO_OUTPUT'] || 'STDOUT'
97
+ end
98
+ when 'generate'
99
+ Rzo::Trollop.options(argv) do
100
+ banner "#{prog_name} #{subcommand} options:"
101
+ opt :vagrantfile, 'Output Vagrantfile', short: 'o', default: env['RZO_VAGRANTFILE'] || 'Vagrantfile'
102
+ end
103
+ else
104
+ Rzo::Trollop.die "Unknown subcommand: #{subcommand.inspect}"
105
+ end
106
+ end
107
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
108
+
109
+ # The name of the executable, could be `rizzo` or `rzo`
110
+ NAME = File.basename($PROGRAM_NAME).freeze
111
+
112
+ # rubocop:disable Layout/IndentHeredoc
113
+ BANNER = <<-"EOBANNER".freeze
114
+ usage: #{NAME} [GLOBAL OPTIONS] SUBCOMMAND [ARGS]
115
+ Sub Commands:
116
+
117
+ config Print out the combined rizzo json config
118
+ generate Initialize Vagrantfile in top control repo
119
+
120
+ Global options: (Note, command line arguments supersede ENV vars in {}'s)
121
+ EOBANNER
122
+ end
123
+ end