~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Tarmac
  • Author(s): Vincent Ladeuil
  • Date: 2017-01-30 14:42:05 UTC
  • mfrom: (6620.1.1 trunk)
  • Revision ID: tarmac-20170130144205-r8fh2xpmiuxyozpv
Merge  2.7 into trunk including fix for bug #1657238 [r=vila]

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2009-2012 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
16
16
 
17
17
"""Tools for dealing with the Launchpad API."""
18
18
 
 
19
from __future__ import absolute_import
 
20
 
19
21
# Importing this module will be expensive, since it imports launchpadlib and
20
22
# its dependencies. However, our plan is to only load this module when it is
21
23
# needed by a command that uses it.
22
24
 
23
25
 
 
26
import httplib2
24
27
import os
25
28
import re
26
29
import urlparse
33
36
    trace,
34
37
    transport,
35
38
    )
 
39
from bzrlib.i18n import gettext
36
40
from bzrlib.plugins.launchpad.lp_registration import (
37
41
    InvalidLaunchpadInstance,
38
42
    )
46
50
    STAGING_SERVICE_ROOT,
47
51
    Launchpad,
48
52
    )
49
 
 
 
53
from launchpadlib import uris
50
54
 
51
55
# Declare the minimum version of launchpadlib that we need in order to work.
52
 
# 1.5.1 is the version of launchpadlib packaged in Ubuntu 9.10, the most
53
 
# recent Ubuntu release at the time of writing.
54
 
MINIMUM_LAUNCHPADLIB_VERSION = (1, 5, 1)
 
56
# 1.6.0 is the version of launchpadlib packaged in Ubuntu 10.04, the most
 
57
# recent Ubuntu LTS release supported on the desktop at the time of writing.
 
58
MINIMUM_LAUNCHPADLIB_VERSION = (1, 6, 0)
55
59
 
56
60
 
57
61
def get_cache_directory():
73
77
            installed_version, installed_version)
74
78
 
75
79
 
76
 
# The older versions of launchpadlib only provided service root constants for
77
 
# edge and staging, whilst newer versions drop edge. Therefore service root
78
 
# URIs for which we do not always have constants are derived from the staging
79
 
# one, which does always exist.
80
 
#
81
 
# It is necessary to derive, rather than use hardcoded URIs because
82
 
# launchpadlib <= 1.5.4 requires service root URIs that end in a path of
83
 
# /beta/, whilst launchpadlib >= 1.5.5 requires service root URIs with no path
84
 
# info.
85
 
#
86
 
# Once we have a hard dependency on launchpadlib >= 1.5.4 we can replace all of
87
 
# bzr's local knowledge of individual Launchpad instances with use of the
88
 
# launchpadlib.uris module.
89
 
LAUNCHPAD_API_URLS = {
90
 
    'production': STAGING_SERVICE_ROOT.replace('api.staging.launchpad.net',
91
 
        'api.launchpad.net'),
92
 
    'qastaging': STAGING_SERVICE_ROOT.replace('api.staging.launchpad.net',
93
 
        'api.qastaging.launchpad.net'),
94
 
    'staging': STAGING_SERVICE_ROOT,
95
 
    'dev': STAGING_SERVICE_ROOT.replace('api.staging.launchpad.net',
96
 
        'api.launchpad.dev'),
97
 
    }
 
80
def lookup_service_root(service_root):
 
81
    try:
 
82
        return uris.lookup_service_root(service_root)
 
83
    except ValueError:
 
84
        if service_root != 'qastaging':
 
85
            raise
 
86
        staging_root = uris.lookup_service_root('staging')
 
87
        return staging_root.replace('staging', 'qastaging')
98
88
 
99
89
 
100
90
def _get_api_url(service):
111
101
    else:
112
102
        lp_instance = service._lp_instance
113
103
    try:
114
 
        return LAUNCHPAD_API_URLS[lp_instance]
115
 
    except KeyError:
 
104
        return lookup_service_root(lp_instance)
 
105
    except ValueError:
116
106
        raise InvalidLaunchpadInstance(lp_instance)
117
107
 
118
108
 
123
113
        errors.BzrError.__init__(self, branch=branch, url=branch.base)
124
114
 
125
115
 
126
 
def login(service, timeout=None, proxy_info=None):
 
116
def login(service, timeout=None, proxy_info=None,
 
117
          version=Launchpad.DEFAULT_VERSION):
127
118
    """Log in to the Launchpad API.
128
119
 
129
120
    :return: The root `Launchpad` object from launchpadlib.
130
121
    """
 
