Merge lp:~sergiusens/snapcraft/sources_for_sources into lp:~dholbach/snapcraft/1498347

Proposed by Sergio Schvezov
Status: Superseded
Proposed branch: lp:~sergiusens/snapcraft/sources_for_sources
Merge into: lp:~dholbach/snapcraft/1498347
Diff against target: 1488 lines (+594/-275)
37 files modified
debian/changelog (+42/-5)
debian/control (+11/-0)
debian/rules (+3/-0)
debian/snapcraft-examples.install (+1/-0)
debian/snapcraft.install (+3/-0)
debian/source/options (+0/-5)
debian/tests/control (+3/-2)
debian/tests/runexamples (+2/-0)
debian/tests/runtests (+2/-0)
docs/your-first-snap.md (+2/-2)
examples/downloader-with-wiki-parts/snapcraft.yaml (+1/-0)
integration-tests/data/build-tools/Makefile (+6/-0)
integration-tests/data/build-tools/icon.svg (+1/-0)
integration-tests/data/build-tools/snapcraft.yaml (+14/-0)
integration-tests/data/pip-requirements/snapcraft.yaml (+2/-2)
integration-tests/runtests.sh (+44/-17)
integration-tests/units/examples.pxu (+10/-0)
integration-tests/units/jobs.pxu (+37/-0)
integration-tests/units/testplans.pxu (+6/-1)
plugins/python2-project.yaml (+3/-3)
plugins/python2.yaml (+0/-3)
plugins/python3-project.yaml (+3/-3)
plugins/python3.yaml (+0/-3)
runtests.sh (+67/-35)
snapcraft/__init__.py (+16/-0)
snapcraft/cmds.py (+2/-0)
snapcraft/common.py (+11/-0)
snapcraft/plugin.py (+15/-19)
snapcraft/plugins/go_project.py (+3/-1)
snapcraft/plugins/python2.py (+0/-59)
snapcraft/plugins/python2_project.py (+65/-5)
snapcraft/plugins/python3.py (+0/-61)
snapcraft/plugins/python3_project.py (+62/-5)
snapcraft/repo.py (+83/-26)
snapcraft/tests/test_plugin.py (+0/-14)
snapcraft/tests/test_repo.py (+38/-0)
snapcraft/yaml.py (+36/-4)
To merge this branch: bzr merge lp:~sergiusens/snapcraft/sources_for_sources
Reviewer Review Type Date Requested Status
Daniel Holbach Pending
Review via email: mp+272201@code.launchpad.net

Commit message

Allow using local sources through an env var (mostly useful for launchpad building)

Description of the change

In launchpad, geoip does not work so our code gets stuck. For now we will use whatever the builder is using. We need a longer plan strategy for this one.

To post a comment you must log in.

Unmerged revisions

209. By Sergio Schvezov

Be more resilient to geop failing

208. By Sergio Schvezov

Add flag to use local sources

207. By Sergio Schvezov

preparing a changelog by sergiusens approved by sergiusens,dholbach

206. By Michael Vogt

The go plugin should only download in the pull phase by mvo approved by sergiusens

205. By Ted Gould

Ensure C library configuration tools don't use system paths by ted approved by sergiusens

204. By Sergio Schvezov

Show skipped packages only once per filter by sergiusens approved by chipaca

203. By Sergio Schvezov

do NOT print in tests by sergiusens approved by fgimenez

202. By Sergio Schvezov

Make the py 2 and 3 projects smarter and have dependencies pulled during the pull phase by sergiusens approved by chipaca

201. By Michael Vogt

Add quotes around $TEST_PLAN and pass the $1 directly to run_test_plan instead of indirectly in runtests.sh by mvo approved by sergiusens,fgimenez,dholbach

200. By Zygmunt Krynicki

