Class: Chef::Util::Diff
- Inherits:
-
Object
- Object
- Chef::Util::Diff
- Defined in:
- lib/chef/util/diff.rb
Instance Method Summary collapse
- #diff(old_file, new_file) ⇒ Object
-
#for_output ⇒ Object
@todo: to_a, to_s, to_json, inspect defs, accessors for @diff and @error @todo: move coercion to UTF-8 into to_json.
- #for_reporting ⇒ Object
-
#udiff(old_file, new_file) ⇒ Object
produces a unified-output-format diff with 3 lines of context ChefFS uses udiff() directly.
- #use_tempfile_if_missing(file) {|file| ... } ⇒ Object
Instance Method Details
#diff(old_file, new_file) ⇒ Object
75 76 77 78 79 80 81 |
# File 'lib/chef/util/diff.rb', line 75 def diff(old_file, new_file) use_tempfile_if_missing(old_file) do |old_file| use_tempfile_if_missing(new_file) do |new_file| @error = do_diff(old_file, new_file) end end end |
#for_output ⇒ Object
@todo: to_a, to_s, to_json, inspect defs, accessors for @diff and @error @todo: move coercion to UTF-8 into to_json
49 50 51 52 |
# File 'lib/chef/util/diff.rb', line 49 def for_output # formatted output to a terminal uses arrays of strings and returns error strings @diff.nil? ? [ @error ] : @diff end |
#for_reporting ⇒ Object
54 55 56 57 58 59 |
# File 'lib/chef/util/diff.rb', line 54 def for_reporting # caller needs to ensure that new files aren't posted to resource reporting return nil if @diff.nil? @diff.join("\\n") end |
#udiff(old_file, new_file) ⇒ Object
produces a unified-output-format diff with 3 lines of context ChefFS uses udiff() directly
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/chef/util/diff.rb', line 85 def udiff(old_file, new_file) require "diff/lcs" require "diff/lcs/hunk" diff_str = "" file_length_difference = 0 old_data = IO.readlines(old_file).map(&:chomp) new_data = IO.readlines(new_file).map(&: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| 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 diff_str << old_hunk.diff(:unified) << "\n" diff_str end |
#use_tempfile_if_missing(file) {|file| ... } ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/chef/util/diff.rb', line 61 def use_tempfile_if_missing(file) tempfile = nil unless TargetIO::File.exist?(file) Chef::Log.trace("File #{file} does not exist to diff against, using empty tempfile") tempfile = Tempfile.new("chef-diff") file = tempfile.path end yield file unless tempfile.nil? tempfile.close tempfile.unlink end end |