From 58fe662dc7dab94ded1fa668cbf7552385122567 Mon Sep 17 00:00:00 2001 From: "maruel@chromium.org" Date: Fri, 3 Jun 2011 20:59:27 +0000 Subject: [PATCH] Add support for empty files, __init__.py is a common example. Use p.is_new signal and set it manually with rietveld patches. Add regression test for +x. R=dpranke@chromium.org BUG= TEST= Review URL: http://codereview.chromium.org/7054057 git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@87858 0039d316-1c4b-4281-b951-d872f2087c98 --- apply_issue.py | 14 ++++++-------- checkout.py | 28 ++++++++++++++++++---------- rietveld.py | 13 +++++++++---- tests/patch_test.py | 9 +++++++++ 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/apply_issue.py b/apply_issue.py index 72b5298c18..69faf8dc25 100755 --- a/apply_issue.py +++ b/apply_issue.py @@ -22,7 +22,8 @@ import scm def main(): parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) parser.add_option( - '-v', '--verbose', action='count', help='Prints debugging infos') + '-v', '--verbose', action='count', default=0, + help='Prints debugging infos') parser.add_option( '-i', '--issue', type='int', help='Rietveld issue number') parser.add_option( @@ -38,13 +39,10 @@ def main(): default='http://codereview.chromium.org', help='Rietveld server') options, args = parser.parse_args() - LOG_FORMAT = '%(levelname)s %(filename)s(%(lineno)d): %(message)s' - if not options.verbose: - logging.basicConfig(level=logging.WARNING, format=LOG_FORMAT) - elif options.verbose == 1: - logging.basicConfig(level=logging.INFO, format=LOG_FORMAT) - elif options.verbose > 1: - logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT) + logging.basicConfig( + format='%(levelname)s %(filename)s(%(lineno)d): %(message)s', + level=[logging.WARNING, logging.INFO, logging.DEBUG][ + min(2, options.verbose)]) if args: parser.error('Extra argument(s) "%s" not understood' % ' '.join(args)) if not options.issue: diff --git a/checkout.py b/checkout.py index a5cf5801f1..21c283e8cb 100644 --- a/checkout.py +++ b/checkout.py @@ -127,10 +127,14 @@ class RawCheckout(CheckoutBase): with open(os.path.join(filename), 'wb') as f: f.write(p.get()) else: - stdout = subprocess2.check_output( - ['patch', '-p%s' % p.patchlevel], - stdin=p.get(), - cwd=self.project_path) + if p.diff_hunks: + stdout = subprocess2.check_output( + ['patch', '-p%s' % p.patchlevel], + stdin=p.get(), + cwd=self.project_path) + elif p.is_new: + # There is only a header. Just create the file. + open(os.path.join(self.project_path, p.filename), 'w').close() for post in post_processor: post(self, p) except OSError, e: @@ -258,8 +262,6 @@ class SvnCheckout(CheckoutBase, SvnMixIn): stdout += self._check_output_svn( ['delete', p.filename, '--force'], credentials=False) else: - new = not os.path.exists(p.filename) - # svn add while creating directories otherwise svn add on the # contained files will silently fail. # First, find the root directory that exists. @@ -278,10 +280,14 @@ class SvnCheckout(CheckoutBase, SvnMixIn): with open(os.path.join(self.project_path, p.filename), 'wb') as f: f.write(p.get()) else: - cmd = ['patch', '-p%s' % p.patchlevel, '--forward', '--force'] - stdout += subprocess2.check_output( - cmd, stdin=p.get(), cwd=self.project_path) - if new: + if p.diff_hunks: + cmd = ['patch', '-p%s' % p.patchlevel, '--forward', '--force'] + stdout += subprocess2.check_output( + cmd, stdin=p.get(), cwd=self.project_path) + elif p.is_new: + # There is only a header. Just create the file. + open(os.path.join(self.project_path, p.filename), 'w').close() + if p.is_new: stdout += self._check_output_svn( ['add', p.filename, '--force'], credentials=False) for prop in p.svn_properties: @@ -410,6 +416,8 @@ class GitCheckoutBase(CheckoutBase): f.write(p.get()) stdout += self._check_output_git(['add', p.filename]) else: + # No need to do anything special with p.is_new or if not + # p.diff_hunks. git apply manages all that already. stdout += self._check_output_git( ['apply', '--index', '-p%s' % p.patchlevel], stdin=p.get()) for prop in p.svn_properties: diff --git a/rietveld.py b/rietveld.py index 56e0a44191..c2045ac331 100644 --- a/rietveld.py +++ b/rietveld.py @@ -142,12 +142,17 @@ class Rietveld(object): props, is_new=(status[0] == 'A'))) else: - if state['num_chunks']: + # Ignores num_chunks since it may only contain an header. + try: diff = self.get_file_diff(issue, patchset, state['id']) - else: - raise patch.UnsupportedPatchFormat( - filename, 'File doesn\'t have a diff.') + except urllib2.HTTPError, e: + if e.code == 404: + raise patch.UnsupportedPatchFormat( + filename, 'File doesn\'t have a diff.') out.append(patch.FilePatchDiff(filename, diff, props)) + if status[0] == 'A': + # It won't be set for empty file. + out[-1].is_new = True else: # Line too long (N/80) # pylint: disable=C0301 diff --git a/tests/patch_test.py b/tests/patch_test.py index dd4b72efeb..034915754e 100755 --- a/tests/patch_test.py +++ b/tests/patch_test.py @@ -512,6 +512,15 @@ class PatchTest(unittest.TestCase): self.assertEquals( [('svn:executable', '*')], patch.FilePatchDiff('natsort_test.py', diff, []).svn_properties) + diff = ( + 'diff --git a/natsort_test.py b/natsort_test.py\n' + 'new file mode 100644\n' + '--- /dev/null\n' + '+++ b/natsort_test.py\n' + '@@ -0,0 +1,1 @@\n' + '+#!/usr/bin/env python\n') + self.assertEquals( + [], patch.FilePatchDiff('natsort_test.py', diff, []).svn_properties) if __name__ == '__main__':