~bzr-pqm/bzr/bzr.dev

3251.4.2 by Aaron Bentley
Clean up Launchpad directory service code
1
# Copyright (C) 2006 - 2008 Canonical Ltd
0.4.1 by Martin Pool
Start lp-register command
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0.4.1 by Martin Pool
Start lp-register command
16
2898.3.8 by James Henstridge
Get rid of relative imports in Launchpad plugin.
17
"""Launchpad.net integration plugin for Bazaar."""
0.4.1 by Martin Pool
Start lp-register command
18
0.4.17 by Martin Pool
Allow xmlrpc service url to be overridden by $BZR_LP_XMLRPC_URL
19
# The XMLRPC server address can be overridden by setting the environment
20
# variable $BZR_LP_XMLRPL_URL
21
0.4.9 by Martin Pool
Don't transmit non-standard xmlrpc <nil> value.
22
# see http://bazaar-vcs.org/Specs/BranchRegistrationTool
23
4283.3.1 by Vincent Ladeuil
Make built-in plugins display the same version than bzrlib.
24
# Since we are a built-in plugin we share the bzrlib version
25
from bzrlib import version_info
26
4031.2.11 by John Arbash Meinel
Turn a bunch of imports into lazy imports.
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
0.4.1 by Martin Pool
Start lp-register command
35
from bzrlib.commands import Command, Option, register_command
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
36
from bzrlib.directory_service import directories
4031.2.5 by Jonathan Lange
Refactor the code so we don't do too many remote requests.
37
from bzrlib.errors import (
38
    BzrCommandError,
39
    InvalidURL,
40
    NoPublicBranch,
41
    NotBranchError,
42
    )
2245.8.6 by Martin Pool
Documentation under 'help launchpad'
43
from bzrlib.help_topics import topic_registry
4031.2.7 by Jonathan Lange
Move the imports to the top of the module.
44
from bzrlib.plugins.launchpad.lp_registration import (
45
    LaunchpadService,
46
    NotLaunchpadBranch,
47
    )
0.4.4 by Martin Pool
Start forming xmlrpc requests
48
49
0.4.2 by Martin Pool
Rename command to 'register-branch'
50
class cmd_register_branch(Command):
51
    """Register a branch with launchpad.net.
0.4.1 by Martin Pool
Start lp-register command
52
53
    This command lists a bzr branch in the directory of branches on
2400.2.4 by Robert Collins
(robertc) Typo in the help for ``register-branch`` fixed. (Robert Collins, #96770)
54
    launchpad.net.  Registration allows the branch to be associated with
0.4.1 by Martin Pool
Start lp-register command
55
    bugs or specifications.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
56
4416.7.1 by Neil Martinsen-Burrell
Fix 238764 refer to projects rather than products in launchpad plugin
57
    Before using this command you must register the project to which the
0.4.1 by Martin Pool
Start lp-register command
58
    branch belongs, and create an account for yourself on launchpad.net.
0.4.3 by Martin Pool
More command line processing
59
60
    arguments:
3200.2.3 by Robert Collins
Tweak wording.
61
        public_url: The publicly visible url for the branch to register.
3200.2.1 by Robert Collins
* The ``register-branch`` command will now use the public url of the branch
62
                    This must be an http or https url (which Launchpad can read
63
                    from to access the branch). Local file urls, SFTP urls, and
64
                    bzr+ssh urls will not work.
65
                    If no public_url is provided, bzr will use the configured
3200.2.3 by Robert Collins
Tweak wording.
66
                    public_url if there is one for the current branch, and
67
                    otherwise error.
0.4.3 by Martin Pool
More command line processing
68
69
    example:
4416.7.1 by Neil Martinsen-Burrell
Fix 238764 refer to projects rather than products in launchpad plugin
70
        bzr register-branch http://foo.com/bzr/fooproject.mine \\
71
                --project fooproject
0.4.1 by Martin Pool
Start lp-register command
72
    """
