Class: OctocatalogDiff::Cli::Options
- Inherits:
-
Object
- Object
- OctocatalogDiff::Cli::Options
- Defined in:
- lib/octocatalog-diff/cli/options.rb
Overview
This class contains the option parser. ‘parse_options’ is the external entry point.
Defined Under Namespace
Classes: DocBuildError, Option
Constant Summary collapse
- BANNER =
The usage banner.
'Usage: catalog-diff -n <hostname>[,<hostname>...] [-f <from environment>] [-t <to environment>]'.freeze
Class Method Summary collapse
-
.classes ⇒ Object
List of classes.
-
.option_classes ⇒ Array<Class>
Read in *.rb files in the ‘options’ directory and create classes from them.
-
.option_globally_or_per_branch(opts = {}) ⇒ Object
Sets up options that can be defined globally or for just one branch.
-
.option_globally_or_per_branch_array(opts = {}) ⇒ Object
See description of ‘option_globally_or_per_branch`.
-
.option_globally_or_per_branch_boolean(opts) ⇒ Object
See description of ‘option_globally_or_per_branch`.
-
.option_globally_or_per_branch_string(opts) ⇒ Object
See description of ‘option_globally_or_per_branch`.
-
.parse_options(argv, defaults = {}) ⇒ Hash
Method to call all of the other methods in this class.
-
.post_process(processor, options) ⇒ Object
Code that can run after a translation and operate upon all options.
-
.translate_option(translator, value) ⇒ ?
If a translator was provided, run the translator on the supplied value.
-
.validate_option(opts, value) ⇒ Object
If a validator was provided, run the validator on the supplied value.
Class Method Details
.classes ⇒ Object
List of classes
20 21 22 |
# File 'lib/octocatalog-diff/cli/options.rb', line 20 def self.classes @classes ||= [] end |
.option_classes ⇒ Array<Class>
Read in *.rb files in the ‘options’ directory and create classes from them. Sort the classes according to weight and name and return the list of sorted classes.
83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/octocatalog-diff/cli/options.rb', line 83 def self.option_classes files = Dir.glob(File.join(File.dirname(__FILE__), 'options', '*.rb')) files.each { |file| load file } # Populates self.classes classes.sort do |a, b| [ a.weight <=> b.weight, a.name.downcase <=> b.name.downcase, a.object_id <=> b.object_id ].find(&:nonzero?) end end |
.option_globally_or_per_branch(opts = {}) ⇒ Object
Sets up options that can be defined globally or for just one branch. For example, with a CLI name of ‘puppet-binary’ this will acknowledge 3 options: –puppet-binary (global), –from-puppet-binary (for the from branch only), and –to-puppet-binary (for the to branch only). The only options that will be created are the ‘to’ and ‘from’ variants, but the global option will populate any of the ‘to’ and ‘from’ variants that are missing.
101 102 103 104 105 106 107 108 |
# File 'lib/octocatalog-diff/cli/options.rb', line 101 def self.option_globally_or_per_branch(opts = {}) opts[:filename] = opts[:filename] = caller[0].split(':').first datatype = opts.fetch(:datatype, '') return option_globally_or_per_branch_string(opts) if datatype.is_a?(String) return option_globally_or_per_branch_array(opts) if datatype.is_a?(Array) return option_globally_or_per_branch_boolean(opts) if datatype.is_a?(TrueClass) || datatype.is_a?(FalseClass) raise ArgumentError, "option_globally_or_per_branch not equipped to handle #{datatype.class}" end |
.option_globally_or_per_branch_array(opts = {}) ⇒ Object
See description of ‘option_globally_or_per_branch`. This implements the logic for an array.
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/octocatalog-diff/cli/options.rb', line 151 def self.option_globally_or_per_branch_array(opts = {}) parser = opts.fetch(:parser) = opts.fetch(:options) cli_name = opts.fetch(:cli_name) option_name = opts.fetch(:option_name) desc = opts.fetch(:desc) flag = "#{cli_name} STRING1[,STRING2[,...]]" from_option = "from_#{option_name}".to_sym to_option = "to_#{option_name}".to_sym parser.on("--#{flag}", Array, "#{desc} globally") do |x| validate_option(opts, x) translated = translate_option(opts[:translator], x) [to_option] ||= [] [to_option].concat translated [from_option] ||= [] [from_option].concat translated end parser.on("--to-#{flag}", Array, "#{desc} for the to branch") do |x| validate_option(opts, x) [to_option] ||= [] [to_option].concat translate_option(opts[:translator], x) end parser.on("--from-#{flag}", Array, "#{desc} for the from branch") do |x| validate_option(opts, x) [from_option] ||= [] [from_option].concat translate_option(opts[:translator], x) end end |
.option_globally_or_per_branch_boolean(opts) ⇒ Object
See description of ‘option_globally_or_per_branch`. This implements the logic for a boolean value.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/octocatalog-diff/cli/options.rb', line 187 def self.option_globally_or_per_branch_boolean(opts) parser = opts.fetch(:parser) = opts.fetch(:options) cli_name = opts.fetch(:cli_name) option_name = opts.fetch(:option_name) desc = opts.fetch(:desc) flag = cli_name from_option = "from_#{option_name}".to_sym to_option = "to_#{option_name}".to_sym parser.on("--[no-]#{flag}", "#{desc} globally") do |x| translated = translate_option(opts[:translator], x) [to_option] = translated [from_option] = translated post_process(opts[:post_process], ) end parser.on("--[no-]to-#{flag}", "#{desc} for the to branch") do |x| translated = translate_option(opts[:translator], x) [to_option] = translated post_process(opts[:post_process], ) end parser.on("--[no-]from-#{flag}", "#{desc} for the from branch") do |x| translated = translate_option(opts[:translator], x) [from_option] = translated post_process(opts[:post_process], ) end end |
.option_globally_or_per_branch_string(opts) ⇒ Object
See description of ‘option_globally_or_per_branch`. This implements the logic for a string value.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/octocatalog-diff/cli/options.rb', line 116 def self.option_globally_or_per_branch_string(opts) parser = opts.fetch(:parser) = opts.fetch(:options) cli_name = opts.fetch(:cli_name) option_name = opts.fetch(:option_name) desc = opts.fetch(:desc) flag = "#{cli_name} STRING" from_option = "from_#{option_name}".to_sym to_option = "to_#{option_name}".to_sym parser.on("--#{flag}", "#{desc} globally") do |x| validate_option(opts, x) translated = translate_option(opts[:translator], x) [to_option] ||= translated [from_option] ||= translated post_process(opts[:post_process], ) end parser.on("--to-#{flag}", "#{desc} for the to branch") do |x| validate_option(opts, x) [to_option] = translate_option(opts[:translator], x) post_process(opts[:post_process], ) end parser.on("--from-#{flag}", "#{desc} for the from branch") do |x| validate_option(opts, x) [from_option] = translate_option(opts[:translator], x) post_process(opts[:post_process], ) end end |
.parse_options(argv, defaults = {}) ⇒ Hash
Method to call all of the other methods in this class. Except in very specific circumstances, this should be the method called from outside of this class.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/octocatalog-diff/cli/options.rb', line 63 def self.(argv, defaults = {}) = defaults.dup Options.classes.clear ::OptionParser.new do |parser| parser. = "#{BANNER}\n\n" option_classes.each do |klass| obj = klass.new obj.parse(parser, ) end parser.on_tail('-v', '--version', 'Show version information about this program and quit.') do puts "octocatalog-diff #{OctocatalogDiff::Version::VERSION}" exit end end.parse! argv end |
.post_process(processor, options) ⇒ Object
Code that can run after a translation and operate upon all options. This returns nothing but may modify options that were input.
245 246 247 248 |
# File 'lib/octocatalog-diff/cli/options.rb', line 245 def self.post_process(processor, ) return if processor.nil? processor.call() end |
.translate_option(translator, value) ⇒ ?
If a translator was provided, run the translator on the supplied value. The translator is expected to return the data type needed for the option (typically a String but can really be anything). Note that the translator runs after the validator if both a validator and translator are supplied.
236 237 238 239 |
# File 'lib/octocatalog-diff/cli/options.rb', line 236 def self.translate_option(translator, value) return value if translator.nil? translator.call(value) end |
.validate_option(opts, value) ⇒ Object
If a validator was provided, run the validator on the supplied value. The validator is expected to throw an error if there is a problem. Note that the validator runs before the translator if both a validator and translator are supplied.
220 221 222 223 224 225 226 227 228 |
# File 'lib/octocatalog-diff/cli/options.rb', line 220 def self.validate_option(opts, value) # Special value to help build documentation automatically, since the source file location # for `option_globally_or_per_branch` is always this file. raise DocBuildError, opts[:filename] if value == :DOC_BUILD_FILENAME validator = opts[:validator] return true unless validator validator.call(value) end |