Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(165)

Side by Side Diff: codereview/views.py

Issue 11868043: Add ability to review commit messages.
Patch Set: Created 11 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2008 Google Inc. 1 # Copyright 2008 Google Inc.
2 # 2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"); 3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License. 4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at 5 # You may obtain a copy of the License at
6 # 6 #
7 # http://www.apache.org/licenses/LICENSE-2.0 7 # http://www.apache.org/licenses/LICENSE-2.0
8 # 8 #
9 # Unless required by applicable law or agreed to in writing, software 9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS, 10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and 12 # See the License for the specific language governing permissions and
13 # limitations under the License. 13 # limitations under the License.
14 14
15 """Views for Rietveld.""" 15 """Views for Rietveld."""
16 16
17 17
18 import binascii 18 import binascii
19 import copy
19 import datetime 20 import datetime
20 import email # see incoming_mail() 21 import email # see incoming_mail()
21 import email.utils 22 import email.utils
23 import difflib
22 import itertools 24 import itertools
23 import json 25 import json
24 import logging 26 import logging
25 import md5 27 import md5
26 import mimetypes 28 import mimetypes
27 import os 29 import os
28 import random 30 import random
29 import re 31 import re
30 import tarfile 32 import tarfile
31 import tempfile 33 import tempfile
(...skipping 1704 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 1738
1737 ps_key = db.Key.from_path( 1739 ps_key = db.Key.from_path(
1738 models.PatchSet.kind(), 1740 models.PatchSet.kind(),
1739 db.allocate_ids(db.Key.from_path(models.PatchSet.kind(), 1, 1741 db.allocate_ids(db.Key.from_path(models.PatchSet.kind(), 1,
1740 parent=issue.key()), 1)[0], 1742 parent=issue.key()), 1)[0],
1741 parent=issue.key()) 1743 parent=issue.key())
1742 1744
1743 patchset = models.PatchSet(issue=issue, data=data, url=url, key=ps_key) 1745 patchset = models.PatchSet(issue=issue, data=data, url=url, key=ps_key)
1744 patchset.put() 1746 patchset.put()
1745 1747
1748 commitPatch = _create_commit_message_patch(patchset,
1749 patchset.issue.description)
1750 commitPatch.put()
1751
1746 if not separate_patches: 1752 if not separate_patches:
1747 try: 1753 try:
1748 patches = engine.ParsePatchSet(patchset) 1754 patches = engine.ParsePatchSet(patchset)
1749 except: 1755 except:
1750 # catch all exceptions happening in engine.ParsePatchSet, 1756 # catch all exceptions happening in engine.ParsePatchSet,
1751 # engine.SplitPatch. With malformed diffs a variety of exceptions could 1757 # engine.SplitPatch. With malformed diffs a variety of exceptions could
1752 # happen there. 1758 # happen there.
1753 logging.exception('Exception during patch parsing') 1759 logging.exception('Exception during patch parsing')
1754 patches = [] 1760 patches = []
1755 if not patches: 1761 if not patches:
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1821 @issue_editor_required 1827 @issue_editor_required
1822 @xsrf_required 1828 @xsrf_required
1823 def add(request): 1829 def add(request):
1824 """/<issue>/add - Add a new PatchSet to an existing Issue.""" 1830 """/<issue>/add - Add a new PatchSet to an existing Issue."""
1825 issue = request.issue 1831 issue = request.issue
1826 form = AddForm(request.POST, request.FILES) 1832 form = AddForm(request.POST, request.FILES)
1827 if not _add_patchset_from_form(request, issue, form): 1833 if not _add_patchset_from_form(request, issue, form):
1828 return show(request, issue.key().id(), form) 1834 return show(request, issue.key().id(), form)
1829 return HttpResponseRedirect(reverse(show, args=[issue.key().id()])) 1835 return HttpResponseRedirect(reverse(show, args=[issue.key().id()]))
1830 1836
1837 def _create_commit_message_patch(patchset, description):
1838 filename = "COMMIT_MSG"
tfarina1 2013/07/26 00:55:56 Can you rename this to "Commit Message"? So it mat
Andi 2013/07/29 08:38:34 I'd also would like to see a module constant for t
jparent1 2013/08/14 20:16:52 Done.
jparent1 2013/08/14 20:16:52 Done.
1839
1840 diff = ""
1841 udiff = difflib.unified_diff("",description.splitlines(1),·
1842 fromfile="\dev\\null",tofile=filename)
1843 for line in udiff:
1844 diff += line
1845
1846 patch_key = db.Key.from_path(
1847 models.Patch.kind(),
1848 db.allocate_ids(db.Key.from_path(models.Patch.kind(), 1,
1849 parent=patchset.key()), 1)[0],
1850 parent=patchset.key())
1851 commitPatch = models.Patch(patchset=patchset, text=utils.to_dbtext(diff),·
1852 filename=filename, key=patch_key,
1853 no_base_file=True)
1854 return commitPatch
1831 1855
1832 def _add_patchset_from_form(request, issue, form, message_key='message', 1856 def _add_patchset_from_form(request, issue, form, message_key='message',
1833 emails_add_only=False): 1857 emails_add_only=False):
1834 """Helper for add() and upload().""" 1858 """Helper for add() and upload()."""
1835 if form.is_valid(): 1859 if form.is_valid():
1836 data_url = _get_data_url(form) 1860 data_url = _get_data_url(form)
1837 if not form.is_valid(): 1861 if not form.is_valid():
1838 return None 1862 return None
1839 account = models.Account.get_account_for_user(request.user) 1863 account = models.Account.get_account_for_user(request.user)
1840 if account.blocked: 1864 if account.blocked:
1841 return None 1865 return None
1842 if not issue.edit_allowed: 1866 if not issue.edit_allowed:
1843 # This check is done at each call site but check again as a safety measure. 1867 # This check is done at each call site but check again as a safety measure.
1844 return None 1868 return None
1845 data, url, separate_patches = data_url 1869 data, url, separate_patches = data_url
1846 message = form.cleaned_data[message_key] 1870 message = form.cleaned_data[message_key]
1847 ps_key = db.Key.from_path( 1871 ps_key = db.Key.from_path(
1848 models.PatchSet.kind(), 1872 models.PatchSet.kind(),
1849 db.allocate_ids(db.Key.from_path(models.PatchSet.kind(), 1, 1873 db.allocate_ids(db.Key.from_path(models.PatchSet.kind(), 1,
1850 parent=issue.key()), 1)[0], 1874 parent=issue.key()), 1)[0],
1851 parent=issue.key()) 1875 parent=issue.key())
1852 patchset = models.PatchSet(issue=issue, message=message, data=data, url=url, 1876 patchset = models.PatchSet(issue=issue, message=message, data=data, url=url,
1853 key=ps_key) 1877 key=ps_key)
1854 patchset.put() 1878 patchset.put()
1855 1879
1880 commitPatch = _create_commit_message_patch(patchset,
1881 patchset.issue.description)
1882 commitPatch.put()
1883
1856 if not separate_patches: 1884 if not separate_patches:
1857 try: 1885 try:
1858 patches = engine.ParsePatchSet(patchset) 1886 patches = engine.ParsePatchSet(patchset)
1859 except: 1887 except:
1860 logging.exception('Exception during patchset parsing') 1888 logging.exception('Exception during patchset parsing')
1861 patches = [] 1889 patches = []
1862 if not patches: 1890 if not patches:
1863 patchset.delete() 1891 patchset.delete()
1864 errkey = url and 'url' or 'data' 1892 errkey = url and 'url' or 'data'
1865 form.errors[errkey] = ['Patch set contains no recognizable patches'] 1893 form.errors[errkey] = ['Patch set contains no recognizable patches']
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
2242 2270
2243 if form.is_valid() and not issue.local_base: 2271 if form.is_valid() and not issue.local_base:
2244 base = form.get_base() 2272 base = form.get_base()
2245 2273
2246 if not form.is_valid(): 2274 if not form.is_valid():
2247 return respond(request, 'edit.html', {'issue': issue, 'form': form}) 2275 return respond(request, 'edit.html', {'issue': issue, 'form': form})
2248 cleaned_data = form.cleaned_data 2276 cleaned_data = form.cleaned_data
2249 2277
2250 was_closed = issue.closed 2278 was_closed = issue.closed
2251 issue.subject = cleaned_data['subject'] 2279 issue.subject = cleaned_data['subject']
2280 old_description = issue.description
2252 issue.description = cleaned_data['description'] 2281 issue.description = cleaned_data['description']
2282 ·
2283 # If the description was updated, it would get out of sync with the special
2284 # COMMIT_MSG file in the last pastchset. So we clone the last patchset,
2285 # modulo a new COMMIT_MSG patch.·
2286 if issue.description != old_description:
2287
2288 def clone_without_key(obj, **extra_args):
2289 """ Clones an object, without copying the key """
2290 klass = obj.__class__
2291 props = {}
2292 for k, v in klass.properties().iteritems():
2293 if not (type(v) == db.DateTimeProperty and
2294 (getattr(v, 'auto_now') or getattr(v, 'auto_now_add'))):
2295 if type(v) == db.ReferenceProperty:
2296 value = getattr(klass, k).get_value_for_datastore(obj)
2297 else:
2298 value = v.__get__(obj, klass)
2299 props[k] = value
2300 props.update(extra_args)····
2301 return klass(**props)····
2302
2303 # Create a new patchset from the last one.
2304 patchsets = list(issue.patchset_set.order('created'))
2305 last_patchset = patchsets[-1]
2306 new_patchset_msg = 'Auto-generated patchset by description update.'
2307 new_patchset = clone_without_key(last_patchset, parent=issue,
2308 message=new_patchset_msg)
2309 new_patchset.put()
2310 ·
2311 # Add the new commit message patch.
2312 commitPatch = _create_commit_message_patch(new_patchset, issue.description)
2313 commitPatch.put()
2314
2315 # And copy all the patches over from last patchset.
2316 for patch in list(last_patchset.patch_set):
2317 # Skip the old commit message, since we just created a new one.
2318 if patch.filename == "COMMIT_MSG":
2319 continue
2320 new_patch = clone_without_key(patch, parent=new_patchset,
2321 patchset=new_patchset)
2322 new_patch.put()
2323
2253 issue.closed = cleaned_data['closed'] 2324 issue.closed = cleaned_data['closed']
2254 issue.private = cleaned_data.get('private', False) 2325 issue.private = cleaned_data.get('private', False)
2255 base_changed = (issue.base != base) 2326 base_changed = (issue.base != base)
2256 issue.base = base 2327 issue.base = base
2257 issue.reviewers = reviewers 2328 issue.reviewers = reviewers
2258 issue.cc = cc 2329 issue.cc = cc
2259 if base_changed: 2330 if base_changed:
2260 for patchset in issue.patchset_set: 2331 for patchset in issue.patchset_set:
2261 db.run_in_transaction(_delete_cached_contents, list(patchset.patch_set)) 2332 db.run_in_transaction(_delete_cached_contents, list(patchset.patch_set))
2262 issue.calculate_updates_for() 2333 issue.calculate_updates_for()
(...skipping 2233 matching lines...) Expand 10 before | Expand all | Expand 10 after
4496 if form.is_valid(): 4567 if form.is_valid():
4497 client_id = form.cleaned_data['client_id'] 4568 client_id = form.cleaned_data['client_id']
4498 client_secret = form.cleaned_data['client_secret'] 4569 client_secret = form.cleaned_data['client_secret']
4499 additional_client_ids = form.cleaned_data['additional_client_ids'] 4570 additional_client_ids = form.cleaned_data['additional_client_ids']
4500 auth_utils.SecretKey.set_config(client_id, client_secret, 4571 auth_utils.SecretKey.set_config(client_id, client_secret,
4501 additional_client_ids) 4572 additional_client_ids)
4502 return HttpResponseRedirect(reverse(set_client_id_and_secret)) 4573 return HttpResponseRedirect(reverse(set_client_id_and_secret))
4503 else: 4574 else:
4504 form = ClientIDAndSecretForm() 4575 form = ClientIDAndSecretForm()
4505 return respond(request, 'set_client_id_and_secret.html', {'form': form}) 4576 return respond(request, 'set_client_id_and_secret.html', {'form': form})
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b