Bug 1241398 - Show the diff for created and deleted files in mach build-backend --diff. r=gps

This commit is contained in:
Mike Hommey 2016-01-21 15:50:26 +09:00
parent cd5682e071
commit 79fda1d209
2 changed files with 37 additions and 8 deletions

View File

@ -20,7 +20,10 @@ from mach.mixin.logging import LoggingMixin
import mozpack.path as mozpath
from ..preprocessor import Preprocessor
from ..pythonutil import iter_modules_in_path
from ..util import FileAvoidWrite
from ..util import (
FileAvoidWrite,
simple_diff,
)
from ..frontend.data import ContextDerived
from .configenvironment import ConfigEnvironment
from mozbuild.base import ExecutionSummary
@ -136,8 +139,17 @@ class BuildBackend(LoggingMixin):
# Purge backend files created in previous run, but not created anymore
delete_files = self._backend_output_list - self._backend_output_files
for path in delete_files:
full_path = mozpath.join(self.environment.topobjdir, path)
try:
os.unlink(mozpath.join(self.environment.topobjdir, path))
with open(full_path, 'r') as existing:
old_content = existing.read()
if old_content:
self.file_diffs[full_path] = simple_diff(
full_path, old_content.splitlines(), None)
except IOError:
pass
try:
os.unlink(full_path)
self._deleted_count += 1
except OSError:
pass
@ -199,12 +211,12 @@ class BuildBackend(LoggingMixin):
self._backend_output_files.add(mozpath.relpath(fh.name, self.environment.topobjdir))
existed, updated = fh.close()
if fh.diff:
self.file_diffs[fh.name] = fh.diff
if not existed:
self._created_count += 1
elif updated:
self._updated_count += 1
if fh.diff:
self.file_diffs[fh.name] = fh.diff
else:
self._unchanged_count += 1

View File

@ -111,6 +111,23 @@ def ensureParentDir(path):
raise
def simple_diff(filename, old_lines, new_lines):
"""Returns the diff between old_lines and new_lines, in unified diff form,
as a list of lines.
old_lines and new_lines are lists of non-newline terminated lines to
compare.
old_lines can be None, indicating a file creation.
new_lines can be None, indicating a file deletion.
"""
old_name = '/dev/null' if old_lines is None else filename
new_name = '/dev/null' if new_lines is None else filename
return difflib.unified_diff(old_lines or [], new_lines or [],
old_name, new_name, n=4, lineterm='')
class FileAvoidWrite(BytesIO):
"""File-like object that buffers output and only writes if content changed.
@ -177,11 +194,10 @@ class FileAvoidWrite(BytesIO):
if self._capture_diff:
try:
old_lines = old_content.splitlines() if old_content else []
old_lines = old_content.splitlines() if existed else None
new_lines = buf.splitlines()
self.diff = difflib.unified_diff(old_lines, new_lines,
self.name, self.name, n=4, lineterm='')
self.diff = simple_diff(self.name, old_lines, new_lines)
# FileAvoidWrite isn't unicode/bytes safe. So, files with non-ascii
# content or opened and written in different modes may involve
# implicit conversion and this will make Python unhappy. Since
@ -189,7 +205,8 @@ class FileAvoidWrite(BytesIO):
# This can go away once FileAvoidWrite uses io.BytesIO and
# io.StringIO. But that will require a lot of work.
except (UnicodeDecodeError, UnicodeEncodeError):
self.diff = 'Binary or non-ascii file changed: %s' % self.name
self.diff = ['Binary or non-ascii file changed: %s' %
self.name]
return existed, True