lib/pdk/config/namespace.rb in pdk-2.7.1 vs lib/pdk/config/namespace.rb in pdk-3.0.0
- old
+ new
@@ -34,11 +34,11 @@
@persistent_defaults = persistent_defaults
@mounts = {}
@loaded_from_file = false
@read_only = false
- instance_eval(&block) if block_given?
+ instance_eval(&block) if block
end
# Pre-configure a value in the namespace.
#
# Allows you to specify validators and a default value for value in the
@@ -48,11 +48,11 @@
# @param block [Proc] a block that is evaluated within the new [self].
#
# @return [nil]
def setting(key, &block)
@settings[key.to_s] ||= default_setting_class.new(key.to_s, self)
- @settings[key.to_s].instance_eval(&block) if block_given?
+ @settings[key.to_s].instance_eval(&block) if block
end
# Mount a provided [self] (or subclass) into the namespace.
#
# @param key [String,Symbol] the name of the namespace to be mounted.
@@ -64,13 +64,14 @@
# subclass thereof.
#
# @return [self] the mounted namespace.
def mount(key, obj, &block)
raise ArgumentError, 'Only PDK::Config::Namespace objects can be mounted into a namespace' unless obj.is_a?(PDK::Config::Namespace)
+
obj.parent = self
obj.name = key.to_s
- obj.instance_eval(&block) if block_given?
+ obj.instance_eval(&block) if block
@mounts[key.to_s] = obj
end
# Create and mount a new child namespace.
#
@@ -96,13 +97,15 @@
# Check if it's a mount first...
return @mounts[key.to_s] unless @mounts[key.to_s].nil?
# Check if it's a setting, otherwise nil
return nil if settings[key.to_s].nil?
return settings[key.to_s].value unless settings[key.to_s].value.nil?
+
# Duplicate arrays and hashes so that they are isolated from changes being made
default_value = PDK::Util.deep_duplicate(settings[key.to_s].default)
return default_value if default_value.nil? || !@persistent_defaults
+
# Persist the default value
settings[key.to_s].value = default_value
save_data
default_value
end
@@ -123,10 +126,11 @@
def fetch(key, default_value)
# Check if it's a mount first...
return @mounts[key.to_s] unless @mounts[key.to_s].nil?
# Check if it's a setting, otherwise default_value
return default_value if settings[key.to_s].nil?
+
# Check if has a value, otherwise default_value
settings[key.to_s].value.nil? ? default_value : settings[key.to_s].value
end
# After the value has been set in memory, the value will then be
@@ -137,10 +141,11 @@
#
# @return [nil]
def []=(key, value)
# You can't set the value of a mount
raise ArgumentError, 'Namespace mounts can not be set a value' unless @mounts[key.to_s].nil?
+
set_volatile_value(key, value)
# Persist the change
save_data
end
@@ -155,29 +160,29 @@
# should be persisted to disk.
def to_h
new_hash = {}
settings.each_pair { |k, v| new_hash[k] = v.value }
@mounts.each_pair { |k, mount_point| new_hash[k] = mount_point.to_h if mount_point.include_in_parent? }
- new_hash.delete_if { |_, v| v.nil? }
+ new_hash.delete_if { |_k, v| v.nil? } # rubocop :disable Style/CollectionCompact
new_hash
end
# Resolves all filtered settings, including child namespaces, fully namespaced and filling in default values.
#
# @param filter [String] Only resolve setting names which match the filter. See #be_resolved? for matching rules
# @return [Hash{String => Object}] All resolved settings for example {'user.module_defaults.author' => 'johndoe'}
def resolve(filter = nil)
resolved = {}
# Resolve the settings
- settings.values.each do |setting|
+ settings.each_value do |setting|
setting_name = setting.qualified_name
if be_resolved?(setting_name, filter)
resolved[setting_name] = setting.value.nil? ? setting.default : setting.value
end
end
# Resolve the mounts
- @mounts.values.each { |mount| resolved.merge!(mount.resolve(filter)) }
+ @mounts.each_value { |mount| resolved.merge!(mount.resolve(filter)) }
resolved
end
# @return [Boolean] true if the namespace has a parent, otherwise false.
def child_namespace?
@@ -237,11 +242,12 @@
# @param filter [String] The filter used to test on the name.
# @return [Boolean] Whether the name passes the filter.
def be_resolved?(name, filter = nil)
return true if filter.nil? # If we're not filtering, this value should always be resolved
return true if name == filter # If it's exactly the same name then it should be resolved
- name.start_with?(filter + '.') # If name is a subkey of the filter then it should be resolved
+
+ name.start_with?("#{filter}.") # If name is a subkey of the filter then it should be resolved
end
# @abstract Subclass and override {#parse_file} to implement parsing logic
# for a particular config file format.
#
@@ -271,10 +277,11 @@
# writing to disk.
def create_missing_setting(key, initial_value = nil)
# Need to use `@settings` and `@mounts` here to stop recursive calls
return unless @mounts[key.to_s].nil?
return unless @settings[key.to_s].nil?
+
@settings[key.to_s] = default_setting_class.new(key.to_s, self, initial_value)
end
# Set the value of the named key.
#
@@ -284,10 +291,11 @@
# @param key [String,Symbol] the name of the configuration value.
# @param value [Object] the value of the configuration value.
def set_volatile_value(key, value)
# Need to use `settings` here to force the backing file to be loaded
return create_missing_setting(key, value) if settings[key.to_s].nil?
+
# Need to use `@settings` here to stop recursive calls from []=
@settings[key.to_s].value = value
end
# Helper method to read files.
@@ -303,13 +311,11 @@
PDK::Util::Filesystem.read_file(filename)
rescue Errno::ENOENT => e
raise PDK::Config::LoadError, e.message
rescue Errno::EACCES
- raise PDK::Config::LoadError, 'Unable to open %{file} for reading' % {
- file: filename,
- }
+ raise PDK::Config::LoadError, format('Unable to open %{file} for reading', file: filename)
end
# Persist the contents of the namespace to disk.
#
# Directories will be automatically created and the contents of the
@@ -326,23 +332,23 @@
PDK::Util::Filesystem.mkdir_p(File.dirname(file))
PDK::Util::Filesystem.write_file(file, serialize_data(to_h))
rescue Errno::EACCES
- raise PDK::Config::LoadError, 'Unable to open %{file} for writing' % {
- file: file,
- }
+ raise PDK::Config::LoadError, format('Unable to open %{file} for writing', file: file)
rescue SystemCallError => e
raise PDK::Config::LoadError, e.message
end
# Memoised accessor for the loaded data.
#
# @return [Hash<String => PDK::Config::Setting>] the contents of the namespace.
def settings
return @settings if @loaded_from_file
+
@loaded_from_file = true
return @settings if file.nil?
+
parse_file(file) do |key, parsed_setting|
# Create a settings chain if a setting already exists
parsed_setting.previous_setting = @settings[key] unless @settings[key].nil?
@settings[key] = parsed_setting
end