3200.2.1 by Robert Collins
* The ``register-branch`` command will now use the public url of the branch
73
    takes_args = ['public_url?']
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
74
    takes_options = [
4416.7.1 by Neil Martinsen-Burrell
Fix 238764 refer to projects rather than products in launchpad plugin
75
         Option('project',
76
                'Launchpad project short name to associate with the branch.',
0.4.15 by Martin Pool
(register-branch) Add command-line options
77
                unicode),
4416.7.3 by Neil Martinsen-Burrell
Retain --product options for register-branch, but deprecate it in favor of --project
78
         Option('product',
79
                'Launchpad product short name to associate with the branch.', 
80
                unicode,
81
                hidden=True),
0.4.15 by Martin Pool
(register-branch) Add command-line options
82
         Option('branch-name',
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
83
                'Short name for the branch; '
84
                'by default taken from the last component of the url.',
0.4.15 by Martin Pool
(register-branch) Add command-line options
85
                unicode),
86
         Option('branch-title',
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
87
                'One-sentence description of the branch.',
0.4.15 by Martin Pool
(register-branch) Add command-line options
88
                unicode),
89
         Option('branch-description',
2598.1.5 by Martin Pool
Fix one more option message.
90
                'Longer description of the purpose or contents of the branch.',
0.4.15 by Martin Pool
(register-branch) Add command-line options
91
                unicode),
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
92
         Option('author',
93
                "Branch author's email address, if not yourself.",
0.4.16 by Martin Pool
(register-branch) Add --author option and respect --dry-run
94
                unicode),
0.4.19 by test at canonical
add possibility to link to a bug when registering a branch. factor out some common functionality from BranchRegistrationRequest.
95
         Option('link-bug',
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
96
                'The bug this branch fixes.',
0.4.19 by test at canonical
add possibility to link to a bug when registering a branch. factor out some common functionality from BranchRegistrationRequest.
97
                int),
0.4.15 by Martin Pool
(register-branch) Add command-line options
98
         Option('dry-run',
2598.1.1 by Martin Pool
Add test for and documentation of option style, fix up existing options to comply
99
                'Prepare the request but don\'t actually send it.')
0.4.15 by Martin Pool
(register-branch) Add command-line options
100
        ]
101
102
3200.2.1 by Robert Collins
* The ``register-branch`` command will now use the public url of the branch
103
    def run(self,
104
            public_url=None,
4416.7.1 by Neil Martinsen-Burrell
Fix 238764 refer to projects rather than products in launchpad plugin
105
            project='',
4416.7.3 by Neil Martinsen-Burrell
Retain --product options for register-branch, but deprecate it in favor of --project
106
            product=None,
0.4.15 by Martin Pool
(register-branch) Add command-line options
107
            branch_name='',
108
            branch_title='',
109
            branch_description='',
0.4.16 by Martin Pool
(register-branch) Add --author option and respect --dry-run
110
            author='',
0.4.19 by test at canonical
add possibility to link to a bug when registering a branch. factor out some common functionality from BranchRegistrationRequest.
111
            link_bug=None,
0.4.15 by Martin Pool
(register-branch) Add command-line options
112
            dry_run=False):
2898.3.8 by James Henstridge
Get rid of relative imports in Launchpad plugin.
113
        from bzrlib.plugins.launchpad.lp_registration import (
1668.1.12 by Martin Pool
(launchpad plugin) Improved --dry-run that uses a dummy xmlrpc service.
114
            LaunchpadService, BranchRegistrationRequest, BranchBugLinkRequest,
115
            DryRunLaunchpadService)
3200.2.1 by Robert Collins
* The ``register-branch`` command will now use the public url of the branch
116
        if public_url is None:
117
            try:
4031.2.11 by John Arbash Meinel
Turn a bunch of imports into lazy imports.
118
                b = _mod_branch.Branch.open_containing('.')[0]
3200.2.1 by Robert Collins
* The ``register-branch`` command will now use the public url of the branch
119
            except NotBranchError:
120
                raise BzrCommandError('register-branch requires a public '
121
                    'branch url - see bzr help register-branch.')
122
            public_url = b.get_public_branch()
123
            if public_url is None:
124
                raise NoPublicBranch(b)
4416.7.3 by Neil Martinsen-Burrell
Retain --product options for register-branch, but deprecate it in favor of --project
125
        if product is not None:
126
            project = product
127
            trace.note('--product is deprecated; please use --project.')
128
3200.2.1 by Robert Collins
* The ``register-branch`` command will now use the public url of the branch
129
130
        rego = BranchRegistrationRequest(branch_url=public_url,
0.4.15 by Martin Pool
(register-branch) Add command-line options
131
                                         branch_name=branch_name,
132
                                         branch_title=branch_title,
133
                                         branch_description=branch_description,
4416.7.1 by Neil Martinsen-Burrell
Fix 238764 refer to projects rather than products in launchpad plugin
134
                                         product_name=project,
0.4.16 by Martin Pool
(register-branch) Add --author option and respect --dry-run
135
                                         author_email=author,
0.4.15 by Martin Pool
(register-branch) Add command-line options
136
                                         )
