~greatmay12/+junk/test1

« back to all changes in this revision

Viewing changes to build/lib.linux-x86_64-2.6/bzrlib/plugins/launchpad/__init__.py

  • Committer: thitipong at ndrsolution
  • Date: 2011-11-14 06:31:02 UTC
  • Revision ID: thitipong@ndrsolution.com-20111114063102-9obte3yfi2azku7d
ndr redirect version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006-2010 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Launchpad.net integration plugin for Bazaar."""
 
18
 
 
19
# The XMLRPC server address can be overridden by setting the environment
 
20
# variable $BZR_LP_XMLRPC_URL
 
21
 
 
22
# see http://bazaar-vcs.org/Specs/BranchRegistrationTool
 
23
 
 
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
)
 
40
from bzrlib.directory_service import directories
 
41
from bzrlib.errors import (
 
42
    BzrCommandError,
 
43
    DependencyNotPresent,
 
44
    InvalidURL,
 
45
    NoPublicBranch,
 
46
    NotBranchError,
 
47
    )
 
48
from bzrlib.help_topics import topic_registry
 
49
from bzrlib.option import (
 
50
        Option,
 
51
        ListOption,
 
52
)
 
53
 
 
54
 
 
55
class cmd_register_branch(Command):
 
56
    __doc__ = """Register a branch with launchpad.net.
 
57
 
 
58
    This command lists a bzr branch in the directory of branches on
 
59
    launchpad.net.  Registration allows the branch to be associated with
 
60
    bugs or specifications.
 
61
 
 
62
    Before using this command you must register the project to which the
 
63
    branch belongs, and create an account for yourself on launchpad.net.
 
64
 
 
65
    arguments:
 
66
        public_url: The publicly visible url for the branch to register.
 
67
                    This must be an http or https url (which Launchpad can read
 
68
                    from to access the branch). Local file urls, SFTP urls, and
 
69
                    bzr+ssh urls will not work.
 
70
                    If no public_url is provided, bzr will use the configured
 
71
                    public_url if there is one for the current branch, and
 
72
                    otherwise error.
 
73
 
 
74
    example:
 
75
        bzr register-branch http://foo.com/bzr/fooproject.mine \\
 
76
                --project fooproject
 
77
    """
 
78
    takes_args = ['public_url?']
 
79
    takes_options = [
 
80
         Option('project',
 
81
                'Launchpad project short name to associate with the branch.',
 
82
                unicode),
 
83
         Option('product',
 
84
                'Launchpad product short name to associate with the branch.', 
 
85
                unicode,
 
86
                hidden=True),
 
87
         Option('branch-name',
 
88
                'Short name for the branch; '
 
89
                'by default taken from the last component of the url.',
 
90
                unicode),
 
91
         Option('branch-title',
 
92
                'One-sentence description of the branch.',
 
93
                unicode),
 
94
         Option('branch-description',
 
95
                'Longer description of the purpose or contents of the branch.',
 
96
                unicode),
 
97
         Option('author',
 
98
                "Branch author's email address, if not yourself.",
 
99
                unicode),
 
100
         Option('link-bug',
 
101
                'The bug this branch fixes.',
 
102
                int),
 
103
         Option('dry-run',
 
104
                'Prepare the request but don\'t actually send it.')
 
105
        ]
 
106
 
 
107
 
 
108
    def run(self,
 
109
            public_url=None,
 
110
            project='',
 
111
            product=None,
 
112
            branch_name='',
 
113
            branch_title='',
 
114
            branch_description='',
 
115
            author='',
 
116
            link_bug=None,
 
117
            dry_run=False):
 
118
        from bzrlib.plugins.launchpad.lp_registration import (
 
119
            BranchRegistrationRequest, BranchBugLinkRequest,
 
120
            DryRunLaunchpadService, LaunchpadService)
 
121
        if public_url is None:
 
122
            try:
 
123
                b = _mod_branch.Branch.open_containing('.')[0]
 
124
            except NotBranchError:
 
125
                raise BzrCommandError('register-branch requires a public '
 
126
                    'branch url - see bzr help register-branch.')
 
127
            public_url = b.get_public_branch()
 
128
            if public_url is None:
 
129
                raise NoPublicBranch(b)
 
130
        if product is not None:
 
131
            project = product
 
132
            trace.note('--product is deprecated; please use --project.')
 
133
 
 
134
 
 
135
        rego = BranchRegistrationRequest(branch_url=public_url,
 
136
                                         branch_name=branch_name,
 
137
                                         branch_title=branch_title,
 
138
                                         branch_description=branch_description,
 
139
                                         product_name=project,
 
140
                                         author_email=author,
 
141
                                         )
 
142
        linko = BranchBugLinkRequest(branch_url=public_url,
 
143
                                     bug_id=link_bug)
 
144
        if not dry_run:
 
145
            service = LaunchpadService()
 
146
            # This gives back the xmlrpc url that can be used for future
 
147
            # operations on the branch.  It's not so useful to print to the
 
148
            # user since they can't do anything with it from a web browser; it
 
149
            # might be nice for the server to tell us about an html url as
 
150
            # well.
 
151
        else:
 
152
            # Run on service entirely in memory
 
153
            service = DryRunLaunchpadService()
 
154
        service.gather_user_credentials()
 
155
        rego.submit(service)
 
156
        if link_bug:
 
157
            linko.submit(service)
 
158
        print 'Branch registered.'
 
159
 
 
160
register_command(cmd_register_branch)
 
161
 
 
162
 
 
163
class cmd_launchpad_open(Command):
 
164
    __doc__ = """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
 
 
