class Dyph::Differ

Public Class Methods

default_diff2() click to toggle source

@return [TwoWayDiffer]

# File lib/dyph/differ.rb, line 64
def self.default_diff2
  Dyph::TwoWayDiffers::HeckelDiff
end
default_diff3() click to toggle source

@return [ThreeWayDiffer]

# File lib/dyph/differ.rb, line 69
def self.default_diff3
  Dyph::Support::Diff3
end
default_merge_options() click to toggle source

@return [Hash] the default options for a merge

# File lib/dyph/differ.rb, line 52
def self.default_merge_options
  {
    split_function: identity,
    join_function: identity,
    conflict_function: identity,
    diff2: default_diff2,
    diff3: default_diff3,
    use_class_processors: true
  }
end
identity() click to toggle source

@return [Proc] helper proc for identity

# File lib/dyph/differ.rb, line 47
def self.identity
  -> (x) { x }
end
merge(left, base, right, options = {}) click to toggle source

Perform a three way diff, which attempts to merge left and right relative to a common base @param left [Object] @param base [Object] @param right [Object] @param options [Hash] custom split, join, conflict functions, can also override the diff2 and diff3 algorithm. (see default_merge_options) @return [MergeResult]

# File lib/dyph/differ.rb, line 9
def self.merge(left, base, right, options = {})
  options = default_merge_options.merge(options)

  split_function, join_function, conflict_function = set_processors(base, options)
  split_left, split_base, split_right = [left, base, right].map { |t| split_function.call(t) }
  merge_result = Dyph::Support::Merger.merge(split_left, split_base, split_right, diff2: options[:diff2], diff3: options[:diff3] )
  collated_merge_results = Dyph::Support::Collater.collate_merge(merge_result, join_function, conflict_function)

  if collated_merge_results.success?
    Dyph::Support::SanityCheck.ensure_no_lost_data(split_left, split_base, split_right, collated_merge_results.results)
  end

  collated_merge_results
end
split_on_new_line() click to toggle source

@return [Proc] helper proc for keeping newlines on string

# File lib/dyph/differ.rb, line 37
def self.split_on_new_line
  -> (some_string) { some_string.split(/(\n)/).each_slice(2).map { |x| x.join } }
end
standard_join() click to toggle source

@return [Proc] helper proc for joining an array

# File lib/dyph/differ.rb, line 42
def self.standard_join
  -> (array) { array.join }
end
two_way_diff(left, right, options = {}) click to toggle source

Perform a two way diff @param left [Array] @param right [Array] @param options [Hash] Pass in an optional diff2 class @return [Array] array of Dyph::Action

# File lib/dyph/differ.rb, line 29
def self.two_way_diff(left, right, options = {})
  diff2 = options[:diff2] || default_diff2
  diff_results = diff2.execute_diff(left, right)
  raw_merge = Dyph::TwoWayDiffers::OutputConverter.merge_results(diff_results[:old_text], diff_results[:new_text],)
  Dyph::TwoWayDiffers::OutputConverter.objectify(raw_merge)
end

Private Class Methods

check_for_class_overrides(klass, split_function, join_function, conflict_function) click to toggle source
# File lib/dyph/differ.rb, line 84
def self.check_for_class_overrides(klass, split_function, join_function, conflict_function)
  if klass.constants.include?(:DIFF_PREPROCESSOR)
    split_function = klass::DIFF_PREPROCESSOR
  end

  if klass.constants.include?(:DIFF_POSTPROCESSOR)
    join_function  = klass::DIFF_POSTPROCESSOR
  end

  if klass.constants.include?(:DIFF_CONFLICT_PROCESSOR)
    conflict_function = klass::DIFF_CONFLICT_PROCESSOR
  end

  [split_function, join_function, conflict_function]
end
set_processors(base, options) click to toggle source
# File lib/dyph/differ.rb, line 73
def self.set_processors(base, options)
  split_function    = options[:split_function]
  join_function     = options[:join_function]
  conflict_function = options[:conflict_function]
  if options[:use_class_processors]
    check_for_class_overrides(base.class, split_function, join_function, conflict_function)
  else
    [split_function, join_function, conflict_function]
  end
end