Merge lp:~ted/snapcraft/python-pip into lp:~snappy-dev/snapcraft/core

Proposed by Ted Gould on 2015-09-14
Status: Merged
Approved by: Sergio Schvezov on 2015-09-18
Approved revision: 159
Merged at revision: 178
Proposed branch: lp:~ted/snapcraft/python-pip
Merge into: lp:~snappy-dev/snapcraft/core
Diff against target: 237 lines (+95/-11)
11 files modified
integration-tests/data/pip-requirements/icon.svg (+2/-0)
integration-tests/data/pip-requirements/requirements.txt (+1/-0)
integration-tests/data/pip-requirements/snapcraft.yaml (+14/-0)
integration-tests/units/jobs.pxu (+11/-0)
plugins/python2.yaml (+3/-0)
plugins/python3.yaml (+3/-0)
snapcraft/plugins/python2.py (+25/-0)
snapcraft/plugins/python2_project.py (+2/-5)
snapcraft/plugins/python3.py (+25/-0)
snapcraft/plugins/python3_project.py (+5/-4)
snapcraft/yaml.py (+4/-2)
To merge this branch: bzr merge lp:~ted/snapcraft/python-pip
Reviewer Review Type Date Requested Status
Sergio Schvezov 2015-09-14 Approve on 2015-09-18
Review via email: mp+270959@code.launchpad.net

Commit Message

Add in support for PIP requirements.txt files in the python plugins.

Description of the Change

Add in support for PIP requirements.txt files in the python plugins.

To post a comment you must log in.
lp:~ted/snapcraft/python-pip updated on 2015-09-14
149. By Ted Gould on 2015-09-14

Update to trunk

Sergio Schvezov (sergiusens) wrote :

Are you rendering the py3 and py2 examples useless here by removing handle_source options?

I also bring this question up often enough (internally at least); with this implemented in python instead of python-project, what is the reason for python-project (or any .*-project at all?)

Sergio Schvezov (sergiusens) wrote :

hey this looks good, it just seems that py2 took a different path than py3.

This also removes the use case (which is rather neat) that the py2-project and py3-project examples bring in.

review: Needs Fixing
Sergio Schvezov (sergiusens) wrote :

python2 and python3 for pip is fine fwiw

lp:~ted/snapcraft/python-pip updated on 2015-09-16
150. By Ted Gould on 2015-09-14

Grabbin' trunk

151. By Ted Gould on 2015-09-16

Put PYTHONPATH in the overall environment instead of a custom one

152. By Ted Gould on 2015-09-16

Move PYTHONPATH to the env function in Python 2 as well

153. By Ted Gould on 2015-09-16

Switch python2 to use target as well

Ted Gould (ted) wrote :

So, some slight modifications. Switched from --root to --target as it seems in recursive cases that causes "bad things to happen" in that it appends twice. But target doesn't have that problem. Also moved the PYTHONPATH to the standard snapcraft environment handling. Now I can build a Nova snap:

https://github.com/ted-gould/nova/blob/master/snapcraft.yaml

Still would like to figure out if we can fix the command line support in setuptools to not put in the full path in a shebang, but that's not really a pip issue.

lp:~ted/snapcraft/python-pip updated on 2015-09-17
154. By Ted Gould on 2015-09-17

Put back a require on python2

155. By Ted Gould on 2015-09-17

Return the source options to python2 project

Ted Gould (ted) wrote :

On Tue, 2015-09-15 at 05:53 +0000, Sergio Schvezov wrote:

> hey this looks good, it just seems that py2 took a different path than py3.
>
> This also removes the use case (which is rather neat) that the py2-project and py3-project examples bring in.

<snip>
I was confused, I didn't see your comments in the diff... handled now.
Thanks!

lp:~ted/snapcraft/python-pip updated on 2015-09-17
156. By Ted Gould on 2015-09-17

Updating to trunk

Sergio Schvezov (sergiusens) wrote :

This is what I see when doing

cd examples/webcam-webui
../../bin/snapcraft

