lib/chamber/settings.rb in chamber-1.0.3 vs lib/chamber/settings.rb in chamber-2.0.0

- old
+ new

@@ -1,20 +1,36 @@ require 'hashie/mash' require 'chamber/system_environment' require 'chamber/namespace_set' +require 'chamber/filters/namespace_filter' +require 'chamber/filters/encryption_filter' +require 'chamber/filters/decryption_filter' +require 'chamber/filters/environment_filter' +require 'chamber/filters/boolean_conversion_filter' +require 'chamber/filters/secure_filter' ### # Internal: Represents the base settings storage needed for Chamber. # -class Chamber +module Chamber class Settings attr_reader :namespaces def initialize(options = {}) - self.namespaces = options.fetch(:namespaces, NamespaceSet.new) - self.data = options.fetch(:settings, Hashie::Mash.new) + self.namespaces = options[:namespaces] || [] + self.raw_data = options[:settings] || {} + self.decryption_key = options[:decryption_key] + self.encryption_key = options[:encryption_key] + self.pre_filters = options[:pre_filters] || [ + Filters::NamespaceFilter, + ] + self.post_filters = options[:post_filters] || [ + Filters::DecryptionFilter, + Filters::EnvironmentFilter, + Filters::BooleanConversionFilter, + ] end ### # Internal: Converts a Settings object into a hash that is compatible as an # environment variable hash. @@ -66,87 +82,132 @@ ### # Internal: Merges a Settings object with another Settings object or # a hash-like object. # - # Also, if merging Settings, it will merge the namespaces as well. + # Also, if merging Settings, it will merge all other Settings data as well. # # Example: # # settings = Settings.new settings: { my_setting: 'my value' } # other_settings = Settings.new settings: { my_other_setting: 'my other value' } # - # settings.merge! other_settings + # settings.merge other_settings # # settings # # => { # 'my_setting' => 'my value', # 'my_other_setting' => 'my other value', # } # + # Returns a new Settings object + # + def merge(other) + other_settings = if other.is_a? Settings + other + elsif other.is_a? Hash + Settings.new(settings: other) + end + + Settings.new( + encryption_key: encryption_key || other_settings.encryption_key, + decryption_key: decryption_key || other_settings.decryption_key, + namespaces: (namespaces + other_settings.namespaces), + settings: raw_data.merge(other_settings.raw_data)) + end + + ### + # Internal: Returns the Settings data as a Hash for easy manipulation. + # Changes made to the hash will *not* be reflected in the original Settings + # object. + # # Returns a Hash # - def merge!(other) - self.data = data.merge(other.to_hash) - self.namespaces = (namespaces + other.namespaces) if other.respond_to? :namespaces + def to_hash + data.to_hash end + ### + # Internal: Determines whether a Settings is equal to another hash-like + # object. + # + # Returns a Boolean + # + def ==(other) + self.to_hash == other.to_hash + end + + ### + # Internal: Determines whether a Settings is equal to another Settings. + # + # Returns a Boolean + # def eql?(other) other.is_a?( Chamber::Settings) && self.data == other.data && self.namespaces == other.namespaces end - def to_hash - data + def secured + Settings.new( metadata.merge( + settings: raw_data, + pre_filters: [Filters::SecureFilter])) end - def method_missing(name, *args) - return data.public_send(name, *args) if data.respond_to?(name) - - super + def secure + Settings.new( metadata.merge( + settings: @raw_data, + pre_filters: [Filters::EncryptionFilter], + post_filters: [] )) end - def respond_to_missing?(name, include_private = false) - data.respond_to?(name, include_private) - end - protected - attr_reader :raw_data - attr_writer :namespaces + attr_accessor :pre_filters, + :post_filters, + :encryption_key, + :decryption_key, + :raw_data - def data - @data ||= Hashie::Mash.new + def raw_data=(new_raw_data) + @raw_data = Hashie::Mash.new(new_raw_data) end - def data=(raw_data) - @raw_data = Hashie::Mash.new(raw_data) + def namespaces=(raw_namespaces) + @namespaces = NamespaceSet.new(raw_namespaces) + end - namespace_checked_data = if data_is_namespaced? - namespace_filtered_data - else - self.raw_data - end + def raw_data + @filtered_raw_data ||= pre_filters.reduce(@raw_data) do |filtered_data, filter| + filter.execute({data: filtered_data}. + merge(metadata)) + end + end - @data = SystemEnvironment.inject_into(namespace_checked_data) + def data + @data ||= post_filters.reduce(raw_data) do |filtered_data, filter| + filter.execute({data: filtered_data}. + merge(metadata)) + end end - private - - def data_is_namespaced? - @data_is_namespaced ||= raw_data.keys.any? { |key| namespaces.include? key } + def metadata + { + namespaces: self.namespaces, + decryption_key: self.decryption_key, + encryption_key: self.encryption_key, + } end - def namespace_filtered_data - @namespace_filtered_data ||= -> do - data = Hashie::Mash.new + public - namespaces.each do |namespace| - data.merge!(raw_data[namespace]) if raw_data[namespace] - end + def method_missing(name, *args) + return data.public_send(name, *args) if data.respond_to?(name) - data - end.call + super + end + + def respond_to_missing?(name, include_private = false) + data.respond_to?(name, include_private) end end end