Add 'simple' and 'has-leftovers' flags to all integration tests job units. by zyga approved by dholbach,elopio

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2015-08-18 12:37:44 +0000
3+++ debian/changelog 2015-09-24 04:06:53 +0000
4@@ -1,8 +1,45 @@
5-snapcraft (0.2) UNRELEASED; urgency=medium
6-
7- *
8-
9- -- Daniel Holbach <daniel.holbach@ubuntu.com> Tue, 18 Aug 2015 14:23:24 +0200
10+snapcraft (0.2) wily; urgency=medium
11+
12+ * Better setuptools support:
13+ - Better support python-setuptools (LP: #1481864),
14+ - Used builddir as a base for setup.py overrides (LP: #1498212),
15+ - Fix build (LP: #1494825),
16+ * Plugin fixes:
17+ - Add demo.qml back to the snapcraft.yaml for the QML Demo (LP: #1491301),
18+ - stage package libgudev-1.0-0, which makes the godd snap actually
19+ work (LP: #1498347),
20+ - Wrap setup.py calls to configure the shebang writer (LP: #1486680),
21+ - Update tomcat upstream URL, fixes example again (LP: #1491303),
22+ - Add libgudev-1.0-dev as build-tools for godd example,
23+ Ensure C library configuration tools don't use system
24+ paths (LP: #1496789),
25+ * Snapcraft cli:
26+ - On clean, check the contents of the parts dir only if it
27+ exists. (LP: #1497371)
28+ - Load the config before trying to run (LP: #1498140),
29+ - Notify user why the password is being requested (LP: #1481499),
30+ - Fix numerous issues in snapcraft run (LP: #1486659),
31+ * Snapcraft stage-packages:
32+ - Enable ports for architectures that are not amd64 or
33+ i386 (LP: #1498157),
34+ - Improving stage-package handling (LP: #1497453, LP: #1497582)
35+ - Fetch all packages in a single download run with proper
36+ progress (LP: #1498333),
37+ * Snapcraft wiki queries excessive (LP: #1496381),
38+ * Snapcraft internals:
39+ - Add 'simple' and 'has-leftovers' flags to all integration tests job
40+ units. (LP: #1484596),
41+ - Regex for binary and service names (LP: #1495662),
42+ - Provide a nice error when tabs found in snapcraft.yaml (LP: #1477875),
43+ - Use relative paths for image creation (LP: #1497108),
44+ - Use the python logger (LP: #1476452),
45+ - snapcraft now has less exit points (LP: #1477639),
46+ - Depend and Build-Depend on python3-requests (LP: #1496363),
47+ - Add autopkgtest, reshuffle build-deps accordingly (LP: #1496392),
48+ - Fix "snapcraft run" (LP: #1484720),
49+ * Examples packaged (LP: #1498189).
50+
51+ -- Sergio Schvezov <sergio.schvezov@canonical.com> Wed, 24 Sep 2015 14:23:24 -0300
52
53 snapcraft (0.1) wily; urgency=low
54
55
56=== modified file 'debian/control'
57--- debian/control 2015-09-16 14:26:10 +0000
58+++ debian/control 2015-09-24 04:06:53 +0000
59@@ -39,3 +39,14 @@
60 a single toolset, but instead is a collection of tools that enable the
61 natural workflow of an upstream to be extended with a simple release step
62 into Snappy.
63+
64+Package: snapcraft-examples
65+Architecture: all
66+Depends: snapcraft (= ${binary:Version}), ${misc:Depends}, ${python3:Depends}
67+Description: examples for snapcraft
68+ Snapcraft aims to make upstream developers' lives easier and as such is not
69+ a single toolset, but instead is a collection of tools that enable the
70+ natural workflow of an upstream to be extended with a simple release step
71+ into Snappy.
72+ .
73+ This package contains examples for snapcraft.
74
75=== modified file 'debian/rules'
76--- debian/rules 2015-09-16 14:26:10 +0000
77+++ debian/rules 2015-09-24 04:06:53 +0000
78@@ -3,3 +3,6 @@
79
80 %:
81 dh $@ --with python3 --buildsystem=pybuild
82+
83+override_dh_compress:
84+ dh_compress -X/usr/share/snapcraft/examples
85
86=== added file 'debian/snapcraft-examples.install'
87--- debian/snapcraft-examples.install 1970-01-01 00:00:00 +0000
88+++ debian/snapcraft-examples.install 2015-09-24 04:06:53 +0000
89@@ -0,0 +1,1 @@
90+examples /usr/share/snapcraft
91
92=== added file 'debian/snapcraft.install'
93--- debian/snapcraft.install 1970-01-01 00:00:00 +0000
94+++ debian/snapcraft.install 2015-09-24 04:06:53 +0000
95@@ -0,0 +1,3 @@
96+/usr/bin
97+/usr/lib/python*
98+/usr/share/snapcraft
99
100=== modified file 'debian/source/options'
101--- debian/source/options 2015-07-06 16:48:22 +0000
102+++ debian/source/options 2015-09-24 04:06:53 +0000
103@@ -1,7 +1,2 @@
104 # Ignore standard files (like .bzr)
105 tar-ignore
106-
107-# Ignore examples folder because it likely contains a bunch of stuff we don't
108-# care about (like downloaded go1.4 binaries and such). It's not important
109-# for it to be distributed with the source.
110-tar-ignore = "examples"
111
112=== modified file 'debian/tests/control'
113--- debian/tests/control 2015-09-17 14:56:20 +0000
114+++ debian/tests/control 2015-09-24 04:06:53 +0000
115@@ -1,5 +1,6 @@
116-Test-Command: ./runtests.sh
117-Restrictions: allow-stderr, isolation-container
118+Tests: runtests
119+ runexamples
120+Restrictions: allow-stderr, isolation-container, rw-build-tree
121 Depends: @,
122 build-essential,
123 pep8,
124
125=== added file 'debian/tests/runexamples'
126--- debian/tests/runexamples 1970-01-01 00:00:00 +0000
127+++ debian/tests/runexamples 2015-09-24 04:06:53 +0000
128@@ -0,0 +1,2 @@
129+#!/bin/sh
130+./runtests.sh plainbox examples
131
132=== added file 'debian/tests/runtests'
133--- debian/tests/runtests 1970-01-01 00:00:00 +0000
134+++ debian/tests/runtests 2015-09-24 04:06:53 +0000
135@@ -0,0 +1,2 @@
136+#!/bin/sh
137+./runtests.sh
138
139=== modified file 'docs/your-first-snap.md'
140--- docs/your-first-snap.md 2015-09-14 20:53:28 +0000
141+++ docs/your-first-snap.md 2015-09-24 04:06:53 +0000
142@@ -268,8 +268,8 @@
143 description: Exposes your webcam over a web UI
144 icon: icon.png
145 services:
146- - name: webcam-webui
147- start: bin/webcam-webui
148+ webcam-webui:
149+ start: bin/webcam-webui
150
151 parts:
152 golang-static-http:
153
154=== modified file 'examples/downloader-with-wiki-parts/snapcraft.yaml'
155--- examples/downloader-with-wiki-parts/snapcraft.yaml 2015-09-21 05:04:31 +0000
156+++ examples/downloader-with-wiki-parts/snapcraft.yaml 2015-09-24 04:06:53 +0000
157@@ -14,3 +14,4 @@
158 source: .
159 after:
160 - curl
161+build-packages: [libssl-dev]
162
163=== added directory 'integration-tests/data/build-tools'
164=== added file 'integration-tests/data/build-tools/Makefile'
165--- integration-tests/data/build-tools/Makefile 1970-01-01 00:00:00 +0000
166+++ integration-tests/data/build-tools/Makefile 2015-09-24 04:06:53 +0000
167@@ -0,0 +1,6 @@
168+
169+all:
170+ @echo "Makin' like a Makefile"
171+
172+install:
173+ @echo "Installin' like a Makefile"
174
175=== added file 'integration-tests/data/build-tools/icon.svg'
176--- integration-tests/data/build-tools/icon.svg 1970-01-01 00:00:00 +0000
177+++ integration-tests/data/build-tools/icon.svg 2015-09-24 04:06:53 +0000
178@@ -0,0 +1,1 @@
179+<svg/>
180
181=== added file 'integration-tests/data/build-tools/snapcraft.yaml'
182--- integration-tests/data/build-tools/snapcraft.yaml 1970-01-01 00:00:00 +0000
183+++ integration-tests/data/build-tools/snapcraft.yaml 2015-09-24 04:06:53 +0000
184@@ -0,0 +1,14 @@
185+name: build-tools-test
186+version: 0.1
187+vendor: Napoleon Bonaparte <napoleon@short-guys-rock.co.fr>
188+summary: one line summary
189+description: a longer description
190+icon: icon.svg
191+
192+parts:
193+ make-project:
194+ source: .
195+ stage-packages:
196+ - libxml2-dev
197+ - libxslt1-dev
198+ - libglib2.0-dev
199
200=== modified file 'integration-tests/data/pip-requirements/snapcraft.yaml'
201--- integration-tests/data/pip-requirements/snapcraft.yaml 2015-09-09 20:19:12 +0000
202+++ integration-tests/data/pip-requirements/snapcraft.yaml 2015-09-24 04:06:53 +0000
203@@ -7,8 +7,8 @@
204
205 parts:
206 python2:
207- type: python2
208+ type: python2-project
209 requirements: requirements.txt
210 python3:
211- type: python3
212+ type: python3-project
213 requirements: requirements.txt
214
215=== modified file 'integration-tests/runtests.sh'
216--- integration-tests/runtests.sh 2015-08-04 23:46:54 +0000
217+++ integration-tests/runtests.sh 2015-09-24 04:06:53 +0000
218@@ -17,24 +17,43 @@
219
220 set -e
221
222-if [ -z "$SNAPCRAFT" ]; then
223- export SNAPCRAFT=snapcraft
224-fi
225+run_test_plan(){
226+ TEST_PLAN=$1
227+
228+ if [ -z "$SNAPCRAFT" ]; then
229+ export SNAPCRAFT=snapcraft
230+ fi
231
232-# Create a temporary directory so that we can run 'manage.py develop' and
233-# create the .provider file there
234-temp_dir=$(mktemp -d)
235-# Develop the provider, this will let us run tests on it
236-./manage.py develop -d $temp_dir
237-# Set PROVIDERPATH (see plainbox(1)) so that we can see the provider
238-# without installing it.
239-export PROVIDERPATH=$PROVIDERPATH:$temp_dir
240-# Run the 'normal' test plan
241-plainbox run \
242- -T 2015.com.canonical.snapcraft::normal \
243- -f json -o $temp_dir/result.json
244-# Analyze the result and fail if there are any failures
245-python3 - << __PYTHON__
246+ # Create a temporary directory so that we can run 'manage.py develop' and
247+ # create the .provider file there
248+ temp_dir=$(mktemp -d)
249+ # Develop the provider, this will let us run tests on it
250+ ./manage.py develop -d $temp_dir
251+ # Set PROVIDERPATH (see plainbox(1)) so that we can see the provider
252+ # without installing it.
253+ export PROVIDERPATH=$PROVIDERPATH:$temp_dir
254+ # create symlink from the provider's data directory to examples for them to
255+ # be available to the tests
256+ if [ "$TEST_PLAN" = "examples" ]; then
257+ BASEDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )"/.. && pwd )
258+ TARGET_PATH=${BASEDIR}/integration-tests/data/examples
259+ if [ -z $ADT_ARTIFACTS ]; then
260+ EXAMPLES_PATH=${BASEDIR}/examples
261+ else
262+ EXAMPLES_PATH=/usr/share/snapcraft/examples
263+ fi
264+ ln -fs ${EXAMPLES_PATH} ${TARGET_PATH}
265+ fi
266+ # Run the test plan
267+ plainbox run \
268+ -T 2015.com.canonical.snapcraft::"$TEST_PLAN" \
269+ -f json -o $temp_dir/result.json
270+ # remove the examples symlink
271+ if [ "$TEST_PLAN" = "examples" ]; then
272+ rm ${TARGET_PATH}
273+ fi
274+ # Analyze the result and fail if there are any failures
275+ python3 - << __PYTHON__
276 import json
277 with open("$temp_dir/result.json", "rt", encoding="utf-8") as stream:
278 results = json.load(stream)
279@@ -46,3 +65,11 @@
280 print("Overall: {0}".format("fail" if failed else "pass"))
281 raise SystemExit(failed)
282 __PYTHON__
283+}
284+
285+if [ -z "$1" ]; then
286+ echo "need test plan as first argument"
287+ exit 1
288+fi
289+
290+run_test_plan "$@"
291
292=== added file 'integration-tests/units/examples.pxu'
293--- integration-tests/units/examples.pxu 1970-01-01 00:00:00 +0000
294+++ integration-tests/units/examples.pxu 2015-09-24 04:06:53 +0000
295@@ -0,0 +1,10 @@
296+id: snapcraft/examples/build
297+plugin: shell
298+command:
299+ set -e
300+ for example in ${PLAINBOX_PROVIDER_DATA}/examples/*
301+ do
302+ cp -rT ${example//:} ${PLAINBOX_SESSION_SHARE}
303+ cd ${PLAINBOX_SESSION_SHARE} && ${SNAPCRAFT}
304+ rm -rf ${PLAINBOX_SESSION_SHARE}/*
305+ done
306
307=== modified file 'integration-tests/units/jobs.pxu'
308--- integration-tests/units/jobs.pxu 2015-09-21 19:20:43 +0000
309+++ integration-tests/units/jobs.pxu 2015-09-24 04:06:53 +0000
310@@ -6,6 +6,7 @@
311 OUTPUT=$(${SNAPCRAFT} pull 2>&1)
312 test $? = 1 || exit 1
313 echo $OUTPUT | grep "Could not find snapcraft\.yaml\."
314+flags: simple has-leftovers
315
316 id: snapcraft/normal/no-yaml-run
317 plugin: shell
318@@ -26,6 +27,7 @@
319 # care where (and you don't need snappy-metadata to find it)
320 touch copy-meta # instructs Makefile to copy snappy/ itself
321 ${SNAPCRAFT} assemble
322+flags: simple has-leftovers
323
324 id: snapcraft/normal/assemble-meta
325 plugin: shell
326@@ -48,6 +50,7 @@
327 if [ -e ./snap/bin/not-wrapped.wrapper ]; then
328 exit 1
329 fi
330+flags: simple has-leftovers
331
332 id: snapcraft/normal/local-source
333 plugin: shell
334@@ -60,6 +63,7 @@
335 test "$(readlink parts/make-project/build)" = "$(pwd)"
336 ${SNAPCRAFT} stage
337 test -e stamp-install
338+flags: simple has-leftovers
339
340 id: snapcraft/normal/local-plugin
341 plugin: shell
342@@ -69,6 +73,7 @@
343 cp -rT $PLAINBOX_PROVIDER_DATA/local-plugin .
344 ${SNAPCRAFT} stage
345 test -e stage/build-stamp
346+flags: simple has-leftovers
347
348 id: snapcraft/normal/simple-tar
349 plugin: shell
350@@ -89,6 +94,7 @@
351 test -e stage/parent
352 test -e stage/slash
353 test "$(./stage/bin/test)" = "tarproject"
354+flags: simple has-leftovers
355
356 id: snapcraft/normal/pypi-config
357 plugin: shell
358@@ -103,6 +109,7 @@
359 test -f ./snap/usr/bin/python3
360 test -f ./snap/meta/hooks/config
361 grep -q 'exec "usr/bin/config.py" $*' ./snap/meta/hooks/config
362+flags: simple has-leftovers
363
364 id: snapcraft/normal/simple-make
365 plugin: shell
366@@ -112,6 +119,7 @@
367 cp -rT $PLAINBOX_PROVIDER_DATA/simple-make .
368 ${SNAPCRAFT} stage
369 test "$(./stage/bin/test)" = "Hello world"
370+flags: simple has-leftovers
371
372 id: snapcraft/normal/simple-make-filesets
373 plugin: shell
374@@ -130,6 +138,7 @@
375 grep -q 'file1' ./snap/share/file1
376 grep -q 'file2' ./snap/share/file2
377 grep -q 'file1' ./snap/new/dir2/file1
378+flags: simple has-leftovers
379
380 id: snapcraft/normal/simple-make-clean
381 plugin: shell
382@@ -149,6 +158,7 @@
383 # Clean a second time doesn't fail.
384 # Regression test for https://bugs.launchpad.net/snapcraft/+bug/1497371
385 ${SNAPCRAFT} clean
386+flags: simple has-leftovers
387
388 id: snapcraft/normal/simple-cmake
389 plugin: shell
390@@ -158,6 +168,7 @@
391 cp -rT $PLAINBOX_PROVIDER_DATA/simple-cmake .
392 ${SNAPCRAFT} stage
393 test "$(./stage/bin/simple-cmake)" = "It's a CMake world"
394+flags: simple has-leftovers
395
396 id: snapcraft/normal/simple-copy
397 plugin: shell
398@@ -167,6 +178,7 @@
399 cp -rT $PLAINBOX_PROVIDER_DATA/simple-copy .
400 ${SNAPCRAFT} stage
401 test "$(cat ./stage/dst)" = "I got copied"
402+flags: simple has-leftovers
403
404 id: snapcraft/normal/conflicts
405 plugin: shell
406@@ -177,6 +189,7 @@
407 OUTPUT=$(${SNAPCRAFT} stage 2>&1)
408 test $? = 1 || exit 1
409 echo $OUTPUT | grep "Error: parts p1 and p2 have the following file paths in common which have different contents: bin/test" # squished output by bash
410+flags: simple has-leftovers
411
412 id: snapcraft/normal/dependencies
413 plugin: shell
414@@ -189,6 +202,7 @@
415 test "$(${SNAPCRAFT} shell p3)" = 'p1
416 p1
417 p2'
418+flags: simple has-leftovers
419
420 id: snapcraft/normal/dependencies-circular
421 plugin: shell
422@@ -200,6 +214,7 @@
423 OUTPUT=$(${SNAPCRAFT} pull 2>&1)
424 test $? = 1 || exit 1
425 echo $OUTPUT | grep -i "circular dependency"
426+flags: simple has-leftovers
427
428 id: snapcraft/normal/dependencies-fail
429 plugin: shell
430@@ -210,6 +225,7 @@
431 sed -i '/after/d' snapcraft.yaml
432 ${SNAPCRAFT} build
433 test $? = 1 || exit 1
434+flags: simple has-leftovers
435
436 id: snapcraft/normal/bzr-head
437 plugin: shell
438@@ -225,6 +241,7 @@
439 test "$(bzr revno -r -1 parts/bzr/src)" = "2"
440 ${SNAPCRAFT} pull # test pull doesn't fail
441 test "$(bzr revno -r -1 parts/bzr/src)" = "2"
442+flags: simple has-leftovers
443
444 id: snapcraft/normal/bzr-tag
445 plugin: shell
446@@ -241,6 +258,7 @@
447 test "$(bzr revno -r -1 parts/bzr/src)" = "1"
448 ${SNAPCRAFT} pull # test pull doesn't fail
449 test "$(bzr revno -r -1 parts/bzr/src)" = "1"
450+flags: simple has-leftovers
451
452 id: snapcraft/normal/git-head
453 plugin: shell
454@@ -257,6 +275,7 @@
455 test "$(git -C parts/git/src log -1 --oneline | cut -d' ' -f2)" = "2"
456 ${SNAPCRAFT} pull
457 test "$(git -C parts/git/src log -1 --oneline | cut -d' ' -f2)" = "2"
458+flags: simple has-leftovers
459
460 id: snapcraft/normal/git-tag
461 plugin: shell
462@@ -274,6 +293,7 @@
463 test "$(git -C parts/git/src log -1 --oneline | cut -d' ' -f2)" = "1"
464 ${SNAPCRAFT} pull
465 test "$(git -C parts/git/src log -1 --oneline | cut -d' ' -f2)" = "1"
466+flags: simple has-leftovers
467
468 id: snapcraft/normal/git-branch
469 plugin: shell
470@@ -294,6 +314,7 @@
471 test "$(git -C parts/git/src log -2 --oneline | cut -d' ' -f2 | tr '\n' ' ')" = "3 1 "
472 ${SNAPCRAFT} pull
473 test "$(git -C parts/git/src log -2 --oneline | cut -d' ' -f2 | tr '\n' ' ')" = "3 1 "
474+flags: simple has-leftovers
475
476 id: snapcraft/normal/hg-head
477 plugin: shell
478@@ -310,6 +331,7 @@
479 test "$(hg log --cwd parts/mercurial/src --template "{desc}" -r -1)" = "2"
480 ${SNAPCRAFT} pull
481 test "$(hg log --cwd parts/mercurial/src --template "{desc}" -r -1)" = "2"
482+flags: simple has-leftovers
483
484 id: snapcraft/normal/hg-tag
485 plugin: shell
486@@ -327,6 +349,7 @@
487 test "$(ls -1 parts/mercurial/src/ | wc -l )" = "1"
488 ${SNAPCRAFT} pull
489 test "$(ls -1 parts/mercurial/src/ | wc -l )" = "1"
490+flags: simple has-leftovers
491
492 id: snapcraft/normal/hg-branch
493 plugin: shell
494@@ -345,6 +368,7 @@
495 test -e parts/mercurial/src/second
496 ${SNAPCRAFT} pull
497 test -e parts/mercurial/src/second
498+flags: simple has-leftovers
499
500 id: snapcraft/normal/pip-requirements
501 plugin: shell
502@@ -355,3 +379,16 @@
503 ${SNAPCRAFT} pull
504 test -f parts/python2/install/usr/lib/python2.7/argparse.py
505 test -f parts/python3/install/usr/lib/python3.4/argparse.py
506+flags: simple has-leftovers
507+
508+id: snapcraft/normal/build-tool-paths
509+plugin: shell
510+estimated_duration: 30
511+command:
512+ set -ex
513+ cp -rT $PLAINBOX_PROVIDER_DATA/build-tools .
514+ ${SNAPCRAFT} stage
515+ ${SNAPCRAFT} shell pkg-config --cflags glib-2.0 | grep -q `pwd`
516+ ${SNAPCRAFT} shell xml2-config --cflags | grep -q `pwd`
517+ ${SNAPCRAFT} shell xslt-config --cflags | grep -q `pwd`
518+flags: simple has-leftovers
519
520=== modified file 'integration-tests/units/testplans.pxu'
521--- integration-tests/units/testplans.pxu 2015-07-02 18:29:47 +0000
522+++ integration-tests/units/testplans.pxu 2015-09-24 04:06:53 +0000
523@@ -1,4 +1,9 @@
524 unit: test plan
525 id: normal
526-name: Tests for Snapcraft
527+name: Tests for Snapcraft
528 include: snapcraft/normal/.*
529+
530+unit: test plan
531+id: examples
532+name: Test for building Snapcraft examples
533+include: snapcraft/examples/.*
534
535=== modified file 'plugins/python2-project.yaml'
536--- plugins/python2-project.yaml 2015-09-22 03:08:07 +0000
537+++ plugins/python2-project.yaml 2015-09-24 04:06:53 +0000
538@@ -1,8 +1,8 @@
539-requires:
540- - python2
541 options:
542+ requirements:
543+ required: false
544 source:
545- required: true
546+ required: false
547 source-type:
548 source-tag:
549 source-branch:
550
551=== removed file 'plugins/python2.yaml'
552--- plugins/python2.yaml 2015-09-01 14:10:18 +0000
553+++ plugins/python2.yaml 1970-01-01 00:00:00 +0000
554@@ -1,3 +0,0 @@
555-options:
556- requirements:
557- required: false
558
559=== modified file 'plugins/python3-project.yaml'
560--- plugins/python3-project.yaml 2015-09-22 03:08:07 +0000
561+++ plugins/python3-project.yaml 2015-09-24 04:06:53 +0000
562@@ -1,8 +1,8 @@
563-requires:
564- - python3
565 options:
566+ requirements:
567+ required: false
568 source:
569- required: true
570+ required: false
571 source-type:
572 source-tag:
573 source-branch:
574
575=== removed file 'plugins/python3.yaml'
576--- plugins/python3.yaml 2015-09-09 21:35:18 +0000
577+++ plugins/python3.yaml 1970-01-01 00:00:00 +0000
578@@ -1,3 +0,0 @@
579-options:
580- requirements:
581- required: false
582
583=== modified file 'runtests.sh'
584--- runtests.sh 2015-09-17 07:31:24 +0000
585+++ runtests.sh 2015-09-24 04:06:53 +0000
586@@ -20,39 +20,62 @@
587 export PATH=$(pwd)/bin:$PATH
588 export PYTHONPATH=$(pwd):$PYTHONPATH
589
590-SRC_PATHS="bin snapcraft snapcraft/tests"
591-
592-# These three checks could easily be done with flake8 in one shot if
593-# we had python3-flake8 provide flake8
594-# Ignore 501 (line-too-long)
595-pep8 $SRC_PATHS --ignore=E501
596-
597-pyflakes3 $SRC_PATHS
598-
599-# mccabe in 'warning' mode as we have high complexity
600-mccabe_list=
601-for unit in $(find snapcraft -type f -name '*.py')
602-do
603- output=$(python3 -m mccabe --min 10 "$unit")
604- [ -n "$output" ] && mccabe_list="- $unit:\n $output\n$mccabe_list"
605-done
606-
607-if [ -n "$mccabe_list" ]; then
608- echo -e "\e[1;31mThe project has gotten complex\e[0m."
609- echo "Here's the list of units exceeding 10:"
610- echo -e "$mccabe_list"
611-fi
612-
613-if which python3-coverage >/dev/null 2>&1; then
614- python3-coverage erase
615- python3-coverage run --branch --source snapcraft -m unittest
616- mv .coverage .coverage.unit
617-else
618- python3 -m unittest
619-fi
620-
621-if [ -z "$SNAPCRAFT_TESTS_SKIP_PLAINBOX" ]; then
622-(
623+parseargs(){
624+ if [[ "$#" -eq 0 ]] || [[ "$1" == "all" ]]; then
625+ export RUN_UNIT="true"
626+ export RUN_PLAINBOX="true"
627+ export PLAINBOX_TEST_PLANS="normal"
628+ else
629+ if [ "$1" == "unit" ] ; then
630+ export RUN_UNIT="true"
631+ elif [ "$1" == "plainbox" ] ; then
632+ export RUN_PLAINBOX="true"
633+ if [ "$#" -gt 1 ]; then
634+ export PLAINBOX_TEST_PLANS="$2"
635+ else
636+ export PLAINBOX_TEST_PLANS="normal"
637+ fi
638+ else
639+ echo "Not recognized option, should be one of all, unit or plainbox"
640+ exit 1
641+ fi
642+ fi
643+}
644+
645+run_unit_tests(){
646+ SRC_PATHS="bin snapcraft snapcraft/tests"
647+
648+ # These three checks could easily be done with flake8 in one shot if
649+ # we had python3-flake8 provide flake8
650+ # Ignore 501 (line-too-long)
651+ pep8 $SRC_PATHS --ignore=E501
652+
653+ pyflakes3 $SRC_PATHS
654+
655+ # mccabe in 'warning' mode as we have high complexity
656+ mccabe_list=
657+ for unit in $(find snapcraft -type f -name '*.py')
658+ do
659+ output=$(python3 -m mccabe --min 10 "$unit")
660+ [ -n "$output" ] && mccabe_list="- $unit:\n $output\n$mccabe_list"
661+ done
662+
663+ if [ -n "$mccabe_list" ]; then
664+ echo -e "\e[1;31mThe project has gotten complex\e[0m."
665+ echo "Here's the list of units exceeding 10:"
666+ echo -e "$mccabe_list"
667+ fi
668+
669+ if which python3-coverage >/dev/null 2>&1; then
670+ python3-coverage erase
671+ python3-coverage run --branch --source snapcraft -m unittest
672+ mv .coverage .coverage.unit
673+ else
674+ python3 -m unittest
675+ fi
676+}
677+
678+run_plainbox(){
679 # well, well, what can we do
680 if ! which plainbox >/dev/null; then
681 cat <<EOF
682@@ -73,8 +96,17 @@
683
684 # Go to the plainbox provider of snapcraft tests
685 cd integration-tests
686- ./runtests.sh
687-)
688+ ./runtests.sh $PLAINBOX_TEST_PLANS
689+}
690+
691+parseargs "$@"
692+
693+if [ ! -z "$RUN_UNIT" ]; then
694+ run_unit_tests
695+fi
696+
697+if [ -z "$SNAPCRAFT_TESTS_SKIP_PLAINBOX" ] && [ ! -z "$RUN_PLAINBOX" ] ; then
698+ run_plainbox
699 fi
700
701 if which python3-coverage >/dev/null 2>&1; then
702
703=== modified file 'snapcraft/__init__.py'
704--- snapcraft/__init__.py 2015-09-21 14:16:55 +0000
705+++ snapcraft/__init__.py 2015-09-24 04:06:53 +0000
706@@ -69,8 +69,17 @@
707 cwd = self.builddir
708 if True:
709 print(' '.join(cmd))
710+ self.makedirs(cwd)
711 return snapcraft.common.run(cmd, cwd=cwd, **kwargs)
712
713+ def run_output(self, cmd, cwd=None, **kwargs):
714+ if cwd is None:
715+ cwd = self.builddir
716+ if True:
717+ print(' '.join(cmd))
718+ self.makedirs(cwd)
719+ return snapcraft.common.run_output(cmd, cwd=cwd, **kwargs)
720+
721 def isurl(self, url):
722 return snapcraft.common.isurl(url)
723
724@@ -108,6 +117,13 @@
725 ubuntu = snapcraft.repo.Ubuntu(self.ubuntudir, sources=self.PLUGIN_STAGE_SOURCES)
726 ubuntu.get(self.PLUGIN_STAGE_PACKAGES + part_stage_packages)
727 ubuntu.unpack(self.installdir)
728+ self._fixup(self.installdir)
729+
730+ def _fixup(self, root):
731+ if os.path.isfile(os.path.join(root, 'usr', 'bin', 'xml2-config')):
732+ self.run(['sed', '-i', '-e', 's|prefix=/usr|prefix={}/usr|'.format(root), os.path.join(root, 'usr', 'bin', 'xml2-config')])
733+ if os.path.isfile(os.path.join(root, 'usr', 'bin', 'xslt-config')):
734+ self.run(['sed', '-i', '-e', 's|prefix=/usr|prefix={}/usr|'.format(root), os.path.join(root, 'usr', 'bin', 'xslt-config')])
735
736
737 def _get_source_handler(source_type, source):
738
739=== modified file 'snapcraft/cmds.py'
740--- snapcraft/cmds.py 2015-09-21 19:20:43 +0000
741+++ snapcraft/cmds.py 2015-09-24 04:06:53 +0000
742@@ -267,6 +267,8 @@
743 for f in common:
744 this = os.path.join(part.installdir, f)
745 other = os.path.join(parts_files[other_part_name]['installdir'], f)
746+ if os.path.islink(this) and os.path.islink(other):
747+ continue
748 if not filecmp.cmp(this, other, shallow=False):
749 conflict_files.append(f)
750
751
752=== modified file 'snapcraft/common.py'
753--- snapcraft/common.py 2015-09-17 18:02:05 +0000
754+++ snapcraft/common.py 2015-09-24 04:06:53 +0000
755@@ -49,6 +49,17 @@
756 return subprocess.call(['/bin/sh', f.name] + cmd, **kwargs) == 0
757
758
759+def run_output(cmd, **kwargs):
760+ assert isinstance(cmd, list), "run command must be a list"
761+ # FIXME: This is gross to keep writing this, even when env is the same
762+ with tempfile.NamedTemporaryFile(mode='w+') as f:
763+ f.write(assemble_env())
764+ f.write('\n')
765+ f.write('exec $*')
766+ f.flush()
767+ return subprocess.check_output(['/bin/sh', f.name] + cmd, **kwargs).decode('utf8').strip()
768+
769+
770 def fatal():
771 sys.exit(1)
772
773
774=== modified file 'snapcraft/plugin.py'
775--- snapcraft/plugin.py 2015-09-22 03:08:07 +0000
776+++ snapcraft/plugin.py 2015-09-24 04:06:53 +0000
777@@ -39,15 +39,8 @@
778 }
779
780
781-def is_local_plugin(name):
782- return name.startswith("x-")
783-
784-
785-def plugindir(name):
786- if is_local_plugin(name):
787- return os.path.abspath(os.path.join('parts', 'plugins'))
788- else:
789- return common.get_plugindir()
790+def _local_plugindir():
791+ return os.path.abspath(os.path.join('parts', 'plugins'))
792
793
794 class PluginError(Exception):
795@@ -87,10 +80,12 @@
796 return
797
798 def _load_config(self, name):
799- configPath = os.path.join(plugindir(name), name + ".yaml")
800- if not os.path.exists(configPath):
801+ config_path = os.path.join(common.get_plugindir(), name + ".yaml")
802+ if not os.path.exists(config_path):
803+ config_path = os.path.join(_local_plugindir(), name + ".yaml")
804+ if not os.path.exists(config_path):
805 raise PluginError('Unknown plugin: {}'.format(name))
806- with open(configPath, 'r') as fp:
807+ with open(config_path, 'r') as fp:
808 self.config = yaml.load(fp) or {}
809
810 def _make_options(self, name, properties):
811@@ -121,14 +116,15 @@
812 options = self._make_options(name, properties)
813 module_name = name.replace('-', '_')
814
815- # Load code from local plugin dir if it is there
816- if is_local_plugin(name):
817- sys.path = [plugindir(name)] + sys.path
818- else:
819- module_name = 'snapcraft.plugins.' + module_name
820+ try:
821+ module = importlib.import_module('snapcraft.plugins.' + module_name)
822+ except ImportError:
823+ module = None
824
825- module = importlib.import_module(module_name)
826- if is_local_plugin(name):
827+ if not module:
828+ logger.info('Searching for local plugin for %s', name)
829+ sys.path = [_local_plugindir()] + sys.path
830+ module = importlib.import_module(module_name)
831 sys.path.pop(0)
832
833 for prop_name in dir(module):
834
835=== modified file 'snapcraft/plugins/go_project.py'
836--- snapcraft/plugins/go_project.py 2015-07-31 15:16:47 +0000
837+++ snapcraft/plugins/go_project.py 2015-09-24 04:06:53 +0000
838@@ -27,7 +27,9 @@
839 self.fullname = self.options.source.split("://")[1]
840
841 def pull(self):
842- return self.run(['go', 'get', '-t', self.fullname])
843+ # use -d to only download (build will happen later)
844+ # use -t to also get the test-deps
845+ return self.run(['go', 'get', '-t', '-d', self.fullname])
846
847 def build(self):
848 if not self.run(['go', 'build', self.fullname]):
849
850=== removed file 'snapcraft/plugins/python2.py'
851--- snapcraft/plugins/python2.py 2015-09-17 15:14:49 +0000
852+++ snapcraft/plugins/python2.py 1970-01-01 00:00:00 +0000
853@@ -1,59 +0,0 @@
854-# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
855-#
856-# Copyright (C) 2015 Canonical Ltd
857-#
858-# This program is free software: you can redistribute it and/or modify
859-# it under the terms of the GNU General Public License version 3 as
860-# published by the Free Software Foundation.
861-#
862-# This program is distributed in the hope that it will be useful,
863-# but WITHOUT ANY WARRANTY; without even the implied warranty of
864-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
865-# GNU General Public License for more details.
866-#
867-# You should have received a copy of the GNU General Public License
868-# along with this program. If not, see <http://www.gnu.org/licenses/>.
869-
870-import os
871-import snapcraft
872-
873-
874-class Python2Plugin(snapcraft.BasePlugin):
875-
876- _PLUGIN_STAGE_PACKAGES = [
877- 'python-dev',
878- 'python-setuptools',
879- ]
880-
881- def __init__(self, name, options):
882- if options.requirements:
883- self.requirements = options.requirements
884- self._PLUGIN_STAGE_PACKAGES.extend(['python-pkg-resources', 'python-setuptools'])
885- else:
886- self.requirements = None
887- super().__init__(name, options)
888-
889- def snap_fileset(self):
890- return [
891- '-usr/share',
892- ]
893-
894- # note that we don't need to set PYTHONHOME here,
895- # python discovers this automatically from it installed
896- # location. And PATH is automatically set by snapcraft.
897-
898- def env(self, root):
899- return ["PYTHONPATH=%s" % os.path.join(
900- root, 'usr', 'lib', 'python2.7', 'dist-packages')]
901-
902- def pull(self):
903- # A nice idea here would be to be asking setup tools
904- # to use the deb layout, but that doesn't work with
905- # prefix sadly
906-
907- if self.requirements and not (self.run(
908- ['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(
909- ['python2', os.path.join(self.installdir, 'usr', 'bin', 'easy_install'), '--prefix', os.path.join(self.installdir, 'usr'), 'pip']) and self.run(
910- ['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)])):
911- return False
912- return True
913
914=== modified file 'snapcraft/plugins/python2_project.py'
915--- snapcraft/plugins/python2_project.py 2015-09-21 22:22:36 +0000
916+++ snapcraft/plugins/python2_project.py 2015-09-24 04:06:53 +0000
917@@ -22,20 +22,76 @@
918
919 class Python2ProjectPlugin(snapcraft.BasePlugin):
920
921- # note that we don't need to setup env(), python figures it out
922- # see python2.py for more details
923+ _PLUGIN_STAGE_PACKAGES = [
924+ 'python-dev',
925+ 'python-pkg-resources',
926+ 'python-setuptools',
927+ ]
928+
929+ def __init__(self, name, options):
930+ super().__init__(name, options)
931+ self.requirements = options.requirements
932+ self.source = options.source
933+
934+ def env(self, root):
935+ return ["PYTHONPATH=%s" % os.path.join(
936+ root, 'usr', 'lib', self.python_version, 'dist-packages')]
937
938 def pull(self):
939- return self.handle_source_options()
940+ if self.source and not self.handle_source_options():
941+ return False
942+
943+ return self._pip()
944+
945+ def _pip(self):
946+ setup = 'setup.py'
947+ if os.listdir(self.sourcedir):
948+ setup = os.path.join(self.sourcedir, 'setup.py')
949+
950+ if self.requirements:
951+ requirements = os.path.join(os.getcwd(), self.requirements)
952+
953+ if not os.path.exists(setup) and not self.requirements:
954+ return True
955+
956+ easy_install = os.path.join(
957+ self.installdir, 'usr', 'bin', 'easy_install')
958+ prefix = os.path.join(self.installdir, 'usr')
959+ site_packages_dir = os.path.join(
960+ prefix, 'lib', self.python_version, 'site-packages')
961+
962+ if not os.path.exists(site_packages_dir):
963+ os.symlink(
964+ os.path.join(prefix, 'lib', self.python_version, 'dist-packages'),
965+ site_packages_dir)
966+
967+ if not self.run(['python2', easy_install, '--prefix', prefix, 'pip']):
968+ return False
969+
970+ pip2 = os.path.join(self.installdir, 'usr', 'bin', 'pip2')
971+ pip_install = ['python2', pip2, 'install', '--target',
972+ site_packages_dir]
973+
974+ if self.requirements and not self.run(
975+ pip_install + ['--requirement', requirements]):
976+ return False
977+
978+ if os.path.exists(setup) and not self.run(pip_install + ['.', ]):
979+ return False
980+
981+ return True
982
983 def build(self):
984 # If setuptools is used, it tries to create files in the
985 # dist-packages dir and import from there, so it needs to exist
986 # and be in the PYTHONPATH. It's harmless if setuptools isn't
987 # used.
988+
989+ if not os.path.exists(os.path.join(self.builddir, 'setup.py')):
990+ return True
991+
992 os.makedirs(self.dist_packages_dir, exist_ok=True)
993 setuptemp = self.copy_setup()
994-
995 return self.run(
996 ['python2', setuptemp.name, 'install', '--install-layout=deb',
997 '--prefix={}/usr'.format(self.installdir)], cwd=self.builddir)
998@@ -43,7 +99,11 @@
999 @property
1000 def dist_packages_dir(self):
1001 return os.path.join(
1002- self.installdir, 'usr', 'lib', 'python2.7', 'dist-packages')
1003+ self.installdir, 'usr', 'lib', self.python_version, 'dist-packages')
1004+
1005+ @property
1006+ def python_version(self):
1007+ return self.run_output(['pyversions', '-i'])
1008
1009 # Takes the setup.py file and puts a couple little gems on the
1010 # front to make things work better.
1011
1012=== removed file 'snapcraft/plugins/python3.py'
1013--- snapcraft/plugins/python3.py 2015-09-17 15:14:49 +0000
1014+++ snapcraft/plugins/python3.py 1970-01-01 00:00:00 +0000
1015@@ -1,61 +0,0 @@
1016-# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
1017-#
1018-# Copyright (C) 2015 Canonical Ltd
1019-#
1020-# This program is free software: you can redistribute it and/or modify
1021-# it under the terms of the GNU General Public License version 3 as
1022-# published by the Free Software Foundation.
1023-#
1024-# This program is distributed in the hope that it will be useful,
1025-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1026-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1027-# GNU General Public License for more details.
1028-#
1029-# You should have received a copy of the GNU General Public License
1030-# along with this program. If not, see <http://www.gnu.org/licenses/>.
1031-
1032-import os
1033-import snapcraft
1034-
1035-
1036-class Python3Plugin(snapcraft.BasePlugin):
1037-
1038- _PLUGIN_STAGE_PACKAGES = [
1039- 'python3-dev',
1040- 'python3-setuptools',
1041- ]
1042-
1043- def __init__(self, name, options):
1044- if options.requirements:
1045- self.requirements = options.requirements
1046- self._PLUGIN_STAGE_PACKAGES.extend(['python3-pkg-resources', 'python3-setuptools'])
1047- else:
1048- self.requirements = None
1049- super().__init__(name, options)
1050-
1051- def snap_fileset(self):
1052- return [
1053- '-usr/share',
1054- ]
1055-
1056- # note that we don't need to set PYTHONHOME here,
1057- # python discovers this automatically from it installed
1058- # location, see https://code.launchpad.net/~mvo/snapcraft/python3-project/+merge/264521/comments/664308
1059- #
1060- # PATH is automatically set by snapcraft
1061-
1062- def env(self, root):
1063- return ["PYTHONPATH=%s" % os.path.join(
1064- root, 'usr', 'lib', 'python3', 'dist-packages')]
1065-
1066- def pull(self):
1067- # A nice idea here would be to be asking setup tools
1068- # to use the deb layout, but that doesn't work with
1069- # prefix sadly
1070-
1071- if self.requirements and not (self.run(
1072- ['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(
1073- ['python3', os.path.join(self.installdir, 'usr', 'bin', 'easy_install3'), '--prefix', os.path.join(self.installdir, 'usr'), 'pip']) and self.run(
1074- ['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)])):
1075- return False
1076- return True
1077
1078=== modified file 'snapcraft/plugins/python3_project.py'
1079--- snapcraft/plugins/python3_project.py 2015-09-21 22:22:36 +0000
1080+++ snapcraft/plugins/python3_project.py 2015-09-24 04:06:53 +0000
1081@@ -22,21 +22,74 @@
1082
1083 class Python3ProjectPlugin(snapcraft.BasePlugin):
1084
1085- # note that we don't need to setup env(), python figures it out
1086- # see python3.py for more details
1087+ _PLUGIN_STAGE_PACKAGES = [
1088+ 'python3-dev',
1089+ 'python3-pkg-resources',
1090+ 'python3-setuptools',
1091+ ]
1092+
1093+ def __init__(self, name, options):
1094+ super().__init__(name, options)
1095+ self.requirements = options.requirements
1096+ self.source = options.source
1097
1098 def env(self, root):
1099 return ["PYTHONPATH=%s" % os.path.join(
1100- root, 'usr', 'lib', 'python3', 'dist-packages')]
1101+ root, 'usr', 'lib', self.python_version, 'dist-packages')]
1102
1103 def pull(self):
1104- return self.handle_source_options()
1105+ if self.source and not self.handle_source_options():
1106+ return False
1107+
1108+ return self._pip()
1109+
1110+ def _pip(self):
1111+ setup = 'setup.py'
1112+ if os.listdir(self.sourcedir):
1113+ setup = os.path.join(self.sourcedir, 'setup.py')
1114+
1115+ if self.requirements:
1116+ requirements = os.path.join(os.getcwd(), self.requirements)
1117+
1118+ if not os.path.exists(setup) and not self.requirements:
1119+ return True
1120+
1121+ easy_install = os.path.join(
1122+ self.installdir, 'usr', 'bin', 'easy_install3')
1123+ prefix = os.path.join(self.installdir, 'usr')
1124+ site_packages_dir = os.path.join(
1125+ prefix, 'lib', self.python_version, 'site-packages')
1126+
1127+ if not os.path.exists(site_packages_dir):
1128+ os.symlink(
1129+ os.path.join(prefix, 'lib', 'python3', 'dist-packages'),
1130+ site_packages_dir)
1131+
1132+ if not self.run(['python3', easy_install, '--prefix', prefix, 'pip']):
1133+ return False
1134+
1135+ pip3 = os.path.join(self.installdir, 'usr', 'bin', 'pip3')
1136+ pip_install = ['python3', pip3, 'install', '--target',
1137+ site_packages_dir]
1138+
1139+ if self.requirements and not self.run(
1140+ pip_install + ['--requirement', requirements]):
1141+ return False
1142+
1143+ if os.path.exists(setup) and not self.run(pip_install + ['.', ]):
1144+ return False
1145+
1146+ return True
1147
1148 def build(self):
1149 # If setuptools is used, it tries to create files in the
1150 # dist-packages dir and import from there, so it needs to exist
1151 # and be in the PYTHONPATH. It's harmless if setuptools isn't
1152 # used.
1153+
1154+ if not os.path.exists(os.path.join(self.builddir, 'setup.py')):
1155+ return True
1156+
1157 os.makedirs(self.dist_packages_dir, exist_ok=True)
1158 setuptemp = self.copy_setup()
1159 return self.run(
1160@@ -46,7 +99,11 @@
1161 @property
1162 def dist_packages_dir(self):
1163 return os.path.join(
1164- self.installdir, 'usr', 'lib', 'python3', 'dist-packages')
1165+ self.installdir, 'usr', 'lib', self.python_version, 'dist-packages')
1166+
1167+ @property
1168+ def python_version(self):
1169+ return self.run_output(['py3versions', '-i'])
1170
1171 # Takes the setup.py file and puts a couple little gems on the
1172 # front to make things work better.
1173
1174=== modified file 'snapcraft/repo.py'
1175--- snapcraft/repo.py 2015-09-21 15:21:15 +0000
1176+++ snapcraft/repo.py 2015-09-24 04:06:53 +0000
1177@@ -14,6 +14,7 @@
1178 # You should have received a copy of the GNU General Public License
1179 # along with this program. If not, see <http://www.gnu.org/licenses/>.
1180
1181+import apt
1182 import glob
1183 import itertools
1184 import os
1185@@ -22,18 +23,19 @@
1186 import urllib
1187 import urllib.request
1188
1189-import apt
1190 from xml.etree import ElementTree
1191
1192-_DEFAULT_SOURCES = '''deb http://${mirror}archive.ubuntu.com/ubuntu/ vivid main restricted
1193-deb http://${mirror}archive.ubuntu.com/ubuntu/ vivid-updates main restricted
1194-deb http://${mirror}archive.ubuntu.com/ubuntu/ vivid universe
1195-deb http://${mirror}archive.ubuntu.com/ubuntu/ vivid-updates universe
1196-deb http://${mirror}archive.ubuntu.com/ubuntu/ vivid multiverse
1197-deb http://${mirror}archive.ubuntu.com/ubuntu/ vivid-updates multiverse
1198-deb http://security.ubuntu.com/ubuntu vivid-security main restricted
1199-deb http://security.ubuntu.com/ubuntu vivid-security universe
1200-deb http://security.ubuntu.com/ubuntu vivid-security multiverse
1201+import snapcraft.common
1202+
1203+_DEFAULT_SOURCES = '''deb http://${prefix}.ubuntu.com/${suffix}/ ${release} main restricted
1204+deb http://${prefix}.ubuntu.com/${suffix}/ ${release}-updates main restricted
1205+deb http://${prefix}.ubuntu.com/${suffix}/ ${release} universe
1206+deb http://${prefix}.ubuntu.com/${suffix}/ ${release}-updates universe
1207+deb http://${prefix}.ubuntu.com/${suffix}/ ${release} multiverse
1208+deb http://${prefix}.ubuntu.com/${suffix}/ ${release}-updates multiverse
1209+deb http://${security}.ubuntu.com/${suffix} ${release}-security main restricted
1210+deb http://${security}.ubuntu.com/${suffix} ${release}-security universe
1211+deb http://${security}.ubuntu.com/${suffix} ${release}-security multiverse
1212 '''
1213 _GEOIP_SERVER = "http://geoip.ubuntu.com/lookup"
1214
1215@@ -61,11 +63,16 @@
1216 class Ubuntu:
1217
1218 def __init__(self, rootdir, recommends=False, sources=_DEFAULT_SOURCES):
1219- sources = sources or _DEFAULT_SOURCES
1220 self.downloaddir = os.path.join(rootdir, 'download')
1221 self.rootdir = rootdir
1222- self.apt_cache = _setup_apt_cache(rootdir, sources)
1223 self.recommends = recommends
1224+ sources = sources or _DEFAULT_SOURCES
1225+ local = False
1226+ if 'SNAPCRAFT_LOCAL_SOURCES' in os.environ:
1227+ print('using local sources')
1228+ sources = _get_local_sources_list()
1229+ local = True
1230+ self.apt_cache = _setup_apt_cache(rootdir, sources, local)
1231
1232 def get(self, package_names):
1233 os.makedirs(self.downloaddir, exist_ok=True)
1234@@ -78,18 +85,35 @@
1235 except KeyError:
1236 raise PackageNotFoundError(name)
1237
1238+ skipped_essential = []
1239+ skipped_blacklisted = []
1240+
1241+ # unmark some base packages here
1242+ # note that this will break the consistency check inside apt_cache
1243+ # (self.apt_cache.broken_count will be > 0)
1244+ # but that is ok as it was consistent before we excluded
1245+ # these base package
1246 for pkg in self.apt_cache:
1247 # those should be already on each system, it also prevents
1248 # diving into downloading libc6
1249 if (pkg.candidate.priority in 'essential' and
1250 pkg.name not in package_names):
1251- print('Skipping priority essential/imporant %s' % pkg.name)
1252+ skipped_essential.append(pkg.name)
1253+ pkg.mark_keep()
1254 continue
1255 if (pkg.name in manifest_dep_names and pkg.name not in package_names):
1256- print('Skipping blacklisted from manifest package %s' % pkg.name)
1257+ skipped_blacklisted.append(pkg.name)
1258+ pkg.mark_keep()
1259 continue
1260- if pkg.marked_install:
1261- pkg.candidate.fetch_binary(destdir=self.downloaddir)
1262+
1263+ if skipped_essential:
1264+ print('Skipping priority essential packages:', skipped_essential)
1265+ if skipped_blacklisted:
1266+ print('Skipping blacklisted from manifest packages:', skipped_blacklisted)
1267+
1268+ # download the remaining ones with proper progress
1269+ apt.apt_pkg.config.set("Dir::Cache::Archives", self.downloaddir)
1270+ self.apt_cache.fetch_archives()
1271
1272 def unpack(self, rootdir):
1273 pkgs_abs_path = glob.glob(os.path.join(self.downloaddir, '*.deb'))
1274@@ -114,7 +138,19 @@
1275 return manifest_dep_names
1276
1277
1278-def get_geoip_country_code_prefix():
1279+def _get_local_sources_list():
1280+ sources_list = glob.glob('/etc/apt/sources.list.d/*.list')
1281+ sources_list.append('/etc/apt/sources.list')
1282+
1283+ sources = ''
1284+ for source in sources_list:
1285+ with open(source) as f:
1286+ sources += f.read()
1287+
1288+ return sources
1289+
1290+
1291+def _get_geoip_country_code_prefix():
1292 try:
1293 with urllib.request.urlopen(_GEOIP_SERVER) as f:
1294 xml_data = f.read()
1295@@ -122,20 +158,41 @@
1296 cc = et.find("CountryCode")
1297 if cc is None:
1298 return ""
1299- return cc.text.lower() + "."
1300+ return cc.text.lower()
1301 except (ElementTree.ParseError, urllib.error.URLError):
1302 pass
1303- return ""
1304-
1305-
1306-def _setup_apt_cache(rootdir, sources):
1307+ return ''
1308+
1309+
1310+def _format_sources_list(sources, arch, release='vivid'):
1311+ if arch in ('amd64', 'i386'):
1312+ geoip_prefix = _get_geoip_country_code_prefix()
1313+ prefix = geoip_prefix + '.archive' if geoip_prefix else 'archive'
1314+ suffix = 'ubuntu'
1315+ security = 'security'
1316+ else:
1317+ prefix = 'ports'
1318+ suffix = 'ubuntu-ports'
1319+ security = 'ports'
1320+
1321+ return string.Template(sources).substitute({
1322+ 'prefix': prefix,
1323+ 'release': release,
1324+ 'suffix': suffix,
1325+ 'security': security,
1326+ })
1327+
1328+
1329+def _setup_apt_cache(rootdir, sources, local=False):
1330 os.makedirs(os.path.join(rootdir, 'etc', 'apt'), exist_ok=True)
1331 srcfile = os.path.join(rootdir, 'etc', 'apt', 'sources.list')
1332+
1333+ if not local:
1334+ sources = _format_sources_list(sources, snapcraft.common.get_arch())
1335+
1336 with open(srcfile, 'w') as f:
1337- mirror_prefix = get_geoip_country_code_prefix()
1338- sources_list = string.Template(sources).substitute(
1339- {"mirror": mirror_prefix})
1340- f.write(sources_list)
1341+ f.write(sources)
1342+
1343 progress = apt.progress.text.AcquireProgress()
1344 apt_cache = apt.Cache(rootdir=rootdir, memonly=True)
1345 apt_cache.update(fetch_progress=progress, sources_list=srcfile)
1346
1347=== modified file 'snapcraft/tests/test_plugin.py'
1348--- snapcraft/tests/test_plugin.py 2015-09-22 03:08:07 +0000
1349+++ snapcraft/tests/test_plugin.py 2015-09-24 04:06:53 +0000
1350@@ -16,7 +16,6 @@
1351
1352 import logging
1353 import os
1354-import sys
1355 import tempfile
1356
1357 import fixtures
1358@@ -210,19 +209,6 @@
1359
1360 self.assertEqual('test stage mock-part\n', fake_logger.output)
1361
1362- def test_local_plugins(self):
1363- """Ensure local plugins are loaded from parts/plugins"""
1364- def mock_import_modules(module_name):
1365- # called with the name only and sys.path set
1366- self.assertEqual(module_name, "x_mock")
1367- self.assertTrue(sys.path[0].endswith("parts/plugins"))
1368- return mock_plugin
1369- with patch("importlib.import_module", side_effect=mock_import_modules):
1370- plugin.PluginHandler(
1371- "x-mock", "mock-part", {}, load_config=False, load_code=True)
1372- # sys.path is cleaned afterwards
1373- self.assertFalse(sys.path[0].endswith("parts/plugins"))
1374-
1375 def test_non_local_plugins(self):
1376 """Ensure regular plugins are loaded from snapcraft only"""
1377 def mock_import_modules(module_name):
1378
1379=== modified file 'snapcraft/tests/test_repo.py'
1380--- snapcraft/tests/test_repo.py 2015-09-21 15:14:29 +0000
1381+++ snapcraft/tests/test_repo.py 2015-09-24 04:06:53 +0000
1382@@ -16,6 +16,7 @@
1383
1384 import os
1385 import tempfile
1386+import unittest.mock
1387
1388 from snapcraft import repo
1389 from snapcraft import tests
1390@@ -23,6 +24,43 @@
1391
1392 class UbuntuTestCase(tests.TestCase):
1393
1394+ @unittest.mock.patch('snapcraft.repo._get_geoip_country_code_prefix')
1395+ def test_sources_amd64_vivid(self, mock_cc):
1396+ mock_cc.return_value = 'ar'
1397+
1398+ sources_list = repo._format_sources_list(
1399+ repo._DEFAULT_SOURCES, 'amd64', 'vivid')
1400+
1401+ expected_sources_list = '''deb http://ar.archive.ubuntu.com/ubuntu/ vivid main restricted
1402+deb http://ar.archive.ubuntu.com/ubuntu/ vivid-updates main restricted
1403+deb http://ar.archive.ubuntu.com/ubuntu/ vivid universe
1404+deb http://ar.archive.ubuntu.com/ubuntu/ vivid-updates universe
1405+deb http://ar.archive.ubuntu.com/ubuntu/ vivid multiverse
1406+deb http://ar.archive.ubuntu.com/ubuntu/ vivid-updates multiverse
1407+deb http://security.ubuntu.com/ubuntu vivid-security main restricted
1408+deb http://security.ubuntu.com/ubuntu vivid-security universe
1409+deb http://security.ubuntu.com/ubuntu vivid-security multiverse
1410+'''
1411+ self.assertEqual(sources_list, expected_sources_list)
1412+
1413+ @unittest.mock.patch('snapcraft.repo._get_geoip_country_code_prefix')
1414+ def test_sources_armhf_trusty(self, mock_cc):
1415+ sources_list = repo._format_sources_list(
1416+ repo._DEFAULT_SOURCES, 'armhf', 'trusty')
1417+
1418+ expected_sources_list = '''deb http://ports.ubuntu.com/ubuntu-ports/ trusty main restricted
1419+deb http://ports.ubuntu.com/ubuntu-ports/ trusty-updates main restricted
1420+deb http://ports.ubuntu.com/ubuntu-ports/ trusty universe
1421+deb http://ports.ubuntu.com/ubuntu-ports/ trusty-updates universe
1422+deb http://ports.ubuntu.com/ubuntu-ports/ trusty multiverse
1423+deb http://ports.ubuntu.com/ubuntu-ports/ trusty-updates multiverse
1424+deb http://ports.ubuntu.com/ubuntu-ports trusty-security main restricted
1425+deb http://ports.ubuntu.com/ubuntu-ports trusty-security universe
1426+deb http://ports.ubuntu.com/ubuntu-ports trusty-security multiverse
1427+'''
1428+ self.assertEqual(sources_list, expected_sources_list)
1429+ self.assertFalse(mock_cc.called)
1430+
1431 def test_fix_symlinks(self):
1432 tempdirObj = tempfile.TemporaryDirectory()
1433 self.addCleanup(tempdirObj.cleanup)
1434
1435=== modified file 'snapcraft/yaml.py'
1436--- snapcraft/yaml.py 2015-09-18 18:04:48 +0000
1437+++ snapcraft/yaml.py 2015-09-24 04:06:53 +0000
1438@@ -166,14 +166,46 @@
1439
1440 def runtime_env(self, root):
1441 env = []
1442- env.append('PATH="{0}/bin:{0}/usr/bin:$PATH"'.format(root))
1443- env.append('LD_LIBRARY_PATH="{0}/lib:{0}/usr/lib:{0}/lib/{1}:{0}/usr/lib/{1}:$LD_LIBRARY_PATH"'.format(root, snapcraft.common.get_arch_triplet()))
1444+ env.append('PATH="' + ':'.join([
1445+ '{0}/bin',
1446+ '{0}/usr/bin',
1447+ '$PATH'
1448+ ]).format(root) + '"')
1449+ env.append('LD_LIBRARY_PATH="' + ':'.join([
1450+ '{0}/lib',
1451+ '{0}/usr/lib',
1452+ '{0}/lib/{1}',
1453+ '{0}/usr/lib/{1}',
1454+ '$LD_LIBRARY_PATH'
1455+ ]).format(root, snapcraft.common.get_arch_triplet()) + '"')
1456 return env
1457
1458 def build_env(self, root):
1459 env = []
1460- env.append('CFLAGS="-I{0}/include -I{0}/usr/include -I{0}/include/{1} -I{0}/usr/include/{1} $CFLAGS"'.format(root, snapcraft.common.get_arch_triplet()))
1461- env.append('LDFLAGS="-L{0}/lib -L{0}/usr/lib -L{0}/lib/{1} -L{0}/usr/lib/{1} $LDFLAGS"'.format(root, snapcraft.common.get_arch_triplet()))
1462+ env.append('CFLAGS="' + ' '.join([
1463+ '-I{0}/include',
1464+ '-I{0}/usr/include',
1465+ '-I{0}/include/{1}',
1466+ '-I{0}/usr/include/{1}',
1467+ '$CFLAGS'
1468+ ]).format(root, snapcraft.common.get_arch_triplet()) + '"')
1469+ env.append('LDFLAGS="' + ' '.join([
1470+ '-L{0}/lib',
1471+ '-L{0}/usr/lib',
1472+ '-L{0}/lib/{1}',
1473+ '-L{0}/usr/lib/{1}',
1474+ '$LDFLAGS'
1475+ ]).format(root, snapcraft.common.get_arch_triplet()) + '"')
1476+ env.append('PKG_CONFIG_SYSROOT_DIR={0}'.format(root))
1477+ env.append('PKG_CONFIG_PATH=' + ':'.join([
1478+ '{0}/usr/lib/pkgconfig',
1479+ '{0}/usr/lib/{1}/pkgconfig',
1480+ '{0}/usr/share/pkgconfig',
1481+ '{0}/usr/local/lib/pkgconfig',
1482+ '{0}/usr/local/lib/{1}/pkgconfig',
1483+ '{0}/usr/local/share/pkgconfig',
1484+ '$PKG_CONFIG_PATH'
1485+ ]).format(root, snapcraft.common.get_arch_triplet()))
1486 return env
1487
1488 def build_env_for_part(self, part):

Subscribers

People subscribed via source and target branches