Module: Xcodeproj::Differ
- Defined in:
- lib/xcodeproj/differ.rb
Overview
Computes the recursive diff of Hashes, Array and other objects.
Useful to compare two projects. Inspired from ‘active_support/core_ext/hash/diff’.
Type specific handlers collapse
-
.array_diff(value_1, value_2, options) ⇒ Object
Returns the recursive diff of two arrays.
-
.generic_diff(value_1, value_2, options) ⇒ Object
Returns the diff of two generic objects.
-
.hash_diff(value_1, value_2, options) ⇒ Object
Computes the recursive difference of two hashes.
Cleaning collapse
-
.clean_hash(hash, key) ⇒ Hash
Returns a copy of the hash where the given key is removed recursively.
-
.clean_hash!(hash, key) ⇒ void
Recursively cleans a key from the given hash.
Class Method Summary collapse
-
.diff(value_1, value_2, options = {}) ⇒ Hash, Nil
Computes the recursive difference of two given values.
-
.project_diff(project_1, project_2, key_1 = 'project_1', key_2 = 'project_2') ⇒ Object
Optimized for reducing the noise from the tree hash of projects.
Class Method Details
.array_diff(value_1, value_2, options) ⇒ Object
Returns the recursive diff of two arrays.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/xcodeproj/differ.rb', line 111 def self.array_diff(value_1, value_2, ) ensure_class(value_1, Array) ensure_class(value_2, Array) return nil if value_1 == value_2 new_objects_value_1 = array_non_unique_diff(value_1, value_2) new_objects_value_2 = array_non_unique_diff(value_2, value_1) return nil if value_1.empty? && value_2.empty? matched_diff = {} if id_key = [:id_key] matched_value_1 = [] matched_value_2 = [] new_objects_value_1.each do |entry_value_1| if entry_value_1.is_a?(Hash) id_value = entry_value_1[id_key] entry_value_2 = new_objects_value_2.find do |entry| entry[id_key] == id_value end if entry_value_2 matched_value_1 << entry_value_1 matched_value_2 << entry_value_2 diff = diff(entry_value_1, entry_value_2, ) matched_diff[id_value] = diff if diff end end end new_objects_value_1 -= matched_value_1 new_objects_value_2 -= matched_value_2 end if new_objects_value_1.empty? && new_objects_value_2.empty? if matched_diff.empty? nil else matched_diff end else result = {} result[[:key_1]] = new_objects_value_1 unless new_objects_value_1.empty? result[[:key_2]] = new_objects_value_2 unless new_objects_value_2.empty? result[:diff] = matched_diff unless matched_diff.empty? result end end |
.clean_hash(hash, key) ⇒ Hash
Returns a copy of the hash where the given key is removed recursively.
187 188 189 190 191 |
# File 'lib/xcodeproj/differ.rb', line 187 def self.clean_hash(hash, key) new_hash = hash.dup self.clean_hash!(new_hash, key) new_hash end |
.clean_hash!(hash, key) ⇒ void
This method returns an undefined value.
Recursively cleans a key from the given hash.
203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/xcodeproj/differ.rb', line 203 def self.clean_hash!(hash, key) hash.delete(key) hash.each do |_, value| case value when Hash clean_hash!(value, key) when Array value.each { |entry| clean_hash!(entry, key) if entry.is_a?(Hash) } end end end |
.diff(value_1, value_2, options = {}) ⇒ Hash, Nil
Computes the recursive difference of two given values.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/xcodeproj/differ.rb', line 45 def self.diff(value_1, value_2, = {}) [:key_1] ||= 'value_1' [:key_2] ||= 'value_2' [:id_key] ||= nil method = if value_1.class == value_2.class case value_1 when Hash then :hash_diff when Array then :array_diff else :generic_diff end else :generic_diff end send(method, value_1, value_2, ) end |
.generic_diff(value_1, value_2, options) ⇒ Object
Returns the diff of two generic objects.
162 163 164 165 166 167 168 169 |
# File 'lib/xcodeproj/differ.rb', line 162 def self.generic_diff(value_1, value_2, ) return nil if value_1 == value_2 { [:key_1] => value_1, [:key_2] => value_2, } end |
.hash_diff(value_1, value_2, options) ⇒ Object
Computes the recursive difference of two hashes.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/xcodeproj/differ.rb', line 85 def self.hash_diff(value_1, value_2, ) ensure_class(value_1, Hash) ensure_class(value_2, Hash) return nil if value_1 == value_2 result = {} all_keys = (value_1.keys + value_2.keys).uniq all_keys.each do |key| key_value_1 = value_1[key] key_value_2 = value_2[key] diff = diff(key_value_1, key_value_2, ) if diff result[key] = diff if diff end end if result.empty? nil else result end end |
.project_diff(project_1, project_2, key_1 = 'project_1', key_2 = 'project_2') ⇒ Object
Optimized for reducing the noise from the tree hash of projects
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/xcodeproj/differ.rb', line 64 def self.project_diff(project_1, project_2, key_1 = 'project_1', key_2 = 'project_2') project_1 = project_1.to_tree_hash unless project_1.is_a?(Hash) project_2 = project_2.to_tree_hash unless project_2.is_a?(Hash) = { :key_1 => key_1, :key_2 => key_2, :id_key => 'displayName', } diff(project_1, project_2, ) end |