55require 'json'
66require 'set'
77require 'stringio'
8+ require 'yaml'
89
910require_relative '../catalog'
1011
@@ -153,6 +154,11 @@ def catdiff
153154 # out any such parameters from the result array.
154155 filter_diffs_for_absent_files ( result ) if @opts [ :suppress_absent_file_details ]
155156
157+ # If --ignore-equivalent-yaml-files is specified, then for any YAML file that is changed, parse the YAML
158+ # to construct the object. If the objects are identical this means the YAML file differs only in whitespace
159+ # or comments but not in function. Remove these.
160+ filter_diffs_for_equivalent_yaml_files ( result ) if @opts [ :ignore_equivalent_yaml_files ]
161+
156162 # That's it!
157163 @logger . debug "Exiting catdiff; change count: #{ result . size } "
158164 result
@@ -165,6 +171,33 @@ def filter_diffs_for_ignored_items(result)
165171 result . reject! { |item | ignored? ( item ) }
166172 end
167173
174+ # To ignore YAML file differences that are only due to whitespace or comments (i.e., the YAML files themselves
175+ # are functionally equivalent), parse the YAML content from both catalogs and compare objects. Remove when
176+ # objects are identical.
177+ # @param result [Array] Full result array (modified by this method)
178+ def filter_diffs_for_equivalent_yaml_files ( result )
179+ result . reject! { |item | equivalent_yaml_files? ( item ) }
180+ end
181+
182+ # Actually do the comparison of YAML objects for appropriate resources.
183+ # @param diff [Array] Difference
184+ # @return [Boolean] true if this difference is a YAML file with identical objects, false otherwise
185+ def equivalent_yaml_files? ( diff )
186+ # Skip additions or removals - focus only on changes
187+ return false unless diff [ 0 ] == '~' || diff [ 0 ] == '!'
188+
189+ # Make sure we are comparing file content for a file ending in .yaml or .yml extension
190+ return false unless diff [ 1 ] =~ /^File\f .+\. ya?ml\f parameters\f content$/
191+
192+ # Attempt to convert the old (diff[2]) and new (diff[3]) into YAML objects. Assuming
193+ # that doesn't error out, the return value is whether or not they're equal.
194+ obj_old = YAML . load ( diff [ 2 ] )
195+ obj_new = YAML . load ( diff [ 3 ] )
196+ obj_old == obj_new
197+ rescue # Rescue everything - if something failed, we aren't sure what's going on, so we'll return false.
198+ false
199+ end
200+
168201 # If a file has ensure => absent, there are certain parameters that don't matter anymore. Filter
169202 # out any such parameters from the result array.
170203 # @param result [Array] Diff result list (modified by this method)
0 commit comments