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)}