1 2 3 4 5 6 7 8 9 10 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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
# frozen_string_literal: true
# Custom extensions namespace
module Puppet_X # rubocop:disable Style/ClassAndModuleCamelCase
# Elastic helpers
module Elastic
# Utility extension for consistent to_yaml behavior.
module SortedHash
# Upon extension, modify the hash appropriately to render
# sorted yaml dependent upon whichever way is supported for
# this version of Puppet/Ruby's yaml implementation.
def self.extended(base)
if RUBY_VERSION >= '1.9'
# We can sort the hash in Ruby >= 1.9 by recursively
# re-inserting key/values in sorted order. Native to_yaml will
# call .each and get sorted pairs back.
tmp = base.to_a.sort
base.clear
tmp.each do |key, val|
case val
when base.class
val.extend Puppet_X::Elastic::SortedHash
when Array
val.map do |elem|
if elem.is_a? base.class
elem.extend(Puppet_X::Elastic::SortedHash)
else
elem
end
end
end
base[key] = val
end
else
# Otherwise, recurse into the hash to extend all nested
# hashes with the sorted each_pair method.
#
# Ruby < 1.9 doesn't support any notion of sorted hashes,
# so we have to expressly monkey patch each_pair, which is
# called by ZAML (the yaml library used in Puppet < 4; Puppet
# >= 4 deprecates Ruby 1.8)
#
# Note that respond_to? is used here as there were weird
# problems with .class/.is_a?
base.merge! base do |_, ov, _|
if ov.respond_to? :each_pair
ov.extend Puppet_X::Elastic::SortedHash
elsif ov.is_a? Array
ov.map do |elem|
if elem.respond_to? :each_pair
elem.extend Puppet_X::Elastic::SortedHash
else
elem
end
end
else
ov
end
end
end
end
# Override each_pair with a method that yields key/values in
# sorted order.
def each_pair
return to_enum(:each_pair) unless block_given?
keys.sort.each do |key|
yield key, self[key]
end
self
end
end
end
end
|