def get_patch(self, issue, patchset): """Returns a PatchSet object containing the details to apply this patch.""" props = self.get_patchset_properties(issue, patchset) or {} out = [] for filename, state in props.get('files', {}).iteritems(): logging.debug('%s' % filename) # If not status, just assume it's a 'M'. Rietveld often gets it wrong and # just has status: null. Oh well. status = state.get('status') or 'M' if status[0] not in ('A', 'D', 'M', 'R'): raise patch.UnsupportedPatchFormat( filename, 'Change with status \'%s\' is not supported.' % status) svn_props = self.parse_svn_properties( state.get('property_changes', ''), filename) if state.get('is_binary'): if status[0] == 'D': if status[0] != status.strip(): raise patch.UnsupportedPatchFormat( filename, 'Deleted file shouldn\'t have property change.') out.append( patch.FilePatchDelete(filename, state['is_binary'])) else: content = self.get_file_content(issue, patchset, state['id']) if not content or content == 'None': # As a precaution due to a bug in upload.py for git checkout, refuse # empty files. If it's empty, it's not a binary file. raise patch.UnsupportedPatchFormat( filename, 'Binary file is empty. Maybe the file wasn\'t uploaded in the ' 'first place?') out.append( patch.FilePatchBinary(filename, content, svn_props, is_new=(status[0] == 'A'))) continue try: diff = self.get_file_diff(issue, patchset, state['id']) except urllib2.HTTPError, e: if e.code == 404: raise patch.UnsupportedPatchFormat( filename, 'File doesn\'t have a diff.') raise # FilePatchDiff() will detect file deletion automatically. p = patch.FilePatchDiff(filename, diff, svn_props) out.append(p) if status[0] == 'A': # It won't be set for empty file. p.is_new = True if (len(status) > 1 and status[1] == '+' and not (p.source_filename or p.svn_properties)): raise patch.UnsupportedPatchFormat( filename, 'Failed to process the svn properties')
def testPatchsetOrder(self): # Deletes must be last. # File renames/move/copy must be first. patches = [ patch.FilePatchDiff('chrome/file.cc', RAW.PATCH, []), patch.FilePatchDiff( 'tools\\clang_check/README.chromium', GIT.DELETE, []), patch.FilePatchDiff('tools/run_local_server.sh', GIT.RENAME, []), patch.FilePatchDiff( 'chromeos\\views/webui_menu_widget.h', GIT.RENAME_PARTIAL, []), patch.FilePatchDiff('pp', GIT.COPY, []), patch.FilePatchDiff('foo', GIT.NEW, []), patch.FilePatchDelete('other/place/foo', True), patch.FilePatchBinary('bar', 'data', [], is_new=False), ] expected = [ 'pp', 'chromeos/views/webui_menu_widget.h', 'tools/run_local_server.sh', 'bar', 'chrome/file.cc', 'foo', 'other/place/foo', 'tools/clang_check/README.chromium', ] patchset = patch.PatchSet(patches) self.assertEquals(expected, patchset.filenames)
def get_patch(self, _issue, _patchset): self.patchsets.append(patch.PatchSet([ patch.FilePatchDiff('chrome/file.cc', SVN_PATCH, []), patch.FilePatchDelete('other/place/foo', True), patch.FilePatchBinary('foo', 'data', [], True), ])) return self.patchsets[-1]
def get_patch(): return patch.PatchSet([ patch.FilePatchDelete('foo2', True), patch.FilePatchDiff('foo', GIT_NEW, []), patch.FilePatchBinary('foo1', 'data', [], True), patch.FilePatchDiff('foo3', GIT_PATCH, []), ])
def get_patches(self): return patch.PatchSet([ patch.FilePatchDiff('new_dir/subdir/new_file', GIT.NEW_SUBDIR, []), patch.FilePatchDiff('chrome/file.cc', GIT.PATCH, []), # TODO(maruel): Test with is_new == False. patch.FilePatchBinary('bin_file', '\x00', [], is_new=True), patch.FilePatchDelete('extra', False), ])
def get_patches(self): return patch.PatchSet([ patch.FilePatchDiff( 'svn_utils_test.txt', GIT_PATCH, []), # TODO(maruel): Test with is_new == False. patch.FilePatchBinary('bin_file', '\x00', [], is_new=True), patch.FilePatchDelete('extra', False), patch.FilePatchDiff('new_dir/subdir/new_file', PATCH_ADD, []), ])
def get_patch(self, issue, patchset): """Returns a PatchSet object containing the details to apply this patch.""" props = self.get_patchset_properties(issue, patchset) or {} out = [] for filename, state in props.get('files', {}).iteritems(): logging.debug('%s' % filename) status = state.get('status') if not status: raise patch.UnsupportedPatchFormat( filename, 'File\'s status is None, patchset upload is incomplete.') if status[0] not in ('A', 'D', 'M'): raise patch.UnsupportedPatchFormat( filename, 'Change with status \'%s\' is not supported.' % status) svn_props = self.parse_svn_properties( state.get('property_changes', ''), filename) if state.get('is_binary'): if status[0] == 'D': if status[0] != status.strip(): raise patch.UnsupportedPatchFormat( filename, 'Deleted file shouldn\'t have property change.') out.append( patch.FilePatchDelete(filename, state['is_binary'])) else: out.append( patch.FilePatchBinary(filename, self.get_file_content( issue, patchset, state['id']), svn_props, is_new=(status[0] == 'A'))) continue try: diff = self.get_file_diff(issue, patchset, state['id']) except urllib2.HTTPError, e: if e.code == 404: raise patch.UnsupportedPatchFormat( filename, 'File doesn\'t have a diff.') raise # FilePatchDiff() will detect file deletion automatically. p = patch.FilePatchDiff(filename, diff, svn_props) out.append(p) if status[0] == 'A': # It won't be set for empty file. p.is_new = True if (len(status) > 1 and status[1] == '+' and not (p.source_filename or p.svn_properties)): raise patch.UnsupportedPatchFormat( filename, 'Failed to process the svn properties')
def testRelPath(self): patches = patch.PatchSet([ patch.FilePatchDiff('pp', GIT.COPY, []), patch.FilePatchDiff( 'chromeos\\views/webui_menu_widget.h', GIT.RENAME_PARTIAL, []), patch.FilePatchDiff('tools/run_local_server.sh', GIT.RENAME, []), patch.FilePatchBinary('bar', 'data', [], is_new=False), patch.FilePatchDiff('chrome/file.cc', RAW.PATCH, []), patch.FilePatchDiff('foo', GIT.NEW, []), patch.FilePatchDelete('other/place/foo', True), patch.FilePatchDiff( 'tools\\clang_check/README.chromium', GIT.DELETE, []), ]) expected = [ 'pp', 'chromeos/views/webui_menu_widget.h', 'tools/run_local_server.sh', 'bar', 'chrome/file.cc', 'foo', 'other/place/foo', 'tools/clang_check/README.chromium', ] self.assertEquals(expected, patches.filenames) # Test patch #4. orig_name = patches.patches[4].filename orig_source_name = patches.patches[4].source_filename or orig_name patches.set_relpath(os.path.join('a', 'bb')) # Expect posixpath all the time. expected = [posixpath.join('a', 'bb', x) for x in expected] self.assertEquals(expected, patches.filenames) # Make sure each header is updated accordingly. header = [] new_name = posixpath.join('a', 'bb', orig_name) new_source_name = posixpath.join('a', 'bb', orig_source_name) for line in RAW.PATCH.splitlines(True): if line.startswith('@@'): break if line[:3] == '---': line = line.replace(orig_source_name, new_source_name) if line[:3] == '+++': line = line.replace(orig_name, new_name) header.append(line) header = ''.join(header) self.assertEquals(header, patches.patches[4].diff_header)
def testFilePatchBinaryNew(self): p = patch.FilePatchBinary('foo', 'data', [], is_new=True) self._check_patch(p, 'foo', 'data', is_binary=True, is_new=True)