lib/sfn/config.rb in sfn-1.1.16 vs lib/sfn/config.rb in sfn-1.2.0

- old
+ new

@@ -4,10 +4,37 @@ module Sfn # Top level configuration class Config < Bogo::Config + # Override attribute helper to detect Hash types and automatically + # add type conversion for CLI provided values + description update + # + # @param name [String, Symbol] name of attribute + # @param type [Class, Array<Class>] valid types + # @param info [Hash] attribute information + # @return [Hash] + def self.attribute(name, type, info=Smash.new) + if([type].flatten.any?{|t| t.ancestors.include?(Hash)}) + unless(info[:coerce]) + info[:coerce] = lambda do |v| + case v + when String + Smash[v.split(',').map{|x| v.split(/[=:]/, 2)}] + when Hash + v.to_smash + else + v + end + end + info[:description] ||= '' + info[:description] << ' (Key:Value[,Key:Value,...])' + end + end + super(name, type, info) + end + # Only values allowed designating bool type BOOLEAN_VALUES = [TrueClass, FalseClass] autoload :Conf, 'sfn/config/conf' autoload :Create, 'sfn/config/create' @@ -25,49 +52,46 @@ autoload :Update, 'sfn/config/update' autoload :Validate, 'sfn/config/validate' attribute( :config, String, - :description => 'Configuration file path' + :description => 'Configuration file path', + :short_flag => 'c' ) attribute( :credentials, Smash, - :coerce => proc{|v| - case v - when String - Smash[v.split(',').map{|x| v.split(/[=:]/, 2)}] - when Hash - v.to_smash - else - v - end - }, - :description => 'Provider credentials' + :description => 'Provider credentials', + :short_flag => 'C' ) attribute( :ignore_parameters, String, :multiple => true, - :description => 'Parameters to ignore during modifications' + :description => 'Parameters to ignore during modifications', + :short_flag => 'i' ) attribute( :interactive_parameters, [TrueClass, FalseClass], :default => true, - :description => 'Prompt for template parameters' + :description => 'Prompt for template parameters', + :short_flag => 'I' ) attribute( :poll, [TrueClass, FalseClass], :default => true, - :description => 'Poll stack events on modification actions' + :description => 'Poll stack events on modification actions', + :short_flag => 'p' ) attribute( :defaults, [TrueClass, FalseClass], - :description => 'Automatically accept default values' + :description => 'Automatically accept default values', + :short_flag => 'd' ) attribute( :yes, [TrueClass, FalseClass], - :description => 'Automatically accept any requests for confirmation' + :description => 'Automatically accept any requests for confirmation', + :short_flag => 'y' ) attribute :conf, Conf, :coerce => proc{|v| Conf.new(v)} attribute :create, Create, :coerce => proc{|v| Create.new(v)} attribute :update, Update, :coerce => proc{|v| Update.new(v)} @@ -101,11 +125,12 @@ if(a.ancestors.include?(Bogo::Config) && !a.attributes.empty?) a.attributes end end.compact.reverse.inject(Smash.new){|m, n| m.deep_merge(n)}.map do |name, info| next unless info[:description] - short = name.chars.zip(name.chars.map(&:upcase)).flatten.detect do |c| - !shorts.include?(c) + short = info[:short_flag] + if(!short.to_s.empty? && shorts.include?(short)) + raise ArgumentError.new "Short flag already in use! (`#{short}` not available for `#{klass}`)" end shorts << short info[:short] = short info[:long] = name.tr('_', '-') info[:boolean] = [info[:type]].compact.flatten.all?{|t| BOOLEAN_VALUES.include?(t)}