diff options
author | ameyavarade <ameya.varade@clogeny.com> | 2013-10-07 20:54:26 +0530 |
---|---|---|
committer | adamedx <adamed@opscode.com> | 2013-10-10 12:45:14 -0700 |
commit | f6c97951e30b0744079ac6e13cc7fff80238b97f (patch) | |
tree | 51cea05f20c29c2ae77b0b589ab74440497434d3 /lib | |
parent | 61bdcde9650f0fcc20717a5d57a49fe024e0043b (diff) | |
download | chef-f6c97951e30b0744079ac6e13cc7fff80238b97f.tar.gz |
Implemented changes related to diff-lcs for knife diff
Diffstat (limited to 'lib')
-rw-r--r-- | lib/chef/chef_fs/command_line.rb | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/lib/chef/chef_fs/command_line.rb b/lib/chef/chef_fs/command_line.rb index dd5e62b755..f41ca38824 100644 --- a/lib/chef/chef_fs/command_line.rb +++ b/lib/chef/chef_fs/command_line.rb @@ -19,6 +19,8 @@ require 'chef/chef_fs/file_system' require 'chef/chef_fs/file_system/operation_failed_error' require 'chef/chef_fs/file_system/operation_not_allowed_error' +require 'diff/lcs' +require 'diff/lcs/hunk' class Chef module ChefFS @@ -235,6 +237,43 @@ class Chef return [ [ :error, old_entry, new_entry, nil, nil, e ] ] end + # @todo: abstract out udiff. Same code for udiff is exist in 'chef/util/diff' + # produces a unified-output-format diff with 3 lines of context + def self.udiff(old_file, new_file) + diff_str = "" + file_length_difference = 0 + + old_data = IO.readlines(old_file).map { |e| e.chomp } + new_data = IO.readlines(new_file).map { |e| e.chomp } + diff_data = ::Diff::LCS.diff(old_data, new_data) + + return diff_str if old_data.empty? && new_data.empty? + return "No differences encountered\n" if diff_data.empty? + + # write diff header (standard unified format) + ft = File.stat(old_file).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z') + diff_str << "--- #{old_file}\t#{ft}\n" + ft = File.stat(new_file).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z') + diff_str << "+++ #{new_file}\t#{ft}\n" + + # loop over diff hunks. if a hunk overlaps with the last hunk, + # join them. otherwise, print out the old one. + old_hunk = hunk = nil + diff_data.each do |piece| + begin + hunk = ::Diff::LCS::Hunk.new(old_data, new_data, piece, 3, file_length_difference) + file_length_difference = hunk.file_length_difference + next unless old_hunk + next if hunk.merge(old_hunk) + diff_str << old_hunk.diff(:unified) << "\n" + ensure + old_hunk = hunk + end + end + diff_str << old_hunk.diff(:unified) << "\n" + return diff_str + end + private def self.sort_keys(json_object) @@ -268,7 +307,7 @@ class Chef old_tempfile.write(old_value) old_tempfile.close - result = `diff -u #{old_tempfile.path} #{new_tempfile.path}` + result = udiff(old_tempfile.path, new_tempfile.path) result = result.gsub(/^--- #{old_tempfile.path}/, "--- #{old_path}") result = result.gsub(/^\+\+\+ #{new_tempfile.path}/, "+++ #{new_path}") result |