Module: Af::OptionParser::Dsl
- Defined in:
- lib/fiksu-af/option_parser/dsl.rb
Overview
Utility base class for executing Ruby scripts on the command line. Provides methods to define, gather, parse and cast command line options. Options are stored as class instance variables.
Constant Summary collapse
- @@opt_group_stack =
Class methods ###
[]
Instance Method Summary collapse
-
#opt(long_name, *extra_stuff, &b) ⇒ Object
Declare a command line option switch.
- #opt_check(var_name, *extra_stuff, &b) ⇒ Object
- #opt_error(text) ⇒ Object
- #opt_get_top_of_stack ⇒ Object
-
#opt_group(group_name, *extra_stuff) ⇒ Object
Declare a command line options group.
- #opt_select(var_name, *extra_stuff, &b) ⇒ Object
- #usage ⇒ Object
Instance Method Details
#opt(long_name, *extra_stuff, &b) ⇒ Object
Declare a command line option switch.
Arguments
* long_name - long version of the switch
* extra_stuff - hash with the following possible keys:
:type - (:option_type) the OptionType
:argument - (:requirements) is a parameter value requied (valid values: :required, :optional, :none)
:short - (:short_name) the single letter used for this option (i.e., :e = '-e')
:argument_note - used in --? as the typename of the parameter (e.g. ENGLISH_WORD)
:note - used in --? as the help text
:environment_variable - the name of the environment variable associated with this switch
:default - (:default_value) the default value of the parameter
:method - (:evaluation_method) called to evaluate argument: lambda{|argument,option| ... }
:group - (:option_group_name) name of group
:hidden - should option only be shown in --?
:disabled - (default: false)
:choices - array of valid choices, e.g: [:blue, :green, :red]
:set - (:value_to_set_target_variable) value to set if option specified (use for switches where --blue means set @color = 'blue')
:no_accessor - (:do_not_create_accessor) don't class_eval 'attr_accessor :#{target_variable}'
:var - (:target_variable) name of instance variable to set
:target_container - name of object to set instance value
:containing_class - name of class path for this option (for: af_opt_class_path)
if block is passed it is used as :method
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 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 180 181 182 183 184 185 186 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/fiksu-af/option_parser/dsl.rb', line 86 def opt(long_name, *extra_stuff, &b) factory_hash = opt_get_top_of_stack # Ensure long name is in the proper string format. long_name = long_name.to_s unless long_name.starts_with? "--" long_name = "--#{long_name.gsub(/_/,'-')}" end factory_hash[:var] = long_name[2..-1].gsub(/-/, '_').gsub(/[^0-9a-zA-Z]/, '_') # Create hash for processed options. maybe_hash = extra_stuff[-1] if maybe_hash.is_a? Hash # if maybe_hash is a Hash, then the rest of extra_stuff is an array, which # is expected to be: # NOTE (String) # or: # TYPE (Symbol) # or: # REQUIREMENT (Symbol) extra_stuff.pop factory_hash.merge! maybe_hash end # Iterate through and process all of the other arguments. while extra_stuff.length > 0 extra = extra_stuff.shift if extra.is_a? Symbol if [:required, :optional, :none].include? extra factory_hash[:argument] = extra elsif OptionType.valid_option_type_names.include? extra factory_hash[:type] = extra else raise MisconfiguredOptionError.new("#{long_name}: extra options: #{extra.inspect} are not understood") end elsif extra.is_a? String factory_hash[:note] = extra else raise MisconfiguredOptionError.new("#{long_name}: extra options: #{extra.inspect} are not understood") end end unless factory_hash[:type] # If we are not just setting a switch, then we can use the default value # and assume this switch has a required argument. if factory_hash[:default].present? && factory_hash[:set].nil? type = OptionType.find_by_value(factory_hash[:default]).try(:short_name) factory_hash[:type] = type unless type.nil? end end # Determine argument requirement type. factory_hash[:argument] = if factory_hash[:argument] == :required ::Af::OptionParser::GetOptions::REQUIRED_ARGUMENT elsif factory_hash[:argument] == :none ::Af::OptionParser::GetOptions::NO_ARGUMENT elsif factory_hash[:argument] == :optional ::Af::OptionParser::GetOptions::OPTIONAL_ARGUMENT elsif factory_hash[:argument] == nil if factory_hash[:type] if factory_hash[:type] == :switch ::Af::OptionParser::GetOptions::OPTIONAL_ARGUMENT else ::Af::OptionParser::GetOptions::REQUIRED_ARGUMENT end else factory_hash[:type] = :switch ::Af::OptionParser::GetOptions::OPTIONAL_ARGUMENT end else factory_hash[:argument] end # Determine argument type if it is not explictly given unless factory_hash[:type] if factory_hash[:set] type = OptionType.find_by_value(factory_hash[:set]).try(:short_name) factory_hash[:type] = type unless type.nil? end end # Add the switch to the store, along with all of it's options. if factory_hash[:short] short = factory_hash[:short].to_s unless short[0] == '-' short = "-#{short}" end factory_hash[:short] = short end if factory_hash[:type] type = OptionType.find_by_short_name(factory_hash[:type]) raise MisconfiguredOptionError.new("#{long_name}: option type #{factory_hash[:type].inspect} is not recognized. " + "(valid option types: #{OptionType.valid_option_type_names.join(', ')})") unless type factory_hash[:type] = type end factory_hash[:method] = b if b unless factory_hash[:argument_note] unless type.argument_note.blank? factory_hash[:argument_note] = type.argument_note end end # rename keys in factory hash from the UI names to the API names { env: :environment_variable, default: :default_value, type: :option_type, var: :target_variable, set: :value_to_set_target_variable, no_accessor: :do_not_create_accessor, group: :option_group_name, short: :short_name, method: :evaluation_method, argument: :requirements }.each do |current_key_name, new_key_name| if factory_hash.has_key? current_key_name factory_hash[new_key_name] = factory_hash.delete(current_key_name) end end # Add long_name to OptionStore if it's not present. Otherwise, retrieve the value # associated with that key and merge the value into factory_hash OptionStore.factory(factory_hash[:containing_class] || self).get_option(long_name).merge!(factory_hash) end |
#opt_check(var_name, *extra_stuff, &b) ⇒ Object
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/fiksu-af/option_parser/dsl.rb', line 215 def opt_check(var_name, *extra_stuff, &b) factory_hash = {} factory_hash[:target_variable] = var_name[0..-1] # Set the target_container when using an application component if extra_stuff[0][:target_container].present? factory_hash[:target_container] = extra_stuff[0][:target_container] end if extra_stuff[-1].is_a? Hash action, targets = extra_stuff[-1].flatten if [:requires, :excludes].include?(action) factory_hash[:action] = action if targets.is_a? Array factory_hash[:targets] = targets else raise MisconfiguredOptionError.new("#{var_name}: check targets '#{targets.inspect}' must be Array") end raise MisconfiguredOptionError.new("#{var_name}: check action '#{action}' given block") unless b.nil? elsif action == :check raise MisconfiguredOptionError.new("#{var_name}: check action '#{action}' requires block") if b.nil? factory_hash[:block] = b else raise MisconfiguredOptionError.new("unknown check action '#{action}' for #{var_name}") end else raise MisconfiguredOptionError.new("check: #{var_name} must be given a hash") end # Add var_name to OptionStore if it's not present. Otherwise, retrieve the value # associated with that key and merge the value into factory_hash OptionStore.factory(self).get_option_check(var_name).merge!(factory_hash) end |
#opt_error(text) ⇒ Object
282 283 284 285 |
# File 'lib/fiksu-af/option_parser/dsl.rb', line 282 def opt_error(text) puts "ERROR: #{text} (--? for help)" exit 1 end |
#opt_get_top_of_stack ⇒ Object
9 10 11 |
# File 'lib/fiksu-af/option_parser/dsl.rb', line 9 def opt_get_top_of_stack return (@@opt_group_stack[-1] || {}).clone end |
#opt_group(group_name, *extra_stuff) ⇒ Object
Declare a command line options group.
Arguments
* group_name - name of the group
* extra_stuff (Hash)
* :title - display title of the group (optional)
* :description - details about group
* :priority - order to show groups in help --?
* :hidden - true if this group's options should only be seen with --?
* :disabled - (default: false)
* :containing_class - name of class path for this option (for: af_opt_class_path)
* anything else in this hash can be passed to yield block as defaults for other opt/opt_group invocations
* yeilds to block if given with extra_stuff in a global space that opt/opt_group calls use as defaults
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/fiksu-af/option_parser/dsl.rb', line 27 def opt_group(group_name, *extra_stuff) # grab information from our yield scope factory_hash = opt_get_top_of_stack # update factory_hash with information in array area first (left parameters of the dsl) maybe_title = extra_stuff.shift if maybe_title.is_a? String factory_hash[:title] = maybe_title else extra_stuff.unshift(maybe_title) end # then fold in the hash maybe_hash = extra_stuff[-1] || {} if maybe_hash.is_a? Hash factory_hash.merge! maybe_hash end # Add group_name to OptionStore if it's not present. Otherwise, retrieve the value # associated with that key and merge the value into factory_hash OptionStore.factory(self).get_option_group(group_name).merge!(factory_hash) # if a block is given, then let the yielded block # have access to our scoped hash. if block_given? begin @@opt_group_stack.push factory_hash.merge({ group: group_name }) yield ensure @@opt_group_stack.pop end end end |
#opt_select(var_name, *extra_stuff, &b) ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/fiksu-af/option_parser/dsl.rb', line 249 def opt_select(var_name, *extra_stuff, &b) factory_hash = {} factory_hash[:target_variable] = var_name[0..-1] # Set the target_container when using an application component if extra_stuff[0][:target_container].present? factory_hash[:target_container] = extra_stuff[0][:target_container] end if extra_stuff[-1].is_a? Hash action, targets = extra_stuff[-1].flatten if [:one_of, :one_or_more_of, :none_or_one_of].include?(action) factory_hash[:action] = action if targets.is_a? Symbol factory_hash[:targets] = [targets] elsif targets.is_a? Array factory_hash[:targets] = targets else raise MisconfiguredOptionError.new("#{var_name}: select targets '#{targets.inspect}' must be Symbol or Array") end raise MisconfiguredOptionError.new("#{var_name}: select action '#{action}' given block") unless b.nil? else raise MisconfiguredOptionError.new("unknown select action '#{action}' for #{var_name}") end else raise MisconfiguredOptionError.new("select: #{var_name} must be given a hash") end # Add var_name to OptionStore if it's not present. Otherwise, retrieve the value # associated with that key and merge the value into factory_hash OptionStore.factory(self).get_option_select(var_name).merge!(factory_hash) end |
#usage ⇒ Object
287 288 289 |
# File 'lib/fiksu-af/option_parser/dsl.rb', line 287 def usage return "USAGE: rails runner #{self.name}.run [OPTIONS]" end |