Merge lp:~jelmer/bzr-pqm/lazy-commands into lp:bzr-pqm
- lazy-commands
- Merge into devel
Proposed by
Jelmer Vernooij
Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | 81 |
Merged at revision: | 89 |
Proposed branch: | lp:~jelmer/bzr-pqm/lazy-commands |
Merge into: | lp:bzr-pqm |
Diff against target: |
342 lines (+168/-152) 2 files modified
__init__.py (+3/-152) cmds.py (+165/-0) |
To merge this branch: | bzr merge lp:~jelmer/bzr-pqm/lazy-commands |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marius Kruger (community) | Approve | ||
Bzr-pqm-devel | Pending | ||
Review via email:
|
Commit message
Description of the change
Lazily load the command implementations of bzr-pqm.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '__init__.py' | |||
2 | --- __init__.py 2010-09-09 12:27:00 +0000 | |||
3 | +++ __init__.py 2011-12-16 16:01:58 +0000 | |||
4 | @@ -16,9 +16,7 @@ | |||
5 | 16 | """Functionality for controlling a Patch Queue Manager (pqm). | 16 | """Functionality for controlling a Patch Queue Manager (pqm). |
6 | 17 | """ | 17 | """ |
7 | 18 | 18 | ||
11 | 19 | from bzrlib.commands import Command, register_command | 19 | from bzrlib.commands import plugin_cmds |
9 | 20 | from bzrlib.option import Option | ||
10 | 21 | from bzrlib.errors import BzrCommandError | ||
12 | 22 | 20 | ||
13 | 23 | 21 | ||
14 | 24 | version_info = (1, 4, 0, 'dev', 0) | 22 | version_info = (1, 4, 0, 'dev', 0) |
15 | @@ -30,155 +28,8 @@ | |||
16 | 30 | __version__ = version_string | 28 | __version__ = version_string |
17 | 31 | 29 | ||
18 | 32 | 30 | ||
168 | 33 | class cmd_pqm_submit(Command): | 31 | plugin_cmds.register_lazy('cmd_pqm_submit', [], 'bzrlib.plugins.pqm.cmds') |
169 | 34 | """Submit the parent tree to the pqm. | 32 | plugin_cmds.register_lazy('cmd_lp_land', [], 'bzrlib.plugins.pqm.cmds') |
21 | 35 | |||
22 | 36 | This acts like: | ||
23 | 37 | $ echo "star-merge $PARENT $TARGET" | ||
24 | 38 | | gpg --cl | ||
25 | 39 | | mail pqm@somewhere -s "merge text" | ||
26 | 40 | |||
27 | 41 | But it pays attention to who the local committer is | ||
28 | 42 | (using their e-mail address), and uses the local | ||
29 | 43 | gpg signing configuration. (As well as target pqm | ||
30 | 44 | settings, etc.) | ||
31 | 45 | |||
32 | 46 | The reason we use 'parent' instead of the local branch | ||
33 | 47 | is that most likely the local branch is not a public | ||
34 | 48 | branch. And the branch must be available to the pqm. | ||
35 | 49 | |||
36 | 50 | This can be configured at the branch level using ~/.bazaar/locations.conf. | ||
37 | 51 | Here is an example: | ||
38 | 52 | [/home/emurphy/repo] | ||
39 | 53 | pqm_email = PQM <pqm@example.com> | ||
40 | 54 | pqm_user_email = User Name <user@example.com> | ||
41 | 55 | submit_branch = http://code.example.com/code/project/devel | ||
42 | 56 | # Set public_branch appropriately for all branches in repository: | ||
43 | 57 | public_branch = http://code.example.com/code/emurphy/project | ||
44 | 58 | public_branch:policy = appendpath | ||
45 | 59 | [/home/emurphy/repo/branch] | ||
46 | 60 | # Override public_branch for this repository: | ||
47 | 61 | public_branch = http://alternate.host.example.com/other/public/branch | ||
48 | 62 | |||
49 | 63 | smtp_server = host:port | ||
50 | 64 | smtp_username = | ||
51 | 65 | smtp_password = | ||
52 | 66 | |||
53 | 67 | If you don't specify the smtp server, the message will be sent via localhost. | ||
54 | 68 | """ | ||
55 | 69 | |||
56 | 70 | takes_args = ['location?'] | ||
57 | 71 | takes_options = [ | ||
58 | 72 | Option('message', | ||
59 | 73 | help='Message to use on merge to pqm. ' | ||
60 | 74 | 'Currently must be a single line because of pqm limits.', | ||
61 | 75 | short_name='m', | ||
62 | 76 | type=unicode), | ||
63 | 77 | Option('dry-run', help='Print request instead of sending.'), | ||
64 | 78 | Option('public-location', type=str, | ||
65 | 79 | help='Use this url as the public location to the pqm.'), | ||
66 | 80 | Option('submit-branch', type=str, | ||
67 | 81 | help='Use this url as the target submission branch.'), | ||
68 | 82 | Option('ignore-local', help='Do not check the local branch or tree.'), | ||
69 | 83 | ] | ||
70 | 84 | |||
71 | 85 | def run(self, location=None, message=None, public_location=None, | ||
72 | 86 | dry_run=False, submit_branch=None, ignore_local=False): | ||
73 | 87 | from bzrlib import trace, bzrdir | ||
74 | 88 | if __name__ != 'bzrlib.plugins.pqm': | ||
75 | 89 | trace.warning('The bzr-pqm plugin needs to be called' | ||
76 | 90 | ' "bzrlib.plugins.pqm" not "%s"\n' | ||
77 | 91 | 'Please rename the plugin.', | ||
78 | 92 | __name__) | ||
79 | 93 | return 1 | ||
80 | 94 | from bzrlib.plugins.pqm.pqm_submit import submit | ||
81 | 95 | |||
82 | 96 | if ignore_local: | ||
83 | 97 | tree, b, relpath = None, None, None | ||
84 | 98 | else: | ||
85 | 99 | if location is None: | ||
86 | 100 | location = '.' | ||
87 | 101 | tree, b, relpath = bzrdir.BzrDir.open_containing_tree_or_branch( | ||
88 | 102 | location) | ||
89 | 103 | if b is not None: | ||
90 | 104 | b.lock_read() | ||
91 | 105 | self.add_cleanup(b.unlock) | ||
92 | 106 | if relpath and not tree and location != '.': | ||
93 | 107 | raise BzrCommandError( | ||
94 | 108 | 'No working tree was found, but we were not given the ' | ||
95 | 109 | 'exact path to the branch.\n' | ||
96 | 110 | 'We found a branch at: %s' % (b.base,)) | ||
97 | 111 | if message is None: | ||
98 | 112 | raise BzrCommandError( | ||
99 | 113 | 'You must supply a commit message for the pqm to use.') | ||
100 | 114 | submit(b, message=message, dry_run=dry_run, | ||
101 | 115 | public_location=public_location, | ||
102 | 116 | submit_location=submit_branch, | ||
103 | 117 | tree=tree, ignore_local=ignore_local) | ||
104 | 118 | |||
105 | 119 | class cmd_lp_land(Command): | ||
106 | 120 | """Land the merge proposal for this branch via PQM. | ||
107 | 121 | |||
108 | 122 | The branch will be submitted to PQM according to the merge proposal. If | ||
109 | 123 | there is more than one one outstanding proposal for the branch, its | ||
110 | 124 | location must be specified. | ||
111 | 125 | """ | ||
112 | 126 | |||
113 | 127 | takes_args = ['location?'] | ||
114 | 128 | |||
115 | 129 | takes_options = [ | ||
116 | 130 | Option('dry-run', help='Display the PQM message instead of sending.'), | ||
117 | 131 | Option( | ||
118 | 132 | 'testfix', | ||
119 | 133 | help="This is a testfix (tags commit with [testfix])."), | ||
120 | 134 | Option( | ||
121 | 135 | 'no-qa', | ||
122 | 136 | help="Does not require QA (tags commit with [no-qa])."), | ||
123 | 137 | Option( | ||
124 | 138 | 'incremental', | ||
125 | 139 | help="Incremental to other bug fix (tags commit with [incr])."), | ||
126 | 140 | Option( | ||
127 | 141 | 'rollback', type=int, | ||
128 | 142 | help=( | ||
129 | 143 | "Rollback given revision number. (tags commit with " | ||
130 | 144 | "[rollback=revno]).")), | ||
131 | 145 | ] | ||
132 | 146 | |||
133 | 147 | def run(self, location=None, dry_run=False, testfix=False, | ||
134 | 148 | no_qa=False, incremental=False, rollback=None): | ||
135 | 149 | from bzrlib.plugins.pqm.lpland import Submitter | ||
136 | 150 | from bzrlib import branch as _mod_branch | ||
137 | 151 | from bzrlib.plugins.pqm.lpland import ( | ||
138 | 152 | MissingReviewError, MissingBugsError, MissingBugsIncrementalError) | ||
139 | 153 | |||
140 | 154 | branch = _mod_branch.Branch.open_containing('.')[0] | ||
141 | 155 | if dry_run: | ||
142 | 156 | outf = self.outf | ||
143 | 157 | else: | ||
144 | 158 | outf = None | ||
145 | 159 | if rollback and (no_qa or incremental): | ||
146 | 160 | print "--rollback option used. Ignoring --no-qa and --incremental." | ||
147 | 161 | try: | ||
148 | 162 | submitter = Submitter(branch, location, testfix, no_qa, | ||
149 | 163 | incremental, rollback=rollback).run(outf) | ||
150 | 164 | except MissingReviewError: | ||
151 | 165 | raise BzrCommandError( | ||
152 | 166 | "Cannot land branches that haven't got approved code " | ||
153 | 167 | "reviews. Get an 'Approved' vote so we can fill in the " | ||
154 | 168 | "[r=REVIEWER] section.") | ||
155 | 169 | except MissingBugsError: | ||
156 | 170 | raise BzrCommandError( | ||
157 | 171 | "Branch doesn't have linked bugs and doesn't have no-qa " | ||
158 | 172 | "option set. Use --no-qa, or link the related bugs to the " | ||
159 | 173 | "branch.") | ||
160 | 174 | except MissingBugsIncrementalError: | ||
161 | 175 | raise BzrCommandError( | ||
162 | 176 | "--incremental option requires bugs linked to the branch. " | ||
163 | 177 | "Link the bugs or remove the --incremental option.") | ||
164 | 178 | |||
165 | 179 | |||
166 | 180 | register_command(cmd_pqm_submit) | ||
167 | 181 | register_command(cmd_lp_land) | ||
170 | 182 | 33 | ||
171 | 183 | 34 | ||
172 | 184 | def test_suite(): | 35 | def test_suite(): |
173 | 185 | 36 | ||
174 | === added file 'cmds.py' | |||
175 | --- cmds.py 1970-01-01 00:00:00 +0000 | |||
176 | +++ cmds.py 2011-12-16 16:01:58 +0000 | |||
177 | @@ -0,0 +1,165 @@ | |||
178 | 1 | # Copyright (C) 2006-2010 by Canonical Ltd | ||
179 | 2 | # | ||
180 | 3 | # This program is free software; you can redistribute it and/or modify | ||
181 | 4 | # it under the terms of the GNU General Public License as published by | ||
182 | 5 | # the Free Software Foundation; either version 2 of the License, or | ||
183 | 6 | # (at your option) any later version. | ||
184 | 7 | # | ||
185 | 8 | # This program is distributed in the hope that it will be useful, | ||
186 | 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
187 | 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
188 | 11 | # GNU General Public License for more details. | ||
189 | 12 | # | ||
190 | 13 | # You should have received a copy of the GNU General Public License along | ||
191 | 14 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
192 | 15 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
193 | 16 | """Functionality for controlling a Patch Queue Manager (pqm). | ||
194 | 17 | """ | ||
195 | 18 | |||
196 | 19 | from bzrlib.commands import Command | ||
197 | 20 | from bzrlib.option import Option | ||
198 | 21 | from bzrlib.errors import BzrCommandError | ||
199 | 22 | |||
200 | 23 | |||
201 | 24 | class cmd_pqm_submit(Command): | ||
202 | 25 | """Submit the parent tree to the pqm. | ||
203 | 26 | |||
204 | 27 | This acts like: | ||
205 | 28 | $ echo "star-merge $PARENT $TARGET" | ||
206 | 29 | | gpg --cl | ||
207 | 30 | | mail pqm@somewhere -s "merge text" | ||
208 | 31 | |||
209 | 32 | But it pays attention to who the local committer is | ||
210 | 33 | (using their e-mail address), and uses the local | ||
211 | 34 | gpg signing configuration. (As well as target pqm | ||
212 | 35 | settings, etc.) | ||
213 | 36 | |||
214 | 37 | The reason we use 'parent' instead of the local branch | ||
215 | 38 | is that most likely the local branch is not a public | ||
216 | 39 | branch. And the branch must be available to the pqm. | ||
217 | 40 | |||
218 | 41 | This can be configured at the branch level using ~/.bazaar/locations.conf. | ||
219 | 42 | Here is an example: | ||
220 | 43 | [/home/emurphy/repo] | ||
221 | 44 | pqm_email = PQM <pqm@example.com> | ||
222 | 45 | pqm_user_email = User Name <user@example.com> | ||
223 | 46 | submit_branch = http://code.example.com/code/project/devel | ||
224 | 47 | # Set public_branch appropriately for all branches in repository: | ||
225 | 48 | public_branch = http://code.example.com/code/emurphy/project | ||
226 | 49 | public_branch:policy = appendpath | ||
227 | 50 | [/home/emurphy/repo/branch] | ||
228 | 51 | # Override public_branch for this repository: | ||
229 | 52 | public_branch = http://alternate.host.example.com/other/public/branch | ||
230 | 53 | |||
231 | 54 | smtp_server = host:port | ||
232 | 55 | smtp_username = | ||
233 | 56 | smtp_password = | ||
234 | 57 | |||
235 | 58 | If you don't specify the smtp server, the message will be sent via localhost. | ||
236 | 59 | """ | ||
237 | 60 | |||
238 | 61 | takes_args = ['location?'] | ||
239 | 62 | takes_options = [ | ||
240 | 63 | Option('message', | ||
241 | 64 | help='Message to use on merge to pqm. ' | ||
242 | 65 | 'Currently must be a single line because of pqm limits.', | ||
243 | 66 | short_name='m', | ||
244 | 67 | type=unicode), | ||
245 | 68 | Option('dry-run', help='Print request instead of sending.'), | ||
246 | 69 | Option('public-location', type=str, | ||
247 | 70 | help='Use this url as the public location to the pqm.'), | ||
248 | 71 | Option('submit-branch', type=str, | ||
249 | 72 | help='Use this url as the target submission branch.'), | ||
250 | 73 | Option('ignore-local', help='Do not check the local branch or tree.'), | ||
251 | 74 | ] | ||
252 | 75 | |||
253 | 76 | def run(self, location=None, message=None, public_location=None, | ||
254 | 77 | dry_run=False, submit_branch=None, ignore_local=False): | ||
255 | 78 | from bzrlib import bzrdir | ||
256 | 79 | from bzrlib.plugins.pqm.pqm_submit import submit | ||
257 | 80 | |||
258 | 81 | if ignore_local: | ||
259 | 82 | tree, b, relpath = None, None, None | ||
260 | 83 | else: | ||
261 | 84 | if location is None: | ||
262 | 85 | location = '.' | ||
263 | 86 | tree, b, relpath = bzrdir.BzrDir.open_containing_tree_or_branch( | ||
264 | 87 | location) | ||
265 | 88 | if b is not None: | ||
266 | 89 | b.lock_read() | ||
267 | 90 | self.add_cleanup(b.unlock) | ||
268 | 91 | if relpath and not tree and location != '.': | ||
269 | 92 | raise BzrCommandError( | ||
270 | 93 | 'No working tree was found, but we were not given the ' | ||
271 | 94 | 'exact path to the branch.\n' | ||
272 | 95 | 'We found a branch at: %s' % (b.base,)) | ||
273 | 96 | if message is None: | ||
274 | 97 | raise BzrCommandError( | ||
275 | 98 | 'You must supply a commit message for the pqm to use.') | ||
276 | 99 | submit(b, message=message, dry_run=dry_run, | ||
277 | 100 | public_location=public_location, | ||
278 | 101 | submit_location=submit_branch, | ||
279 | 102 | tree=tree, ignore_local=ignore_local) | ||
280 | 103 | |||
281 | 104 | class cmd_lp_land(Command): | ||
282 | 105 | """Land the merge proposal for this branch via PQM. | ||
283 | 106 | |||
284 | 107 | The branch will be submitted to PQM according to the merge proposal. If | ||
285 | 108 | there is more than one one outstanding proposal for the branch, its | ||
286 | 109 | location must be specified. | ||
287 | 110 | """ | ||
288 | 111 | |||
289 | 112 | takes_args = ['location?'] | ||
290 | 113 | |||
291 | 114 | takes_options = [ | ||
292 | 115 | Option('dry-run', help='Display the PQM message instead of sending.'), | ||
293 | 116 | Option( | ||
294 | 117 | 'testfix', | ||
295 | 118 | help="This is a testfix (tags commit with [testfix])."), | ||
296 | 119 | Option( | ||
297 | 120 | 'no-qa', | ||
298 | 121 | help="Does not require QA (tags commit with [no-qa])."), | ||
299 | 122 | Option( | ||
300 | 123 | 'incremental', | ||
301 | 124 | help="Incremental to other bug fix (tags commit with [incr])."), | ||
302 | 125 | Option( | ||
303 | 126 | 'rollback', type=int, | ||
304 | 127 | help=( | ||
305 | 128 | "Rollback given revision number. (tags commit with " | ||
306 | 129 | "[rollback=revno]).")), | ||
307 | 130 | ] | ||
308 | 131 | |||
309 | 132 | def run(self, location=None, dry_run=False, testfix=False, | ||
310 | 133 | no_qa=False, incremental=False, rollback=None): | ||
311 | 134 | from bzrlib.plugins.pqm.lpland import Submitter | ||
312 | 135 | from bzrlib import branch as _mod_branch | ||
313 | 136 | from bzrlib.plugins.pqm.lpland import ( | ||
314 | 137 | MissingReviewError, MissingBugsError, MissingBugsIncrementalError) | ||
315 | 138 | |||
316 | 139 | branch = _mod_branch.Branch.open_containing('.')[0] | ||
317 | 140 | if dry_run: | ||
318 | 141 | outf = self.outf | ||
319 | 142 | else: | ||
320 | 143 | outf = None | ||
321 | 144 | if rollback and (no_qa or incremental): | ||
322 | 145 | print "--rollback option used. Ignoring --no-qa and --incremental." | ||
323 | 146 | try: | ||
324 | 147 | submitter = Submitter(branch, location, testfix, no_qa, | ||
325 | 148 | incremental, rollback=rollback).run(outf) | ||
326 | 149 | except MissingReviewError: | ||
327 | 150 | raise BzrCommandError( | ||
328 | 151 | "Cannot land branches that haven't got approved code " | ||
329 | 152 | "reviews. Get an 'Approved' vote so we can fill in the " | ||
330 | 153 | "[r=REVIEWER] section.") | ||
331 | 154 | except MissingBugsError: | ||
332 | 155 | raise BzrCommandError( | ||
333 | 156 | "Branch doesn't have linked bugs and doesn't have no-qa " | ||
334 | 157 | "option set. Use --no-qa, or link the related bugs to the " | ||
335 | 158 | "branch.") | ||
336 | 159 | except MissingBugsIncrementalError: | ||
337 | 160 | raise BzrCommandError( | ||
338 | 161 | "--incremental option requires bugs linked to the branch. " | ||
339 | 162 | "Link the bugs or remove the --incremental option.") | ||
340 | 163 | |||
341 | 164 | |||
342 | 165 |
looks pretty mechanical to me, so +1 from me.
(I haven't tried to run it at all)