213
class cmd_launchpad_login(Command):
 
214
    __doc__ = """Show or set the Launchpad user ID.
 
215
 
 
216
    When communicating with Launchpad, some commands need to know your
 
217
    Launchpad user ID.  This command can be used to set or show the
 
218
    user ID that Bazaar will use for such communication.
 
219
 
 
220
    :Examples:
 
221
      Show the Launchpad ID of the current user::
 
222
 
 
223
          bzr launchpad-login
 
224
 
 
225
      Set the Launchpad ID of the current user to 'bob'::
 
226
 
 
227
          bzr launchpad-login bob
 
228
    """
 
229
    aliases = ['lp-login']
 
230
    takes_args = ['name?']
 
231
    takes_options = [
 
232
        'verbose',
 
233
        Option('no-check',
 
234
               "Don't check that the user name is valid."),
 
235
        ]
 
236
 
 
237
    def run(self, name=None, no_check=False, verbose=False):
 
238
        # This is totally separate from any launchpadlib login system.
 
239
        from bzrlib.plugins.launchpad import account
 
240
        check_account = not no_check
 
241
 
 
242
        if name is None:
 
243
            username = account.get_lp_login()
 
244
            if username:
 
245
                if check_account:
 
246
                    account.check_lp_login(username)
 
247
                    if verbose:
 
248
                        self.outf.write(
 
249
                            "Launchpad user ID exists and has SSH keys.\n")
 
250
                self.outf.write(username + '\n')
 
251
            else:
 
252
                self.outf.write('No Launchpad user ID configured.\n')
 
253
                return 1
 
254
        else:
 
255
            name = name.lower()
 
256
            if check_account:
 
257
                account.check_lp_login(name)
 
258
                if verbose:
 
259
                    self.outf.write(
 
260
                        "Launchpad user ID exists and has SSH keys.\n")
 
261
            account.set_lp_login(name)
 
262
            if verbose:
 
263
                self.outf.write("Launchpad user ID set to '%s'.\n" % (name,))
 
264
 
 
265
register_command(cmd_launchpad_login)
 
266
 
 
267
 
 
268
# XXX: cmd_launchpad_mirror is untested
 
269
class cmd_launchpad_mirror(Command):
 
