Merge lp:~wgrant/launchpad/better-createManyTasks into lp:launchpad

Proposed by William Grant
Status: Merged
Approved by: William Grant
Approved revision: no longer in the source branch.
Merged at revision: 15232
Proposed branch: lp:~wgrant/launchpad/better-createManyTasks
Merge into: lp:launchpad
Diff against target: 220 lines (+52/-102)
4 files modified
lib/lp/bugs/interfaces/bug.py (+0/-3)
lib/lp/bugs/model/bug.py (+0/-4)
lib/lp/bugs/model/bugnomination.py (+3/-1)
lib/lp/bugs/model/bugtask.py (+49/-94)
To merge this branch: bzr merge lp:~wgrant/launchpad/better-createManyTasks
Reviewer Review Type Date Requested Status
Ian Booth (community) Approve
Review via email: mp+105422@code.launchpad.net

Commit message

Rewrite BugTask.createManyTasks to be a bit cleaner, and reimplement createTask on top of it.

Description of the change

BugTask.createManyTasks was added yesterday to more efficiently approve distroseries nominations. But it's pretty badly duplicated with createTask, and roughly twice as long as it needs to be.

This branch rewrites both of them to share code, be cleaner, and be slightly faster.

To post a comment you must log in.
Revision history for this message
Ian Booth (wallyworld) wrote :

