~launchpad-pqm/launchpad/devel

13779.3.4 by Steve Kowalik
Update copyright years, and fix more test failures for dead things.
1
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
8687.15.17 by Karl Fogel
Add the copyright header block to the rest of the files under lib/lp/.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4983.1.1 by Curtis Hovey
Added lint exceptions to __init__.py and interface/*.py.
4
# pylint: disable-msg=E0211,E0213
4414.5.1 by Tim Penhey
Initial cut for branch landing targets.
5
4414.5.2 by Tim Penhey
Renaming from landing target to merge proposal.
6
"""The interface for branch merge proposals."""
4414.5.1 by Tim Penhey
Initial cut for branch landing targets.
7
8
__metaclass__ = type
9
__all__ = [
5600.2.2 by Tim Penhey
Resubmit merge proposals.
10
    'BRANCH_MERGE_PROPOSAL_FINAL_STATES',
4414.5.2 by Tim Penhey
Renaming from landing target to merge proposal.
11
    'IBranchMergeProposal',
6334.6.5 by Aaron Bentley
Get email-to-branch-merge-proposal lookup started
12
    'IBranchMergeProposalGetter',
7658.3.16 by Stuart Bishop
Reapply backed out db changes
13
    'IBranchMergeProposalJob',
7675.624.18 by Tim Penhey
Make one job source for all merge proposal jobs.
14
    'IBranchMergeProposalJobSource',
6475.2.22 by Barry Warsaw
mergeRF
15
    'IBranchMergeProposalListingBatchNavigator',
7675.624.3 by Tim Penhey
Make the code review comment email sent by a job.
16
    'ICodeReviewCommentEmailJob',
17
    'ICodeReviewCommentEmailJobSource',
7659.3.2 by Aaron Bentley
Implement CreateMergeProposalJob
18
    'ICreateMergeProposalJob',
19
    'ICreateMergeProposalJobSource',
11486.4.4 by Aaron Bentley
Fake merge of job removal.
20
    'IGenerateIncrementalDiffJob',
21
    'IGenerateIncrementalDiffJobSource',
11733.1.1 by Tim Penhey
Rename the MergeProposalCreatedJob to be MergeProposalReviewRequestedEmailJob.
22
    'IMergeProposalNeedsReviewEmailJob',
23
    'IMergeProposalNeedsReviewEmailJobSource',
10482.1.16 by Tim Penhey
Register the global utilities.
24
    'IMergeProposalUpdatedEmailJob',
25
    'IMergeProposalUpdatedEmailJobSource',
10482.1.8 by Tim Penhey
Make review requests a job.
26
    'IReviewRequestedEmailJob',
27
    'IReviewRequestedEmailJobSource',
7675.624.49 by Tim Penhey
Not yet passing, but getting close.
28
    'IUpdatePreviewDiffJob',
10100.1.21 by Jonathan Lange
Lots of trivial import fixes.
29
    'IUpdatePreviewDiffJobSource',
10100.1.15 by Jonathan Lange
Fix imports in the scanner. PEP 8 etc.
30
    'notify_modified',
4414.5.1 by Tim Penhey
Initial cut for branch landing targets.
31
    ]
32
7675.429.1 by Tim Penhey
Add interface and expected behaviour tests.
33
9042.1.1 by Aaron Bentley
Implement notify_modified.
34
from lazr.lifecycle.event import ObjectModifiedEvent
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
35
from lazr.restful.declarations import (
36
    call_with,
37
    export_as_webservice_entry,
38
    export_factory_operation,
39
    export_read_operation,
40
    export_write_operation,
41
    exported,
12505.7.7 by Ian Booth
Expose api to devel not 1.0
42
    operation_for_version,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
43
    operation_parameters,
12505.5.3 by Ian Booth
Add getRelatedBugTasks to webservice interface
44
    operation_returns_collection_of,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
45
    operation_returns_entry,
46
    rename_parameters_as,
47
    REQUEST_USER,
48
    )
49
from lazr.restful.fields import (
50
    CollectionField,
51
    Reference,
11812.2.2 by Aaron Bentley
Provide new resubmit UI.
52
    ReferenceChoice,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
53
    )
9042.1.1 by Aaron Bentley
Implement notify_modified.
54
from zope.event import notify
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
55
from zope.interface import (
56
    Attribute,
57
    Interface,
58
    )
7658.3.16 by Stuart Bishop
Reapply backed out db changes
59
from zope.schema import (
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
60
    Bool,
61
    Bytes,
62
    Choice,
63
    Datetime,
64
    Int,
65
    Object,
66
    Text,
67
    TextLine,
68
    )
4414.5.1 by Tim Penhey
Initial cut for branch landing targets.
69
11812.2.1 by Aaron Bentley
Allow changing branches, description and ignoring link.
70
from canonical.database.constants import DEFAULT
14600.1.12 by Curtis Hovey
Move i18n to lp.
71
from lp import _
14560.2.25 by Curtis Hovey
Merged c.l.interfaces.launchpad with lp.app.interfaces.launchpad.
72
from lp.app.interfaces.launchpad import IPrivacy
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
73
from canonical.launchpad.webapp.interfaces import ITableBatchNavigator
74
from lp.code.enums import (
75
    BranchMergeProposalStatus,
76
    CodeReviewVote,
77
    )
8138.1.2 by Jonathan Lange
Run migrater over lp.code. Many tests broken and imports failing.
78
from lp.code.interfaces.branch import IBranch
13779.3.1 by Steve Kowalik
Consign StaticDiff and all that supported it to a watery grave.
79
from lp.code.interfaces.diff import IPreviewDiff
8138.1.2 by Jonathan Lange
Run migrater over lp.code. Many tests broken and imports failing.
80
from lp.registry.interfaces.person import IPerson
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
81
from lp.services.fields import (
14509.2.1 by Ian Booth
Change reviewer attribute validation to allow mp to be reviewed by private teams
82
    PersonChoice,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
83
    PublicPersonChoice,
84
    Summary,
85
    Whiteboard,
86
    )
87
from lp.services.job.interfaces.job import (
88
    IJob,
89
    IJobSource,
90
    IRunnableJob,
7675.845.24 by Edwin Grubbs
Addressed more reviewer comments.
91
    ITwistedJobSource,
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
92
    )
4414.6.1 by Tim Penhey
Missed import
93
4414.5.1 by Tim Penhey
Initial cut for branch landing targets.
94
5600.2.2 by Tim Penhey
Resubmit merge proposals.
95
BRANCH_MERGE_PROPOSAL_FINAL_STATES = (
5600.2.1 by Tim Penhey
State transition test complete.
96
    BranchMergeProposalStatus.REJECTED,
97
    BranchMergeProposalStatus.MERGED,
5600.2.10 by Tim Penhey
Rename supercede to supersede, and shorten the databse field name.
98
    BranchMergeProposalStatus.SUPERSEDED,
5600.2.1 by Tim Penhey
State transition test complete.
99
    )
100
5280.3.4 by Tim Penhey
Getting the interface for the merge proposal to match the tests.
101
9373.2.1 by Aaron Bentley
Implement IPrivacy for BranchMergeProposal.
102
class IBranchMergeProposal(IPrivacy):
4414.5.2 by Tim Penhey
Renaming from landing target to merge proposal.
103
    """Branch merge proposals show intent of landing one branch on another."""
4414.5.1 by Tim Penhey
Initial cut for branch landing targets.
104
7325.8.3 by Paul Hummer
Fixed the test, and now bmp's can be fetched through the API.
105
    export_as_webservice_entry()
106
4414.6.3 by Tim Penhey
Making sure the tests actually pass.
107
    id = Int(
108
        title=_('DB ID'), required=True, readonly=True,
12328.2.2 by Curtis Hovey
Fixed the IBranchMergeProposal documentation.
109
        description=_("The tracking number for this merge proposal."))
4414.6.3 by Tim Penhey
Making sure the tests actually pass.
110
7325.8.13 by Paul Hummer
Added registrant_link attribute
111
    registrant = exported(
112
        PublicPersonChoice(
113
            title=_('Person'), required=True,
114
            vocabulary='ValidPersonOrTeam', readonly=True,
12328.2.2 by Curtis Hovey
Fixed the IBranchMergeProposal documentation.
115
            description=_('The person who registered the merge proposal.')))
4414.5.1 by Tim Penhey
Initial cut for branch landing targets.
116
7325.8.4 by Paul Hummer
Added source branch attribute to bmp api
117
    source_branch = exported(
11812.2.2 by Aaron Bentley
Provide new resubmit UI.
118
        ReferenceChoice(
119
            title=_('Source Branch'), schema=IBranch, vocabulary='Branch',
7325.8.4 by Paul Hummer
Added source branch attribute to bmp api
120
            required=True, readonly=True,
121
            description=_("The branch that has code to land.")))
4414.5.1 by Tim Penhey
Initial cut for branch landing targets.
122
7325.8.5 by Paul Hummer
Added target_branch attribute
123
    target_branch = exported(
11812.2.2 by Aaron Bentley
Provide new resubmit UI.
124
        ReferenceChoice(
7325.8.5 by Paul Hummer
Added target_branch attribute
125
            title=_('Target Branch'),
11812.2.2 by Aaron Bentley
Provide new resubmit UI.
126
            schema=IBranch, vocabulary='Branch', required=True, readonly=True,
7325.8.5 by Paul Hummer
Added target_branch attribute
127
            description=_(
128
                "The branch that the source branch will be merged into.")))
4414.5.1 by Tim Penhey
Initial cut for branch landing targets.
129
7675.343.1 by Aaron Bentley
Rename dependent branch to prerequisite branch.
130
    prerequisite_branch = exported(
11812.2.2 by Aaron Bentley
Provide new resubmit UI.
131
        ReferenceChoice(
132
            title=_('Prerequisite Branch'),
133
            schema=IBranch, vocabulary='Branch', required=False,
134
            readonly=True, description=_(
135
                "The branch that the source branch branched from. "
11812.2.10 by Aaron Bentley
Updates from review.
136
                "If this branch is the same as the target branch, then "
11812.2.2 by Aaron Bentley
Provide new resubmit UI.
137
                "leave this field blank.")))
4414.5.2 by Tim Penhey
Renaming from landing target to merge proposal.
138
9373.2.1 by Aaron Bentley
Implement IPrivacy for BranchMergeProposal.
139
    # This is redefined from IPrivacy.private because the attribute is
140
    # read-only. The value is determined by the involved branches.
141
    private = exported(
142
        Bool(
143
            title=_("Proposal is confidential"), required=False,
144
            readonly=True, default=False,
145
            description=_(
146
                "If True, this proposal is visible only to subscribers.")))
147
7675.548.1 by Tim Penhey
Add a description for the merge proposal.
148
    description = exported(
10427.15.4 by Tim Penhey
Include changes to the description in modification email.
149
        Text(title=_('Description'), required=False,
7675.548.1 by Tim Penhey
Add a description for the merge proposal.
150
             description=_(
151
                "A detailed description of the changes that are being "
152
                "addressed by the branch being proposed to be merged."),
153
             max_length=50000))
154
4414.5.2 by Tim Penhey
Renaming from landing target to merge proposal.
155
    whiteboard = Whiteboard(
156
        title=_('Whiteboard'), required=False,
157
        description=_('Notes about the merge.'))
158
7325.8.7 by Paul Hummer
Added queue_states attribute
159
    queue_status = exported(
160
        Choice(
161
            title=_('Status'),
7573.2.2 by Paul Hummer
Added try/except block, catching the oops
162
            vocabulary=BranchMergeProposalStatus, required=True,
163
            readonly=True,
7325.8.7 by Paul Hummer
Added queue_states attribute
164
            description=_("The current state of the proposal.")))
5280.3.4 by Tim Penhey
Getting the interface for the merge proposal to match the tests.
165
7839.4.10 by Jonathan Lange
Clarify the interface a bit
166
    # Not to be confused with a code reviewer. A code reviewer is someone who
167
    # can vote or has voted on a proposal.
7325.8.14 by Paul Hummer
Added reviewer_link attribute
168
    reviewer = exported(
14509.2.1 by Ian Booth
Change reviewer attribute validation to allow mp to be reviewed by private teams
169
        PersonChoice(
7325.8.14 by Paul Hummer
Added reviewer_link attribute
170
            title=_('Review person or team'), required=False,
7325.8.20 by Paul Hummer
Made changes requested in the review
171
            readonly=True, vocabulary='ValidPersonOrTeam',
7325.8.14 by Paul Hummer
Added reviewer_link attribute
172
            description=_("The person that accepted (or rejected) the code "
173
                          "for merging.")))
6821.4.1 by Aaron Bentley
Ensure root_message_id is recorded when known
174
10054.23.8 by Aaron Bentley
Update from review.
175
    next_preview_diff_job = Attribute(
176
        'The next BranchMergeProposalJob that will update a preview diff.')
10054.23.1 by Aaron Bentley
Merged stable into jobstatus.
177
7667.9.3 by Tim Penhey
Merge in the updates from the -orm branch review.
178
    preview_diff = exported(
7667.9.2 by Tim Penhey
Reworking interface inheritance, and using delegates for object composition.
179
        Reference(
180
            IPreviewDiff,
181
            title=_('The current diff of the source branch against the '
182
                    'target branch.'), readonly=True))
7667.8.1 by Tim Penhey
Initial ORM stuff for preview diffs.
183
8879.3.9 by Paul Hummer
Exposed IBranchMergeProposal.setStatus through the API
184
    reviewed_revision_id = exported(
185
        Text(
10100.1.15 by Jonathan Lange
Fix imports in the scanner. PEP 8 etc.
186
            title=_(
187
                "The revision id that has been approved by the reviewer.")),
7675.508.7 by Tim Penhey
Fix the broken tests.
188
        exported_as='reviewed_revid')
5579.1.1 by Tim Penhey
Added the new fields.
189
7325.8.8 by Paul Hummer
Added commit_message attribute
190
    commit_message = exported(
191
        Summary(
192
            title=_("Commit Message"), required=False,
193
            description=_("The commit message that should be used when "
9737.2.7 by Tim Penhey
Change the launchpad fields to allow stripping of the text.
194
                          "merging the source branch."),
195
            strip_text=True))
5579.1.1 by Tim Penhey
Added the new fields.
196
7325.8.9 by Paul Hummer
Added queue_position attribute
197
    queue_position = exported(
198
        Int(
199
            title=_("Queue Position"), required=False, readonly=True,
200
            description=_("The position in the queue.")))
5579.1.11 by Tim Penhey
Changed the schema to use Choice and Int rather than attribute.
201
7325.8.15 by Paul Hummer
Added queuer_link attribute
202
    queuer = exported(
203
        PublicPersonChoice(
204
            title=_('Queuer'), vocabulary='ValidPerson',
205
            required=False, readonly=True,
206
            description=_("The person that queued up the branch.")))
5579.1.11 by Tim Penhey
Changed the schema to use Choice and Int rather than attribute.
207
7325.8.17 by Paul Hummer
Added queued_revision_id attribute
208
    queued_revision_id = exported(
209
        Text(
210
            title=_("Queued Revision ID"), readonly=True,
7325.8.20 by Paul Hummer
Made changes requested in the review
211
            required=False,
7325.8.17 by Paul Hummer
Added queued_revision_id attribute
212
            description=_("The revision id that has been queued for "
8879.3.12 by Paul Hummer
Changed references to revision_id to be revno in the API
213
                          "landing.")),
7675.508.7 by Tim Penhey
Fix the broken tests.
214
        exported_as='queued_revid')
5579.1.1 by Tim Penhey
Added the new fields.
215
7325.8.25 by Paul Hummer
Reverted the hack to expose merge proposal merged_revno
216
    merged_revno = exported(
217
        Int(
7325.8.10 by Paul Hummer
merged_revno attribute added
218
            title=_("Merged Revision Number"), required=False,
7325.8.27 by Paul Hummer
Made merged_revno readonly again
219
            readonly=True,
7325.8.10 by Paul Hummer
merged_revno attribute added
220
            description=_("The revision number on the target branch which "
7325.8.25 by Paul Hummer
Reverted the hack to expose merge proposal merged_revno
221
                          "contains the merge from the source branch.")))
7325.8.23 by Paul Hummer
Added read_only attribute to the interfaces
222
7325.8.11 by Paul Hummer
Addded date_merged attribute
223
    date_merged = exported(
224
        Datetime(
225
            title=_('Date Merged'), required=False,
7325.8.20 by Paul Hummer
Made changes requested in the review
226
            readonly=True,
7325.8.11 by Paul Hummer
Addded date_merged attribute
227
            description=_("The date that the source branch was merged into "
228
                          "the target branch")))
4414.6.8 by Tim Penhey
Added two necessary fields.
229
6475.2.22 by Barry Warsaw
mergeRF
230
    title = Attribute(
231
        "A nice human readable name to describe the merge proposal. "
232
        "This is generated from the source and target branch, and used "
233
        "as the tal fmt:link text and for email subjects.")
234
7325.8.16 by Paul Hummer
Added merge_reporter attribute
235
    merge_reporter = exported(
236
        PublicPersonChoice(
237
            title=_("Merge Reporter"), vocabulary="ValidPerson",
238
            required=False, readonly=True,
239
            description=_("The user that marked the branch as merged.")))
4414.6.12 by Tim Penhey
Updates following DB review
240
7325.8.18 by Paul Hummer
Added supersedes and superseded by
241
    supersedes = exported(
242
        Reference(
243
            title=_("Supersedes"),
7325.8.20 by Paul Hummer
Made changes requested in the review
244
            schema=Interface, required=False, readonly=True,
7325.8.18 by Paul Hummer
Added supersedes and superseded by
245
            description=_("The branch merge proposal that this one "
246
                          "supersedes.")))
247
    superseded_by = exported(
248
        Reference(
249
            title=_("Superseded By"), schema=Interface,
7325.8.20 by Paul Hummer
Made changes requested in the review
250
            required=False, readonly=True,
7325.8.18 by Paul Hummer
Added supersedes and superseded by
251
            description=_(
252
                "The branch merge proposal that supersedes this one.")))
5600.2.1 by Tim Penhey
State transition test complete.
253
7325.8.12 by Paul Hummer
Added date attributes
254
    date_created = exported(
255
        Datetime(
256
            title=_('Date Created'), required=True, readonly=True))
257
    date_review_requested = exported(
258
        Datetime(
259
            title=_('Date Review Requested'), required=False, readonly=True))
260
    date_reviewed = exported(
261
        Datetime(
262
            title=_('Date Reviewed'), required=False, readonly=True))
263
    date_queued = exported(
264
        Datetime(
265
            title=_('Date Queued'), required=False, readonly=True))
6821.4.1 by Aaron Bentley
Ensure root_message_id is recorded when known
266
    root_message_id = Text(
267
        title=_('The email message id from the first message'),
268
        required=False)
7719.1.2 by Paul Hummer
Exposed IBranchMergeProposal.all_comments through the API
269
    all_comments = exported(
270
        CollectionField(
271
            title=_("All messages discussing this merge proposal"),
14027.3.1 by Jeroen Vermeulen
Fix lots of lint in recently-changed files.
272
            # Really ICodeReviewComment.
273
            value_type=Reference(schema=Interface),
7719.1.2 by Paul Hummer
Exposed IBranchMergeProposal.all_comments through the API
274
            readonly=True))
5280.3.4 by Tim Penhey
Getting the interface for the merge proposal to match the tests.
275
7735.4.6 by Tim Penhey
Might as well expose the address through the api.
276
    address = exported(
277
        TextLine(
278
            title=_('The email address for this proposal.'),
279
            readonly=True,
280
            description=_('Any emails sent to this address will result'
281
                          'in comments being added.')))
7719.2.1 by Paul Hummer
Exposed getComment through the API
282
283
    @operation_parameters(
7719.2.2 by Paul Hummer
Got getMessage entirely working.
284
        id=Int(
285
            title=_("A CodeReviewComment ID.")))
14027.3.1 by Jeroen Vermeulen
Fix lots of lint in recently-changed files.
286
    # Really ICodeReviewComment.
287
    @operation_returns_entry(Interface)
7719.2.1 by Paul Hummer
Exposed getComment through the API
288
    @export_read_operation()
6334.6.36 by Aaron Bentley
Rename code review messages to code review comments
289
    def getComment(id):
290
        """Return the CodeReviewComment with the specified ID."""
5608.11.5 by Aaron Bentley
Make comment pages reachable
291
12505.5.5 by Ian Booth
Fix merge issues
292
    @call_with(user=REQUEST_USER)
14027.3.1 by Jeroen Vermeulen
Fix lots of lint in recently-changed files.
293
    # Really IBugTask.
294
    @operation_returns_collection_of(Interface)
12505.5.5 by Ian Booth
Fix merge issues
295
    @export_read_operation()
12505.7.7 by Ian Booth
Expose api to devel not 1.0
296
    @operation_for_version('devel')
12505.6.1 by Ian Booth
Remove DecoratedBug and refactor mp linked_bugs to use branch.getRelatedBugTasks
297
    def getRelatedBugTasks(user):
298
        """Return the Bug tasks related to this merge proposal."""
299
11486.2.7 by Aaron Bentley
Move revision selection to model code.
300
    def getRevisionsSinceReviewStart():
301
        """Return all the revisions added since the review began.
302
303
        Revisions are grouped by creation (i.e. push) time.
304
        :return: An iterator of (date, iterator of revision data)
305
        """
306
7719.2.21 by Paul Hummer
Fixed a busticated reference
307
    def getVoteReference(id):
7719.2.15 by Paul Hummer
Implemented getVote for IBranchMergeProposal
308
        """Return the CodeReviewVoteReference with the specified ID."""
309
5608.7.1 by Aaron Bentley
Start work on updates
310
    def getNotificationRecipients(min_level):
311
        """Return the people who should be notified.
5608.5.8 by Aaron Bentley
Docs and cleanup
312
313
        Recipients will be returned as a dictionary where the key is the
314
        person, and the values are (subscription, rationale) tuples.
315
316
        :param min_level: The minimum notification level needed to be
317
            notified.
318
        """
319
5608.9.16 by Aaron Bentley
Updates from review
320
    # Cannot specify value type without creating a circular dependency
7944.2.2 by Paul Hummer
Added code to make the tests pass, exposing IBranchMergeProposal.votes
321
    votes = exported(
322
        CollectionField(
323
            title=_('The votes cast or expected for this proposal'),
14027.3.1 by Jeroen Vermeulen
Fix lots of lint in recently-changed files.
324
            # Really ICodeReviewVoteReference.
325
            value_type=Reference(schema=Interface),
10100.1.15 by Jonathan Lange
Fix imports in the scanner. PEP 8 etc.
326
            readonly=True,
7944.2.2 by Paul Hummer
Added code to make the tests pass, exposing IBranchMergeProposal.votes
327
            )
5608.9.16 by Aaron Bentley
Updates from review
328
        )
5608.9.2 by Aaron Bentley
Change createVote to nominateReviewer, add BranchMergeProposal.votes
329
5579.2.4 by Tim Penhey
UI works now.
330
    def isValidTransition(next_state, user=None):
331
        """True if it is valid for user update the proposal to next_state."""
332
8879.3.9 by Paul Hummer
Exposed IBranchMergeProposal.setStatus through the API
333
    @call_with(user=REQUEST_USER)
7675.508.1 by Tim Penhey
Send the revision id as well.
334
    @rename_parameters_as(revision_id='revid')
8879.3.9 by Paul Hummer
Exposed IBranchMergeProposal.setStatus through the API
335
    @operation_parameters(
336
        status=Choice(
337
            title=_("The new status of the merge proposal."),
338
            vocabulary=BranchMergeProposalStatus),
8879.3.12 by Paul Hummer
Changed references to revision_id to be revno in the API
339
        revision_id=Text(
340
            description=_("An optional parameter for specifying the "
341
                "revision of the branch for the status change."),
342
            required=False))
8879.3.9 by Paul Hummer
Exposed IBranchMergeProposal.setStatus through the API
343
    @export_write_operation()
344
    def setStatus(status, user, revision_id):
8879.3.1 by Paul Hummer
Added setState to IBranchMergeProposal
345
        """Set the state of the merge proposal to the specified status.
346
347
        :param status: The new status of the merge proposal.
8879.3.7 by Paul Hummer
Changed the method to setStatus
348
        :param user: The user making the change.
7675.508.1 by Tim Penhey
Send the revision id as well.
349
        :param revision_id: The revision id to provide to the underlying
350
            status change method.
8879.3.1 by Paul Hummer
Added setState to IBranchMergeProposal
351
        """
352
5280.3.9 by Tim Penhey
Updates following review
353
    def setAsWorkInProgress():
354
        """Set the state of the merge proposal to 'Work in progress'.
355
356
        This is often useful if the proposal was rejected and is being worked
357
        on again, or if the code failed to merge and requires rework.
358
        """
359
5280.3.4 by Tim Penhey
Getting the interface for the merge proposal to match the tests.
360
    def requestReview():
361
        """Set the state of merge proposal to 'Needs review'.
362
363
        As long as the branch is not yet merged, a review can be requested.
364
        Requesting a review sets the date_review_requested.
365
        """
366
5280.3.6 by Tim Penhey
Added in the reviewed revision id.
367
    def approveBranch(reviewer, revision_id):
5280.3.5 by Tim Penhey
Tests pass, however still need to change to record revision numbers.
368
        """Mark the proposal as 'Code approved'.
5280.3.4 by Tim Penhey
Getting the interface for the merge proposal to match the tests.
369
370
        The time that the branch was approved is recoreded in `date_reviewed`.
371
5280.4.3 by Tim Penhey
Workflow works nicely, resisting hard gold plating.
372
        :param reviewer: A person authorised to review branches for merging.
373
        :param revision_id: The revision id of the branch that was
5280.3.6 by Tim Penhey
Added in the reviewed revision id.
374
                            reviewed by the `reviewer`.
375
5280.3.4 by Tim Penhey
Getting the interface for the merge proposal to match the tests.
376
        :raises: UserNotBranchReviewer if the reviewer is not in the team of
377
                 the branch reviewer for the target branch.
378
        """
379
5280.4.3 by Tim Penhey
Workflow works nicely, resisting hard gold plating.
380
    def rejectBranch(reviewer, revision_id):
5280.3.5 by Tim Penhey
Tests pass, however still need to change to record revision numbers.
381
        """Mark the proposal as 'Rejected'.
5280.3.4 by Tim Penhey
Getting the interface for the merge proposal to match the tests.
382
383
        The time that the branch was rejected is recoreded in `date_reviewed`.
384
5280.4.3 by Tim Penhey
Workflow works nicely, resisting hard gold plating.
385
        :param reviewer: A person authorised to review branches for merging.
386
        :param revision_id: The revision id of the branch that was
387
                            reviewed by the `reviewer`.
388
5280.3.4 by Tim Penhey
Getting the interface for the merge proposal to match the tests.
389
        :raises: UserNotBranchReviewer if the reviewer is not in the team of
390
                 the branch reviewer for the target branch.
391
        """
392
5579.1.2 by Tim Penhey
Test now passes.
393
    def enqueue(queuer, revision_id):
394
        """Put the proposal into the merge queue for the target branch.
395
396
        If the proposal is not in the Approved state before this method
397
        is called, approveBranch is called with the reviewer and revision_id
398
        specified.
10721.3.1 by Robert Collins
Use the reviewed revision id by default when queueing merge proposals. Also permit a non reviewer to retry a merge-failed proposal.
399
10721.3.3 by Robert Collins
Action review feedback: nuke tabs, delete mergeFailed as its buggy, unused and redundant.
400
        If None is supplied as the revision_id, the proposals
401
        reviewed_revision_id is used.
5579.1.2 by Tim Penhey
Test now passes.
402
        """
403
404
    def dequeue():
405
        """Take the proposal out of the merge queue of the target branch.
406
407
        :raises: BadStateTransition if the proposal is not in the queued
408
                 state.
409
        """
410
411
    def moveToFrontOfQueue():
412
        """Move the queue proposal to the front of the queue."""
413
5280.4.5 by Tim Penhey
A few make lint updates
414
    def markAsMerged(merged_revno=None, date_merged=None,
415
                     merge_reporter=None):
4414.6.8 by Tim Penhey
Added two necessary fields.
416
        """Mark the branch merge proposal as merged.
417
5280.4.5 by Tim Penhey
A few make lint updates
418
        If the `merged_revno` is supplied, then the `BranchRevision` is
419
        checked to see that revision is available in the target branch.  If it
420
        is then the date from that revision is used as the `date_merged`.  If
421
        it is not available, then the `date_merged` is set as if the
422
        merged_revno was not supplied.
4414.6.8 by Tim Penhey
Added two necessary fields.
423
5280.4.5 by Tim Penhey
A few make lint updates
424
        If no `merged_revno` is supplied, the `date_merged` is set to the
425
        value of date_merged, or if the parameter date_merged is None, then
426
        UTC_NOW is used.
4414.6.8 by Tim Penhey
Added two necessary fields.
427
428
        :param merged_revno: The revision number in the target branch that
429
                             contains the merge of the source branch.
430
        :type merged_revno: ``int``
431
432
        :param date_merged: The date/time that the merge took place.
433
        :type merged_revno: ``datetime`` or a stringified date time value.
4414.6.12 by Tim Penhey
Updates following DB review
434
435
        :param merge_reporter: The user that is marking the branch as merged.
436
        :type merge_reporter: ``Person``
4414.6.8 by Tim Penhey
Added two necessary fields.
437
        """
5280.4.1 by Tim Penhey
Adding menu bits.
438
11812.2.1 by Aaron Bentley
Allow changing branches, description and ignoring link.
439
    def resubmit(registrant, source_branch=None, target_branch=None,
440
                 prerequisite_branch=DEFAULT):
5600.2.10 by Tim Penhey
Rename supercede to supersede, and shorten the databse field name.
441
        """Mark the branch merge proposal as superseded and return a new one.
5600.2.1 by Tim Penhey
State transition test complete.
442
443
        The new proposal is created as work-in-progress, and copies across
9327.2.6 by Aaron Bentley
Add tests and docs for BMP.resubmit changes.
444
        user-entered data like the whiteboard.  All the current proposal's
445
        reviewers, including those who have only been nominated, are requested
446
        to review the new proposal.
11812.2.1 by Aaron Bentley
Allow changing branches, description and ignoring link.
447
448
        :param registrant: The person registering the new proposal.
449
        :param source_branch: The source_branch for the new proposal (defaults
450
            to the current source_branch).
451
        :param target_branch: The target_branch for the new proposal (defaults
452
            to the current target_branch).
453
        :param prerequisite_branch: The prerequisite_branch for the new
454
            proposal (defaults to the current prerequisite_branch).
455
        :param description: The description for the new proposal (defaults to
456
            the current description).
5600.2.1 by Tim Penhey
State transition test complete.
457
        """
458
459
    def isMergable():
5600.2.8 by Tim Penhey
Updates following review.
460
        """Is the proposal in a state that allows it to being merged?
5280.4.1 by Tim Penhey
Adding menu bits.
461
5600.2.1 by Tim Penhey
State transition test complete.
462
        As long as the proposal isn't in one of the end states, it is valid
463
        to be merged.
5280.4.3 by Tim Penhey
Workflow works nicely, resisting hard gold plating.
464
        """
465
5280.4.14 by Tim Penhey
More ui tweaks.
466
    def getUnlandedSourceBranchRevisions():
5280.4.25 by Tim Penhey
Updates following review.
467
        """Return a sequence of `BranchRevision` objects.
5280.4.3 by Tim Penhey
Workflow works nicely, resisting hard gold plating.
468
12599.4.2 by Leonard Richardson
Merge from trunk.
469
        Returns up to 10 revisions that are in the revision history for the
5280.4.3 by Tim Penhey
Workflow works nicely, resisting hard gold plating.
470
        source branch that are not in the revision history of the target
471
        branch.  These are the revisions that have been committed to the
472
        source branch since it branched off the target branch.
5280.4.1 by Tim Penhey
Adding menu bits.
473
        """
5575.1.4 by Aaron Bentley
Implement objects for code review messages
474
7719.2.10 by Paul Hummer
Exposed ICodeReviewVoteReference through the API
475
    @operation_parameters(
476
        reviewer=Reference(
477
            title=_("A reviewer."), schema=IPerson),
478
        review_type=Text())
7719.2.11 by Paul Hummer
Working around circular imports still
479
    @call_with(registrant=REQUEST_USER)
14027.3.1 by Jeroen Vermeulen
Fix lots of lint in recently-changed files.
480
    # Really ICodeReviewVoteReference.
481
    @operation_returns_entry(Interface)
7719.2.10 by Paul Hummer
Exposed ICodeReviewVoteReference through the API
482
    @export_write_operation()
6438.2.3 by Tim Penhey
Add the tables for reviews done, and requested reviews.
483
    def nominateReviewer(reviewer, registrant, review_type=None):
6438.3.19 by Aaron Bentley
Update doc
484
        """Set the specified person as a reviewer.
485
486
        If they are not already a reviewer, a vote is created.  Otherwise,
487
        the details are updated.
488
        """
5608.9.1 by Aaron Bentley
Initial cut of CodeReviewVote support
489
7055.6.11 by Tim Penhey
Lots of changes to do with the request reviewer, voting and comment pages.
490
    def getUsersVoteReference(user):
491
        """Get the existing vote reference for the given user.
492
493
        :return: A `CodeReviewVoteReference` or None.
494
        """
495
7719.2.11 by Paul Hummer
Working around circular imports still
496
    @operation_parameters(
497
        subject=Text(), content=Text(),
8555.2.9 by Tim Penhey
Move CodeReviewVote enum.
498
        vote=Choice(vocabulary=CodeReviewVote), review_type=Text(),
7719.2.11 by Paul Hummer
Working around circular imports still
499
        parent=Reference(schema=Interface))
500
    @call_with(owner=REQUEST_USER)
9601.3.5 by Aaron Bentley
Fix comment
501
    # ICodeReviewComment supplied as Interface to avoid circular imports.
502
    @export_factory_operation(Interface, [])
7055.6.11 by Tim Penhey
Lots of changes to do with the request reviewer, voting and comment pages.
503
    def createComment(owner, subject, content=None, vote=None,
7334.4.3 by Tim Penhey
Remove the date_created from the interface definition for createComment.
504
                      review_type=None, parent=None):
6334.6.39 by Aaron Bentley
Fix a few missed instances.
505
        """Create an ICodeReviewComment associated with this merge proposal.
5575.1.4 by Aaron Bentley
Implement objects for code review messages
506
507
        :param owner: The person who the message is from.
508
        :param subject: The subject line to use for the message.
509
        :param content: The text to use for the message content.  If
510
            unspecified, the text of the merge proposal is used.
6334.6.39 by Aaron Bentley
Fix a few missed instances.
511
        :param parent: The previous CodeReviewComment in the thread.  If
5575.1.4 by Aaron Bentley
Implement objects for code review messages
512
            unspecified, the root message is used.
513
        """
5575.1.23 by Aaron Bentley
Add object wrapping for CodeReviewSubscription
514
7407.1.11 by Tim Penhey
Add the original attachments if they are ones we'd display.
515
    def createCommentFromMessage(message, vote, review_type,
8970.5.5 by Aaron Bentley
Update interface
516
                                 original_email):
6334.6.36 by Aaron Bentley
Rename code review messages to code review comments
517
        """Create an `ICodeReviewComment` from an IMessage.
6334.6.28 by Aaron Bentley
More text tweaks
518
519
        :param message: The IMessage to use.
520
        :param vote: A CodeReviewVote (or None).
7055.6.11 by Tim Penhey
Lots of changes to do with the request reviewer, voting and comment pages.
521
        :param review_type: A string (or None).
8970.5.5 by Aaron Bentley
Update interface
522
        :param original_email: Original email message.
6334.6.28 by Aaron Bentley
More text tweaks
523
        """
6334.6.9 by Aaron Bentley
Implement message creation from email handler
524
5600.2.6 by Tim Penhey
Fixed delete.
525
    def deleteProposal():
526
        """Delete the proposal to merge."""
6334.6.5 by Aaron Bentley
Get email-to-branch-merge-proposal lookup started
527
7667.9.5 by Tim Penhey
Expose the updatePreviewDiff through the API.
528
    @operation_parameters(
9222.4.11 by Aaron Bentley
Remove diffstat parameter from pretty much everything.
529
        diff_content=Bytes(), source_revision_id=TextLine(),
7675.343.1 by Aaron Bentley
Rename dependent branch to prerequisite branch.
530
        target_revision_id=TextLine(), prerequisite_revision_id=TextLine(),
9222.4.11 by Aaron Bentley
Remove diffstat parameter from pretty much everything.
531
        conflicts=Text())
7667.9.5 by Tim Penhey
Expose the updatePreviewDiff through the API.
532
    @export_write_operation()
9222.4.11 by Aaron Bentley
Remove diffstat parameter from pretty much everything.
533
    def updatePreviewDiff(diff_content, source_revision_id,
7675.343.1 by Aaron Bentley
Rename dependent branch to prerequisite branch.
534
                          target_revision_id, prerequisite_revision_id=None,
9222.4.11 by Aaron Bentley
Remove diffstat parameter from pretty much everything.
535
                          conflicts=None):
7667.8.3 by Tim Penhey
Renamed merge_diff to preview_diff and more review comments.
536
        """Update the preview diff for this proposal.
7667.8.1 by Tim Penhey
Initial ORM stuff for preview diffs.
537
7667.8.4 by Tim Penhey
Removed commented out Store.add, and fix a missed merge_diff -> preview_diff rename.
538
        If there is not an existing preview diff, one will be created.
7667.8.3 by Tim Penhey
Renamed merge_diff to preview_diff and more review comments.
539
540
        :param diff_content: The raw bytes of the diff content to be put in
541
            the librarian.
7667.8.1 by Tim Penhey
Initial ORM stuff for preview diffs.
542
        :param diff_stat: Text describing the files added, remove or modified.
543
        :param source_revision_id: The revision id that was used from the
544
            source branch.
545
        :param target_revision_id: The revision id that was used from the
546
            target branch.
11486.2.8 by Aaron Bentley
lint fixes.
547
        :param prerequisite_revision_id: The revision id that was used from
548
            the prerequisite branch.
7667.8.1 by Tim Penhey
Initial ORM stuff for preview diffs.
549
        :param conflicts: Text describing the conflicts if any.
550
        """
551
552
7658.3.16 by Stuart Bishop
Reapply backed out db changes
553
class IBranchMergeProposalJob(Interface):
554
    """A Job related to a Branch Merge Proposal."""
555
9963.7.2 by Aaron Bentley
Allow BranchMergeProposal jobs to be retrieved by their id.
556
    id = Int(
557
        title=_('DB ID'), required=True, readonly=True,
558
        description=_("The tracking number for this job."))
559
7658.3.16 by Stuart Bishop
Reapply backed out db changes
560
    branch_merge_proposal = Object(
561
        title=_('The BranchMergeProposal this job is about'),
562
        schema=IBranchMergeProposal, required=True)
563
564
    job = Object(title=_('The common Job attributes'), schema=IJob,
565
        required=True)
566
567
    metadata = Attribute('A dict of data about the job.')
568
569
    def destroySelf():
570
        """Destroy this object."""
571
7628.1.1 by Aaron Bentley
Get ReviewDiffJob.run working.
572
7675.845.24 by Edwin Grubbs
Addressed more reviewer comments.
573
class IBranchMergeProposalJobSource(ITwistedJobSource):
7675.624.18 by Tim Penhey
Make one job source for all merge proposal jobs.
574
    """A job source that will get all supported merge proposal jobs."""
575
11486.4.13 by Aaron Bentley
Lint fixes.
576
11486.4.4 by Aaron Bentley
Fake merge of job removal.
577
class IBranchMergeProposalJobSource(IJobSource):
578
    """A job source that will get all supported merge proposal jobs."""
7675.624.18 by Tim Penhey
Make one job source for all merge proposal jobs.
579
11486.4.13 by Aaron Bentley
Lint fixes.
580
6475.2.22 by Barry Warsaw
mergeRF
581
class IBranchMergeProposalListingBatchNavigator(ITableBatchNavigator):
582
    """A marker interface for registering the appropriate listings."""
583
584
6334.6.5 by Aaron Bentley
Get email-to-branch-merge-proposal lookup started
585
class IBranchMergeProposalGetter(Interface):
586
    """Utility for getting BranchMergeProposals."""
587
588
    def get(id):
589
        """Return the BranchMergeProposal with specified id."""
6461.3.1 by Tim Penhey
Initial work for merge proposal listings.
590
591
    def getProposalsForContext(context, status=None, visible_by_user=None):
592
        """Return BranchMergeProposals associated with the context.
593
7839.4.2 by Jonathan Lange
Improve docstrings a bit.
594
        :param context: Either an `IPerson` or `IProduct`.
6461.3.1 by Tim Penhey
Initial work for merge proposal listings.
595
        :param status: An iterable of queue_status of the proposals to return.
596
            If None is specified, all the proposals of all possible states
597
            are returned.
598
        :param visible_by_user: If a person is not supplied, only merge
599
            proposals based on public branches are returned.  If a person is
600
            supplied, merge proposals based on both public branches, and the
601
            private branches that the person is entitled to see are returned.
602
            Private branches are only visible to the owner and subscribers of
603
            the branch, and to LP admins.
6461.3.6 by Tim Penhey
Updates following review.
604
        :raises BadBranchMergeProposalSearchContext: If the context is not
6461.3.1 by Tim Penhey
Initial work for merge proposal listings.
605
            understood.
606
        """
6475.2.22 by Barry Warsaw
mergeRF
607
8615.10.3 by Paul Hummer
Added getProposalsForParticipant to get proposals by participant
608
    def getProposalsForParticipant(participant, status=None,
609
        visible_by_user=None):
610
        """Return BranchMergeProposals associated with the context.
611
612
        :param participant: An `IPerson` that is participating in the merge
613
            proposal, either a reviewer or reviewee.
614
        :param status: An iterable of queue_status of the proposals to return.
615
            If None is specified, all the proposals of all possible states
616
            are returned.
617
        :param visible_by_user: If a person is not supplied, only merge
618
            proposals based on public branches are returned.  If a person is
619
            supplied, merge proposals based on both public branches, and the
620
            private branches that the person is entitled to see are returned.
621
            Private branches are only visible to the owner and subscribers of
622
            the branch, and to LP admins.
623
        """
624
7756.2.1 by Tim Penhey
Reworks the active reviews page for products.
625
    def getVotesForProposals(proposals):
626
        """Return a dict containing a mapping of proposals to vote references.
627
628
        The values of the dict are lists of CodeReviewVoteReference objects.
629
        """
630
6475.2.22 by Barry Warsaw
mergeRF
631
    def getVoteSummariesForProposals(proposals):
632
        """Return the vote summaries for the proposals.
633
634
        A vote summary is a dict has a 'comment_count' and may also have
635
        values for each of the CodeReviewVote enumerated values.
636
637
        :return: A dict keyed on the proposals.
638
        """
6971.3.2 by Tim Penhey
Add events for approve and rejection of branch merge proposals.
639
7325.8.18 by Paul Hummer
Added supersedes and superseded by
640
for name in ['supersedes', 'superseded_by']:
641
    IBranchMergeProposal[name].schema = IBranchMergeProposal
642
7628.1.1 by Aaron Bentley
Get ReviewDiffJob.run working.
643
8963.10.10 by Aaron Bentley
Fix test failures, do more interface inheritance.
644
class ICreateMergeProposalJob(IRunnableJob):
7659.3.2 by Aaron Bentley
Implement CreateMergeProposalJob
645
    """A Job that creates a branch merge proposal.
646
647
    It uses a Message, which must contain a merge directive.
648
    """
649
7659.3.16 by Aaron Bentley
Updates from review
650
7675.624.76 by Tim Penhey
More lockfile fixes.
651
class ICreateMergeProposalJobSource(IJobSource):
7659.3.16 by Aaron Bentley
Updates from review
652
    """Acquire MergeProposalJobs."""
653
7659.3.2 by Aaron Bentley
Implement CreateMergeProposalJob
654
    def create(message_bytes):
655
        """Return a CreateMergeProposalJob for this message."""
7659.3.11 by Aaron Bentley
Merge trunk into merge-directive-bundles
656
7658.3.16 by Stuart Bishop
Reapply backed out db changes
657
11733.1.1 by Tim Penhey
Rename the MergeProposalCreatedJob to be MergeProposalReviewRequestedEmailJob.
658
class IMergeProposalNeedsReviewEmailJob(IRunnableJob):
659
    """Email about a merge proposal needing a review.."""
660
661
662
class IMergeProposalNeedsReviewEmailJobSource(Interface):
663
    """Interface for acquiring MergeProposalNeedsReviewEmailJobs."""
7658.3.16 by Stuart Bishop
Reapply backed out db changes
664
665
    def create(bmp):
11733.1.1 by Tim Penhey
Rename the MergeProposalCreatedJob to be MergeProposalReviewRequestedEmailJob.
666
        """Create a needs review email job for the specified proposal."""
7658.3.16 by Stuart Bishop
Reapply backed out db changes
667
10482.1.7 by Tim Penhey
Update the branch merge proposal job source interfaces to inherit from IJobSource.
668
7675.624.49 by Tim Penhey
Not yet passing, but getting close.
669
class IUpdatePreviewDiffJob(IRunnableJob):
670
    """Interface for the job to update the diff for a merge proposal."""
671
10482.1.31 by Tim Penhey
Updates while on skype with reviewer.
672
    def checkReady():
7675.624.49 by Tim Penhey
Not yet passing, but getting close.
673
        """Check to see if this job is ready to run."""
674
675
7675.624.18 by Tim Penhey
Make one job source for all merge proposal jobs.
676
class IUpdatePreviewDiffJobSource(Interface):
9222.1.44 by Aaron Bentley
Updates from review.
677
    """Create or retrieve jobs that update preview diffs."""
9222.1.31 by Aaron Bentley
Add and test script for running preview diff update jobs.
678
679
    def create(bmp):
9222.1.44 by Aaron Bentley
Updates from review.
680
        """Create a job to update the diff for this merge proposal."""
9222.1.31 by Aaron Bentley
Add and test script for running preview diff update jobs.
681
9963.7.3 by Aaron Bentley
Add IUpdatePreviewDiffJobSource.get
682
    def get(id):
683
        """Return the UpdatePreviewDiffJob with this id."""
684
9222.1.31 by Aaron Bentley
Add and test script for running preview diff update jobs.
685
11486.4.4 by Aaron Bentley
Fake merge of job removal.
686
class IGenerateIncrementalDiffJob(IRunnableJob):
687
    """Interface for the job to update the diff for a merge proposal."""
688
689
690
class IGenerateIncrementalDiffJobSource(Interface):
691
    """Create or retrieve jobs that update preview diffs."""
692
693
    def create(bmp, old_revision_id, new_revision_id):
694
        """Create job to generate incremental diff for this merge proposal."""
695
696
    def get(id):
697
        """Return the GenerateIncrementalDiffJob with this id."""
698
699
10482.1.1 by Tim Penhey
Make the code review comment email sent by a job.
700
class ICodeReviewCommentEmailJob(IRunnableJob):
701
    """Interface for the job to send code review comment email."""
702
703
    code_review_comment = Attribute('The code review comment.')
704
705
7675.624.18 by Tim Penhey
Make one job source for all merge proposal jobs.
706
class ICodeReviewCommentEmailJobSource(Interface):
10482.1.1 by Tim Penhey
Make the code review comment email sent by a job.
707
    """Create or retrieve jobs that update preview diffs."""
708
709
    def create(code_review_comment):
710
        """Create a job to email subscribers about the comment."""
711
712
10482.1.8 by Tim Penhey
Make review requests a job.
713
class IReviewRequestedEmailJob(IRunnableJob):
714
    """Interface for the job to sends review request emails."""
715
11542.3.3 by Ian Booth
Refactor initial changes
716
    reviewer = Attribute('The person or team asked to do the review. '
717
                         'If left blank, then the default reviewer for the '
718
                         'selected target branch will be used.')
7675.624.64 by Tim Penhey
Typo.
719
    requester = Attribute('The person who has asked for the review.')
10482.1.8 by Tim Penhey
Make review requests a job.
720
721
7675.624.18 by Tim Penhey
Make one job source for all merge proposal jobs.
722
class IReviewRequestedEmailJobSource(Interface):
10482.1.8 by Tim Penhey
Make review requests a job.
723
    """Create or retrieve jobs that email review requests."""
724
725
    def create(review_request):
726
        """Create a job to email a review request.
727
728
        :param review_request: A vote reference for the requested review.
729
        """
7675.624.3 by Tim Penhey
Make the code review comment email sent by a job.
730
731
10482.1.16 by Tim Penhey
Register the global utilities.
732
class IMergeProposalUpdatedEmailJob(IRunnableJob):
10482.1.14 by Tim Penhey
Start the job process.
733
    """Interface for the job to sends email about merge proposal updates."""
734
10482.1.18 by Tim Penhey
Emails describing merge proposal updates now jobified.
735
    editor = Attribute('The person that did the editing.')
7675.624.66 by Tim Penhey
Much lint cleanup.
736
    delta_text = Attribute(
737
        'The textual representation of the changed fields.')
10482.1.14 by Tim Penhey
Start the job process.
738
739
7675.624.18 by Tim Penhey
Make one job source for all merge proposal jobs.
740
class IMergeProposalUpdatedEmailJobSource(Interface):
10482.1.14 by Tim Penhey
Start the job process.
741
    """Create or retrieve jobs that email about merge proposal updates."""
742
10482.1.18 by Tim Penhey
Emails describing merge proposal updates now jobified.
743
    def create(merge_proposal, delta_text, editor):
10482.1.14 by Tim Penhey
Start the job process.
744
        """Create a job to email merge proposal updates to subscribers.
745
10482.1.18 by Tim Penhey
Emails describing merge proposal updates now jobified.
746
        :param merge_proposal: The merge proposal that has been edited.
747
        :param delta_text: The text representation of the changed fields.
748
        :param editor: The person who did the editing.
10482.1.14 by Tim Penhey
Start the job process.
749
        """
750
10482.1.18 by Tim Penhey
Emails describing merge proposal updates now jobified.
751
10100.1.15 by Jonathan Lange
Fix imports in the scanner. PEP 8 etc.
752
# XXX: JonathanLange 2010-01-06: This is only used in the scanner, perhaps it
753
# should be moved there.
11542.3.6 by Ian Booth
Lint fixes
754
9042.1.1 by Aaron Bentley
Implement notify_modified.
755
def notify_modified(proposal, func, *args, **kwargs):
9042.1.4 by Aaron Bentley
Cleanup
756
    """Call func, then notify about the changes it made.
9042.1.1 by Aaron Bentley
Implement notify_modified.
757
758
    :param proposal: the merge proposal to notify about.
759
    :param func: The callable that will modify the merge proposal.
760
    :param args: Additional arguments for the method.
761
    :param kwargs: Keyword arguments for the method.
762
    :return: The return value of the method.
763
    """
13333.13.54 by Gavin Panella
Rename BranchMergeProposalDelta to BranchMergeProposalNoPreviewDiffDelta and BranchMergeProposalWithPreviewDiffDelta to BranchMergeProposalDelta, and change BranchMergeProposalNoPreviewDiffDelta to inherit from BranchMergeProposalDelta.
764
    from lp.code.adapters.branch import BranchMergeProposalNoPreviewDiffDelta
765
    snapshot = BranchMergeProposalNoPreviewDiffDelta.snapshot(proposal)
9042.1.1 by Aaron Bentley
Implement notify_modified.
766
    result = func(*args, **kwargs)
767
    notify(ObjectModifiedEvent(proposal, snapshot, []))
768
    return result