Chromium Code Reviews| Index: tools/svndiff.py |
| =================================================================== |
| --- tools/svndiff.py (revision 10121) |
| +++ tools/svndiff.py (working copy) |
| @@ -7,10 +7,12 @@ |
| ''' |
| ''' |
| -Generates a visual diff of all pending changes in the local SVN checkout. |
| +Generates a visual diff of all pending changes in the local SVN (or git!) |
| +checkout. |
| Launch with --help to see more information. |
| +TODO(epoger): Now that this tool supports either git or svn, rename it. |
| TODO(epoger): Fix indentation in this file (2-space indents, not 4-space). |
| ''' |
| @@ -19,6 +21,7 @@ |
| import os |
| import re |
| import shutil |
| +import subprocess |
| import sys |
| import tempfile |
| import urllib2 |
| @@ -45,10 +48,10 @@ |
| USAGE_STRING = 'Usage: %s [options]' |
| HELP_STRING = ''' |
| -Generates a visual diff of all pending changes in the local SVN checkout. |
| +Generates a visual diff of all pending changes in the local SVN/git checkout. |
| This includes a list of all files that have been added, deleted, or modified |
| -(as far as SVN knows about). For any image modifications, pixel diffs will |
| +(as far as SVN/git knows about). For any image modifications, pixel diffs will |
| be generated. |
| ''' |
| @@ -160,6 +163,46 @@ |
| dest_path=os.path.join(new_flattened_dir, |
| filename_prefix + imagename)) |
| +def _RunCommand(args): |
| + """Run a command (from self._directory) and return stdout as a single |
| + string. |
| + |
| + @param args a list of arguments |
| + """ |
| + proc = subprocess.Popen(args, |
| + stdout=subprocess.PIPE, |
| + stderr=subprocess.PIPE) |
| + (stdout, stderr) = proc.communicate() |
| + if proc.returncode is not 0: |
| + raise Exception('command "%s" failed: %s' % (args, stderr)) |
| + return stdout |
| + |
| +def _GitGetModifiedFiles(): |
| + """Returns a list of locally modified files within the current working dir. |
| + |
| + TODO(epoger): Move this into a git utility package? |
| + """ |
| + status_regex_string = '^...(\S+)' |
| + stdout = _RunCommand(['git', 'status', '-s']) |
|
Stephen White
2013/07/17 10:44:40
GitNit(tm): git status is a "porcelain" command, a
epoger
2013/07/18 15:00:04
Ah, thanks for teaching this git n00b something.
|
| + status_regex = re.compile(status_regex_string, re.MULTILINE) |
| + return status_regex.findall(stdout) |
| + |
| +def _GitExportBaseVersionOfFile(file_within_repo, dest_path): |
| + """Retrieves a copy of the base version of a file within the repository. |
| + |
| + @param file_within_repo path to the file within the repo whose base |
| + version you wish to obtain |
| + @param dest_path destination to which to write the base content |
| + |
| + TODO(epoger): Move this into a git utility package? |
| + """ |
| + args = ['git', 'show', os.path.join('HEAD:.', file_within_repo)] |
|
Stephen White
2013/07/17 10:44:40
Same here. I think the plumbing equivalent is "git
epoger
2013/07/18 15:00:04
I tried "git cat-file" in various permutations, bu
Stephen White
2013/07/18 17:32:38
Sure. Maybe just add a FIXME that we should try to
epoger
2013/07/18 17:40:35
Good idea... done.
|
| + with open(dest_path, 'wb') as outfile: |
| + proc = subprocess.Popen(args, stdout=outfile) |
| + proc.communicate() |
| + if proc.returncode is not 0: |
| + raise Exception('command "%s" failed' % args) |
| + |
| def SvnDiff(path_to_skdiff, dest_dir, source_dir): |
| """Generates a visual diff of all pending changes in source_dir. |
| @@ -174,6 +217,7 @@ |
| dest_dir = os.path.abspath(dest_dir) |
| os.chdir(source_dir) |
| + using_svn = os.path.isdir('.svn') |
| # Prepare temporary directories. |
| modified_flattened_dir = os.path.join(dest_dir, 'modified_flattened') |
| @@ -185,9 +229,12 @@ |
| # Get a list of all locally modified (including added/deleted) files, |
| # descending subdirectories. |
| - svn_repo = svn.Svn('.') |
| - modified_file_paths = svn_repo.GetFilesWithStatus( |
| - svn.STATUS_ADDED | svn.STATUS_DELETED | svn.STATUS_MODIFIED) |
| + if using_svn: |
| + svn_repo = svn.Svn('.') |
| + modified_file_paths = svn_repo.GetFilesWithStatus( |
| + svn.STATUS_ADDED | svn.STATUS_DELETED | svn.STATUS_MODIFIED) |
| + else: |
| + modified_file_paths = _GitGetModifiedFiles() |
| # For each modified file: |
| # 1. copy its current contents into modified_flattened_dir |
| @@ -197,8 +244,12 @@ |
| # Special handling for JSON files, in the hopes that they |
| # contain GM result summaries. |
| (_unused, original_file_path) = tempfile.mkstemp() |
| - svn_repo.ExportBaseVersionOfFile(modified_file_path, |
| - original_file_path) |
| + if using_svn: |
| + svn_repo.ExportBaseVersionOfFile( |
| + modified_file_path, original_file_path) |
| + else: |
| + _GitExportBaseVersionOfFile( |
| + modified_file_path, original_file_path) |
| platform_prefix = re.sub(os.sep, '__', |
| os.path.dirname(modified_file_path)) + '__' |
| _CallJsonDiff(old_json_path=original_file_path, |
| @@ -214,9 +265,14 @@ |
| shutil.copyfile(modified_file_path, |
| os.path.join(modified_flattened_dir, |
| dest_filename)) |
| - svn_repo.ExportBaseVersionOfFile( |
| - modified_file_path, |
| - os.path.join(original_flattened_dir, dest_filename)) |
| + if using_svn: |
| + svn_repo.ExportBaseVersionOfFile( |
| + modified_file_path, |
| + os.path.join(original_flattened_dir, dest_filename)) |
| + else: |
| + _GitExportBaseVersionOfFile( |
| + modified_file_path, |
| + os.path.join(original_flattened_dir, dest_filename)) |
| # Run skdiff: compare original_flattened_dir against modified_flattened_dir |
| RunCommand('%s %s %s %s' % (path_to_skdiff, original_flattened_dir, |