Looks ok to me. Net LOC reduction as well.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/bugs/interfaces/bug.py'
2--- lib/lp/bugs/interfaces/bug.py 2012-05-10 13:13:05 +0000
3+++ lib/lp/bugs/interfaces/bug.py 2012-05-11 02:47:18 +0000
4@@ -779,9 +779,6 @@
5 def removeWatch(bug_watch, owner):
6 """Remove a bug watch from the bug."""
7
8- def addManyTasks(owners, targets):
9- """Create multiple bug tasks on this bug."""
10-
11 @call_with(owner=REQUEST_USER)
12 @operation_parameters(target=copy_field(IBugTask['target']))
13 @export_factory_operation(IBugTask, [])
14
15=== modified file 'lib/lp/bugs/model/bug.py'
16--- lib/lp/bugs/model/bug.py 2012-05-10 17:18:14 +0000
17+++ lib/lp/bugs/model/bug.py 2012-05-11 02:47:18 +0000
18@@ -1237,10 +1237,6 @@
19 """See `IBug`."""
20 return getUtility(IBugTaskSet).createTask(self, owner, target)
21
22- def addManyTasks(self, owner, targets):
23- """See `IBug`."""
24- return getUtility(IBugTaskSet).createManyTasks(self, owner, targets)
25-
26 def addWatch(self, bugtracker, remotebug, owner):
27 """See `IBug`."""
28 # We shouldn't add duplicate bug watches.
29
30=== modified file 'lib/lp/bugs/model/bugnomination.py'
31--- lib/lp/bugs/model/bugnomination.py 2012-05-10 13:13:05 +0000
32+++ lib/lp/bugs/model/bugnomination.py 2012-05-11 02:47:18 +0000
33@@ -22,6 +22,7 @@
34 ForeignKey,
35 SQLObjectNotFound,
36 )
37+from zope.component import getUtility
38 from zope.interface import implements
39
40 from lp.app.errors import NotFoundError
41@@ -32,6 +33,7 @@
42 IBugNomination,
43 IBugNominationSet,
44 )
45+from lp.bugs.interfaces.bugtask import IBugTaskSet
46 from lp.registry.interfaces.person import validate_public_person
47 from lp.services.database.constants import UTC_NOW
48 from lp.services.database.datetimecol import UtcDateTimeCol
49@@ -91,7 +93,7 @@
50 targets.append(distroseries)
51 else:
52 targets.append(self.productseries)
53- bugtasks = self.bug.addManyTasks(approver, targets)
54+ bugtasks = getUtility(IBugTaskSet).createManyTasks(self.bug, approver, targets)
55 for bug_task in bugtasks:
56 self.bug.addChange(BugTaskAdded(UTC_NOW, approver, bug_task))
57
58
59=== modified file 'lib/lp/bugs/model/bugtask.py'
60--- lib/lp/bugs/model/bugtask.py 2012-05-10 23:14:38 +0000
61+++ lib/lp/bugs/model/bugtask.py 2012-05-11 02:47:18 +0000
62@@ -1611,109 +1611,64 @@
63 params = BugTaskSearchParams(user, **kwargs)
64 return self.search(params)
65
66- def _initNewTask(self, bug, owner, target, status, importance, assignee,
67- milestone):
68- if not status:
69+ def createManyTasks(self, bug, owner, targets, status=None,
70+ importance=None, assignee=None, milestone=None):
71+ """See `IBugTaskSet`."""
72+ if status is None:
73 status = IBugTask['status'].default
74- if not importance:
75+ if importance is None:
76 importance = IBugTask['importance'].default
77- if not assignee:
78- assignee = None
79- if not milestone:
80- milestone = None
81-
82- # Make sure there's no task for this bug already filed
83- # against the target.
84- validate_new_target(bug, target)
85-
86- target_key = bug_target_to_key(target)
87- if not bug.private and bug.security_related:
88- product = target_key['product']
89- distribution = target_key['distribution']
90- if product and product.security_contact:
91- bug.subscribe(product.security_contact, owner)
92- elif distribution and distribution.security_contact:
93- bug.subscribe(distribution.security_contact, owner)
94-
95- non_target_create_params = dict(
96- bug=bug,
97- _status=status,
98- importance=importance,
99- assignee=assignee,
100- owner=owner,
101- milestone=milestone)
102- create_params = non_target_create_params.copy()
103- create_params.update(target_key)
104- return create_params, non_target_create_params
105-
106- def createManyTasks(self, bug, owner, targets,
107- status=IBugTask['status'].default,
108- importance=IBugTask['importance'].default,
109- assignee=None, milestone=None):
110- """See `IBugTaskSet`."""
111- params = [self._initNewTask(bug, owner, target, status, importance,
112- assignee, milestone) for target in targets]
113-
114- fieldnames = (
115- 'assignee',
116- 'bug',
117- 'distribution',
118- 'distroseries',
119- 'importance',
120- 'milestone',
121- 'owner',
122- 'product',
123- 'productseries',
124- 'sourcepackagename',
125- '_status',
126- )
127-
128- fields = [getattr(BugTask, field) for field in fieldnames]
129- # Values need to be a list of tuples in the order we're declaring our
130- # fields.
131- values = [[p[0].get(field) for field in fieldnames] for p in params]
132-
133- taskset = create(fields, values, get_objects=True)
134+ target_keys = []
135+ pillars = set()
136+ for target in targets:
137+ validate_new_target(bug, target)
138+ pillars.add(target.pillar)
139+ target_keys.append(bug_target_to_key(target))
140+ if bug.information_type == InformationType.UNEMBARGOEDSECURITY:
141+ for pillar in pillars:
142+ if pillar.security_contact:
143+ bug.subscribe(pillar.security_contact, owner)
144+
145+ values = [
146+ (bug, owner, key['product'], key['productseries'],
147+ key['distribution'], key['distroseries'],
148+ key['sourcepackagename'], status, importance, assignee,
149+ milestone)
150+ for key in target_keys]
151+ tasks = create(
152+ (BugTask.bug, BugTask.owner, BugTask.product,
153+ BugTask.productseries, BugTask.distribution,
154+ BugTask.distroseries, BugTask.sourcepackagename, BugTask._status,
155+ BugTask.importance, BugTask.assignee, BugTask.milestone),
156+ values, get_objects=True)
157+
158 del get_property_cache(bug).bugtasks
159- for bugtask in taskset:
160+ for bugtask in tasks:
161 bugtask.updateTargetNameCache()
162 if bugtask.conjoined_slave:
163 bugtask._syncFromConjoinedSlave()
164- return taskset
165+ return tasks
166
167- def createTask(self, bug, owner, target,
168- status=IBugTask['status'].default,
169- importance=IBugTask['importance'].default,
170+ def createTask(self, bug, owner, target, status=None, importance=None,
171 assignee=None, milestone=None):
172 """See `IBugTaskSet`."""
173- create_params, non_target_create_params = self._initNewTask(bug,
174- owner, target, status, importance, assignee, milestone)
175- bugtask = BugTask(**create_params)
176-
177- if create_params['distribution']:
178- # Create tasks for accepted nominations if this is a source
179- # package addition.
180- accepted_nominations = [
181- nomination for nomination in
182- bug.getNominations(create_params['distribution'])
183- if nomination.isApproved()]
184- for nomination in accepted_nominations:
185- accepted_series_task = BugTask(
186- distroseries=nomination.distroseries,
187- sourcepackagename=create_params['sourcepackagename'],
188- **non_target_create_params)
189- accepted_series_task.updateTargetNameCache()
190-
191- if bugtask.conjoined_slave:
192- bugtask._syncFromConjoinedSlave()
193-
194- bugtask.updateTargetNameCache()
195- del get_property_cache(bug).bugtasks
196- # Because of block_implicit_flushes, it is possible for a new bugtask
197- # to be queued in appropriately, which leads to Bug.bugtasks not
198- # finding the bugtask.
199- Store.of(bugtask).flush()
200- return bugtask
201+ # Create tasks for accepted nominations if this is a source
202+ # package addition. Distribution nominations are for all the
203+ # tasks.
204+ targets = [target]
205+ key = bug_target_to_key(target)
206+ if key['distribution'] is not None:
207+ for nomination in bug.getNominations(key['distribution']):
208+ if not nomination.isApproved():
209+ continue
210+ targets.append(
211+ nomination.distroseries.getSourcePackage(
212+ key['sourcepackagename']))
213+
214+ tasks = self.createManyTasks(
215+ bug, owner, targets, status=status, importance=importance,
216+ assignee=assignee, milestone=milestone)
217+ return [task for task in tasks if task.target == target][0]
218
219 def getStatusCountsForProductSeries(self, user, product_series):
220 """See `IBugTaskSet`."""