Module: K8s::Util
- Defined in:
- lib/k8s/util.rb
Overview
Miscellaneous helpers
Defined Under Namespace
Modules: HashBackport
Constant Summary collapse
- PATH_TR_MAP =
{ '~' => '~0', '/' => '~1' }.freeze
- PATH_REGEX =
%r{(/|~(?!1))}.freeze
Class Method Summary collapse
-
.compact_map(args) {|args| ... } ⇒ Array<nil, Object>
Yield with all non-nil args, returning matching array with corresponding return values or nils.
-
.deep_merge(input, other, overwrite_arrays: true, union_arrays: false, keep_existing: false, merge_nil_values: false, merge_non_hash: false) ⇒ Object
Deep merge hashes.
-
.deep_transform_keys(value = nil, transform_method = nil, &block) ⇒ Object
Deep transform hash keys or hashes inside arrays.
-
.json_patch(patch_to, patch_from) ⇒ Object
Produces a set of json-patch operations so that applying the operations on a, gives you the results of b Used in correctly patching the Kube resources on stack updates.
-
.recursive_compact(hash_or_array) ⇒ Hash, Array
Recursive compact for Hash/Array.
Class Method Details
.compact_map(args) {|args| ... } ⇒ Array<nil, Object>
Yield with all non-nil args, returning matching array with corresponding return values or nils.
Args must be usable as hash keys. Duplicate args will all map to the same return value.
108 109 110 111 112 113 114 115 116 117 |
# File 'lib/k8s/util.rb', line 108 def self.compact_map(args) func_args = args.compact values = yield func_args # Hash{arg => value} value_map = Hash[func_args.zip(values)] args.map{ |arg| value_map[arg] } end |
.deep_merge(input, other, overwrite_arrays: true, union_arrays: false, keep_existing: false, merge_nil_values: false, merge_non_hash: false) ⇒ Object
Deep merge hashes
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 |
# File 'lib/k8s/util.rb', line 25 def self.deep_merge(input, other, overwrite_arrays: true, union_arrays: false, keep_existing: false, merge_nil_values: false, merge_non_hash: false) raise ArgumentError, "input expected to be Hash, was #{input.class.name}" unless input.is_a?(Hash) raise ArgumentError, "other expected to be Hash, was #{other.class.name}" unless other.is_a?(Hash) input.merge(other) do |key, old_value, new_value| case old_value when Hash raise "#{key} : #{new_value.class.name} can not be merged into a Hash" unless new_value.is_a?(Hash) deep_merge( old_value, new_value, overwrite_arrays: overwrite_arrays, union_arrays: union_arrays, keep_existing: keep_existing, merge_nil_values: merge_nil_values, merge_non_hash: merge_non_hash ) when Array if overwrite_arrays new_value elsif union_arrays raise "#{key} : #{new_value.class.name} can not be merged into an Array" unless new_value.is_a?(Array) old_value | new_value else old_value + new_value end else if keep_existing old_value elsif new_value.nil? && merge_nil_values nil elsif merge_non_hash && old_value.respond_to?(:merge) old_value.merge(new_value) else new_value.nil? ? old_value : new_value end end end end |
.deep_transform_keys(value = nil, transform_method = nil, &block) ⇒ Object
Deep transform hash keys or hashes inside arrays
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/k8s/util.rb', line 80 def self.deep_transform_keys(value = nil, transform_method = nil, &block) case value when Array value.map { |v| deep_transform_keys(v, transform_method, &block) } when Hash {}.tap do |result| value.each do |key, value| new_key = if key.is_a?(String) || key.is_a?(Symbol) transform_method ? key.send(transform_method) : block.call(key) else key end result[new_key] = deep_transform_keys(value, transform_method, &block) end end else value end end |
.json_patch(patch_to, patch_from) ⇒ Object
Produces a set of json-patch operations so that applying the operations on a, gives you the results of b Used in correctly patching the Kube resources on stack updates
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/k8s/util.rb', line 139 def self.json_patch(patch_to, patch_from) diffs = Hashdiff.diff(patch_to, patch_from, array_path: true) ops = [] # Each diff is like: # ["+", ["spec", "selector", "food"], "kebab"] # ["-", ["spec", "selector", "drink"], "pepsi"] # or # ["~", ["spec", "selector", "drink"], "old value", "new value"] # the path elements can be symbols too, depending on the input hashes diffs.each do |diff| operator = diff[0] # substitute '/' with '~1' and '~' with '~0' # according to RFC 6901 path = diff[1].map { |p| p.to_s.gsub(PATH_REGEX, PATH_TR_MAP) } if operator == '-' ops << { op: "remove", path: "/" + path.join('/') } elsif operator == '+' ops << { op: "add", path: "/" + path.join('/'), value: diff[2] } elsif operator == '~' ops << { op: "replace", path: "/" + path.join('/'), value: diff[3] } else raise "Unknown diff operator: #{operator}!" end end ops end |
.recursive_compact(hash_or_array) ⇒ Hash, Array
Recursive compact for Hash/Array
123 124 125 126 127 128 129 130 131 |
# File 'lib/k8s/util.rb', line 123 def self.recursive_compact(hash_or_array) p = proc do |*args| v = args.last v.delete_if(&p) if v.respond_to?(:delete_if) && !v.is_a?(Array) v.nil? || v.respond_to?(:empty?) && (v.empty? && (v.is_a?(Hash) || v.is_a?(Array))) end hash_or_array.delete_if(&p) end |