Module: Aspera::Yaml
- Defined in:
- lib/aspera/yaml.rb
Class Method Summary collapse
-
.find_duplicate_keys(node, parent_path = nil, duplicate_keys = nil) ⇒ Array<String>
List of duplicate keys with their paths and occurrences.
-
.safe_load(yaml) ⇒ Object
Safely load YAML content raising an error if duplicate keys are found Validates the yaml, and then call
YAML.safe_load.
Class Method Details
.find_duplicate_keys(node, parent_path = nil, duplicate_keys = nil) ⇒ Array<String>
Returns List of duplicate keys with their paths and occurrences.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/aspera/yaml.rb', line 11 def find_duplicate_keys(node, parent_path = nil, duplicate_keys = nil) duplicate_keys ||= [] parent_path ||= [] return duplicate_keys unless node.respond_to?(:children) if node.is_a?(Psych::Nodes::Mapping) counts = Hash.new(0) key_nodes = Hash.new{ |h, k| h[k] = []} node.children.each_slice(2) do |key_node, value_node| if key_node&.value counts[key_node.value] += 1 key_nodes[key_node.value] << key_node find_duplicate_keys(value_node, parent_path + [key_node.value], duplicate_keys) end end counts.each do |key_str, count| next if count <= 1 path = (parent_path + [key_str]).join('.') occurrences = key_nodes[key_str].map{ |kn| kn.start_line ? kn.start_line + 1 : 'unknown'}.join(', ') duplicate_keys << "#{path}: #{occurrences}" end else node.children.to_a.each{ |child| find_duplicate_keys(child, parent_path, duplicate_keys)} end duplicate_keys end |
.safe_load(yaml) ⇒ Object
Safely load YAML content
raising an error if duplicate keys are found
Validates the yaml, and then call YAML.safe_load
43 44 45 46 47 |
# File 'lib/aspera/yaml.rb', line 43 def safe_load(yaml) duplicate_keys = find_duplicate_keys(Psych.parse_stream(yaml)) raise "Duplicate keys: #{duplicate_keys.join('; ')}" unless duplicate_keys.empty? YAML.safe_load(yaml, permitted_classes: [Time, Date, Symbol]) end |