global
def intuit_diff_direction(src, patchset, limit = nil)
Diff::LCS::Change as its source, as an array will cause the creation
some time. This also works better with Diff::LCS::ContextChange or
WARNING: By default, this examines the whole patch, so this could take
patch should be applied.
Examine the patchset and the source to see in which direction the
def intuit_diff_direction(src, patchset, limit = nil) string = src.kind_of?(String) count = left_match = left_miss = right_match = right_miss = 0 patchset.each do |change| count += 1 case change when Diff::LCS::ContextChange le = string ? src[change.old_position, 1] : src[change.old_position] re = string ? src[change.new_position, 1] : src[change.new_position] case change.action when '-' # Remove details from the old string if le == change.old_element left_match += 1 else left_miss += 1 end when '+' if re == change.new_element right_match += 1 else right_miss += 1 end when '=' left_miss += 1 if le != change.old_element right_miss += 1 if re != change.new_element when '!' if le == change.old_element left_match += 1 elsif re == change.new_element right_match += 1 else left_miss += 1 right_miss += 1 end end when Diff::LCS::Change # With a simplistic change, we can't tell the difference between # the left and right on '!' actions, so we ignore those. On '=' # actions, if there's a miss, we miss both left and right. element = string ? src[change.position, 1] : src[change.position] case change.action when '-' if element == change.element left_match += 1 else left_miss += 1 end when '+' if element == change.element right_match += 1 else right_miss += 1 end when '=' if element != change.element left_miss += 1 right_miss += 1 end end end break if !limit.nil? && (count > limit) end no_left = left_match.zero? && left_miss.positive? no_right = right_match.zero? && right_miss.positive? case [no_left, no_right] when [false, true] :patch when [true, false] :unpatch else case left_match <=> right_match when 1 if left_miss.zero? :patch else :unpatch end when -1 if right_miss.zero? :unpatch else :patch end else fail "The provided patchset does not appear to apply to the provided \ umerable as either source or destination value." end end end