Method: Chef::Provider::File#diff_current

Defined in:
lib/chef/provider/file.rb

#diff_current(temp_path) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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/provider/file.rb', line 70

def diff_current(temp_path)
  suppress_resource_reporting = false

  return [ "(diff output suppressed by config)" ] if Chef::Config[:diff_disabled]
  return [ "(no temp file with new content, diff output suppressed)" ] unless ::File.exists?(temp_path)  # should never happen?

  # solaris does not support diff -N, so create tempfile to diff against if we are creating a new file
  target_path = if ::File.exists?(@current_resource.path)
                  @current_resource.path
                else
                  suppress_resource_reporting = true  # suppress big diffs going to resource reporting service
                  tempfile = Tempfile.new('chef-tempfile')
                  tempfile.path
                end

  diff_filesize_threshold = Chef::Config[:diff_filesize_threshold]
  diff_output_threshold = Chef::Config[:diff_output_threshold]

  if ::File.size(target_path) > diff_filesize_threshold || ::File.size(temp_path) > diff_filesize_threshold
    return [ "(file sizes exceed #{diff_filesize_threshold} bytes, diff output suppressed)" ]
  end

  # MacOSX(BSD?) diff will *sometimes* happily spit out nasty binary diffs
  return [ "(current file is binary, diff output suppressed)"] if is_binary?(target_path)
  return [ "(new content is binary, diff output suppressed)"] if is_binary?(temp_path)

  begin
    # -u: Unified diff format
    result = shell_out("diff -u #{target_path} #{temp_path}" )
  rescue Exception => e
    # Should *not* receive this, but in some circumstances it seems that 
    # an exception can be thrown even using shell_out instead of shell_out!
    return [ "Could not determine diff. Error: #{e.message}" ]
  end

  # diff will set a non-zero return code even when there's 
  # valid stdout results, if it encounters something unexpected
  # So as long as we have output, we'll show it.
  if not result.stdout.empty?
    if result.stdout.length > diff_output_threshold
      [ "(long diff of over #{diff_output_threshold} characters, diff output suppressed)" ]
    else
      val = result.stdout.split("\n")
      val.delete("\\ No newline at end of file")
      @new_resource.diff(val.join("\\n")) unless suppress_resource_reporting
      val
    end
  elsif not result.stderr.empty?
    [ "Could not determine diff. Error: #{result.stderr}" ]
  else
    [ "(no diff)" ]
  end
end