Merge lp:~thumper/launchpad/only-show-latest-bmp-in-revision-mail into lp:launchpad
- only-show-latest-bmp-in-revision-mail
- Merge into devel
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 10325 | ||||
Proposed branch: | lp:~thumper/launchpad/only-show-latest-bmp-in-revision-mail | ||||
Merge into: | lp:launchpad | ||||
Diff against target: |
126 lines (+48/-16) 2 files modified
lib/lp/code/model/branchjob.py (+24/-12) lib/lp/code/model/tests/test_branchjob.py (+24/-4) |
||||
To merge this branch: | bzr merge lp:~thumper/launchpad/only-show-latest-bmp-in-revision-mail | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Hudson-Doyle | Approve | ||
Review via email: mp+19377@code.launchpad.net |
Commit message
Only show the most recent proposal for any given source branch in the revision mail.
Description of the change
Tim Penhey (thumper) wrote : | # |
Michael Hudson-Doyle (mwhudson) wrote : | # |
Hi Tim,
nice branch, just a couple of things to think about.
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -13,6 +13,7 @@
> ]
>
> import contextlib
> +import operator
> import os
> import shutil
> from StringIO import StringIO
> @@ -600,28 +601,43 @@
> authors.
> return authors
>
> - def findRelatedBMP(
> + def findRelatedBMP(
> """Find merge proposals related to the revision-ids and branch.
>
> Only proposals whose source branch last-scanned-id is in the set of
> revision-ids and whose target_branch is the BranchJob branch are
> returned.
>
> + Only return the most recent proposal for any given source branch.
> +
> :param revision_ids: A list of revision-ids to look for.
> :param include_superseded: If true, include merge proposals that are
> superseded in the results.
> """
> store = Store.of(
> conditions = [
> + ]
'conditions' is unused now.
> + result = store.find(
> + (BranchMergePro
> BranchMergeProp
> BranchMergeProp
> - Branch.
> - if not include_superseded:
> - conditions.append(
> - BranchMergeProp
> - BranchMergeProp
> - result = store.find(
> - return result
> + Branch.
> + (BranchMergePro
> + BranchMergeProp
> +
> + proposals = {}
> + for proposal, source in result:
> + # Only show the must recent proposal for any given source.
> + date_created = proposal.
> + source_id = source.id
> +
> + if (source_id not in proposals or
> + date_created > proposals[
> + proposals[
> +
> + return sorted(
> + [proposal for proposal, date_created in proposals.
> + key=operator.
This seems a little complicated, although I admit I can't think of any
obviously clearer ways. Did you think about any ways of doing the
filtering in the database? That seems likely to be complicated too
though...
> def getRevisionMess
> """Return the log message for a revision.
> @@ -654,9 +670,7 @@
> if len(pretty_authors) > 5:
> outf.write('...\n')
> outf.write('\n')
> - bmps = list(
> - self.findRelate
> - include_
> + bmps = self.f...
Tim Penhey (thumper) wrote : | # |
On Tue, 16 Feb 2010 19:27:34 Michael Hudson wrote:
> Review: Approve
> Hi Tim,
>
> nice branch, just a couple of things to think about.
>
> > === modified file 'lib/lp/
> > --- lib/lp/
> > +++ lib/lp/
> > store = Store.of(
> > conditions = [
> > + ]
>
> 'conditions' is unused now.
Removed now.
> > + return sorted(
> > + [proposal for proposal, date_created in
> > proposals.
> > key=operator.
>
> This seems a little complicated, although I admit I can't think of any
> obviously clearer ways. Did you think about any ways of doing the
> filtering in the database? That seems likely to be complicated too
> though...
It could possibly be done, but I don't know how to do it in storm.
We want to group by the source branch and choose the merge proposal with the
latest date_created. I just don't know how to do this.
> > def getRevisionMess
> > """Return the log message for a revision.
> > @@ -654,9 +670,7 @@
> > if len(pretty_authors) > 5:
> > outf.write('...\n')
> > outf.write('\n')
> > - bmps = list(
> > - self.findRelate
> > - include_
> > + bmps = self.findRelate
> > if len(bmps) > 0:
> > outf.write('Related merge proposals:\n')
> > for bmp in bmps:
> >
> > === modified file 'lib/lp/
> > --- lib/lp/
> > +++ lib/lp/
> > + def test_findRelate
> > + """Assert that only the lastest for any particular source is
> > returned.
>
> I don't think it adds anything to start a test method
> comment/docstring with "Assert that". Something like "findRelatedBMP
> only returns the latest proposal for any source." would be better
> IMHO.
Fixed.
> And lastest isn't spelt like that :-)
I was tired. Also fixed.
> > self.assertEqua
> > list(job.
>
> It would be nice to reformat this as
>
> self.assertEqual(
> [desired_proposal], job.findRelated
>
> as you did for the other test.
Done.
1 | === modified file 'lib/lp/code/model/branchjob.py' |
2 | --- lib/lp/code/model/branchjob.py 2010-02-15 23:50:19 +0000 |
3 | +++ lib/lp/code/model/branchjob.py 2010-02-17 00:39:08 +0000 |
4 | @@ -615,8 +615,6 @@ |
5 | superseded in the results. |
6 | """ |
7 | store = Store.of(self.branch) |
8 | - conditions = [ |
9 | - ] |
10 | result = store.find( |
11 | (BranchMergeProposal, Branch), |
12 | BranchMergeProposal.target_branch == self.branch.id, |
13 | |
14 | === modified file 'lib/lp/code/model/tests/test_branchjob.py' |
15 | --- lib/lp/code/model/tests/test_branchjob.py 2010-02-15 23:50:19 +0000 |
16 | +++ lib/lp/code/model/tests/test_branchjob.py 2010-02-17 00:39:08 +0000 |
17 | @@ -551,7 +551,8 @@ |
18 | [desired_proposal], job.findRelatedBMP(['rev2a-id'])) |
19 | |
20 | def test_findRelatedBMP_one_per_source(self): |
21 | - """Assert that only the lastest for any particular source is returned. |
22 | + """findRelatedBMP only returns the most recent proposal for any |
23 | + particular source branch. |
24 | """ |
25 | self.useBzrBranches() |
26 | target_branch, tree = self.create_branch_and_tree('tree') |
27 | @@ -565,8 +566,8 @@ |
28 | source_branch.owner, target_branch) |
29 | job = RevisionsAddedJob.create( |
30 | target_branch, 'rev2b-id', 'rev2b-id', '') |
31 | - self.assertEqual([desired_proposal], |
32 | - list(job.findRelatedBMP(['rev2a-id']))) |
33 | + self.assertEqual( |
34 | + [desired_proposal], job.findRelatedBMP(['rev2a-id'])) |
35 | |
36 | def test_getAuthors(self): |
37 | """Ensure getAuthors returns the authors for the revisions.""" |
Preview Diff
1 | === modified file 'lib/lp/code/model/branchjob.py' |
2 | --- lib/lp/code/model/branchjob.py 2010-02-03 19:29:27 +0000 |
3 | +++ lib/lp/code/model/branchjob.py 2010-02-17 00:50:32 +0000 |
4 | @@ -13,6 +13,7 @@ |
5 | ] |
6 | |
7 | import contextlib |
8 | +import operator |
9 | import os |
10 | import shutil |
11 | from StringIO import StringIO |
12 | @@ -600,28 +601,41 @@ |
13 | authors.update(revision.get_apparent_authors()) |
14 | return authors |
15 | |
16 | - def findRelatedBMP(self, revision_ids, include_superseded=True): |
17 | + def findRelatedBMP(self, revision_ids): |
18 | """Find merge proposals related to the revision-ids and branch. |
19 | |
20 | Only proposals whose source branch last-scanned-id is in the set of |
21 | revision-ids and whose target_branch is the BranchJob branch are |
22 | returned. |
23 | |
24 | + Only return the most recent proposal for any given source branch. |
25 | + |
26 | :param revision_ids: A list of revision-ids to look for. |
27 | :param include_superseded: If true, include merge proposals that are |
28 | superseded in the results. |
29 | """ |
30 | store = Store.of(self.branch) |
31 | - conditions = [ |
32 | + result = store.find( |
33 | + (BranchMergeProposal, Branch), |
34 | BranchMergeProposal.target_branch == self.branch.id, |
35 | BranchMergeProposal.source_branch == Branch.id, |
36 | - Branch.last_scanned_id.is_in(revision_ids)] |
37 | - if not include_superseded: |
38 | - conditions.append( |
39 | - BranchMergeProposal.queue_status != |
40 | - BranchMergeProposalStatus.SUPERSEDED) |
41 | - result = store.find(BranchMergeProposal, *conditions) |
42 | - return result |
43 | + Branch.last_scanned_id.is_in(revision_ids), |
44 | + (BranchMergeProposal.queue_status != |
45 | + BranchMergeProposalStatus.SUPERSEDED)) |
46 | + |
47 | + proposals = {} |
48 | + for proposal, source in result: |
49 | + # Only show the must recent proposal for any given source. |
50 | + date_created = proposal.date_created |
51 | + source_id = source.id |
52 | + |
53 | + if (source_id not in proposals or |
54 | + date_created > proposals[source_id][1]): |
55 | + proposals[source_id] = (proposal, date_created) |
56 | + |
57 | + return sorted( |
58 | + [proposal for proposal, date_created in proposals.itervalues()], |
59 | + key=operator.attrgetter('date_created'), reverse=True) |
60 | |
61 | def getRevisionMessage(self, revision_id, revno): |
62 | """Return the log message for a revision. |
63 | @@ -654,9 +668,7 @@ |
64 | if len(pretty_authors) > 5: |
65 | outf.write('...\n') |
66 | outf.write('\n') |
67 | - bmps = list( |
68 | - self.findRelatedBMP(merged_revisions, |
69 | - include_superseded=False)) |
70 | + bmps = self.findRelatedBMP(merged_revisions) |
71 | if len(bmps) > 0: |
72 | outf.write('Related merge proposals:\n') |
73 | for bmp in bmps: |
74 | |
75 | === modified file 'lib/lp/code/model/tests/test_branchjob.py' |
76 | --- lib/lp/code/model/tests/test_branchjob.py 2010-01-26 02:05:23 +0000 |
77 | +++ lib/lp/code/model/tests/test_branchjob.py 2010-02-17 00:50:32 +0000 |
78 | @@ -7,6 +7,7 @@ |
79 | |
80 | import datetime |
81 | import os |
82 | +import pytz |
83 | import shutil |
84 | from storm.locals import Store |
85 | import tempfile |
86 | @@ -40,8 +41,8 @@ |
87 | from lp.services.job.model.job import Job |
88 | from lp.code.bzr import BranchFormat, RepositoryFormat |
89 | from lp.code.enums import ( |
90 | - BranchSubscriptionDiffSize, BranchSubscriptionNotificationLevel, |
91 | - CodeReviewNotificationLevel) |
92 | + BranchMergeProposalStatus, BranchSubscriptionDiffSize, |
93 | + BranchSubscriptionNotificationLevel, CodeReviewNotificationLevel) |
94 | from lp.code.interfaces.branchjob import ( |
95 | IBranchDiffJob, IBranchJob, IBranchScanJob, IBranchUpgradeJob, |
96 | IReclaimBranchSpaceJob, IReclaimBranchSpaceJobSource, IRevisionMailJob, |
97 | @@ -546,8 +547,27 @@ |
98 | wrong_target_proposal.source_branch.last_scanned_id = 'rev2a-id' |
99 | job = RevisionsAddedJob.create(target_branch, 'rev2b-id', 'rev2b-id', |
100 | '') |
101 | - self.assertEqual([desired_proposal], |
102 | - list(job.findRelatedBMP(['rev2a-id']))) |
103 | + self.assertEqual( |
104 | + [desired_proposal], job.findRelatedBMP(['rev2a-id'])) |
105 | + |
106 | + def test_findRelatedBMP_one_per_source(self): |
107 | + """findRelatedBMP only returns the most recent proposal for any |
108 | + particular source branch. |
109 | + """ |
110 | + self.useBzrBranches() |
111 | + target_branch, tree = self.create_branch_and_tree('tree') |
112 | + the_past = datetime.datetime(2009, 1, 1, tzinfo=pytz.UTC) |
113 | + old_proposal = self.factory.makeBranchMergeProposal( |
114 | + target_branch=target_branch, date_created=the_past, |
115 | + set_state=BranchMergeProposalStatus.MERGED) |
116 | + source_branch = old_proposal.source_branch |
117 | + source_branch.last_scanned_id = 'rev2a-id' |
118 | + desired_proposal = source_branch.addLandingTarget( |
119 | + source_branch.owner, target_branch) |
120 | + job = RevisionsAddedJob.create( |
121 | + target_branch, 'rev2b-id', 'rev2b-id', '') |
122 | + self.assertEqual( |
123 | + [desired_proposal], job.findRelatedBMP(['rev2a-id'])) |
124 | |
125 | def test_getAuthors(self): |
126 | """Ensure getAuthors returns the authors for the revisions.""" |
The revision mail that goes out includes related merge proposals, which is great as long as one doesn't reuse branches. An example is the pending-db-changes that stub has. This branch only shows the latest merge proposal for any given source branch.