3200.2.1 by Robert Collins
* The ``register-branch`` command will now use the public url of the branch
137
        linko = BranchBugLinkRequest(branch_url=public_url,
0.4.19 by test at canonical
add possibility to link to a bug when registering a branch. factor out some common functionality from BranchRegistrationRequest.
138
                                     bug_id=link_bug)
1668.1.12 by Martin Pool
(launchpad plugin) Improved --dry-run that uses a dummy xmlrpc service.
139
        if not dry_run:
140
            service = LaunchpadService()
141
            # This gives back the xmlrpc url that can be used for future
142
            # operations on the branch.  It's not so useful to print to the
143
            # user since they can't do anything with it from a web browser; it
144
            # might be nice for the server to tell us about an html url as
145
            # well.
146
        else:
147
            # Run on service entirely in memory
148
            service = DryRunLaunchpadService()
0.4.19 by test at canonical
add possibility to link to a bug when registering a branch. factor out some common functionality from BranchRegistrationRequest.
149
        service.gather_user_credentials()
1668.1.12 by Martin Pool
(launchpad plugin) Improved --dry-run that uses a dummy xmlrpc service.
150
        branch_object_url = rego.submit(service)
151
        if link_bug:
152
            link_bug_url = linko.submit(service)
153
        print 'Branch registered.'
0.4.1 by Martin Pool
Start lp-register command
154
0.4.2 by Martin Pool
Rename command to 'register-branch'
155
register_command(cmd_register_branch)
2245.8.4 by Martin Pool
lp:/// indirection works
156
2898.3.3 by James Henstridge
Add launchpad-login command.
157
3955.3.5 by Jonathan Lange
Add an untested plugin, make the error handling a little nicer.
158
class cmd_launchpad_open(Command):
159
    """Open a Launchpad branch page in your web browser."""
160
161
    aliases = ['lp-open']
3955.3.7 by Jonathan Lange
Test the launchpad-open command. Fix up some minor bugs.
162
    takes_options = [
163
        Option('dry-run',
164
               'Do not actually open the browser. Just say the URL we would '
165
               'use.'),
166
        ]
3955.3.5 by Jonathan Lange
Add an untested plugin, make the error handling a little nicer.
167
    takes_args = ['location?']
168
4031.2.5 by Jonathan Lange
Refactor the code so we don't do too many remote requests.
169
    def _possible_locations(self, location):
170
        """Yield possible external locations for the branch at 'location'."""
171
        yield location
172
        try:
4031.2.11 by John Arbash Meinel
Turn a bunch of imports into lazy imports.
173
            branch = _mod_branch.Branch.open(location)
4031.2.5 by Jonathan Lange
Refactor the code so we don't do too many remote requests.
174
        except NotBranchError:
175
            return
176
        branch_url = branch.get_public_branch()
177
        if branch_url is not None:
178
            yield branch_url
179
        branch_url = branch.get_push_location()
180
        if branch_url is not None:
181
            yield branch_url
182
183
    def _get_web_url(self, service, location):
184
        for branch_url in self._possible_locations(location):
185
            try:
186
                return service.get_web_url_from_branch_url(branch_url)
187
            except (NotLaunchpadBranch, InvalidURL):
188
                pass
189
        raise NotLaunchpadBranch(branch_url)
190
3955.3.7 by Jonathan Lange
Test the launchpad-open command. Fix up some minor bugs.
191
    def run(self, location=None, dry_run=False):
3955.3.5 by Jonathan Lange
Add an untested plugin, make the error handling a little nicer.
192
        if location is None:
193
            location = u'.'
4031.2.5 by Jonathan Lange
Refactor the code so we don't do too many remote requests.
194
        web_url = self._get_web_url(LaunchpadService(), location)
4031.2.11 by John Arbash Meinel
Turn a bunch of imports into lazy imports.
195
        trace.note('Opening %s in web browser' % web_url)
3955.3.7 by Jonathan Lange
Test the launchpad-open command. Fix up some minor bugs.
196
        if not dry_run:
4511.1.1 by Alexander Belchenko
launchpad plugin: import webbrowse should be explicit and never lazy, otherwise bzr.exe lacks this module.
197
            import webbrowser   # this import should not be lazy
