2
# Copyright 2014 Canonical Ltd.
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License version 3, as
6
# published by the Free Software Foundation.
8
# This program is distributed in the hope that it will be useful, but
9
# WITHOUT ANY WARRANTY; without even the implied warranties of
10
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11
# PURPOSE. See the GNU Affero General Public License for more details.
13
# You should have received a copy of the GNU Affero General Public License
14
# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
from setuptools.package_index import PackageIndex
23
# A branch with all the ez-install deps in a single directory, ie:
24
# lp:~canonical-ci-engineering/ubuntu-ci-services-itself/deps
25
PINNED_BRANCH = os.environ.get('CI_DEPS_BRANCH', '')
26
_deps = os.path.join(os.path.dirname(__file__), '../../.deps')
27
PINNED_LOCAL = os.environ.get('CI_DEPS_LOCAL', os.path.abspath(_deps))
30
class HackPI(PackageIndex):
31
'''Ensure we download our dependencies from where we want
33
We want to be able to pin down the location we download our easy-install
34
dependencies from. This ensures we pull them from the place we desire.
36
def __init__(self, *args, **kwargs):
37
super(HackPI, self).__init__(*args, **kwargs)
38
if len(PINNED_BRANCH):
39
self.info('CI_DEPS_BRANCH({}) requested at {}'.format(
40
PINNED_BRANCH, PINNED_LOCAL))
41
if os.path.exists(PINNED_LOCAL):
42
self.info('local deps exist, checking for updates')
43
subprocess.check_call(['bzr', 'pull'], cwd=PINNED_LOCAL)
45
self.info('Creating new branch for deps')
46
subprocess.check_call(
47
['bzr', 'branch', PINNED_BRANCH, PINNED_LOCAL])
49
def _download_url(self, scheme, url, tmpdir):
50
err = '_download_url should not be called with CI_DEPS_BRANCH enabled'
51
if len(PINNED_BRANCH):
52
raise RuntimeError(err)
53
return super(HackPI, self)._download_url(scheme, url, tmpdir)
55
def process_url(self, url, retrieve=False):
56
if not len(PINNED_BRANCH):
57
return super(HackPI, self).process_url(url, retrieve)
58
self.process_filename(PINNED_LOCAL)
61
# setuptools is built upon the monkey-patching (probably because it has
62
# to override distutils in ways it wasn't designed for). So to hack
63
# setuptools we have to monkey patch it.
64
import setuptools.command.easy_install
65
setuptools.command.easy_install.easy_install.create_index = HackPI
68
def _local_pip_file(dep, ver):
69
HackPI() # ensure our local deps are ready
70
for d in os.listdir(PINNED_LOCAL):
71
if d.startswith('%s-%s' % (dep, ver)):
72
return os.path.join(PINNED_LOCAL, d)
73
raise RuntimeError('Missing dependency: %s' % d)
76
def _handle_openstack():
77
# this stuff is required because the pbr library has a bug:
78
# https://bitbucket.org/pypa/setuptools/issue/73/
79
# in addition the openstack packages like python-glanceclient
80
# fail because they use pbr which does dirty things to setuptools
81
# We do a no-deps option to try and keep what we need for local
82
# development down to a minimum
83
output = subprocess.check_output(['pip', 'freeze'])
84
installed = [x.split('==')[0] for x in output.split('\n')]
90
'python-glanceclient==0.12.0',
91
'python-keystoneclient==0.6.0',
92
'python-novaclient==2.15.0',
93
'python-swiftclient==1.8.0',
97
dep, ver = p.split('==')
100
if len(PINNED_BRANCH):
101
print('using local copy of pip dependency')
102
p = _local_pip_file(dep, ver)
103
subprocess.check_call(['pip', 'install', '--no-deps', p])
106
def setup(name, test_suite, install_requires, **kwargs):
107
'''A simple helper for our components to all call setuptools properly'''
109
# ensure find_packages works if our current directory isn't the component
110
component_dir = os.path.abspath(
111
os.path.join(os.path.dirname(__file__), '../..', name))
112
os.chdir(component_dir)
114
if len(sys.argv) > 1 and sys.argv[1] in ('test', 'develop'):
115
if kwargs.get('requires_openstack'):
116
del kwargs['requires_openstack']
122
'description': '%s component of Ubuntu CI Engine' % name,
123
'author': 'Canonical CI Engineering Team',
125
'packages': setuptools.find_packages(component_dir),
126
'test_suite': test_suite,
127
'install_requires': install_requires,
129
for key, val in kwargs.iteritems():
131
return setuptools.setup(**args)