/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/plugins/launchpad/__init__.py

  • Committer: Martin von Gagern
  • Date: 2010-04-20 08:47:38 UTC
  • mfrom: (5167 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5195.
  • Revision ID: martin.vgagern@gmx.net-20100420084738-ygymnqmdllzrhpfn
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 - 2008 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Launchpad.net integration plugin for Bazaar."""
18
18
 
19
19
# The XMLRPC server address can be overridden by setting the environment
20
 
# variable $BZR_LP_XMLRPL_URL
 
20
# variable $BZR_LP_XMLRPC_URL
21
21
 
22
22
# see http://bazaar-vcs.org/Specs/BranchRegistrationTool
23
23
 
24
 
from bzrlib.branch import Branch
25
 
from bzrlib.commands import Command, Option, register_command
 
24
# Since we are a built-in plugin we share the bzrlib version
 
25
from bzrlib import version_info
 
26
 
 
27
from bzrlib.lazy_import import lazy_import
 
28
lazy_import(globals(), """
 
29
from bzrlib import (
 
30
    branch as _mod_branch,
 
31
    trace,
 
32
    )
 
33
""")
 
34
 
 
35
from bzrlib import bzrdir
 
36
from bzrlib.commands import (
 
37
        Command,
 
38
        register_command,
 
39
)
26
40
from bzrlib.directory_service import directories
27
 
from bzrlib.errors import BzrCommandError, NoPublicBranch, NotBranchError
 
41
from bzrlib.errors import (
 
42
    BzrCommandError,
 
43
    DependencyNotPresent,
 
44
    InvalidURL,
 
45
    NoPublicBranch,
 
46
    NotBranchError,
 
47
    )
28
48
from bzrlib.help_topics import topic_registry
 
49
from bzrlib.option import (
 
50
        Option,
 
51
        ListOption,
 
52
)
29
53
 
30
54
 
31
55
class cmd_register_branch(Command):
34
58
    This command lists a bzr branch in the directory of branches on
35
59
    launchpad.net.  Registration allows the branch to be associated with
36
60
    bugs or specifications.
37
 
    
38
 
    Before using this command you must register the product to which the
 
61
 
 
62
    Before using this command you must register the project to which the
39
63
    branch belongs, and create an account for yourself on launchpad.net.
40
64
 
41
65
    arguments:
48
72
                    otherwise error.
49
73
 
50
74
    example:
51
 
        bzr register-branch http://foo.com/bzr/fooproduct.mine \\
52
 
                --product fooproduct
 
75
        bzr register-branch http://foo.com/bzr/fooproject.mine \\
 
76
                --project fooproject
53
77
    """
54
78
    takes_args = ['public_url?']
55
79
    takes_options = [
 
80
         Option('project',
 
81
                'Launchpad project short name to associate with the branch.',
 
82
                unicode),
56
83
         Option('product',
57
 
                'Launchpad product short name to associate with the branch.',
58
 
                unicode),
 
84
                'Launchpad product short name to associate with the branch.', 
 
85
                unicode,
 
86
                hidden=True),
59
87
         Option('branch-name',
60
88
                'Short name for the branch; '
61
89
                'by default taken from the last component of the url.',
79
107
 
80
108
    def run(self,
81
109
            public_url=None,
82
 
            product='',
 
110
            project='',
 
111
            product=None,
83
112
            branch_name='',
84
113
            branch_title='',
85
114
            branch_description='',
87
116
            link_bug=None,
88
117
            dry_run=False):
89
118
        from bzrlib.plugins.launchpad.lp_registration import (
90
 
            LaunchpadService, BranchRegistrationRequest, BranchBugLinkRequest,
91
 
            DryRunLaunchpadService)
 
119
            BranchRegistrationRequest, BranchBugLinkRequest,
 
120
            DryRunLaunchpadService, LaunchpadService)
92
121
        if public_url is None:
93
122
            try:
94
 
                b = Branch.open_containing('.')[0]
 
123
                b = _mod_branch.Branch.open_containing('.')[0]
95
124
            except NotBranchError:
96
125
                raise BzrCommandError('register-branch requires a public '
97
126
                    'branch url - see bzr help register-branch.')
98
127
            public_url = b.get_public_branch()
99
128
            if public_url is None:
100
129
                raise NoPublicBranch(b)
 
130
        if product is not None:
 
131
            project = product
 
132
            trace.note('--product is deprecated; please use --project.')
 
133
 
101
134
 
102
135
        rego = BranchRegistrationRequest(branch_url=public_url,
103
136
                                         branch_name=branch_name,
104
137
                                         branch_title=branch_title,
105
138
                                         branch_description=branch_description,
106
 
                                         product_name=product,
 
139
                                         product_name=project,
107
140
                                         author_email=author,
108
141
                                         )
109
142
        linko = BranchBugLinkRequest(branch_url=public_url,
119
152
            # Run on service entirely in memory
120
153
            service = DryRunLaunchpadService()
121
154
        service.gather_user_credentials()
122
 
        branch_object_url = rego.submit(service)
 
155
        rego.submit(service)
123
156
        if link_bug:
124
 
            link_bug_url = linko.submit(service)
 
157
            linko.submit(service)
125
158
        print 'Branch registered.'
126
159
 
127
160
register_command(cmd_register_branch)
128
161
 
129
162
 
 
163
class cmd_launchpad_open(Command):
 
164
    """Open a Launchpad branch page in your web browser."""
 
165
 
 
166
    aliases = ['lp-open']
 
167
    takes_options = [
 
168
        Option('dry-run',
 
169
               'Do not actually open the browser. Just say the URL we would '
 
170
               'use.'),
 
171
        ]
 
172
    takes_args = ['location?']
 
173
 
 
174
    def _possible_locations(self, location):
 
175
        """Yield possible external locations for the branch at 'location'."""
 
176
        yield location
 
177
        try:
 
178
            branch = _mod_branch.Branch.open_containing(location)[0]
 
179
        except NotBranchError:
 
180
            return
 
181
        branch_url = branch.get_public_branch()
 
182
        if branch_url is not None:
 
183
            yield branch_url
 
184
        branch_url = branch.get_push_location()
 
185
        if branch_url is not None:
 
186
            yield branch_url
 
187
 
 
188
    def _get_web_url(self, service, location):
 
189
        from bzrlib.plugins.launchpad.lp_registration import (
 
190
            NotLaunchpadBranch)
 
191
        for branch_url in self._possible_locations(location):
 
192
            try:
 
193
                return service.get_web_url_from_branch_url(branch_url)
 
194
            except (NotLaunchpadBranch, InvalidURL):
 
195
                pass
 
196
        raise NotLaunchpadBranch(branch_url)
 
197
 
 
198
    def run(self, location=None, dry_run=False):
 
199
        from bzrlib.plugins.launchpad.lp_registration import (
 
200
            LaunchpadService)
 
201
        if location is None:
 
202
            location = u'.'
 
203
        web_url = self._get_web_url(LaunchpadService(), location)
 
204
        trace.note('Opening %s in web browser' % web_url)
 
205
        if not dry_run:
 
206
            import webbrowser   # this import should not be lazy
 
207
                                # otherwise bzr.exe lacks this module
 
208
            webbrowser.open(web_url)
 
209
 
 
210
register_command(cmd_launchpad_open)
 
211
 
 
212
 
130
213
class cmd_launchpad_login(Command):
131
214
    """Show or set the Launchpad user ID.
132
215
 
146
229
    aliases = ['lp-login']
147
230
    takes_args = ['name?']
148
231
    takes_options = [
 
232
        'verbose',
149
233
        Option('no-check',
150
234
               "Don't check that the user name is valid."),
151
235
        ]
152
236
 
153
 
    def run(self, name=None, no_check=False):
 
237
    def run(self, name=None, no_check=False, verbose=False):
 
238
        # This is totally separate from any launchpadlib login system.
154
239
        from bzrlib.plugins.launchpad import account
155
240
        check_account = not no_check
156
241
 
159
244
            if username:
160
245
                if check_account:
161
246
                    account.check_lp_login(username)
 
247
                    if verbose:
 
248
                        self.outf.write(
 
249
                            "Launchpad user ID exists and has SSH keys.\n")
162
250
                self.outf.write(username + '\n')
163
251
            else:
164
252
                self.outf.write('No Launchpad user ID configured.\n')
165
253
                return 1
166
254
        else:
 
255
            name = name.lower()
167
256
            if check_account:
168
257
                account.check_lp_login(name)
 
258
                if verbose:
 
259
                    self.outf.write(
 
260
                        "Launchpad user ID exists and has SSH keys.\n")
169
261
            account.set_lp_login(name)
 
262
            if verbose:
 
263
                self.outf.write("Launchpad user ID set to '%s'.\n" % (name,))
170
264
 
171
265
register_command(cmd_launchpad_login)
172
266
 
173
267
 
 
268
# XXX: cmd_launchpad_mirror is untested
 
269
class cmd_launchpad_mirror(Command):
 
270
    """Ask Launchpad to mirror a branch now."""
 
271
 
 
272
    aliases = ['lp-mirror']
 
273
    takes_args = ['location?']
 
274
 
 
275
    def run(self, location='.'):
 
276
        from bzrlib.plugins.launchpad import lp_api
 
277
        from bzrlib.plugins.launchpad.lp_registration import LaunchpadService
 
278
        branch = _mod_branch.Branch.open(location)
 
279
        service = LaunchpadService()
 
280
        launchpad = lp_api.login(service)
 
281
        lp_branch = lp_api.load_branch(launchpad, branch)
 
282
        lp_branch.requestMirror()
 
283
 
 
284
 
 
285
register_command(cmd_launchpad_mirror)
 
286
 
 
287
 
 
288
class cmd_lp_propose_merge(Command):
 
289
    """Propose merging a branch on Launchpad.
 
290
 
 
291
    This will open your usual editor to provide the initial comment.  When it
 
292
    has created the proposal, it will open it in your default web browser.
 
293
 
 
294
    The branch will be proposed to merge into SUBMIT_BRANCH.  If SUBMIT_BRANCH
 
295
    is not supplied, the remembered submit branch will be used.  If no submit
 
296
    branch is remembered, the development focus will be used.
 
297
 
 
298
    By default, the SUBMIT_BRANCH's review team will be requested to review
 
299
    the merge proposal.  This can be overriden by specifying --review (-R).
 
300
    The parameter the launchpad account name of the desired reviewer.  This
 
301
    may optionally be followed by '=' and the review type.  For example:
 
302
 
 
303
      bzr lp-propose-merge --review jrandom --review review-team=qa
 
304
 
 
305
    This will propose a merge,  request "jrandom" to perform a review of
 
306
    unspecified type, and request "review-team" to perform a "qa" review.
 
307
    """
 
308
 
 
309
    takes_options = [Option('staging',
 
310
                            help='Propose the merge on staging.'),
 
311
                     Option('message', short_name='m', type=unicode,
 
312
                            help='Commit message.'),
 
313
                     ListOption('review', short_name='R', type=unicode,
 
314
                            help='Requested reviewer and optional type.')]
 
315
 
 
316
    takes_args = ['submit_branch?']
 
317
 
 
318
    aliases = ['lp-submit', 'lp-propose']
 
319
 
 
320
    def run(self, submit_branch=None, review=None, staging=False,
 
321
            message=None):
 
322
        from bzrlib.plugins.launchpad import lp_propose
 
323
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
324
            '.')
 
325
        if review is None:
 
326
            reviews = None
 
327
        else:
 
328
            reviews = []
 
329
            for review in review:
 
330
                if '=' in review:
 
331
                    reviews.append(review.split('=', 2))
 
332
                else:
 
333
                    reviews.append((review, ''))
 
334
            if submit_branch is None:
 
335
                submit_branch = branch.get_submit_branch()
 
336
        if submit_branch is None:
 
337
            target = None
 
338
        else:
 
339
            target = _mod_branch.Branch.open(submit_branch)
 
340
        proposer = lp_propose.Proposer(tree, branch, target, message,
 
341
                                       reviews, staging)
 
342
        proposer.check_proposal()
 
343
        proposer.create_proposal()
 
344
 
 
345
 
 
346
register_command(cmd_lp_propose_merge)
 
347
 
 
348
 
174
349
def _register_directory():
175
350
    directories.register_lazy('lp:', 'bzrlib.plugins.launchpad.lp_directory',
176
351
                              'LaunchpadDirectory',
178
353
_register_directory()
179
354
 
180
355
 
181
 
def test_suite():
182
 
    """Called by bzrlib to fetch tests for this plugin"""
183
 
    from unittest import TestSuite, TestLoader
184
 
    from bzrlib.plugins.launchpad import (
185
 
         test_account, test_lp_directory, test_lp_service, test_register,
186
 
         )
 
356
def load_tests(basic_tests, module, loader):
 
357
    testmod_names = [
 
358
        'test_account',
 
359
        'test_register',
 
360
        'test_lp_api',
 
361
        'test_lp_directory',
 
362
        'test_lp_login',
 
363
        'test_lp_open',
 
364
        'test_lp_service',
 
365
        ]
 
366
    basic_tests.addTest(loader.loadTestsFromModuleNames(
 
367
            ["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
 
368
    return basic_tests
187
369
 
188
 
    loader = TestLoader()
189
 
    suite = TestSuite()
190
 
    for module in [
191
 
        test_account,
192
 
        test_register,
193
 
        test_lp_directory,
194
 
        test_lp_service,
195
 
        ]:
196
 
        suite.addTests(loader.loadTestsFromModule(module))
197
 
    return suite
198
370
 
199
371
_launchpad_help = """Integration with Launchpad.net
200
372
 
208
380
      is then used by the 'lp:' transport to download your branches using
209
381
      bzr+ssh://.
210
382
 
 
383
    * The 'lp:' transport uses Launchpad as a directory service: for example
 
384
      'lp:bzr' and 'lp:python' refer to the main branches of the relevant
 
385
      projects and may be branched, logged, etc. You can also use the 'lp:'
 
386
      transport to refer to specific branches, e.g. lp:~bzr/bzr/trunk.
 
387
 
 
388
    * The 'lp:' bug tracker alias can expand launchpad bug numbers to their
 
389
      URLs for use with 'bzr commit --fixes', e.g. 'bzr commit --fixes lp:12345'
 
390
      will record a revision property that marks that revision as fixing
 
391
      Launchpad bug 12345. When you push that branch to Launchpad it will
 
392
      automatically be linked to the bug report.
 
393
 
211
394
    * The register-branch command tells Launchpad about the url of a
212
395
      public branch.  Launchpad will then mirror the branch, display
213
396
      its contents and allow it to be attached to bugs and other
214
397
      objects.
215
398
 
216
 
    * The 'lp:' transport uses Launchpad as a directory service: for example
217
 
      'lp:bzr' and 'lp:python' refer to the main branches of the relevant
218
 
      projects and may be branched, logged, etc. You can also use the 'lp:'
219
 
      transport to refer to specific branches, e.g. lp:///~bzr/bzr/trunk.
220
 
 
221
399
For more information see http://help.launchpad.net/
222
400
"""
223
401
topic_registry.register('launchpad',