198
                                # otherwise bzr.exe lacks this module
3955.3.7 by Jonathan Lange
Test the launchpad-open command. Fix up some minor bugs.
199
            webbrowser.open(web_url)
3955.3.5 by Jonathan Lange
Add an untested plugin, make the error handling a little nicer.
200
201
register_command(cmd_launchpad_open)
202
203
2898.3.3 by James Henstridge
Add launchpad-login command.
204
class cmd_launchpad_login(Command):
2934.1.1 by Ian Clatworthy
(James Henstridge) add a command for managing the Launchpad user ID
205
    """Show or set the Launchpad user ID.
2898.3.3 by James Henstridge
Add launchpad-login command.
206
207
    When communicating with Launchpad, some commands need to know your
208
    Launchpad user ID.  This command can be used to set or show the
209
    user ID that Bazaar will use for such communication.
210
211
    :Examples:
212
      Show the Launchpad ID of the current user::
213
214
          bzr launchpad-login
215
2898.3.9 by James Henstridge
* Add a simple NEWS item for the command.
216
      Set the Launchpad ID of the current user to 'bob'::
2898.3.3 by James Henstridge
Add launchpad-login command.
217
2898.3.9 by James Henstridge
* Add a simple NEWS item for the command.
218
          bzr launchpad-login bob
2898.3.3 by James Henstridge
Add launchpad-login command.
219
    """
220
    aliases = ['lp-login']
221
    takes_args = ['name?']
222
    takes_options = [
4505.1.2 by Jonathan Lange
Add many more tests, fix the actual bug.
223
        'verbose',
2898.3.4 by James Henstridge
Cleanups from mini-review by Tim.
224
        Option('no-check',
225
               "Don't check that the user name is valid."),
2898.3.3 by James Henstridge
Add launchpad-login command.
226
        ]
227
4505.1.2 by Jonathan Lange
Add many more tests, fix the actual bug.
228
    def run(self, name=None, no_check=False, verbose=False):
2898.3.8 by James Henstridge
Get rid of relative imports in Launchpad plugin.
229
        from bzrlib.plugins.launchpad import account
2898.3.3 by James Henstridge
Add launchpad-login command.
230
        check_account = not no_check
231
232
        if name is None:
233
            username = account.get_lp_login()
234
            if username:
2898.3.4 by James Henstridge
Cleanups from mini-review by Tim.
235
                if check_account:
236
                    account.check_lp_login(username)
4505.1.3 by Jonathan Lange
Add some extra untested verbosity.
237
                    if verbose:
238
                        self.outf.write(
239
                            "Launchpad user ID exists and has SSH keys.\n")
2898.3.3 by James Henstridge
Add launchpad-login command.
240
                self.outf.write(username + '\n')
241
            else:
242
                self.outf.write('No Launchpad user ID configured.\n')
2898.3.9 by James Henstridge
* Add a simple NEWS item for the command.
243
                return 1
2898.3.3 by James Henstridge
Add launchpad-login command.
244
        else:
4216.2.1 by Michael Hudson
well this is it
245
            name = name.lower()
2898.3.3 by James Henstridge
Add launchpad-login command.
246
            if check_account:
247
                account.check_lp_login(name)
4505.1.3 by Jonathan Lange
Add some extra untested verbosity.
248
                if verbose:
249
                    self.outf.write(
250
                        "Launchpad user ID exists and has SSH keys.\n")
2898.3.3 by James Henstridge
Add launchpad-login command.
251
            account.set_lp_login(name)
4505.1.2 by Jonathan Lange
Add many more tests, fix the actual bug.
252
            if verbose:
253
                self.outf.write("Launchpad user ID set to '%s'.\n" % (name,))
2898.3.3 by James Henstridge
Add launchpad-login command.
254
255
register_command(cmd_launchpad_login)
256
257
3251.4.2 by Aaron Bentley
Clean up Launchpad directory service code
258
def _register_directory():
3251.4.3 by Aaron Bentley
More renames and cleanups
259
    directories.register_lazy('lp:', 'bzrlib.plugins.launchpad.lp_directory',
3251.4.2 by Aaron Bentley
Clean up Launchpad directory service code
260
                              'LaunchpadDirectory',
261
                              'Launchpad-based directory service',)
