1
# Copyright (C) 2006-2010 Canonical Ltd
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.
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.
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
17
"""Launchpad.net integration plugin for Bazaar."""
19
# The XMLRPC server address can be overridden by setting the environment
20
# variable $BZR_LP_XMLRPL_URL
22
# see http://bazaar-vcs.org/Specs/BranchRegistrationTool
24
# Since we are a built-in plugin we share the bzrlib version
25
from bzrlib import version_info
27
from bzrlib.lazy_import import lazy_import
28
lazy_import(globals(), """
30
branch as _mod_branch,
35
from bzrlib.commands import Command, Option, register_command
36
from bzrlib.directory_service import directories
37
from bzrlib.errors import (
44
from bzrlib.help_topics import topic_registry
47
class cmd_register_branch(Command):
48
"""Register a branch with launchpad.net.
50
This command lists a bzr branch in the directory of branches on
51
launchpad.net. Registration allows the branch to be associated with
52
bugs or specifications.
54
Before using this command you must register the project to which the
55
branch belongs, and create an account for yourself on launchpad.net.
58
public_url: The publicly visible url for the branch to register.
59
This must be an http or https url (which Launchpad can read
60
from to access the branch). Local file urls, SFTP urls, and
61
bzr+ssh urls will not work.
62
If no public_url is provided, bzr will use the configured
63
public_url if there is one for the current branch, and
67
bzr register-branch http://foo.com/bzr/fooproject.mine \\
70
takes_args = ['public_url?']
73
'Launchpad project short name to associate with the branch.',
76
'Launchpad product short name to associate with the branch.',
80
'Short name for the branch; '
81
'by default taken from the last component of the url.',
83
Option('branch-title',
84
'One-sentence description of the branch.',
86
Option('branch-description',
87
'Longer description of the purpose or contents of the branch.',
90
"Branch author's email address, if not yourself.",
93
'The bug this branch fixes.',
96
'Prepare the request but don\'t actually send it.')
106
branch_description='',
110
from bzrlib.plugins.launchpad.lp_registration import (
111
BranchRegistrationRequest, BranchBugLinkRequest,
112
DryRunLaunchpadService, LaunchpadService)
113
if public_url is None:
115
b = _mod_branch.Branch.open_containing('.')[0]
116
except NotBranchError:
117
raise BzrCommandError('register-branch requires a public '
118
'branch url - see bzr help register-branch.')
119
public_url = b.get_public_branch()
120
if public_url is None:
121
raise NoPublicBranch(b)
122
if product is not None:
124
trace.note('--product is deprecated; please use --project.')
127
rego = BranchRegistrationRequest(branch_url=public_url,
128
branch_name=branch_name,
129
branch_title=branch_title,
130
branch_description=branch_description,
131
product_name=project,
134
linko = BranchBugLinkRequest(branch_url=public_url,
137
service = LaunchpadService()
138
# This gives back the xmlrpc url that can be used for future
139
# operations on the branch. It's not so useful to print to the
140
# user since they can't do anything with it from a web browser; it
141
# might be nice for the server to tell us about an html url as
144
# Run on service entirely in memory
145
service = DryRunLaunchpadService()
146
service.gather_user_credentials()
149
linko.submit(service)
150
print 'Branch registered.'
152
register_command(cmd_register_branch)
155
class cmd_launchpad_open(Command):
156
"""Open a Launchpad branch page in your web browser."""
158
aliases = ['lp-open']
161
'Do not actually open the browser. Just say the URL we would '
164
takes_args = ['location?']
166
def _possible_locations(self, location):
167
"""Yield possible external locations for the branch at 'location'."""
170
branch = _mod_branch.Branch.open_containing(location)[0]
171
except NotBranchError:
173
branch_url = branch.get_public_branch()
174
if branch_url is not None:
176
branch_url = branch.get_push_location()
177
if branch_url is not None:
180
def _get_web_url(self, service, location):
181
from bzrlib.plugins.launchpad.lp_registration import (
183
for branch_url in self._possible_locations(location):
185
return service.get_web_url_from_branch_url(branch_url)
186
except (NotLaunchpadBranch, InvalidURL):
188
raise NotLaunchpadBranch(branch_url)
190
def run(self, location=None, dry_run=False):
191
from bzrlib.plugins.launchpad.lp_registration import (
195
web_url = self._get_web_url(LaunchpadService(), location)
196
trace.note('Opening %s in web browser' % web_url)
198
import webbrowser # this import should not be lazy
199
# otherwise bzr.exe lacks this module
200
webbrowser.open(web_url)
202
register_command(cmd_launchpad_open)
205
class cmd_launchpad_login(Command):
206
"""Show or set the Launchpad user ID.
208
When communicating with Launchpad, some commands need to know your
209
Launchpad user ID. This command can be used to set or show the
210
user ID that Bazaar will use for such communication.
213
Show the Launchpad ID of the current user::
217
Set the Launchpad ID of the current user to 'bob'::
219
bzr launchpad-login bob
221
aliases = ['lp-login']
222
takes_args = ['name?']
226
"Don't check that the user name is valid."),
229
def run(self, name=None, no_check=False, verbose=False):
230
# This is totally separate from any launchpadlib login system.
231
from bzrlib.plugins.launchpad import account
232
check_account = not no_check
235
username = account.get_lp_login()
238
account.check_lp_login(username)
241
"Launchpad user ID exists and has SSH keys.\n")
242
self.outf.write(username + '\n')
244
self.outf.write('No Launchpad user ID configured.\n')
249
account.check_lp_login(name)
252
"Launchpad user ID exists and has SSH keys.\n")
253
account.set_lp_login(name)
255
self.outf.write("Launchpad user ID set to '%s'.\n" % (name,))
257
register_command(cmd_launchpad_login)
260
# XXX: cmd_launchpad_mirror is untested
261
class cmd_launchpad_mirror(Command):
262
"""Ask Launchpad to mirror a branch now."""
264
aliases = ['lp-mirror']
265
takes_args = ['location?']
267
def run(self, location='.'):
268
from bzrlib.plugins.launchpad import lp_api
269
from bzrlib.plugins.launchpad.lp_registration import LaunchpadService
270
branch = _mod_branch.Branch.open(location)
271
service = LaunchpadService()
272
launchpad = lp_api.login(service)
273
lp_branch = lp_api.load_branch(launchpad, branch)
274
lp_branch.requestMirror()
277
register_command(cmd_launchpad_mirror)
280
def _register_directory():
281
directories.register_lazy('lp:', 'bzrlib.plugins.launchpad.lp_directory',
282
'LaunchpadDirectory',
283
'Launchpad-based directory service',)
284
_register_directory()
287
def load_tests(basic_tests, module, loader):
297
basic_tests.addTest(loader.loadTestsFromModuleNames(
298
["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
302
_launchpad_help = """Integration with Launchpad.net
304
Launchpad.net provides free Bazaar branch hosting with integrated bug and
305
specification tracking.
307
The bzr client (through the plugin called 'launchpad') has special
308
features to communicate with Launchpad:
310
* The launchpad-login command tells Bazaar your Launchpad user name. This
311
is then used by the 'lp:' transport to download your branches using
314
* The 'lp:' transport uses Launchpad as a directory service: for example
315
'lp:bzr' and 'lp:python' refer to the main branches of the relevant
316
projects and may be branched, logged, etc. You can also use the 'lp:'
317
transport to refer to specific branches, e.g. lp:~bzr/bzr/trunk.
319
* The 'lp:' bug tracker alias can expand launchpad bug numbers to their
320
URLs for use with 'bzr commit --fixes', e.g. 'bzr commit --fixes lp:12345'
321
will record a revision property that marks that revision as fixing
322
Launchpad bug 12345. When you push that branch to Launchpad it will
323
automatically be linked to the bug report.
325
* The register-branch command tells Launchpad about the url of a
326
public branch. Launchpad will then mirror the branch, display
327
its contents and allow it to be attached to bugs and other
330
For more information see http://help.launchpad.net/
332
topic_registry.register('launchpad',
334
'Using Bazaar with Launchpad.net')