require 'active_support/core_ext' require 'shell' class OptBuilder class_attribute :single_opts class_attribute :collection_opts self.single_opts = [] self.collection_opts = [] def self.inherited(sub) sub.single_opts = [] sub.collection_opts = [] end def self.map_with_single_opts(&block) result = self.single_opts.map do |config| yield config end result += self.superclass.map_with_single_opts(&block) if (self.superclass.respond_to? :map_with_single_opts) result end def self.map_with_collection_opts(&block) result = self.collection_opts.map do |config| yield config end result += self.superclass.map_with_collection_opts(&block) if (self.superclass.respond_to? :map_with_single_opts) result end def self.single(sym,opts={}) attr_writer sym self.single_opts << { :sym => sym, :alias_for => opts[:alias_for] || sym.to_s.dasherize } self.class_eval do define_method sym do result = self.send(:instance_variable_get,"@#{sym.to_s}") result = opts[:default] if result.nil? result end end end def self.collection(sym,opts={}) attr_writer sym self.collection_opts << { :sym => sym, :force_restart => opts[:force_restart], :alias_for => opts[:alias_for] || sym.to_s.dasherize } self.class_eval do define_method sym do value = self.send(:instance_variable_get,"@#{sym.to_s}") || [] self.send(:instance_variable_set,"@#{sym.to_s}", value) value end end end def value_as_option_value(value) return value_array_as_option_value(value) if value.is_a? Array Shell.escape value end def value_array_as_option_value(value_array) ary = value_array.map do |value| value_as_option_value(value) end ary.join " " end def to_s opts = self.class.map_with_single_opts do |config| sym = config[:sym] "-#{config[:alias_for]}=#{value_as_option_value(send(sym))}" unless send(sym).nil? end opts += self.class.map_with_collection_opts do |hash| sym = hash[:sym]; restart = hash[:force_restart] add_char = "" send(sym).map do |value| add_char = "+" unless restart restart = false if restart "-#{hash[:alias_for]}#{add_char}=#{value_as_option_value(value)}" unless send(sym).nil? end end opts.flatten.reject{ |item| item.nil? }.join " " end end