262
_register_directory()
2245.8.5 by Martin Pool
Add short-form lp:PRODUCT url form
263
0.4.1 by Martin Pool
Start lp-register command
264
265
def test_suite():
266
    """Called by bzrlib to fetch tests for this plugin"""
267
    from unittest import TestSuite, TestLoader
2898.3.8 by James Henstridge
Get rid of relative imports in Launchpad plugin.
268
    from bzrlib.plugins.launchpad import (
3955.3.7 by Jonathan Lange
Test the launchpad-open command. Fix up some minor bugs.
269
        test_account,
270
        test_lp_directory,
4505.1.1 by Jonathan Lange
First test for lp-login.
271
        test_lp_login,
3955.3.7 by Jonathan Lange
Test the launchpad-open command. Fix up some minor bugs.
272
        test_lp_open,
273
        test_lp_service,
274
        test_register,
275
        )
2245.8.1 by Martin Pool
Start adding tests for launchpad indirection
276
277
    loader = TestLoader()
278
    suite = TestSuite()
3221.4.2 by Martin Pool
Add in thumpers tests for selection of the right Launchpad instance
279
    for module in [
3221.4.5 by Martin Pool
Tweak indents
280
        test_account,
281
        test_register,
3251.4.3 by Aaron Bentley
More renames and cleanups
282
        test_lp_directory,
4505.1.1 by Jonathan Lange
First test for lp-login.
283
        test_lp_login,
3955.3.7 by Jonathan Lange
Test the launchpad-open command. Fix up some minor bugs.
284
        test_lp_open,
3221.4.5 by Martin Pool
Tweak indents
285
        test_lp_service,
3193.5.3 by Tim Penhey
Tweaks following review.
286
        ]:
3221.4.2 by Martin Pool
Add in thumpers tests for selection of the right Launchpad instance
287
        suite.addTests(loader.loadTestsFromModule(module))
2245.8.1 by Martin Pool
Start adding tests for launchpad indirection
288
    return suite
2245.8.6 by Martin Pool
Documentation under 'help launchpad'
289
290
_launchpad_help = """Integration with Launchpad.net
291
292
Launchpad.net provides free Bazaar branch hosting with integrated bug and
293
specification tracking.
294
3031.1.1 by jml at canonical
Expand the documentation on lp:// URLs and mention the launchpad-login command.
295
The bzr client (through the plugin called 'launchpad') has special
2245.8.6 by Martin Pool
Documentation under 'help launchpad'
296
features to communicate with Launchpad:
297
3031.1.1 by jml at canonical
Expand the documentation on lp:// URLs and mention the launchpad-login command.
298
    * The launchpad-login command tells Bazaar your Launchpad user name. This
299
      is then used by the 'lp:' transport to download your branches using
300
      bzr+ssh://.
301
4258.1.1 by James Westby
Add "--fixes lp:" to the launchpad plugin documentation.
302
    * The 'lp:' transport uses Launchpad as a directory service: for example
303
      'lp:bzr' and 'lp:python' refer to the main branches of the relevant
304
      projects and may be branched, logged, etc. You can also use the 'lp:'
305
      transport to refer to specific branches, e.g. lp:~bzr/bzr/trunk.
306
307
    * The 'lp:' bug tracker alias can expand launchpad bug numbers to their
308
      URLs for use with 'bzr commit --fixes', e.g. 'bzr commit --fixes lp:12345'
309
      will record a revision property that marks that revision as fixing
4258.1.2 by Matt Nordhoff
Fix a typo in the launchpad plugin's help
310
      Launchpad bug 12345. When you push that branch to Launchpad it will
311
      automatically be linked to the bug report.
4258.1.1 by James Westby
Add "--fixes lp:" to the launchpad plugin documentation.
312
3031.1.1 by jml at canonical
Expand the documentation on lp:// URLs and mention the launchpad-login command.
313
    * The register-branch command tells Launchpad about the url of a
2245.8.6 by Martin Pool
Documentation under 'help launchpad'
314
      public branch.  Launchpad will then mirror the branch, display
3031.1.1 by jml at canonical
Expand the documentation on lp:// URLs and mention the launchpad-login command.
315
      its contents and allow it to be attached to bugs and other
2245.8.6 by Martin Pool
Documentation under 'help launchpad'
316
      objects.
317
318
For more information see http://help.launchpad.net/
319
"""
320
topic_registry.register('launchpad',
321
    _launchpad_help,
322
    'Using Bazaar with Launchpad.net')