lib/yaml_extend.rb in yaml_extend-0.0.12 vs lib/yaml_extend.rb in yaml_extend-0.1.0
- old
+ new
@@ -1,42 +1,46 @@
-require "yaml_extend/version"
+require 'yaml_extend/version'
require 'yaml'
require 'deep_merge/rails_compat'
+require_relative 'custom_errors/invalid_key_type_error'
+
#
# Extending the YAML library to allow to inherit from another YAML file(s)
#
module YAML
#
# Extended variant of the #load_file method by providing the
# ability to inherit from other YAML file(s)
#
# @param yaml_path [String] the path to the yaml file to be loaded
- # @param inheritance_key [String] the key used in the yaml file to extend from another YAML file
+ # @param inheritance_key [String|Array]
+ # The key used in the yaml file to extend from another YAML file.
+ # Use an Array if you want to use a tree structure key like "options.extends" => ['options','extends']
# @param extend_existing_arrays [Boolean] extend existing arrays instead of replacing them
# @param config [Hash] a hash to be merged into the result, usually only recursivly called by the method itself
#
# @return [Hash] the resulting yaml config
#
def self.ext_load_file(yaml_path, inheritance_key='extends', extend_existing_arrays=true, config = {})
total_config ||= {}
yaml_path = YAML.make_absolute_path yaml_path
super_config = YAML.load_file(File.open(yaml_path))
- super_inheritance_files = super_config[inheritance_key]
- super_config.delete inheritance_key # we don't merge the super inheritance keys into the base yaml
+ super_inheritance_files = yaml_value_by_key inheritance_key, super_config
+ delete_yaml_key inheritance_key, super_config # we don't merge the super inheritance keys into the base yaml
merged_config = config.clone.deeper_merge(super_config, extend_existing_arrays: extend_existing_arrays)
if super_inheritance_files && super_inheritance_files != ''
super_inheritance_files = [super_inheritance_files] unless super_inheritance_files.is_a? Array # we support strings as well as arrays of type string to extend from
super_inheritance_files.each_with_index do |super_inheritance_file, index|
super_config_path = File.dirname(yaml_path) + '/' + super_inheritance_file
total_config = YAML.ext_load_file super_config_path, inheritance_key, extend_existing_arrays, total_config.deeper_merge(merged_config, extend_existing_arrays: extend_existing_arrays)
end
total_config
else
- merged_config.delete(inheritance_key)
+ delete_yaml_key inheritance_key, merged_config
merged_config
end
end
private
@@ -60,6 +64,42 @@
def self.absolute_path?(path)
private_class_method
path.start_with?('/') || # unix like
(path.length >= 3 && path[1] == ':') # ms windows
end
+
+ # Return the value of the corresponding key
+ # @param key [String|Array]
+ def self.yaml_value_by_key(key, config)
+ return config[key] if key.is_a? String
+ if valid_key_type? key
+ cfg_copy = config.clone
+ key.each do |key|
+ if cfg_copy.nil?
+ return
+ elsif valid_key_type? key
+ cfg_copy = cfg_copy[key]
+ end
+ end
+ cfg_copy
+ end
+ end
+
+ def self.valid_key_type?(key)
+ key.is_a?(Array) || key.is_a?(String) ||
+ raise(InvalidKeyTypeError,"Invalid key of type '#{key.class.name}'. Valid types are String and Array.")
+ end
+
+ def self.delete_yaml_key(key, config)
+ return config.delete(key) if key.is_a? String
+ cfg_ref = config
+ last_ref = nil
+ key.each do |key|
+ if valid_key_type?(key) && !cfg_ref[key].nil?
+ last_ref = cfg_ref
+ cfg_ref = cfg_ref[key] unless cfg_ref.nil?
+ end
+ end
+ last_ref.delete key.last unless last_ref.nil?
+ end
+
end