Merge ~cjwatson/ols-charm-deps:pip-install-code-dir into ols-charm-deps:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 4a649436a8ef9f1af64f469e2b7542b22937cff3
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/ols-charm-deps:pip-install-code-dir
Merge into: ols-charm-deps:master
Diff against target: 78 lines (+51/-5)
2 files modified
layer/ols/lib/ols/base.py (+13/-5)
layer/ols/unit_tests/test_ols.py (+38/-0)
Reviewer Review Type Date Requested Status
Guillermo Gonzalez Approve
Review via email: mp+381664@code.launchpad.net

Commit message

Tell pip to install code dir if it has setup.py

Description of the change

It's sometimes useful to have entry points in the code directory's setup.py that install scripts: for example, lp-signing does this. Support this by adding the code directory to pip's arguments, provided that a setup.py exists there.

To post a comment you must log in.
Revision history for this message
Guillermo Gonzalez (verterok) wrote :

looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/layer/ols/lib/ols/base.py b/layer/ols/lib/ols/base.py
2index 357ad0a..df9d984 100644
3--- a/layer/ols/lib/ols/base.py
4+++ b/layer/ols/lib/ols/base.py
5@@ -374,11 +374,19 @@ def create_virtualenv(wheels_dir, codedir, python_exe):
6 requirements = os.path.join(codedir, 'requirements.txt')
7
8 hookenv.log('Installing from local wheelhouse.')
9- subprocess.check_call(['%s/bin/pip' % env_dir,
10- 'install',
11- '--no-index',
12- '--find-links={}'.format(wheels_dir),
13- '-r', requirements])
14+ pip_args = [
15+ '%s/bin/pip' % env_dir,
16+ 'install',
17+ '--no-index',
18+ '--find-links={}'.format(wheels_dir),
19+ '-r', requirements,
20+ ]
21+ # The payload may have a setup.py. If so, tell pip to install the code
22+ # directory as well, so that any entry points configured by the payload
23+ # will have corresponding scripts built for them.
24+ if os.path.exists(os.path.join(codedir, 'setup.py')):
25+ pip_args.append(codedir)
26+ subprocess.check_call(pip_args)
27
28
29 def render_template(template, context):
30diff --git a/layer/ols/unit_tests/test_ols.py b/layer/ols/unit_tests/test_ols.py
31index b982636..adef577 100644
32--- a/layer/ols/unit_tests/test_ols.py
33+++ b/layer/ols/unit_tests/test_ols.py
34@@ -489,6 +489,44 @@ class BaseTest(TestCase):
35 call('Installing python packages into the venv'),
36 call('Installing from local wheelhouse.')])
37
38+ @patch.object(hookenv, 'log')
39+ def test_create_virtualenv_with_setup_py(self, log):
40+ env_dir = os.path.join(base.code_dir(), 'env')
41+ wheels_dir = os.path.join(base.code_dir(), 'wheels')
42+ requirements = os.path.join(base.code_dir(), 'requirements.txt')
43+ setup_py = os.path.join(base.code_dir(), 'setup.py')
44+ os.makedirs(base.code_dir())
45+ with open(setup_py, 'w'):
46+ pass
47+ ps = FakeProcesses()
48+ self.useFixture(ps)
49+ venv_ok = Mock()
50+ venv_ok.return_value = {'returncode': 0}
51+ ps.add(venv_ok, name='virtualenv')
52+ pip = Mock()
53+ pip.return_value = {'returncode': 0}
54+ pip_bin = '%s/bin/pip' % (env_dir)
55+ ps.add(pip, name=pip_bin)
56+
57+ base.create_virtualenv(wheels_dir, base.code_dir(),
58+ base.python_bin())
59+
60+ venv_ok.assert_called_once_with({'args': [
61+ 'virtualenv',
62+ '--no-download',
63+ '--extra-search-dir=/srv/testservice/code/wheels',
64+ '-p', 'python3',
65+ '--extra-search-dir', '/srv/testservice/code/wheels',
66+ '/srv/testservice/code/env']})
67+
68+ pip.assert_called_once_with({'args': [
69+ pip_bin, 'install', '--no-index',
70+ '--find-links={}'.format(wheels_dir), '-r', requirements,
71+ base.code_dir()]})
72+ log.assert_has_calls([
73+ call('Installing python packages into the venv'),
74+ call('Installing from local wheelhouse.')])
75+
76 def test_render_template(self):
77 tmpl = """
78 {% if True %}

Subscribers

People subscribed via source and target branches