...
Building config
python3 setup.py install --install-layout=deb --prefix=/home/sergiusens/source/launchpad.net/snapcraft/examples/webcam-webui/parts/config/install/usr
running install
Checking .pth file support in /home/sergiusens/source/launchpad.net/snapcraft/examples/webcam-webui/parts/config/install/usr/lib/python3/dist-packages/
/home/sergiusens/source/launchpad.net/snapcraft/examples/webcam-webui/parts/python3/install/usr/bin/python3 -E -c pass
TEST FAILED: /home/sergiusens/source/launchpad.net/snapcraft/examples/webcam-webui/parts/config/install/usr/lib/python3/dist-packages/ does NOT support .pth files
error: bad install directory or PYTHONPATH

You are attempting to install a package to a directory that is not
on PYTHONPATH and which Python does not read ".pth" files from. The
installation directory you specified (via --install-dir, --prefix, or
the distutils default setting) was:

    /home/sergiusens/source/launchpad.net/snapcraft/examples/webcam-webui/parts/config/install/usr/lib/python3/dist-packages/

and your PYTHONPATH environment variable currently contains:

    '/home/sergiusens/source/launchpad.net/snapcraft/examples/webcam-webui/parts/python3/install/usr/lib/python3/dist-packages'

Here are some of your options for correcting the problem:

* You can choose a different installation directory, i.e., one that is
  on PYTHONPATH or supports .pth files

* You can add the installation directory to the PYTHONPATH environment
  variable. (It must then also be on PYTHONPATH whenever you run
  Python and want to use the package(s) you are installing.)

* You can set up the installation directory to support ".pth" files by
  using one of the approaches described here:

  https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations

Please make the appropriate changes for your system and try again.
Failed doing build for config!

lp:~ted/snapcraft/python-pip updated on 2015-09-18
157. By Ted Gould on 2015-09-17

Updating trunk

158. By Ted Gould on 2015-09-17

Grab sergio's test

159. By Sergio Schvezov on 2015-09-18

Environment fixes

Sergio Schvezov (sergiusens) wrote :

Nice

review: Approve
Sergio Schvezov (sergiusens) wrote :