122
    if proxy_info is None:
 
123
        proxy_info = httplib2.proxy_info_from_environment('https')
131
124
    cache_directory = get_cache_directory()
132
125
    launchpad = Launchpad.login_with(
133
126
        'bzr', _get_api_url(service), cache_directory, timeout=timeout,
134
 
        proxy_info=proxy_info)
135
 
    # XXX: Work-around a minor security bug in launchpadlib 1.5.1, which would
136
 
    # create this directory with default umask.
137
 
    os.chmod(cache_directory, 0700)
 
127
        proxy_info=proxy_info, version=version)
 
128
    # XXX: Work-around a minor security bug in launchpadlib < 1.6.3, which
 
129
    # would create this directory with default umask.
 
130
    osutils.chmod_if_possible(cache_directory, 0700)
138
131
    return launchpad
139
132
 
140
133
 
207
200
        if str(launchpad._root_uri) == STAGING_SERVICE_ROOT:
208
201
            return url.replace('bazaar.launchpad.net',
209
202
                               'bazaar.staging.launchpad.net')
210
 
        elif str(launchpad._root_uri) == LAUNCHPAD_API_URLS['qastaging']:
 
203
        elif str(launchpad._root_uri) == lookup_service_root('qastaging'):
211
204
            return url.replace('bazaar.launchpad.net',
212
205
                               'bazaar.qastaging.launchpad.net')
213
206
        return url
235
228
        """Create a Bazaar branch on Launchpad for the supplied branch."""
236
229
        url = cls.tweak_url(bzr_branch.get_push_location(), launchpad)
237
230
        if not cls.plausible_launchpad_url(url):
238
 
            raise errors.BzrError('%s is not registered on Launchpad' %
 
231
            raise errors.BzrError(gettext('%s is not registered on Launchpad') %
239
232
                                  bzr_branch.base)
240
233
        bzr_branch.create_clone_on_transport(transport.get_transport(url))
241
234
        lp_branch = launchpad.branches.getByUrl(url=url)
242
235
        if lp_branch is None:
243
 
            raise errors.BzrError('%s is not registered on Launchpad' % url)
 
236
            raise errors.BzrError(gettext('%s is not registered on Launchpad') %
 
237
                                                                            url)
244
238
        return lp_branch
245
239
 
246
240
    def get_target(self):
249
243
        if lp_branch.project is not None:
250
244
            dev_focus = lp_branch.project.development_focus
251
245
            if dev_focus is None:
252
 
                raise errors.BzrError('%s has no development focus.' %
 
246
                raise errors.BzrError(gettext('%s has no development focus.') %
253
247
                                  lp_branch.bzr_identity)
254
248
            target = dev_focus.branch
255
249
            if target is None:
256
 
                raise errors.BzrError('development focus %s has no branch.' % dev_focus)
 
250
                raise errors.BzrError(gettext(
 
251
                        'development focus %s has no branch.') % dev_focus)
257
252
        elif lp_branch.sourcepackage is not None:
258
253
            target = lp_branch.sourcepackage.getBranch(pocket="Release")
259
254
            if target is None:
260
 
                raise errors.BzrError('source package %s has no branch.' %
 
255
                raise errors.BzrError(gettext(
 
256
                                      'source package %s has no branch.') %
261
257
                                      lp_branch.sourcepackage)
262
258
        else:
263
 
            raise errors.BzrError('%s has no associated product or source package.' %
 
259
            raise errors.BzrError(gettext(
 
260
                        '%s has no associated product or source package.') %
264
261
                                  lp_branch.bzr_identity)
265
262
        return LaunchpadBranch(target, target.bzr_identity)
266
263
 
272
269
        try:
273
270
            if self.lp.last_scanned_id is not None:
274
271
                if self.bzr.last_revision() == self.lp.last_scanned_id:
275
 
                    trace.note('%s is already up-to-date.' %
 
272
                    trace.note(gettext('%s is already up-to-date.') %
276
273
                               self.lp.bzr_identity)
277
274
                    return
278
275
                graph = self.bzr.repository.get_graph()
279
276
                if not graph.is_ancestor(self.lp.last_scanned_id,
280
277
                                         self.bzr.last_revision()):
281
278
                    raise errors.DivergedBranches(self.bzr, self.push_bzr)
282
 
                trace.note('Pushing to %s' % self.lp.bzr_identity)
 
279
                trace.note(gettext('Pushing to %s') % self.lp.bzr_identity)
283
280
            self.bzr.push(self.push_bzr)
284
281
        finally:
285
282
            self.bzr.unlock()