270
    __doc__ = """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
    __doc__ = """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
                     Option('approve',
 
314
                            help='Mark the proposal as approved immediately.'),
 
315
                     ListOption('review', short_name='R', type=unicode,
 
316
                            help='Requested reviewer and optional type.')]
 
317
 
 
318
    takes_args = ['submit_branch?']
 
319
 
 
320
    aliases = ['lp-submit', 'lp-propose']
 
321
 
 
322
    def run(self, submit_branch=None, review=None, staging=False,
 
323
            message=None, approve=False):
 
324
        from bzrlib.plugins.launchpad import lp_propose
 
325
        tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
 
326
            '.')
 
327
        if review is None:
 
328
            reviews = None
 
329
        else:
 
330
            reviews = []
 
331
            for review in review:
 
332
                if '=' in review:
 
333
                    reviews.append(review.split('=', 2))
 
334
                else:
 
335
                    reviews.append((review, ''))
 
336
            if submit_branch is None:
 
337
                submit_branch = branch.get_submit_branch()
 
338
        if submit_branch is None:
 
339
            target = None
 
340
        else:
 
341
            target = _mod_branch.Branch.open(submit_branch)
 
342
        proposer = lp_propose.Proposer(tree, branch, target, message,
 
343
                                       reviews, staging, approve=approve)
 
344
        proposer.check_proposal()
 
345
        proposer.create_proposal()
 
346
 
 
347
 
 
348
register_command(cmd_lp_propose_merge)
 
349
 
 
350
 
 
351
def _register_directory():
 
352
    directories.register_lazy('lp:', 'bzrlib.plugins.launchpad.lp_directory',
 
353
                              'LaunchpadDirectory',
 
354
                              'Launchpad-based directory service',)
 
355
_register_directory()
 
356
 
 
357
 
 
358
def load_tests(basic_tests, module, loader):
 
359
    testmod_names = [
 
360
        'test_account',
 
361
        'test_register',
 
362
        'test_lp_api',
 
363
        'test_lp_directory',
 
364
        'test_lp_login',
 
365
        'test_lp_open',
 
366
        'test_lp_service',
 
367
        ]
 
368
    basic_tests.addTest(loader.loadTestsFromModuleNames(
 
369
            ["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
 
370
    return basic_tests
 
371
 
 
372
 
 
373
_launchpad_help = """Integration with Launchpad.net
 
374
 
 
375
Launchpad.net provides free Bazaar branch hosting with integrated bug and
 
376
specification tracking.
 
377
 
 
378
The bzr client (through the plugin called 'launchpad') has special
 
379
features to communicate with Launchpad:
 
380
 
 
381
    * The launchpad-login command tells Bazaar your Launchpad user name. This
 
382
      is then used by the 'lp:' transport to download your branches using
 
383
      bzr+ssh://.
 
384
 
 
385
    * The 'lp:' transport uses Launchpad as a directory service: for example
 
386
      'lp:bzr' and 'lp:python' refer to the main branches of the relevant
 
387
      projects and may be branched, logged, etc. You can also use the 'lp:'
 
388
      transport to refer to specific branches, e.g. lp:~bzr/bzr/trunk.
 
389
 
 
390
    * The 'lp:' bug tracker alias can expand launchpad bug numbers to their
 
391
      URLs for use with 'bzr commit --fixes', e.g. 'bzr commit --fixes lp:12345'
 
392
      will record a revision property that marks that revision as fixing
 
393
      Launchpad bug 12345. When you push that branch to Launchpad it will
 
394
      automatically be linked to the bug report.
 
395
 
 
396
    * The register-branch command tells Launchpad about the url of a
 
397
      public branch.  Launchpad will then mirror the branch, display
 
398
      its contents and allow it to be attached to bugs and other
 
399
      objects.
 
400
 
 
401
For more information see http://help.launchpad.net/
 
402
"""
 
403
topic_registry.register('launchpad',
 
404
    _launchpad_help,
 
405
    'Using Bazaar with Launchpad.net')