Thanks! This was a tough one!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'integration-tests/data/pip-requirements'
2=== added file 'integration-tests/data/pip-requirements/icon.svg'
3--- integration-tests/data/pip-requirements/icon.svg 1970-01-01 00:00:00 +0000
4+++ integration-tests/data/pip-requirements/icon.svg 2015-09-18 03:31:26 +0000
5@@ -0,0 +1,2 @@
6+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
7+<svg />
8
9=== added file 'integration-tests/data/pip-requirements/requirements.txt'
10--- integration-tests/data/pip-requirements/requirements.txt 1970-01-01 00:00:00 +0000
11+++ integration-tests/data/pip-requirements/requirements.txt 2015-09-18 03:31:26 +0000
12@@ -0,0 +1,1 @@
13+argparse==1.2.2
14
15=== added file 'integration-tests/data/pip-requirements/snapcraft.yaml'
16--- integration-tests/data/pip-requirements/snapcraft.yaml 1970-01-01 00:00:00 +0000
17+++ integration-tests/data/pip-requirements/snapcraft.yaml 2015-09-18 03:31:26 +0000
18@@ -0,0 +1,14 @@
19+name: pip-test
20+version: 1
21+vendor: PIP Tests <pip@pippy.pi>
22+summary: Why do snapcraft files require a summary?
23+description: This seems a bit excessive too
24+icon: icon.svg
25+
26+parts:
27+ python2:
28+ type: python2
29+ requirements: requirements.txt
30+ python3:
31+ type: python3
32+ requirements: requirements.txt
33
34=== modified file 'integration-tests/units/jobs.pxu'
35--- integration-tests/units/jobs.pxu 2015-09-17 20:52:11 +0000
36+++ integration-tests/units/jobs.pxu 2015-09-18 03:31:26 +0000
37@@ -315,3 +315,14 @@
38 test -e parts/mercurial/src/second
39 ${SNAPCRAFT} pull
40 test -e parts/mercurial/src/second
41+
42+id: snapcraft/normal/pip-requirements
43+plugin: shell
44+estimated_duration: 60
45+command:
46+ set -ex
47+ cp -rT $PLAINBOX_PROVIDER_DATA/pip-requirements .
48+ ${SNAPCRAFT} pull
49+ test -f parts/python2/install/usr/lib/python2.7/argparse.py
50+ test -f parts/python3/install/usr/lib/python3.4/argparse.py
51+
52
53=== modified file 'plugins/python2.yaml'
54--- plugins/python2.yaml 2015-07-17 14:44:45 +0000
55+++ plugins/python2.yaml 2015-09-18 03:31:26 +0000
56@@ -0,0 +1,3 @@
57+options:
58+ requirements:
59+ required: false
60
61=== modified file 'plugins/python3.yaml'
62--- plugins/python3.yaml 2015-07-15 15:28:27 +0000
63+++ plugins/python3.yaml 2015-09-18 03:31:26 +0000
64@@ -0,0 +1,3 @@
65+options:
66+ requirements:
67+ required: false
68
69=== modified file 'snapcraft/plugins/python2.py'
70--- snapcraft/plugins/python2.py 2015-09-17 06:24:37 +0000
71+++ snapcraft/plugins/python2.py 2015-09-18 03:31:26 +0000
72@@ -14,6 +14,7 @@
73 # You should have received a copy of the GNU General Public License
74 # along with this program. If not, see <http://www.gnu.org/licenses/>.
75
76+import os
77 import snapcraft
78
79
80@@ -24,6 +25,14 @@
81 'python-setuptools',
82 ]
83
84+ def __init__(self, name, options):
85+ if options.requirements:
86+ self.requirements = options.requirements
87+ self._PLUGIN_STAGE_PACKAGES.extend(['python-pkg-resources', 'python-setuptools'])
88+ else:
89+ self.requirements = None
90+ super().__init__(name, options)
91+
92 def snap_fileset(self):
93 return [
94 '-usr/share',
95@@ -32,3 +41,19 @@
96 # note that we don't need to set PYTHONHOME here,
97 # python discovers this automatically from it installed
98 # location. And PATH is automatically set by snapcraft.
99+
100+ def env(self, root):
101+ return ["PYTHONPATH=%s" % os.path.join(
102+ root, 'usr', 'lib', 'python2.7', 'dist-packages')]
103+
104+ def pull(self):
105+ # A nice idea here would be to be asking setup tools
106+ # to use the deb layout, but that doesn't work with
107+ # prefix sadly
108+
109+ if self.requirements and not (self.run(
110+ ['ln', '-s', os.path.join(self.installdir, 'usr', 'lib', 'python2.7', 'dist-packages'), os.path.join(self.installdir, 'usr', 'lib', 'python2.7', 'site-packages')]) and self.run(
111+ ['python2', os.path.join(self.installdir, 'usr', 'bin', 'easy_install'), '--prefix', os.path.join(self.installdir, 'usr'), 'pip']) and self.run(
112+ ['python2', os.path.join(self.installdir, 'usr', 'bin', 'pip2'), 'install', '--target', os.path.join(self.installdir, 'usr', 'lib', 'python2.7', 'site-packages'), '--requirement', os.path.join(os.getcwd(), self.requirements)])):
113+ return False
114+ return True
115
116=== modified file 'snapcraft/plugins/python2_project.py'
117--- snapcraft/plugins/python2_project.py 2015-09-11 19:53:38 +0000
118+++ snapcraft/plugins/python2_project.py 2015-09-18 03:31:26 +0000
119@@ -1,6 +1,6 @@
120 # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
121 #
122-# Copyright (C) 2015 Canonical Ltd
123+# Copyright © 2015 Canonical Ltd
124 #
125 # This program is free software: you can redistribute it and/or modify
126 # it under the terms of the GNU General Public License version 3 as
127@@ -33,13 +33,10 @@
128 # and be in the PYTHONPATH. It's harmless if setuptools isn't
129 # used.
130 os.makedirs(self.dist_packages_dir, exist_ok=True)
131- env = os.environ.copy()
132- env['PYTHONPATH'] = self.dist_packages_dir
133
134 return self.run(
135 ['python2', 'setup.py', 'install', '--install-layout=deb',
136- '--prefix={}/usr'.format(self.installdir)],
137- env=env)
138+ '--prefix={}/usr'.format(self.installdir)])
139
140 @property
141 def dist_packages_dir(self):
142
143=== modified file 'snapcraft/plugins/python3.py'
144--- snapcraft/plugins/python3.py 2015-09-17 06:24:37 +0000
145+++ snapcraft/plugins/python3.py 2015-09-18 03:31:26 +0000
146@@ -14,6 +14,7 @@
147 # You should have received a copy of the GNU General Public License
148 # along with this program. If not, see <http://www.gnu.org/licenses/>.
149
150+import os
151 import snapcraft
152
153
154@@ -24,6 +25,14 @@
155 'python3-setuptools',
156 ]
157
158+ def __init__(self, name, options):
159+ if options.requirements:
160+ self.requirements = options.requirements
161+ self._PLUGIN_STAGE_PACKAGES.extend(['python3-pkg-resources', 'python3-setuptools'])
162+ else:
163+ self.requirements = None
164+ super().__init__(name, options)
165+
166 def snap_fileset(self):
167 return [
168 '-usr/share',
169@@ -34,3 +43,19 @@
170 # location, see https://code.launchpad.net/~mvo/snapcraft/python3-project/+merge/264521/comments/664308
171 #
172 # PATH is automatically set by snapcraft
173+
174+ def env(self, root):
175+ return ["PYTHONPATH=%s" % os.path.join(
176+ root, 'usr', 'lib', 'python3', 'dist-packages')]
177+
178+ def pull(self):
179+ # A nice idea here would be to be asking setup tools
180+ # to use the deb layout, but that doesn't work with
181+ # prefix sadly
182+
183+ if self.requirements and not (self.run(
184+ ['ln', '-s', os.path.join(self.installdir, 'usr', 'lib', 'python3', 'dist-packages'), os.path.join(self.installdir, 'usr', 'lib', 'python3.4', 'site-packages')]) and self.run(
185+ ['python3', os.path.join(self.installdir, 'usr', 'bin', 'easy_install3'), '--prefix', os.path.join(self.installdir, 'usr'), 'pip']) and self.run(
186+ ['python3', os.path.join(self.installdir, 'usr', 'bin', 'pip3'), 'install', '--target', os.path.join(self.installdir, 'usr', 'lib', 'python3.4', 'site-packages'), '--requirement', os.path.join(os.getcwd(), self.requirements)])):
187+ return False
188+ return True
189
190=== modified file 'snapcraft/plugins/python3_project.py'
191--- snapcraft/plugins/python3_project.py 2015-09-11 19:53:38 +0000
192+++ snapcraft/plugins/python3_project.py 2015-09-18 03:31:26 +0000
193@@ -24,6 +24,10 @@
194 # note that we don't need to setup env(), python figures it out
195 # see python3.py for more details
196
197+ def env(self, root):
198+ return ["PYTHONPATH=%s" % os.path.join(
199+ root, 'usr', 'lib', 'python3', 'dist-packages')]
200+
201 def pull(self):
202 return self.handle_source_options()
203
204@@ -33,12 +37,9 @@
205 # and be in the PYTHONPATH. It's harmless if setuptools isn't
206 # used.
207 os.makedirs(self.dist_packages_dir, exist_ok=True)
208- env = os.environ.copy()
209- env['PYTHONPATH'] = self.dist_packages_dir
210 return self.run(
211 ['python3', 'setup.py', 'install', '--install-layout=deb',
212- '--prefix=%s/usr' % self.installdir],
213- env=env)
214+ '--prefix=%s/usr' % self.installdir])
215
216 @property
217 def dist_packages_dir(self):
218
219=== modified file 'snapcraft/yaml.py'
220--- snapcraft/yaml.py 2015-09-16 19:31:05 +0000
221+++ snapcraft/yaml.py 2015-09-18 03:31:26 +0000
222@@ -183,11 +183,13 @@
223
224 for dep in part.deps:
225 root = dep.installdir
226- env += self.runtime_env(root)
227- env += self.build_env(root)
228 env += dep.env(root)
229 env += self.build_env_for_part(dep)
230
231+ env += part.env(part.installdir)
232+ env += self.runtime_env(part.installdir)
233+ env += self.build_env(part.installdir)
234+
235 return env
236
237 def stage_env(self):

Subscribers

People subscribed via source and target branches

to all changes: