|
1 ############################################################################## |
|
2 # |
|
3 # Copyright (c) 2004-2009 Zope Corporation and Contributors. |
|
4 # All Rights Reserved. |
|
5 # |
|
6 # This software is subject to the provisions of the Zope Public License, |
|
7 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution. |
|
8 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
9 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
10 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
11 # FOR A PARTICULAR PURPOSE. |
|
12 # |
|
13 ############################################################################## |
|
14 import doctest |
|
15 from zope.testing import renormalizing |
|
16 import os |
|
17 import pkg_resources |
|
18 import re |
|
19 import shutil |
|
20 import sys |
|
21 import tempfile |
|
22 import unittest |
|
23 import zc.buildout.easy_install |
|
24 import zc.buildout.testing |
|
25 import zc.buildout.testselectingpython |
|
26 import zipfile |
|
27 |
|
28 os_path_sep = os.path.sep |
|
29 if os_path_sep == '\\': |
|
30 os_path_sep *= 2 |
|
31 |
|
32 |
|
33 def develop_w_non_setuptools_setup_scripts(): |
|
34 """ |
|
35 We should be able to deal with setup scripts that aren't setuptools based. |
|
36 |
|
37 >>> mkdir('foo') |
|
38 >>> write('foo', 'setup.py', |
|
39 ... ''' |
|
40 ... from distutils.core import setup |
|
41 ... setup(name="foo") |
|
42 ... ''') |
|
43 |
|
44 >>> write('buildout.cfg', |
|
45 ... ''' |
|
46 ... [buildout] |
|
47 ... develop = foo |
|
48 ... parts = |
|
49 ... ''') |
|
50 |
|
51 >>> print system(join('bin', 'buildout')), |
|
52 Develop: '/sample-buildout/foo' |
|
53 |
|
54 >>> ls('develop-eggs') |
|
55 - foo.egg-link |
|
56 - z3c.recipe.scripts.egg-link |
|
57 - zc.recipe.egg.egg-link |
|
58 |
|
59 """ |
|
60 |
|
61 def develop_verbose(): |
|
62 """ |
|
63 We should be able to deal with setup scripts that aren't setuptools based. |
|
64 |
|
65 >>> mkdir('foo') |
|
66 >>> write('foo', 'setup.py', |
|
67 ... ''' |
|
68 ... from setuptools import setup |
|
69 ... setup(name="foo") |
|
70 ... ''') |
|
71 |
|
72 >>> write('buildout.cfg', |
|
73 ... ''' |
|
74 ... [buildout] |
|
75 ... develop = foo |
|
76 ... parts = |
|
77 ... ''') |
|
78 |
|
79 >>> print system(join('bin', 'buildout')+' -vv'), # doctest: +ELLIPSIS |
|
80 Installing... |
|
81 Develop: '/sample-buildout/foo' |
|
82 ... |
|
83 Installed /sample-buildout/foo |
|
84 ... |
|
85 |
|
86 >>> ls('develop-eggs') |
|
87 - foo.egg-link |
|
88 - z3c.recipe.scripts.egg-link |
|
89 - zc.recipe.egg.egg-link |
|
90 |
|
91 >>> print system(join('bin', 'buildout')+' -vvv'), # doctest: +ELLIPSIS |
|
92 Installing... |
|
93 Develop: '/sample-buildout/foo' |
|
94 in: '/sample-buildout/foo' |
|
95 ... -q develop -mxN -d /sample-buildout/develop-eggs/... |
|
96 |
|
97 |
|
98 """ |
|
99 |
|
100 def buildout_error_handling(): |
|
101 r"""Buildout error handling |
|
102 |
|
103 Asking for a section that doesn't exist, yields a missing section error: |
|
104 |
|
105 >>> import os |
|
106 >>> os.chdir(sample_buildout) |
|
107 >>> import zc.buildout.buildout |
|
108 >>> buildout = zc.buildout.buildout.Buildout('buildout.cfg', []) |
|
109 >>> buildout['eek'] |
|
110 Traceback (most recent call last): |
|
111 ... |
|
112 MissingSection: The referenced section, 'eek', was not defined. |
|
113 |
|
114 Asking for an option that doesn't exist, a MissingOption error is raised: |
|
115 |
|
116 >>> buildout['buildout']['eek'] |
|
117 Traceback (most recent call last): |
|
118 ... |
|
119 MissingOption: Missing option: buildout:eek |
|
120 |
|
121 It is an error to create a variable-reference cycle: |
|
122 |
|
123 >>> write(sample_buildout, 'buildout.cfg', |
|
124 ... ''' |
|
125 ... [buildout] |
|
126 ... parts = |
|
127 ... x = ${buildout:y} |
|
128 ... y = ${buildout:z} |
|
129 ... z = ${buildout:x} |
|
130 ... ''') |
|
131 |
|
132 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')), |
|
133 ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS |
|
134 While: |
|
135 Initializing. |
|
136 Getting section buildout. |
|
137 Initializing section buildout. |
|
138 Getting option buildout:y. |
|
139 Getting option buildout:z. |
|
140 Getting option buildout:x. |
|
141 Getting option buildout:y. |
|
142 Error: Circular reference in substitutions. |
|
143 |
|
144 It is an error to use funny characters in variable refereces: |
|
145 |
|
146 >>> write(sample_buildout, 'buildout.cfg', |
|
147 ... ''' |
|
148 ... [buildout] |
|
149 ... develop = recipes |
|
150 ... parts = data_dir debug |
|
151 ... x = ${bui$ldout:y} |
|
152 ... ''') |
|
153 |
|
154 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')), |
|
155 While: |
|
156 Initializing. |
|
157 Getting section buildout. |
|
158 Initializing section buildout. |
|
159 Getting option buildout:x. |
|
160 Error: The section name in substitution, ${bui$ldout:y}, |
|
161 has invalid characters. |
|
162 |
|
163 >>> write(sample_buildout, 'buildout.cfg', |
|
164 ... ''' |
|
165 ... [buildout] |
|
166 ... develop = recipes |
|
167 ... parts = data_dir debug |
|
168 ... x = ${buildout:y{z} |
|
169 ... ''') |
|
170 |
|
171 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')), |
|
172 While: |
|
173 Initializing. |
|
174 Getting section buildout. |
|
175 Initializing section buildout. |
|
176 Getting option buildout:x. |
|
177 Error: The option name in substitution, ${buildout:y{z}, |
|
178 has invalid characters. |
|
179 |
|
180 and too have too many or too few colons: |
|
181 |
|
182 >>> write(sample_buildout, 'buildout.cfg', |
|
183 ... ''' |
|
184 ... [buildout] |
|
185 ... develop = recipes |
|
186 ... parts = data_dir debug |
|
187 ... x = ${parts} |
|
188 ... ''') |
|
189 |
|
190 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')), |
|
191 While: |
|
192 Initializing. |
|
193 Getting section buildout. |
|
194 Initializing section buildout. |
|
195 Getting option buildout:x. |
|
196 Error: The substitution, ${parts}, |
|
197 doesn't contain a colon. |
|
198 |
|
199 >>> write(sample_buildout, 'buildout.cfg', |
|
200 ... ''' |
|
201 ... [buildout] |
|
202 ... develop = recipes |
|
203 ... parts = data_dir debug |
|
204 ... x = ${buildout:y:z} |
|
205 ... ''') |
|
206 |
|
207 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')), |
|
208 While: |
|
209 Initializing. |
|
210 Getting section buildout. |
|
211 Initializing section buildout. |
|
212 Getting option buildout:x. |
|
213 Error: The substitution, ${buildout:y:z}, |
|
214 has too many colons. |
|
215 |
|
216 Al parts have to have a section: |
|
217 |
|
218 >>> write(sample_buildout, 'buildout.cfg', |
|
219 ... ''' |
|
220 ... [buildout] |
|
221 ... parts = x |
|
222 ... ''') |
|
223 |
|
224 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')), |
|
225 While: |
|
226 Installing. |
|
227 Getting section x. |
|
228 Error: The referenced section, 'x', was not defined. |
|
229 |
|
230 and all parts have to have a specified recipe: |
|
231 |
|
232 |
|
233 >>> write(sample_buildout, 'buildout.cfg', |
|
234 ... ''' |
|
235 ... [buildout] |
|
236 ... parts = x |
|
237 ... |
|
238 ... [x] |
|
239 ... foo = 1 |
|
240 ... ''') |
|
241 |
|
242 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')), |
|
243 While: |
|
244 Installing. |
|
245 Error: Missing option: x:recipe |
|
246 |
|
247 """ |
|
248 |
|
249 make_dist_that_requires_setup_py_template = """ |
|
250 from setuptools import setup |
|
251 setup(name=%r, version=%r, |
|
252 install_requires=%r, |
|
253 ) |
|
254 """ |
|
255 |
|
256 def make_dist_that_requires(dest, name, requires=[], version=1, egg=''): |
|
257 os.mkdir(os.path.join(dest, name)) |
|
258 open(os.path.join(dest, name, 'setup.py'), 'w').write( |
|
259 make_dist_that_requires_setup_py_template |
|
260 % (name, version, requires) |
|
261 ) |
|
262 |
|
263 def show_who_requires_when_there_is_a_conflict(): |
|
264 """ |
|
265 It's a pain when we require eggs that have requirements that are |
|
266 incompatible. We want the error we get to tell us what is missing. |
|
267 |
|
268 Let's make a few develop distros, some of which have incompatible |
|
269 requirements. |
|
270 |
|
271 >>> make_dist_that_requires(sample_buildout, 'sampley', |
|
272 ... ['demoneeded ==1.0']) |
|
273 >>> make_dist_that_requires(sample_buildout, 'samplez', |
|
274 ... ['demoneeded ==1.1']) |
|
275 |
|
276 Now, let's create a buildout that requires y and z: |
|
277 |
|
278 >>> write('buildout.cfg', |
|
279 ... ''' |
|
280 ... [buildout] |
|
281 ... parts = eggs |
|
282 ... develop = sampley samplez |
|
283 ... find-links = %(link_server)s |
|
284 ... |
|
285 ... [eggs] |
|
286 ... recipe = zc.recipe.egg |
|
287 ... eggs = sampley |
|
288 ... samplez |
|
289 ... ''' % globals()) |
|
290 |
|
291 >>> print system(buildout), |
|
292 Develop: '/sample-buildout/sampley' |
|
293 Develop: '/sample-buildout/samplez' |
|
294 Installing eggs. |
|
295 Getting distribution for 'demoneeded==1.1'. |
|
296 Got demoneeded 1.1. |
|
297 While: |
|
298 Installing eggs. |
|
299 Error: There is a version conflict. |
|
300 We already have: demoneeded 1.1 |
|
301 but sampley 1 requires 'demoneeded==1.0'. |
|
302 |
|
303 Here, we see that sampley required an older version of demoneeded. What |
|
304 if we hadn't required sampley ourselves: |
|
305 |
|
306 >>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb']) |
|
307 >>> make_dist_that_requires(sample_buildout, 'sampleb', |
|
308 ... ['sampley', 'samplea']) |
|
309 >>> write('buildout.cfg', |
|
310 ... ''' |
|
311 ... [buildout] |
|
312 ... parts = eggs |
|
313 ... develop = sampley samplez samplea sampleb |
|
314 ... find-links = %(link_server)s |
|
315 ... |
|
316 ... [eggs] |
|
317 ... recipe = zc.recipe.egg |
|
318 ... eggs = samplea |
|
319 ... samplez |
|
320 ... ''' % globals()) |
|
321 |
|
322 If we use the verbose switch, we can see where requirements are coming from: |
|
323 |
|
324 >>> print system(buildout+' -v'), # doctest: +ELLIPSIS |
|
325 Installing 'zc.buildout', 'setuptools'. |
|
326 We have a develop egg: zc.buildout 1.0.0 |
|
327 We have the best distribution that satisfies 'setuptools'. |
|
328 Picked: setuptools = 0.6 |
|
329 Develop: '/sample-buildout/sampley' |
|
330 Develop: '/sample-buildout/samplez' |
|
331 Develop: '/sample-buildout/samplea' |
|
332 Develop: '/sample-buildout/sampleb' |
|
333 ...Installing eggs. |
|
334 Installing 'samplea', 'samplez'. |
|
335 We have a develop egg: samplea 1 |
|
336 We have a develop egg: samplez 1 |
|
337 Getting required 'demoneeded==1.1' |
|
338 required by samplez 1. |
|
339 We have the distribution that satisfies 'demoneeded==1.1'. |
|
340 Getting required 'sampleb' |
|
341 required by samplea 1. |
|
342 We have a develop egg: sampleb 1 |
|
343 Getting required 'sampley' |
|
344 required by sampleb 1. |
|
345 We have a develop egg: sampley 1 |
|
346 While: |
|
347 Installing eggs. |
|
348 Error: There is a version conflict. |
|
349 We already have: demoneeded 1.1 |
|
350 but sampley 1 requires 'demoneeded==1.0'. |
|
351 """ |
|
352 |
|
353 def show_who_requires_missing_distributions(): |
|
354 """ |
|
355 |
|
356 When working with a lot of eggs, which require eggs recursively, it can |
|
357 be hard to tell why we're requiring things we can't find. Fortunately, |
|
358 buildout will tell us who's asking for something that we can't find. |
|
359 |
|
360 >>> make_dist_that_requires(sample_buildout, 'sampley', ['demoneeded']) |
|
361 >>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb']) |
|
362 >>> make_dist_that_requires(sample_buildout, 'sampleb', |
|
363 ... ['sampley', 'samplea']) |
|
364 >>> write('buildout.cfg', |
|
365 ... ''' |
|
366 ... [buildout] |
|
367 ... parts = eggs |
|
368 ... develop = sampley samplea sampleb |
|
369 ... |
|
370 ... [eggs] |
|
371 ... recipe = zc.recipe.egg |
|
372 ... eggs = samplea |
|
373 ... ''') |
|
374 |
|
375 >>> print system(buildout), |
|
376 Develop: '/sample-buildout/sampley' |
|
377 Develop: '/sample-buildout/samplea' |
|
378 Develop: '/sample-buildout/sampleb' |
|
379 Installing eggs. |
|
380 Couldn't find index page for 'demoneeded' (maybe misspelled?) |
|
381 Getting distribution for 'demoneeded'. |
|
382 While: |
|
383 Installing eggs. |
|
384 Getting distribution for 'demoneeded'. |
|
385 Error: Couldn't find a distribution for 'demoneeded'. |
|
386 """ |
|
387 |
|
388 def show_eggs_from_site_packages(): |
|
389 """ |
|
390 Sometimes you want to know what eggs are coming from site-packages. This |
|
391 might be for a diagnostic, or so that you can get a starting value for the |
|
392 allowed-eggs-from-site-packages option. The -v flag will also include this |
|
393 information. |
|
394 |
|
395 Our "py_path" has the "demoneeded," "demo" |
|
396 packages available. We'll ask for "bigdemo," which will get both of them. |
|
397 |
|
398 Here's our set up. |
|
399 |
|
400 >>> py_path, site_packages_path = make_py() |
|
401 >>> create_sample_sys_install(site_packages_path) |
|
402 |
|
403 >>> write('buildout.cfg', |
|
404 ... ''' |
|
405 ... [buildout] |
|
406 ... parts = eggs |
|
407 ... prefer-final = true |
|
408 ... find-links = %(link_server)s |
|
409 ... |
|
410 ... [primed_python] |
|
411 ... executable = %(py_path)s |
|
412 ... |
|
413 ... [eggs] |
|
414 ... recipe = zc.recipe.egg:eggs |
|
415 ... python = primed_python |
|
416 ... eggs = bigdemo |
|
417 ... ''' % globals()) |
|
418 |
|
419 Now here is the output. The lines that begin with "Egg from site-packages:" |
|
420 indicate the eggs from site-packages that have been selected. You'll see |
|
421 we have two: demo 0.3 and demoneeded 1.1. |
|
422 |
|
423 >>> print system(buildout+" -v"), |
|
424 Installing 'zc.buildout', 'setuptools'. |
|
425 We have a develop egg: zc.buildout V |
|
426 We have the best distribution that satisfies 'setuptools'. |
|
427 Picked: setuptools = V |
|
428 Installing 'zc.recipe.egg'. |
|
429 We have a develop egg: zc.recipe.egg V |
|
430 Installing eggs. |
|
431 Installing 'bigdemo'. |
|
432 We have no distributions for bigdemo that satisfies 'bigdemo'. |
|
433 Getting distribution for 'bigdemo'. |
|
434 Got bigdemo 0.1. |
|
435 Picked: bigdemo = 0.1 |
|
436 Getting required 'demo' |
|
437 required by bigdemo 0.1. |
|
438 We have the best distribution that satisfies 'demo'. |
|
439 Egg from site-packages: demo 0.3 |
|
440 Getting required 'demoneeded' |
|
441 required by demo 0.3. |
|
442 We have the best distribution that satisfies 'demoneeded'. |
|
443 Egg from site-packages: demoneeded 1.1 |
|
444 """ |
|
445 |
|
446 def test_comparing_saved_options_with_funny_characters(): |
|
447 """ |
|
448 If an option has newlines, extra/odd spaces or a %, we need to make sure |
|
449 the comparison with the saved value works correctly. |
|
450 |
|
451 >>> mkdir(sample_buildout, 'recipes') |
|
452 >>> write(sample_buildout, 'recipes', 'debug.py', |
|
453 ... ''' |
|
454 ... class Debug: |
|
455 ... def __init__(self, buildout, name, options): |
|
456 ... options['debug'] = \"\"\" <zodb> |
|
457 ... |
|
458 ... <filestorage> |
|
459 ... path foo |
|
460 ... </filestorage> |
|
461 ... |
|
462 ... </zodb> |
|
463 ... \"\"\" |
|
464 ... options['debug1'] = \"\"\" |
|
465 ... <zodb> |
|
466 ... |
|
467 ... <filestorage> |
|
468 ... path foo |
|
469 ... </filestorage> |
|
470 ... |
|
471 ... </zodb> |
|
472 ... \"\"\" |
|
473 ... options['debug2'] = ' x ' |
|
474 ... options['debug3'] = '42' |
|
475 ... options['format'] = '%3d' |
|
476 ... |
|
477 ... def install(self): |
|
478 ... open('t', 'w').write('t') |
|
479 ... return 't' |
|
480 ... |
|
481 ... update = install |
|
482 ... ''') |
|
483 |
|
484 |
|
485 >>> write(sample_buildout, 'recipes', 'setup.py', |
|
486 ... ''' |
|
487 ... from setuptools import setup |
|
488 ... setup( |
|
489 ... name = "recipes", |
|
490 ... entry_points = {'zc.buildout': ['default = debug:Debug']}, |
|
491 ... ) |
|
492 ... ''') |
|
493 |
|
494 >>> write(sample_buildout, 'recipes', 'README.txt', " ") |
|
495 |
|
496 >>> write(sample_buildout, 'buildout.cfg', |
|
497 ... ''' |
|
498 ... [buildout] |
|
499 ... develop = recipes |
|
500 ... parts = debug |
|
501 ... |
|
502 ... [debug] |
|
503 ... recipe = recipes |
|
504 ... ''') |
|
505 |
|
506 >>> os.chdir(sample_buildout) |
|
507 >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout') |
|
508 |
|
509 >>> print system(buildout), |
|
510 Develop: '/sample-buildout/recipes' |
|
511 Installing debug. |
|
512 |
|
513 If we run the buildout again, we shoudn't get a message about |
|
514 uninstalling anything because the configuration hasn't changed. |
|
515 |
|
516 >>> print system(buildout), |
|
517 Develop: '/sample-buildout/recipes' |
|
518 Updating debug. |
|
519 """ |
|
520 |
|
521 def finding_eggs_as_local_directories(): |
|
522 r""" |
|
523 It is possible to set up find-links so that we could install from |
|
524 a local directory that may contained unzipped eggs. |
|
525 |
|
526 >>> src = tmpdir('src') |
|
527 >>> write(src, 'setup.py', |
|
528 ... ''' |
|
529 ... from setuptools import setup |
|
530 ... setup(name='demo', py_modules=[''], |
|
531 ... zip_safe=False, version='1.0', author='bob', url='bob', |
|
532 ... author_email='bob') |
|
533 ... ''') |
|
534 |
|
535 >>> write(src, 't.py', '#\n') |
|
536 >>> write(src, 'README.txt', '') |
|
537 >>> _ = system(join('bin', 'buildout')+' setup ' + src + ' bdist_egg') |
|
538 |
|
539 Install it so it gets unzipped: |
|
540 |
|
541 >>> d1 = tmpdir('d1') |
|
542 >>> ws = zc.buildout.easy_install.install( |
|
543 ... ['demo'], d1, links=[join(src, 'dist')], |
|
544 ... ) |
|
545 |
|
546 >>> ls(d1) |
|
547 d demo-1.0-py2.4.egg |
|
548 |
|
549 Then try to install it again: |
|
550 |
|
551 >>> d2 = tmpdir('d2') |
|
552 >>> ws = zc.buildout.easy_install.install( |
|
553 ... ['demo'], d2, links=[d1], |
|
554 ... ) |
|
555 |
|
556 >>> ls(d2) |
|
557 d demo-1.0-py2.4.egg |
|
558 |
|
559 """ |
|
560 |
|
561 def make_sure__get_version_works_with_2_digit_python_versions(): |
|
562 """ |
|
563 |
|
564 This is a test of an internal function used by higher-level machinery. |
|
565 |
|
566 We'll start by creating a faux 'python' that executable that prints a |
|
567 2-digit version. This is a bit of a pain to do portably. :( |
|
568 |
|
569 >>> mkdir('demo') |
|
570 >>> write('demo', 'setup.py', |
|
571 ... ''' |
|
572 ... from setuptools import setup |
|
573 ... setup(name='demo', |
|
574 ... entry_points = {'console_scripts': ['demo = demo:main']}, |
|
575 ... ) |
|
576 ... ''') |
|
577 >>> write('demo', 'demo.py', |
|
578 ... ''' |
|
579 ... def main(): |
|
580 ... print 'Python 2.5' |
|
581 ... ''') |
|
582 |
|
583 >>> write('buildout.cfg', |
|
584 ... ''' |
|
585 ... [buildout] |
|
586 ... develop = demo |
|
587 ... parts = |
|
588 ... ''') |
|
589 |
|
590 >>> print system(join('bin', 'buildout')), |
|
591 Develop: '/sample-buildout/demo' |
|
592 |
|
593 >>> import zc.buildout.easy_install |
|
594 >>> ws = zc.buildout.easy_install.working_set( |
|
595 ... ['demo'], sys.executable, ['develop-eggs']) |
|
596 >>> bool(zc.buildout.easy_install.scripts( |
|
597 ... ['demo'], ws, sys.executable, 'bin')) |
|
598 True |
|
599 |
|
600 >>> print system(join('bin', 'demo')), |
|
601 Python 2.5 |
|
602 |
|
603 Now, finally, let's test _get_version: |
|
604 |
|
605 >>> zc.buildout.easy_install._get_version(join('bin', 'demo')) |
|
606 '2.5' |
|
607 |
|
608 """ |
|
609 |
|
610 def create_sections_on_command_line(): |
|
611 """ |
|
612 >>> write('buildout.cfg', |
|
613 ... ''' |
|
614 ... [buildout] |
|
615 ... parts = |
|
616 ... x = ${foo:bar} |
|
617 ... ''') |
|
618 |
|
619 >>> print system(buildout + ' foo:bar=1 -vv'), # doctest: +ELLIPSIS |
|
620 Installing 'zc.buildout', 'setuptools'. |
|
621 ... |
|
622 [foo] |
|
623 bar = 1 |
|
624 ... |
|
625 |
|
626 """ |
|
627 |
|
628 def test_help(): |
|
629 """ |
|
630 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')+' -h'), |
|
631 ... # doctest: +ELLIPSIS |
|
632 Usage: buildout [options] [assignments] [command [command arguments]] |
|
633 <BLANKLINE> |
|
634 Options: |
|
635 <BLANKLINE> |
|
636 -h, --help |
|
637 ... |
|
638 |
|
639 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') |
|
640 ... +' --help'), |
|
641 ... # doctest: +ELLIPSIS |
|
642 Usage: buildout [options] [assignments] [command [command arguments]] |
|
643 <BLANKLINE> |
|
644 Options: |
|
645 <BLANKLINE> |
|
646 -h, --help |
|
647 ... |
|
648 """ |
|
649 |
|
650 def test_bootstrap_with_extension(): |
|
651 """ |
|
652 We had a problem running a bootstrap with an extension. Let's make |
|
653 sure it is fixed. Basically, we don't load extensions when |
|
654 bootstrapping. |
|
655 |
|
656 >>> d = tmpdir('sample-bootstrap') |
|
657 |
|
658 >>> write(d, 'buildout.cfg', |
|
659 ... ''' |
|
660 ... [buildout] |
|
661 ... extensions = some_awsome_extension |
|
662 ... parts = |
|
663 ... ''') |
|
664 |
|
665 >>> os.chdir(d) |
|
666 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') |
|
667 ... + ' bootstrap'), |
|
668 Creating directory '/sample-bootstrap/bin'. |
|
669 Creating directory '/sample-bootstrap/parts'. |
|
670 Creating directory '/sample-bootstrap/eggs'. |
|
671 Creating directory '/sample-bootstrap/develop-eggs'. |
|
672 Generated script '/sample-bootstrap/bin/buildout'. |
|
673 """ |
|
674 |
|
675 |
|
676 def bug_92891_bootstrap_crashes_with_egg_recipe_in_buildout_section(): |
|
677 """ |
|
678 >>> d = tmpdir('sample-bootstrap') |
|
679 |
|
680 >>> write(d, 'buildout.cfg', |
|
681 ... ''' |
|
682 ... [buildout] |
|
683 ... parts = buildout |
|
684 ... eggs-directory = eggs |
|
685 ... |
|
686 ... [buildout] |
|
687 ... recipe = zc.recipe.egg |
|
688 ... eggs = zc.buildout |
|
689 ... scripts = buildout=buildout |
|
690 ... ''') |
|
691 |
|
692 >>> os.chdir(d) |
|
693 >>> print system(os.path.join(sample_buildout, 'bin', 'buildout') |
|
694 ... + ' bootstrap'), |
|
695 Creating directory '/sample-bootstrap/bin'. |
|
696 Creating directory '/sample-bootstrap/parts'. |
|
697 Creating directory '/sample-bootstrap/eggs'. |
|
698 Creating directory '/sample-bootstrap/develop-eggs'. |
|
699 Generated script '/sample-bootstrap/bin/buildout'. |
|
700 |
|
701 >>> print system(os.path.join('bin', 'buildout')), |
|
702 Unused options for buildout: 'scripts' 'eggs'. |
|
703 |
|
704 """ |
|
705 |
|
706 def removing_eggs_from_develop_section_causes_egg_link_to_be_removed(): |
|
707 ''' |
|
708 >>> cd(sample_buildout) |
|
709 |
|
710 Create a develop egg: |
|
711 |
|
712 >>> mkdir('foo') |
|
713 >>> write('foo', 'setup.py', |
|
714 ... """ |
|
715 ... from setuptools import setup |
|
716 ... setup(name='foox') |
|
717 ... """) |
|
718 >>> write('buildout.cfg', |
|
719 ... """ |
|
720 ... [buildout] |
|
721 ... develop = foo |
|
722 ... parts = |
|
723 ... """) |
|
724 |
|
725 >>> print system(join('bin', 'buildout')), |
|
726 Develop: '/sample-buildout/foo' |
|
727 |
|
728 >>> ls('develop-eggs') |
|
729 - foox.egg-link |
|
730 - z3c.recipe.scripts.egg-link |
|
731 - zc.recipe.egg.egg-link |
|
732 |
|
733 Create another: |
|
734 |
|
735 >>> mkdir('bar') |
|
736 >>> write('bar', 'setup.py', |
|
737 ... """ |
|
738 ... from setuptools import setup |
|
739 ... setup(name='fooy') |
|
740 ... """) |
|
741 >>> write('buildout.cfg', |
|
742 ... """ |
|
743 ... [buildout] |
|
744 ... develop = foo bar |
|
745 ... parts = |
|
746 ... """) |
|
747 |
|
748 >>> print system(join('bin', 'buildout')), |
|
749 Develop: '/sample-buildout/foo' |
|
750 Develop: '/sample-buildout/bar' |
|
751 |
|
752 >>> ls('develop-eggs') |
|
753 - foox.egg-link |
|
754 - fooy.egg-link |
|
755 - z3c.recipe.scripts.egg-link |
|
756 - zc.recipe.egg.egg-link |
|
757 |
|
758 Remove one: |
|
759 |
|
760 >>> write('buildout.cfg', |
|
761 ... """ |
|
762 ... [buildout] |
|
763 ... develop = bar |
|
764 ... parts = |
|
765 ... """) |
|
766 >>> print system(join('bin', 'buildout')), |
|
767 Develop: '/sample-buildout/bar' |
|
768 |
|
769 It is gone |
|
770 |
|
771 >>> ls('develop-eggs') |
|
772 - fooy.egg-link |
|
773 - z3c.recipe.scripts.egg-link |
|
774 - zc.recipe.egg.egg-link |
|
775 |
|
776 Remove the other: |
|
777 |
|
778 >>> write('buildout.cfg', |
|
779 ... """ |
|
780 ... [buildout] |
|
781 ... parts = |
|
782 ... """) |
|
783 >>> print system(join('bin', 'buildout')), |
|
784 |
|
785 All gone |
|
786 |
|
787 >>> ls('develop-eggs') |
|
788 - z3c.recipe.scripts.egg-link |
|
789 - zc.recipe.egg.egg-link |
|
790 ''' |
|
791 |
|
792 |
|
793 def add_setuptools_to_dependencies_when_namespace_packages(): |
|
794 ''' |
|
795 Often, a package depends on setuptools soley by virtue of using |
|
796 namespace packages. In this situation, package authors often forget to |
|
797 declare setuptools as a dependency. This is a mistake, but, |
|
798 unfortunately, a common one that we need to work around. If an egg |
|
799 uses namespace packages and does not include setuptools as a depenency, |
|
800 we will still include setuptools in the working set. If we see this for |
|
801 a devlop egg, we will also generate a warning. |
|
802 |
|
803 >>> mkdir('foo') |
|
804 >>> mkdir('foo', 'src') |
|
805 >>> mkdir('foo', 'src', 'stuff') |
|
806 >>> write('foo', 'src', 'stuff', '__init__.py', |
|
807 ... """__import__('pkg_resources').declare_namespace(__name__) |
|
808 ... """) |
|
809 >>> mkdir('foo', 'src', 'stuff', 'foox') |
|
810 >>> write('foo', 'src', 'stuff', 'foox', '__init__.py', '') |
|
811 >>> write('foo', 'setup.py', |
|
812 ... """ |
|
813 ... from setuptools import setup |
|
814 ... setup(name='foox', |
|
815 ... namespace_packages = ['stuff'], |
|
816 ... package_dir = {'': 'src'}, |
|
817 ... packages = ['stuff', 'stuff.foox'], |
|
818 ... ) |
|
819 ... """) |
|
820 >>> write('foo', 'README.txt', '') |
|
821 |
|
822 >>> write('buildout.cfg', |
|
823 ... """ |
|
824 ... [buildout] |
|
825 ... develop = foo |
|
826 ... parts = |
|
827 ... """) |
|
828 |
|
829 >>> print system(join('bin', 'buildout')), |
|
830 Develop: '/sample-buildout/foo' |
|
831 |
|
832 Now, if we generate a working set using the egg link, we will get a warning |
|
833 and we will get setuptools included in the working set. |
|
834 |
|
835 >>> import logging, zope.testing.loggingsupport |
|
836 >>> handler = zope.testing.loggingsupport.InstalledHandler( |
|
837 ... 'zc.buildout.easy_install', level=logging.WARNING) |
|
838 >>> logging.getLogger('zc.buildout.easy_install').propagate = False |
|
839 |
|
840 >>> [dist.project_name |
|
841 ... for dist in zc.buildout.easy_install.working_set( |
|
842 ... ['foox'], sys.executable, |
|
843 ... [join(sample_buildout, 'eggs'), |
|
844 ... join(sample_buildout, 'develop-eggs'), |
|
845 ... ])] |
|
846 ['foox', 'setuptools'] |
|
847 |
|
848 >>> print handler |
|
849 zc.buildout.easy_install WARNING |
|
850 Develop distribution: foox 0.0.0 |
|
851 uses namespace packages but the distribution does not require setuptools. |
|
852 |
|
853 >>> handler.clear() |
|
854 |
|
855 On the other hand, if we have a regular egg, rather than a develop egg: |
|
856 |
|
857 >>> os.remove(join('develop-eggs', 'foox.egg-link')) |
|
858 |
|
859 >>> _ = system(join('bin', 'buildout') + ' setup foo bdist_egg -d' |
|
860 ... + join(sample_buildout, 'eggs')) |
|
861 |
|
862 >>> ls('develop-eggs') |
|
863 - z3c.recipe.scripts.egg-link |
|
864 - zc.recipe.egg.egg-link |
|
865 |
|
866 >>> print 'START ->'; ls('eggs') # doctest: +ELLIPSIS |
|
867 START... |
|
868 - foox-0.0.0-py2.4.egg |
|
869 ... |
|
870 |
|
871 We do not get a warning, but we do get setuptools included in the working set: |
|
872 |
|
873 >>> [dist.project_name |
|
874 ... for dist in zc.buildout.easy_install.working_set( |
|
875 ... ['foox'], sys.executable, |
|
876 ... [join(sample_buildout, 'eggs'), |
|
877 ... join(sample_buildout, 'develop-eggs'), |
|
878 ... ])] |
|
879 ['foox', 'setuptools'] |
|
880 |
|
881 >>> print handler, |
|
882 |
|
883 We get the same behavior if the it is a depedency that uses a |
|
884 namespace package. |
|
885 |
|
886 |
|
887 >>> mkdir('bar') |
|
888 >>> write('bar', 'setup.py', |
|
889 ... """ |
|
890 ... from setuptools import setup |
|
891 ... setup(name='bar', install_requires = ['foox']) |
|
892 ... """) |
|
893 >>> write('bar', 'README.txt', '') |
|
894 |
|
895 >>> write('buildout.cfg', |
|
896 ... """ |
|
897 ... [buildout] |
|
898 ... develop = foo bar |
|
899 ... parts = |
|
900 ... """) |
|
901 |
|
902 >>> print system(join('bin', 'buildout')), |
|
903 Develop: '/sample-buildout/foo' |
|
904 Develop: '/sample-buildout/bar' |
|
905 |
|
906 >>> [dist.project_name |
|
907 ... for dist in zc.buildout.easy_install.working_set( |
|
908 ... ['bar'], sys.executable, |
|
909 ... [join(sample_buildout, 'eggs'), |
|
910 ... join(sample_buildout, 'develop-eggs'), |
|
911 ... ])] |
|
912 ['bar', 'foox', 'setuptools'] |
|
913 |
|
914 >>> print handler, |
|
915 zc.buildout.easy_install WARNING |
|
916 Develop distribution: foox 0.0.0 |
|
917 uses namespace packages but the distribution does not require setuptools. |
|
918 |
|
919 |
|
920 >>> logging.getLogger('zc.buildout.easy_install').propagate = True |
|
921 >>> handler.uninstall() |
|
922 |
|
923 ''' |
|
924 |
|
925 def develop_preserves_existing_setup_cfg(): |
|
926 """ |
|
927 |
|
928 See "Handling custom build options for extensions in develop eggs" in |
|
929 easy_install.txt. This will be very similar except that we'll have an |
|
930 existing setup.cfg: |
|
931 |
|
932 >>> write(extdemo, "setup.cfg", |
|
933 ... ''' |
|
934 ... # sampe cfg file |
|
935 ... |
|
936 ... [foo] |
|
937 ... bar = 1 |
|
938 ... |
|
939 ... [build_ext] |
|
940 ... define = X,Y |
|
941 ... ''') |
|
942 |
|
943 >>> mkdir('include') |
|
944 >>> write('include', 'extdemo.h', |
|
945 ... ''' |
|
946 ... #define EXTDEMO 42 |
|
947 ... ''') |
|
948 |
|
949 >>> dest = tmpdir('dest') |
|
950 >>> zc.buildout.easy_install.develop( |
|
951 ... extdemo, dest, |
|
952 ... {'include-dirs': os.path.join(sample_buildout, 'include')}) |
|
953 '/dest/extdemo.egg-link' |
|
954 |
|
955 >>> ls(dest) |
|
956 - extdemo.egg-link |
|
957 |
|
958 >>> cat(extdemo, "setup.cfg") |
|
959 <BLANKLINE> |
|
960 # sampe cfg file |
|
961 <BLANKLINE> |
|
962 [foo] |
|
963 bar = 1 |
|
964 <BLANKLINE> |
|
965 [build_ext] |
|
966 define = X,Y |
|
967 |
|
968 """ |
|
969 |
|
970 def uninstall_recipes_used_for_removal(): |
|
971 """ |
|
972 Uninstall recipes need to be called when a part is removed too: |
|
973 |
|
974 >>> mkdir("recipes") |
|
975 >>> write("recipes", "setup.py", |
|
976 ... ''' |
|
977 ... from setuptools import setup |
|
978 ... setup(name='recipes', |
|
979 ... entry_points={ |
|
980 ... 'zc.buildout': ["demo=demo:Install"], |
|
981 ... 'zc.buildout.uninstall': ["demo=demo:uninstall"], |
|
982 ... }) |
|
983 ... ''') |
|
984 |
|
985 >>> write("recipes", "demo.py", |
|
986 ... ''' |
|
987 ... class Install: |
|
988 ... def __init__(*args): pass |
|
989 ... def install(self): |
|
990 ... print 'installing' |
|
991 ... return () |
|
992 ... def uninstall(name, options): print 'uninstalling' |
|
993 ... ''') |
|
994 |
|
995 >>> write('buildout.cfg', ''' |
|
996 ... [buildout] |
|
997 ... develop = recipes |
|
998 ... parts = demo |
|
999 ... [demo] |
|
1000 ... recipe = recipes:demo |
|
1001 ... ''') |
|
1002 |
|
1003 >>> print system(join('bin', 'buildout')), |
|
1004 Develop: '/sample-buildout/recipes' |
|
1005 Installing demo. |
|
1006 installing |
|
1007 |
|
1008 |
|
1009 >>> write('buildout.cfg', ''' |
|
1010 ... [buildout] |
|
1011 ... develop = recipes |
|
1012 ... parts = demo |
|
1013 ... [demo] |
|
1014 ... recipe = recipes:demo |
|
1015 ... x = 1 |
|
1016 ... ''') |
|
1017 |
|
1018 >>> print system(join('bin', 'buildout')), |
|
1019 Develop: '/sample-buildout/recipes' |
|
1020 Uninstalling demo. |
|
1021 Running uninstall recipe. |
|
1022 uninstalling |
|
1023 Installing demo. |
|
1024 installing |
|
1025 |
|
1026 |
|
1027 >>> write('buildout.cfg', ''' |
|
1028 ... [buildout] |
|
1029 ... develop = recipes |
|
1030 ... parts = |
|
1031 ... ''') |
|
1032 |
|
1033 >>> print system(join('bin', 'buildout')), |
|
1034 Develop: '/sample-buildout/recipes' |
|
1035 Uninstalling demo. |
|
1036 Running uninstall recipe. |
|
1037 uninstalling |
|
1038 |
|
1039 """ |
|
1040 |
|
1041 def extensions_installed_as_eggs_work_in_offline_mode(): |
|
1042 ''' |
|
1043 >>> mkdir('demo') |
|
1044 |
|
1045 >>> write('demo', 'demo.py', |
|
1046 ... """ |
|
1047 ... def ext(buildout): |
|
1048 ... print 'ext', list(buildout) |
|
1049 ... """) |
|
1050 |
|
1051 >>> write('demo', 'setup.py', |
|
1052 ... """ |
|
1053 ... from setuptools import setup |
|
1054 ... |
|
1055 ... setup( |
|
1056 ... name = "demo", |
|
1057 ... py_modules=['demo'], |
|
1058 ... entry_points = {'zc.buildout.extension': ['ext = demo:ext']}, |
|
1059 ... ) |
|
1060 ... """) |
|
1061 |
|
1062 >>> bdist_egg(join(sample_buildout, "demo"), sys.executable, |
|
1063 ... join(sample_buildout, "eggs")) |
|
1064 |
|
1065 >>> write(sample_buildout, 'buildout.cfg', |
|
1066 ... """ |
|
1067 ... [buildout] |
|
1068 ... extensions = demo |
|
1069 ... parts = |
|
1070 ... offline = true |
|
1071 ... """) |
|
1072 |
|
1073 >>> print system(join(sample_buildout, 'bin', 'buildout')), |
|
1074 ext ['buildout'] |
|
1075 |
|
1076 |
|
1077 ''' |
|
1078 |
|
1079 def changes_in_svn_or_CVS_dont_affect_sig(): |
|
1080 """ |
|
1081 |
|
1082 If we have a develop recipe, it's signature shouldn't be affected to |
|
1083 changes in .svn or CVS directories. |
|
1084 |
|
1085 >>> mkdir('recipe') |
|
1086 >>> write('recipe', 'setup.py', |
|
1087 ... ''' |
|
1088 ... from setuptools import setup |
|
1089 ... setup(name='recipe', |
|
1090 ... entry_points={'zc.buildout': ['default=foo:Foo']}) |
|
1091 ... ''') |
|
1092 >>> write('recipe', 'foo.py', |
|
1093 ... ''' |
|
1094 ... class Foo: |
|
1095 ... def __init__(*args): pass |
|
1096 ... def install(*args): return () |
|
1097 ... update = install |
|
1098 ... ''') |
|
1099 |
|
1100 >>> write('buildout.cfg', |
|
1101 ... ''' |
|
1102 ... [buildout] |
|
1103 ... develop = recipe |
|
1104 ... parts = foo |
|
1105 ... |
|
1106 ... [foo] |
|
1107 ... recipe = recipe |
|
1108 ... ''') |
|
1109 |
|
1110 |
|
1111 >>> print system(join(sample_buildout, 'bin', 'buildout')), |
|
1112 Develop: '/sample-buildout/recipe' |
|
1113 Installing foo. |
|
1114 |
|
1115 >>> mkdir('recipe', '.svn') |
|
1116 >>> mkdir('recipe', 'CVS') |
|
1117 >>> print system(join(sample_buildout, 'bin', 'buildout')), |
|
1118 Develop: '/sample-buildout/recipe' |
|
1119 Updating foo. |
|
1120 |
|
1121 >>> write('recipe', '.svn', 'x', '1') |
|
1122 >>> write('recipe', 'CVS', 'x', '1') |
|
1123 |
|
1124 >>> print system(join(sample_buildout, 'bin', 'buildout')), |
|
1125 Develop: '/sample-buildout/recipe' |
|
1126 Updating foo. |
|
1127 |
|
1128 """ |
|
1129 |
|
1130 if hasattr(os, 'symlink'): |
|
1131 def bug_250537_broken_symlink_doesnt_affect_sig(): |
|
1132 """ |
|
1133 If we have a develop recipe, it's signature shouldn't be affected by |
|
1134 broken symlinks, and better yet, computing the hash should not break |
|
1135 because of the missing target file. |
|
1136 |
|
1137 >>> mkdir('recipe') |
|
1138 >>> write('recipe', 'setup.py', |
|
1139 ... ''' |
|
1140 ... from setuptools import setup |
|
1141 ... setup(name='recipe', |
|
1142 ... entry_points={'zc.buildout': ['default=foo:Foo']}) |
|
1143 ... ''') |
|
1144 >>> write('recipe', 'foo.py', |
|
1145 ... ''' |
|
1146 ... class Foo: |
|
1147 ... def __init__(*args): pass |
|
1148 ... def install(*args): return () |
|
1149 ... update = install |
|
1150 ... ''') |
|
1151 |
|
1152 >>> write('buildout.cfg', |
|
1153 ... ''' |
|
1154 ... [buildout] |
|
1155 ... develop = recipe |
|
1156 ... parts = foo |
|
1157 ... |
|
1158 ... [foo] |
|
1159 ... recipe = recipe |
|
1160 ... ''') |
|
1161 |
|
1162 |
|
1163 >>> print system(join(sample_buildout, 'bin', 'buildout')), |
|
1164 Develop: '/sample-buildout/recipe' |
|
1165 Installing foo. |
|
1166 |
|
1167 >>> write('recipe', 'some-file', '1') |
|
1168 >>> os.symlink(join('recipe', 'some-file'), |
|
1169 ... join('recipe', 'another-file')) |
|
1170 >>> ls('recipe') |
|
1171 l another-file |
|
1172 - foo.py |
|
1173 - foo.pyc |
|
1174 d recipe.egg-info |
|
1175 - setup.py |
|
1176 - some-file |
|
1177 |
|
1178 >>> remove('recipe', 'some-file') |
|
1179 |
|
1180 >>> print system(join(sample_buildout, 'bin', 'buildout')), |
|
1181 Develop: '/sample-buildout/recipe' |
|
1182 Updating foo. |
|
1183 |
|
1184 """ |
|
1185 |
|
1186 def o_option_sets_offline(): |
|
1187 """ |
|
1188 >>> print system(join(sample_buildout, 'bin', 'buildout')+' -vvo'), |
|
1189 ... # doctest: +ELLIPSIS |
|
1190 <BLANKLINE> |
|
1191 ... |
|
1192 offline = true |
|
1193 ... |
|
1194 """ |
|
1195 |
|
1196 def recipe_upgrade(): |
|
1197 """ |
|
1198 |
|
1199 The buildout will upgrade recipes in newest (and non-offline) mode. |
|
1200 |
|
1201 Let's create a recipe egg |
|
1202 |
|
1203 >>> mkdir('recipe') |
|
1204 >>> write('recipe', 'recipe.py', |
|
1205 ... ''' |
|
1206 ... class Recipe: |
|
1207 ... def __init__(*a): pass |
|
1208 ... def install(self): |
|
1209 ... print 'recipe v1' |
|
1210 ... return () |
|
1211 ... update = install |
|
1212 ... ''') |
|
1213 |
|
1214 >>> write('recipe', 'setup.py', |
|
1215 ... ''' |
|
1216 ... from setuptools import setup |
|
1217 ... setup(name='recipe', version='1', py_modules=['recipe'], |
|
1218 ... entry_points={'zc.buildout': ['default = recipe:Recipe']}, |
|
1219 ... ) |
|
1220 ... ''') |
|
1221 |
|
1222 >>> write('recipe', 'README', '') |
|
1223 |
|
1224 >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS |
|
1225 Running setup script 'recipe/setup.py'. |
|
1226 ... |
|
1227 |
|
1228 >>> rmdir('recipe', 'build') |
|
1229 |
|
1230 And update our buildout to use it. |
|
1231 |
|
1232 >>> write('buildout.cfg', |
|
1233 ... ''' |
|
1234 ... [buildout] |
|
1235 ... parts = foo |
|
1236 ... find-links = %s |
|
1237 ... |
|
1238 ... [foo] |
|
1239 ... recipe = recipe |
|
1240 ... ''' % join('recipe', 'dist')) |
|
1241 |
|
1242 >>> print system(buildout), |
|
1243 Getting distribution for 'recipe'. |
|
1244 Got recipe 1. |
|
1245 Installing foo. |
|
1246 recipe v1 |
|
1247 |
|
1248 Now, if we update the recipe egg: |
|
1249 |
|
1250 >>> write('recipe', 'recipe.py', |
|
1251 ... ''' |
|
1252 ... class Recipe: |
|
1253 ... def __init__(*a): pass |
|
1254 ... def install(self): |
|
1255 ... print 'recipe v2' |
|
1256 ... return () |
|
1257 ... update = install |
|
1258 ... ''') |
|
1259 |
|
1260 >>> write('recipe', 'setup.py', |
|
1261 ... ''' |
|
1262 ... from setuptools import setup |
|
1263 ... setup(name='recipe', version='2', py_modules=['recipe'], |
|
1264 ... entry_points={'zc.buildout': ['default = recipe:Recipe']}, |
|
1265 ... ) |
|
1266 ... ''') |
|
1267 |
|
1268 |
|
1269 >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS |
|
1270 Running setup script 'recipe/setup.py'. |
|
1271 ... |
|
1272 |
|
1273 We won't get the update if we specify -N: |
|
1274 |
|
1275 >>> print system(buildout+' -N'), |
|
1276 Updating foo. |
|
1277 recipe v1 |
|
1278 |
|
1279 or if we use -o: |
|
1280 |
|
1281 >>> print system(buildout+' -o'), |
|
1282 Updating foo. |
|
1283 recipe v1 |
|
1284 |
|
1285 But we will if we use neither of these: |
|
1286 |
|
1287 >>> print system(buildout), |
|
1288 Getting distribution for 'recipe'. |
|
1289 Got recipe 2. |
|
1290 Uninstalling foo. |
|
1291 Installing foo. |
|
1292 recipe v2 |
|
1293 |
|
1294 We can also select a particular recipe version: |
|
1295 |
|
1296 >>> write('buildout.cfg', |
|
1297 ... ''' |
|
1298 ... [buildout] |
|
1299 ... parts = foo |
|
1300 ... find-links = %s |
|
1301 ... |
|
1302 ... [foo] |
|
1303 ... recipe = recipe ==1 |
|
1304 ... ''' % join('recipe', 'dist')) |
|
1305 |
|
1306 >>> print system(buildout), |
|
1307 Uninstalling foo. |
|
1308 Installing foo. |
|
1309 recipe v1 |
|
1310 |
|
1311 """ |
|
1312 |
|
1313 def update_adds_to_uninstall_list(): |
|
1314 """ |
|
1315 |
|
1316 Paths returned by the update method are added to the list of paths to |
|
1317 uninstall |
|
1318 |
|
1319 >>> mkdir('recipe') |
|
1320 >>> write('recipe', 'setup.py', |
|
1321 ... ''' |
|
1322 ... from setuptools import setup |
|
1323 ... setup(name='recipe', |
|
1324 ... entry_points={'zc.buildout': ['default = recipe:Recipe']}, |
|
1325 ... ) |
|
1326 ... ''') |
|
1327 |
|
1328 >>> write('recipe', 'recipe.py', |
|
1329 ... ''' |
|
1330 ... import os |
|
1331 ... class Recipe: |
|
1332 ... def __init__(*_): pass |
|
1333 ... def install(self): |
|
1334 ... r = ('a', 'b', 'c') |
|
1335 ... for p in r: os.mkdir(p) |
|
1336 ... return r |
|
1337 ... def update(self): |
|
1338 ... r = ('c', 'd', 'e') |
|
1339 ... for p in r: |
|
1340 ... if not os.path.exists(p): |
|
1341 ... os.mkdir(p) |
|
1342 ... return r |
|
1343 ... ''') |
|
1344 |
|
1345 >>> write('buildout.cfg', |
|
1346 ... ''' |
|
1347 ... [buildout] |
|
1348 ... develop = recipe |
|
1349 ... parts = foo |
|
1350 ... |
|
1351 ... [foo] |
|
1352 ... recipe = recipe |
|
1353 ... ''') |
|
1354 |
|
1355 >>> print system(buildout), |
|
1356 Develop: '/sample-buildout/recipe' |
|
1357 Installing foo. |
|
1358 |
|
1359 >>> print system(buildout), |
|
1360 Develop: '/sample-buildout/recipe' |
|
1361 Updating foo. |
|
1362 |
|
1363 >>> cat('.installed.cfg') # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE |
|
1364 [buildout] |
|
1365 ... |
|
1366 [foo] |
|
1367 __buildout_installed__ = a |
|
1368 b |
|
1369 c |
|
1370 d |
|
1371 e |
|
1372 __buildout_signature__ = ... |
|
1373 |
|
1374 """ |
|
1375 |
|
1376 def log_when_there_are_not_local_distros(): |
|
1377 """ |
|
1378 >>> from zope.testing.loggingsupport import InstalledHandler |
|
1379 >>> handler = InstalledHandler('zc.buildout.easy_install') |
|
1380 >>> import logging |
|
1381 >>> logger = logging.getLogger('zc.buildout.easy_install') |
|
1382 >>> old_propogate = logger.propagate |
|
1383 >>> logger.propagate = False |
|
1384 |
|
1385 >>> dest = tmpdir('sample-install') |
|
1386 >>> import zc.buildout.easy_install |
|
1387 >>> ws = zc.buildout.easy_install.install( |
|
1388 ... ['demo==0.2'], dest, |
|
1389 ... links=[link_server], index=link_server+'index/') |
|
1390 |
|
1391 >>> print handler # doctest: +ELLIPSIS |
|
1392 zc.buildout.easy_install DEBUG |
|
1393 Installing 'demo==0.2'. |
|
1394 zc.buildout.easy_install DEBUG |
|
1395 We have no distributions for demo that satisfies 'demo==0.2'. |
|
1396 ... |
|
1397 |
|
1398 >>> handler.uninstall() |
|
1399 >>> logger.propagate = old_propogate |
|
1400 |
|
1401 """ |
|
1402 |
|
1403 def internal_errors(): |
|
1404 """Internal errors are clearly marked and don't generate tracebacks: |
|
1405 |
|
1406 >>> mkdir(sample_buildout, 'recipes') |
|
1407 |
|
1408 >>> write(sample_buildout, 'recipes', 'mkdir.py', |
|
1409 ... ''' |
|
1410 ... class Mkdir: |
|
1411 ... def __init__(self, buildout, name, options): |
|
1412 ... self.name, self.options = name, options |
|
1413 ... options['path'] = os.path.join( |
|
1414 ... buildout['buildout']['directory'], |
|
1415 ... options['path'], |
|
1416 ... ) |
|
1417 ... ''') |
|
1418 |
|
1419 >>> write(sample_buildout, 'recipes', 'setup.py', |
|
1420 ... ''' |
|
1421 ... from setuptools import setup |
|
1422 ... setup(name = "recipes", |
|
1423 ... entry_points = {'zc.buildout': ['mkdir = mkdir:Mkdir']}, |
|
1424 ... ) |
|
1425 ... ''') |
|
1426 |
|
1427 >>> write(sample_buildout, 'buildout.cfg', |
|
1428 ... ''' |
|
1429 ... [buildout] |
|
1430 ... develop = recipes |
|
1431 ... parts = data-dir |
|
1432 ... |
|
1433 ... [data-dir] |
|
1434 ... recipe = recipes:mkdir |
|
1435 ... ''') |
|
1436 |
|
1437 >>> print system(buildout), # doctest: +ELLIPSIS |
|
1438 Develop: '/sample-buildout/recipes' |
|
1439 While: |
|
1440 Installing. |
|
1441 Getting section data-dir. |
|
1442 Initializing part data-dir. |
|
1443 <BLANKLINE> |
|
1444 An internal error occurred due to a bug in either zc.buildout or in a |
|
1445 recipe being used: |
|
1446 Traceback (most recent call last): |
|
1447 ... |
|
1448 NameError: global name 'os' is not defined |
|
1449 """ |
|
1450 |
|
1451 def whine_about_unused_options(): |
|
1452 ''' |
|
1453 |
|
1454 >>> write('foo.py', |
|
1455 ... """ |
|
1456 ... class Foo: |
|
1457 ... |
|
1458 ... def __init__(self, buildout, name, options): |
|
1459 ... self.name, self.options = name, options |
|
1460 ... options['x'] |
|
1461 ... |
|
1462 ... def install(self): |
|
1463 ... self.options['y'] |
|
1464 ... return () |
|
1465 ... """) |
|
1466 |
|
1467 >>> write('setup.py', |
|
1468 ... """ |
|
1469 ... from setuptools import setup |
|
1470 ... setup(name = "foo", |
|
1471 ... entry_points = {'zc.buildout': ['default = foo:Foo']}, |
|
1472 ... ) |
|
1473 ... """) |
|
1474 |
|
1475 >>> write('buildout.cfg', |
|
1476 ... """ |
|
1477 ... [buildout] |
|
1478 ... develop = . |
|
1479 ... parts = foo |
|
1480 ... a = 1 |
|
1481 ... |
|
1482 ... [foo] |
|
1483 ... recipe = foo |
|
1484 ... x = 1 |
|
1485 ... y = 1 |
|
1486 ... z = 1 |
|
1487 ... """) |
|
1488 |
|
1489 >>> print system(buildout), |
|
1490 Develop: '/sample-buildout/.' |
|
1491 Unused options for buildout: 'a'. |
|
1492 Installing foo. |
|
1493 Unused options for foo: 'z'. |
|
1494 ''' |
|
1495 |
|
1496 def abnormal_exit(): |
|
1497 """ |
|
1498 People sometimes hit control-c while running a builout. We need to make |
|
1499 sure that the installed database Isn't corrupted. To test this, we'll create |
|
1500 some evil recipes that exit uncleanly: |
|
1501 |
|
1502 >>> mkdir('recipes') |
|
1503 >>> write('recipes', 'recipes.py', |
|
1504 ... ''' |
|
1505 ... import os |
|
1506 ... |
|
1507 ... class Clean: |
|
1508 ... def __init__(*_): pass |
|
1509 ... def install(_): return () |
|
1510 ... def update(_): pass |
|
1511 ... |
|
1512 ... class EvilInstall(Clean): |
|
1513 ... def install(_): os._exit(1) |
|
1514 ... |
|
1515 ... class EvilUpdate(Clean): |
|
1516 ... def update(_): os._exit(1) |
|
1517 ... ''') |
|
1518 |
|
1519 >>> write('recipes', 'setup.py', |
|
1520 ... ''' |
|
1521 ... import setuptools |
|
1522 ... setuptools.setup(name='recipes', |
|
1523 ... entry_points = { |
|
1524 ... 'zc.buildout': [ |
|
1525 ... 'clean = recipes:Clean', |
|
1526 ... 'evil_install = recipes:EvilInstall', |
|
1527 ... 'evil_update = recipes:EvilUpdate', |
|
1528 ... 'evil_uninstall = recipes:Clean', |
|
1529 ... ], |
|
1530 ... }, |
|
1531 ... ) |
|
1532 ... ''') |
|
1533 |
|
1534 Now let's look at 3 cases: |
|
1535 |
|
1536 1. We exit during installation after installing some other parts: |
|
1537 |
|
1538 >>> write('buildout.cfg', |
|
1539 ... ''' |
|
1540 ... [buildout] |
|
1541 ... develop = recipes |
|
1542 ... parts = p1 p2 p3 p4 |
|
1543 ... |
|
1544 ... [p1] |
|
1545 ... recipe = recipes:clean |
|
1546 ... |
|
1547 ... [p2] |
|
1548 ... recipe = recipes:clean |
|
1549 ... |
|
1550 ... [p3] |
|
1551 ... recipe = recipes:evil_install |
|
1552 ... |
|
1553 ... [p4] |
|
1554 ... recipe = recipes:clean |
|
1555 ... ''') |
|
1556 |
|
1557 >>> print system(buildout), |
|
1558 Develop: '/sample-buildout/recipes' |
|
1559 Installing p1. |
|
1560 Installing p2. |
|
1561 Installing p3. |
|
1562 |
|
1563 >>> print system(buildout), |
|
1564 Develop: '/sample-buildout/recipes' |
|
1565 Updating p1. |
|
1566 Updating p2. |
|
1567 Installing p3. |
|
1568 |
|
1569 >>> print system(buildout+' buildout:parts='), |
|
1570 Develop: '/sample-buildout/recipes' |
|
1571 Uninstalling p2. |
|
1572 Uninstalling p1. |
|
1573 |
|
1574 2. We exit while updating: |
|
1575 |
|
1576 >>> write('buildout.cfg', |
|
1577 ... ''' |
|
1578 ... [buildout] |
|
1579 ... develop = recipes |
|
1580 ... parts = p1 p2 p3 p4 |
|
1581 ... |
|
1582 ... [p1] |
|
1583 ... recipe = recipes:clean |
|
1584 ... |
|
1585 ... [p2] |
|
1586 ... recipe = recipes:clean |
|
1587 ... |
|
1588 ... [p3] |
|
1589 ... recipe = recipes:evil_update |
|
1590 ... |
|
1591 ... [p4] |
|
1592 ... recipe = recipes:clean |
|
1593 ... ''') |
|
1594 |
|
1595 >>> print system(buildout), |
|
1596 Develop: '/sample-buildout/recipes' |
|
1597 Installing p1. |
|
1598 Installing p2. |
|
1599 Installing p3. |
|
1600 Installing p4. |
|
1601 |
|
1602 >>> print system(buildout), |
|
1603 Develop: '/sample-buildout/recipes' |
|
1604 Updating p1. |
|
1605 Updating p2. |
|
1606 Updating p3. |
|
1607 |
|
1608 >>> print system(buildout+' buildout:parts='), |
|
1609 Develop: '/sample-buildout/recipes' |
|
1610 Uninstalling p2. |
|
1611 Uninstalling p1. |
|
1612 Uninstalling p4. |
|
1613 Uninstalling p3. |
|
1614 |
|
1615 3. We exit while installing or updating after uninstalling: |
|
1616 |
|
1617 >>> write('buildout.cfg', |
|
1618 ... ''' |
|
1619 ... [buildout] |
|
1620 ... develop = recipes |
|
1621 ... parts = p1 p2 p3 p4 |
|
1622 ... |
|
1623 ... [p1] |
|
1624 ... recipe = recipes:evil_update |
|
1625 ... |
|
1626 ... [p2] |
|
1627 ... recipe = recipes:clean |
|
1628 ... |
|
1629 ... [p3] |
|
1630 ... recipe = recipes:clean |
|
1631 ... |
|
1632 ... [p4] |
|
1633 ... recipe = recipes:clean |
|
1634 ... ''') |
|
1635 |
|
1636 >>> print system(buildout), |
|
1637 Develop: '/sample-buildout/recipes' |
|
1638 Installing p1. |
|
1639 Installing p2. |
|
1640 Installing p3. |
|
1641 Installing p4. |
|
1642 |
|
1643 >>> write('buildout.cfg', |
|
1644 ... ''' |
|
1645 ... [buildout] |
|
1646 ... develop = recipes |
|
1647 ... parts = p1 p2 p3 p4 |
|
1648 ... |
|
1649 ... [p1] |
|
1650 ... recipe = recipes:evil_update |
|
1651 ... |
|
1652 ... [p2] |
|
1653 ... recipe = recipes:clean |
|
1654 ... |
|
1655 ... [p3] |
|
1656 ... recipe = recipes:clean |
|
1657 ... |
|
1658 ... [p4] |
|
1659 ... recipe = recipes:clean |
|
1660 ... x = 1 |
|
1661 ... ''') |
|
1662 |
|
1663 >>> print system(buildout), |
|
1664 Develop: '/sample-buildout/recipes' |
|
1665 Uninstalling p4. |
|
1666 Updating p1. |
|
1667 |
|
1668 >>> write('buildout.cfg', |
|
1669 ... ''' |
|
1670 ... [buildout] |
|
1671 ... develop = recipes |
|
1672 ... parts = p1 p2 p3 p4 |
|
1673 ... |
|
1674 ... [p1] |
|
1675 ... recipe = recipes:clean |
|
1676 ... |
|
1677 ... [p2] |
|
1678 ... recipe = recipes:clean |
|
1679 ... |
|
1680 ... [p3] |
|
1681 ... recipe = recipes:clean |
|
1682 ... |
|
1683 ... [p4] |
|
1684 ... recipe = recipes:clean |
|
1685 ... ''') |
|
1686 |
|
1687 >>> print system(buildout), |
|
1688 Develop: '/sample-buildout/recipes' |
|
1689 Uninstalling p1. |
|
1690 Installing p1. |
|
1691 Updating p2. |
|
1692 Updating p3. |
|
1693 Installing p4. |
|
1694 |
|
1695 """ |
|
1696 |
|
1697 def install_source_dist_with_bad_py(): |
|
1698 """ |
|
1699 |
|
1700 >>> mkdir('badegg') |
|
1701 >>> mkdir('badegg', 'badegg') |
|
1702 >>> write('badegg', 'badegg', '__init__.py', '#\\n') |
|
1703 >>> mkdir('badegg', 'badegg', 'scripts') |
|
1704 >>> write('badegg', 'badegg', 'scripts', '__init__.py', '#\\n') |
|
1705 >>> write('badegg', 'badegg', 'scripts', 'one.py', |
|
1706 ... ''' |
|
1707 ... return 1 |
|
1708 ... ''') |
|
1709 |
|
1710 >>> write('badegg', 'setup.py', |
|
1711 ... ''' |
|
1712 ... from setuptools import setup, find_packages |
|
1713 ... setup( |
|
1714 ... name='badegg', |
|
1715 ... version='1', |
|
1716 ... packages = find_packages('.'), |
|
1717 ... zip_safe=False) |
|
1718 ... ''') |
|
1719 |
|
1720 >>> print system(buildout+' setup badegg sdist'), # doctest: +ELLIPSIS |
|
1721 Running setup script 'badegg/setup.py'. |
|
1722 ... |
|
1723 |
|
1724 >>> dist = join('badegg', 'dist') |
|
1725 |
|
1726 >>> write('buildout.cfg', |
|
1727 ... ''' |
|
1728 ... [buildout] |
|
1729 ... parts = eggs bo |
|
1730 ... find-links = %(dist)s |
|
1731 ... |
|
1732 ... [eggs] |
|
1733 ... recipe = zc.recipe.egg |
|
1734 ... eggs = badegg |
|
1735 ... |
|
1736 ... [bo] |
|
1737 ... recipe = zc.recipe.egg |
|
1738 ... eggs = zc.buildout |
|
1739 ... scripts = buildout=bo |
|
1740 ... ''' % globals()) |
|
1741 |
|
1742 >>> print system(buildout);print 'X' # doctest: +ELLIPSIS |
|
1743 Installing eggs. |
|
1744 Getting distribution for 'badegg'. |
|
1745 Got badegg 1. |
|
1746 Installing bo. |
|
1747 ... |
|
1748 SyntaxError: ...'return' outside function... |
|
1749 ... |
|
1750 SyntaxError: ...'return' outside function... |
|
1751 ... |
|
1752 |
|
1753 >>> ls('eggs') # doctest: +ELLIPSIS |
|
1754 d badegg-1-py2.4.egg |
|
1755 ... |
|
1756 |
|
1757 >>> ls('bin') |
|
1758 - bo |
|
1759 - buildout |
|
1760 """ |
|
1761 |
|
1762 def version_requirements_in_build_honored(): |
|
1763 ''' |
|
1764 |
|
1765 >>> update_extdemo() |
|
1766 >>> dest = tmpdir('sample-install') |
|
1767 >>> mkdir('include') |
|
1768 >>> write('include', 'extdemo.h', |
|
1769 ... """ |
|
1770 ... #define EXTDEMO 42 |
|
1771 ... """) |
|
1772 |
|
1773 >>> zc.buildout.easy_install.build( |
|
1774 ... 'extdemo ==1.4', dest, |
|
1775 ... {'include-dirs': os.path.join(sample_buildout, 'include')}, |
|
1776 ... links=[link_server], index=link_server+'index/', |
|
1777 ... newest=False) |
|
1778 ['/sample-install/extdemo-1.4-py2.4-linux-i686.egg'] |
|
1779 |
|
1780 ''' |
|
1781 |
|
1782 def bug_105081_Specific_egg_versions_are_ignored_when_newer_eggs_are_around(): |
|
1783 """ |
|
1784 Buildout might ignore a specific egg requirement for a recipe: |
|
1785 |
|
1786 - Have a newer version of an egg in your eggs directory |
|
1787 - Use 'recipe==olderversion' in your buildout.cfg to request an |
|
1788 older version |
|
1789 |
|
1790 Buildout will go and fetch the older version, but it will *use* |
|
1791 the newer version when installing a part with this recipe. |
|
1792 |
|
1793 >>> write('buildout.cfg', |
|
1794 ... ''' |
|
1795 ... [buildout] |
|
1796 ... parts = x |
|
1797 ... find-links = %(sample_eggs)s |
|
1798 ... |
|
1799 ... [x] |
|
1800 ... recipe = zc.recipe.egg |
|
1801 ... eggs = demo |
|
1802 ... ''' % globals()) |
|
1803 |
|
1804 >>> print system(buildout), |
|
1805 Installing x. |
|
1806 Getting distribution for 'demo'. |
|
1807 Got demo 0.4c1. |
|
1808 Getting distribution for 'demoneeded'. |
|
1809 Got demoneeded 1.2c1. |
|
1810 Generated script '/sample-buildout/bin/demo'. |
|
1811 |
|
1812 >>> print system(join('bin', 'demo')), |
|
1813 4 2 |
|
1814 |
|
1815 >>> write('buildout.cfg', |
|
1816 ... ''' |
|
1817 ... [buildout] |
|
1818 ... parts = x |
|
1819 ... find-links = %(sample_eggs)s |
|
1820 ... |
|
1821 ... [x] |
|
1822 ... recipe = zc.recipe.egg |
|
1823 ... eggs = demo ==0.1 |
|
1824 ... ''' % globals()) |
|
1825 |
|
1826 >>> print system(buildout), |
|
1827 Uninstalling x. |
|
1828 Installing x. |
|
1829 Getting distribution for 'demo==0.1'. |
|
1830 Got demo 0.1. |
|
1831 Generated script '/sample-buildout/bin/demo'. |
|
1832 |
|
1833 >>> print system(join('bin', 'demo')), |
|
1834 1 2 |
|
1835 """ |
|
1836 |
|
1837 def versions_section_ignored_for_dependency_in_favor_of_site_packages(): |
|
1838 r""" |
|
1839 This is a test for a bugfix. |
|
1840 |
|
1841 The error showed itself when at least two dependencies were in a shared |
|
1842 location like site-packages, and the first one met the "versions" setting. The |
|
1843 first dependency would be added, but subsequent dependencies from the same |
|
1844 location (e.g., site-packages) would use the version of the package found in |
|
1845 the shared location, ignoring the version setting. |
|
1846 |
|
1847 We begin with a Python that has demoneeded version 1.1 installed and a |
|
1848 demo version 0.3, all in a site-packages-like shared directory. We need |
|
1849 to create this. ``eggrecipedemo.main()`` shows the number after the dot |
|
1850 (that is, ``X`` in ``1.X``), for the demo package and the demoneeded |
|
1851 package, so this demonstrates that our Python does in fact have demo |
|
1852 version 0.3 and demoneeded version 1.1. |
|
1853 |
|
1854 >>> py_path = make_py_with_system_install(make_py, sample_eggs) |
|
1855 >>> print call_py( |
|
1856 ... py_path, |
|
1857 ... "import tellmy.version; print tellmy.version.__version__"), |
|
1858 1.1 |
|
1859 |
|
1860 Now here's a setup that would expose the bug, using the |
|
1861 zc.buildout.easy_install API. |
|
1862 |
|
1863 >>> example_dest = tmpdir('example_dest') |
|
1864 >>> workingset = zc.buildout.easy_install.install( |
|
1865 ... ['tellmy.version'], example_dest, links=[sample_eggs], |
|
1866 ... executable=py_path, |
|
1867 ... index=None, |
|
1868 ... versions={'tellmy.version': '1.0'}) |
|
1869 >>> for dist in workingset: |
|
1870 ... res = str(dist) |
|
1871 ... if res.startswith('tellmy.version'): |
|
1872 ... print res |
|
1873 ... break |
|
1874 tellmy.version 1.0 |
|
1875 |
|
1876 Before the bugfix, the desired tellmy.version distribution would have |
|
1877 been blocked the one in site-packages. |
|
1878 """ |
|
1879 |
|
1880 def handle_namespace_package_in_both_site_packages_and_buildout_eggs(): |
|
1881 r""" |
|
1882 If you have the same namespace package in both site-packages and in |
|
1883 buildout, we need to be very careful that faux-Python-executables and |
|
1884 scripts generated by easy_install.sitepackage_safe_scripts correctly |
|
1885 combine the two. We show this with the local recipe that uses the |
|
1886 function, z3c.recipe.scripts. |
|
1887 |
|
1888 To demonstrate this, we will create three packages: tellmy.version 1.0, |
|
1889 tellmy.version 1.1, and tellmy.fortune 1.0. tellmy.version 1.1 is installed. |
|
1890 |
|
1891 >>> py_path = make_py_with_system_install(make_py, sample_eggs) |
|
1892 >>> print call_py( |
|
1893 ... py_path, |
|
1894 ... "import tellmy.version; print tellmy.version.__version__") |
|
1895 1.1 |
|
1896 <BLANKLINE> |
|
1897 |
|
1898 Now we will create a buildout that creates a script and a faux-Python script. |
|
1899 We want to see that both can successfully import the specified versions of |
|
1900 tellmy.version and tellmy.fortune. |
|
1901 |
|
1902 >>> write('buildout.cfg', |
|
1903 ... ''' |
|
1904 ... [buildout] |
|
1905 ... parts = eggs |
|
1906 ... find-links = %(link_server)s |
|
1907 ... |
|
1908 ... [primed_python] |
|
1909 ... executable = %(py_path)s |
|
1910 ... |
|
1911 ... [eggs] |
|
1912 ... recipe = z3c.recipe.scripts |
|
1913 ... python = primed_python |
|
1914 ... interpreter = py |
|
1915 ... include-site-packages = true |
|
1916 ... eggs = tellmy.version == 1.0 |
|
1917 ... tellmy.fortune == 1.0 |
|
1918 ... demo |
|
1919 ... script-initialization = |
|
1920 ... import tellmy.version |
|
1921 ... print tellmy.version.__version__ |
|
1922 ... import tellmy.fortune |
|
1923 ... print tellmy.fortune.__version__ |
|
1924 ... ''' % globals()) |
|
1925 |
|
1926 >>> print system(buildout) |
|
1927 Installing eggs. |
|
1928 Getting distribution for 'tellmy.version==1.0'. |
|
1929 Got tellmy.version 1.0. |
|
1930 Getting distribution for 'tellmy.fortune==1.0'. |
|
1931 Got tellmy.fortune 1.0. |
|
1932 Getting distribution for 'demo'. |
|
1933 Got demo 0.4c1. |
|
1934 Getting distribution for 'demoneeded'. |
|
1935 Got demoneeded 1.2c1. |
|
1936 Generated script '/sample-buildout/bin/demo'. |
|
1937 Generated interpreter '/sample-buildout/bin/py'. |
|
1938 <BLANKLINE> |
|
1939 |
|
1940 Finally, we are ready to see if it worked. Prior to the bug fix that |
|
1941 this tests, the results of both calls below was the following:: |
|
1942 |
|
1943 1.1 |
|
1944 Traceback (most recent call last): |
|
1945 ... |
|
1946 ImportError: No module named fortune |
|
1947 <BLANKLINE> |
|
1948 |
|
1949 In other words, we got the site-packages version of tellmy.version, and |
|
1950 we could not import tellmy.fortune at all. The following are the correct |
|
1951 results for the interpreter and for the script. |
|
1952 |
|
1953 >>> print call_py( |
|
1954 ... join('bin', 'py'), |
|
1955 ... "import tellmy.version; " + |
|
1956 ... "print tellmy.version.__version__; " + |
|
1957 ... "import tellmy.fortune; " + |
|
1958 ... "print tellmy.fortune.__version__") # doctest: +ELLIPSIS |
|
1959 1.0 |
|
1960 1.0... |
|
1961 |
|
1962 >>> print system(join('bin', 'demo')) |
|
1963 1.0 |
|
1964 1.0 |
|
1965 4 2 |
|
1966 <BLANKLINE> |
|
1967 """ |
|
1968 |
|
1969 def handle_sys_path_version_hack(): |
|
1970 r""" |
|
1971 This is a test for a bugfix. |
|
1972 |
|
1973 If you use a Python that has a different version of one of your |
|
1974 dependencies, and the new package tries to do sys.path tricks in the |
|
1975 setup.py to get a __version__, and it uses namespace packages, the older |
|
1976 package will be loaded first, making the setup version the wrong number. |
|
1977 While very arguably packages simply shouldn't do this, some do, and we |
|
1978 don't want buildout to fall over when they do. |
|
1979 |
|
1980 To demonstrate this, we will need to create a distribution that has one of |
|
1981 these unpleasant tricks, and a Python that has an older version installed. |
|
1982 |
|
1983 >>> py_path, site_packages_path = make_py() |
|
1984 >>> for version in ('1.0', '1.1'): |
|
1985 ... tmp = tempfile.mkdtemp() |
|
1986 ... try: |
|
1987 ... write(tmp, 'README.txt', '') |
|
1988 ... mkdir(tmp, 'src') |
|
1989 ... mkdir(tmp, 'src', 'tellmy') |
|
1990 ... write(tmp, 'src', 'tellmy', '__init__.py', |
|
1991 ... "__import__(" |
|
1992 ... "'pkg_resources').declare_namespace(__name__)\n") |
|
1993 ... mkdir(tmp, 'src', 'tellmy', 'version') |
|
1994 ... write(tmp, 'src', 'tellmy', 'version', |
|
1995 ... '__init__.py', '__version__=%r\n' % version) |
|
1996 ... write( |
|
1997 ... tmp, 'setup.py', |
|
1998 ... "from setuptools import setup\n" |
|
1999 ... "import sys\n" |
|
2000 ... "sys.path.insert(0, 'src')\n" |
|
2001 ... "from tellmy.version import __version__\n" |
|
2002 ... "setup(\n" |
|
2003 ... " name='tellmy.version',\n" |
|
2004 ... " package_dir = {'': 'src'},\n" |
|
2005 ... " packages = ['tellmy', 'tellmy.version'],\n" |
|
2006 ... " install_requires = ['setuptools'],\n" |
|
2007 ... " namespace_packages=['tellmy'],\n" |
|
2008 ... " zip_safe=True, version=__version__,\n" |
|
2009 ... " author='bob', url='bob', author_email='bob')\n" |
|
2010 ... ) |
|
2011 ... zc.buildout.testing.sdist(tmp, sample_eggs) |
|
2012 ... if version == '1.0': |
|
2013 ... # We install the 1.0 version in site packages the way a |
|
2014 ... # system packaging system (debs, rpms) would do it. |
|
2015 ... zc.buildout.testing.sys_install(tmp, site_packages_path) |
|
2016 ... finally: |
|
2017 ... shutil.rmtree(tmp) |
|
2018 >>> print call_py( |
|
2019 ... py_path, |
|
2020 ... "import tellmy.version; print tellmy.version.__version__") |
|
2021 1.0 |
|
2022 <BLANKLINE> |
|
2023 >>> write('buildout.cfg', |
|
2024 ... ''' |
|
2025 ... [buildout] |
|
2026 ... parts = eggs |
|
2027 ... find-links = %(sample_eggs)s |
|
2028 ... |
|
2029 ... [primed_python] |
|
2030 ... executable = %(py_path)s |
|
2031 ... |
|
2032 ... [eggs] |
|
2033 ... recipe = zc.recipe.egg:eggs |
|
2034 ... python = primed_python |
|
2035 ... eggs = tellmy.version == 1.1 |
|
2036 ... ''' % globals()) |
|
2037 |
|
2038 Before the bugfix, running this buildout would generate this error: |
|
2039 |
|
2040 Installing eggs. |
|
2041 Getting distribution for 'tellmy.version==1.1'. |
|
2042 Installing tellmy.version 1.1 |
|
2043 Caused installation of a distribution: |
|
2044 tellmy.version 1.0 |
|
2045 with a different version. |
|
2046 Got None. |
|
2047 While: |
|
2048 Installing eggs. |
|
2049 Error: There is a version conflict. |
|
2050 We already have: tellmy.version 1.0 |
|
2051 <BLANKLINE> |
|
2052 |
|
2053 You can see the copiously commented fix for this in easy_install.py (see |
|
2054 zc.buildout.easy_install.Installer._call_easy_install and particularly |
|
2055 the comment leading up to zc.buildout.easy_install._easy_install_cmd). |
|
2056 Now the install works correctly, as seen here. |
|
2057 |
|
2058 >>> print system(buildout) |
|
2059 Installing eggs. |
|
2060 Getting distribution for 'tellmy.version==1.1'. |
|
2061 Got tellmy.version 1.1. |
|
2062 <BLANKLINE> |
|
2063 |
|
2064 """ |
|
2065 |
|
2066 def isolated_include_site_packages(): |
|
2067 """ |
|
2068 |
|
2069 This is an isolated test of the include_site_packages functionality, passing |
|
2070 the argument directly to install, overriding a default. |
|
2071 |
|
2072 Our "py_path" has the "demoneeded" and "demo" packages available. We'll |
|
2073 simply be asking for "demoneeded" here. |
|
2074 |
|
2075 >>> py_path, site_packages_path = make_py() |
|
2076 >>> create_sample_sys_install(site_packages_path) |
|
2077 >>> zc.buildout.easy_install.include_site_packages(False) |
|
2078 True |
|
2079 |
|
2080 >>> example_dest = tmpdir('site-packages-example-install') |
|
2081 >>> workingset = zc.buildout.easy_install.install( |
|
2082 ... ['demoneeded'], example_dest, links=[], executable=py_path, |
|
2083 ... index=None, include_site_packages=True) |
|
2084 >>> [dist.project_name for dist in workingset] |
|
2085 ['demoneeded'] |
|
2086 |
|
2087 That worked fine. Let's try again with site packages not allowed (and |
|
2088 reversing the default). |
|
2089 |
|
2090 >>> zc.buildout.easy_install.include_site_packages(True) |
|
2091 False |
|
2092 |
|
2093 >>> zc.buildout.easy_install.clear_index_cache() |
|
2094 >>> rmdir(example_dest) |
|
2095 >>> example_dest = tmpdir('site-packages-example-install') |
|
2096 >>> workingset = zc.buildout.easy_install.install( |
|
2097 ... ['demoneeded'], example_dest, links=[], executable=py_path, |
|
2098 ... index=None, include_site_packages=False) |
|
2099 Traceback (most recent call last): |
|
2100 ... |
|
2101 MissingDistribution: Couldn't find a distribution for 'demoneeded'. |
|
2102 |
|
2103 That's a failure, as expected. |
|
2104 |
|
2105 Now we explore an important edge case. |
|
2106 |
|
2107 Some system Pythons include setuptools (and other Python packages) in their |
|
2108 site-packages (or equivalent) using a .egg-info directory. The pkg_resources |
|
2109 module (from setuptools) considers a package installed using .egg-info to be a |
|
2110 develop egg. |
|
2111 |
|
2112 zc.buildout.buildout.Buildout.bootstrap will make setuptools and zc.buildout |
|
2113 available to the buildout via the eggs directory, for normal eggs; or the |
|
2114 develop-eggs directory, for develop-eggs. |
|
2115 |
|
2116 If setuptools or zc.buildout is found in site-packages and considered by |
|
2117 pkg_resources to be a develop egg, then the bootstrap code will use a .egg-link |
|
2118 in the local develop-eggs, pointing to site-packages, in its entirety. Because |
|
2119 develop-eggs must always be available for searching for distributions, this |
|
2120 indirectly brings site-packages back into the search path for distributions. |
|
2121 |
|
2122 Because of this, we have to take special care that we still exclude |
|
2123 site-packages even in this case. See the comments about site packages in the |
|
2124 Installer._satisfied and Installer._obtain methods for the implementation |
|
2125 (as of this writing). |
|
2126 |
|
2127 In this demonstration, we insert a link to the "demoneeded" distribution |
|
2128 in our develop-eggs, which would bring the package back in, except for |
|
2129 the special care we have taken to exclude it. |
|
2130 |
|
2131 >>> zc.buildout.easy_install.clear_index_cache() |
|
2132 >>> rmdir(example_dest) |
|
2133 >>> example_dest = tmpdir('site-packages-example-install') |
|
2134 >>> mkdir(example_dest, 'develop-eggs') |
|
2135 >>> write(example_dest, 'develop-eggs', 'demoneeded.egg-link', |
|
2136 ... site_packages_path) |
|
2137 >>> workingset = zc.buildout.easy_install.install( |
|
2138 ... ['demoneeded'], example_dest, links=[], |
|
2139 ... path=[join(example_dest, 'develop-eggs')], |
|
2140 ... executable=py_path, |
|
2141 ... index=None, include_site_packages=False) |
|
2142 Traceback (most recent call last): |
|
2143 ... |
|
2144 MissingDistribution: Couldn't find a distribution for 'demoneeded'. |
|
2145 |
|
2146 The MissingDistribution error shows that buildout correctly excluded the |
|
2147 "site-packages" source even though it was indirectly included in the path |
|
2148 via a .egg-link file. |
|
2149 |
|
2150 """ |
|
2151 |
|
2152 def include_site_packages_bug_623590(): |
|
2153 """ |
|
2154 As mentioned in isolated_include_site_packages, some system Pythons |
|
2155 include various Python packages in their site-packages (or equivalent) |
|
2156 using a .egg-info directory. The pkg_resources module (from setuptools) |
|
2157 considers a package installed using .egg-info to be a develop egg |
|
2158 |
|
2159 We generally prefer develop eggs when we are selecting dependencies, because |
|
2160 we expect them to be eggs that buildout has been told to develop. However, |
|
2161 we should not consider these site-packages eggs as develop eggs--they should |
|
2162 not have automatic precedence over eggs available elsewhere. |
|
2163 |
|
2164 We have specific code to handle this case, as identified in bug 623590. |
|
2165 See zc.buildout.easy_install.Installer._satisfied, as of this writing, |
|
2166 for the pertinent code. Here's the test for the bugfix. |
|
2167 |
|
2168 >>> py_path, site_packages_path = make_py() |
|
2169 >>> create_sample_sys_install(site_packages_path) |
|
2170 >>> zc.buildout.easy_install.include_site_packages(False) |
|
2171 True |
|
2172 |
|
2173 >>> example_dest = tmpdir('site-packages-example-install') |
|
2174 >>> workingset = zc.buildout.easy_install.install( |
|
2175 ... ['demo'], example_dest, links=[sample_eggs], executable=py_path, |
|
2176 ... index=None, include_site_packages=True, prefer_final=False) |
|
2177 >>> [(dist.project_name, dist.version) for dist in workingset] |
|
2178 [('demo', '0.4c1'), ('demoneeded', '1.2c1')] |
|
2179 """ |
|
2180 |
|
2181 def allowed_eggs_from_site_packages(): |
|
2182 """ |
|
2183 Sometimes you need or want to control what eggs from site-packages are used. |
|
2184 The allowed-eggs-from-site-packages option allows you to specify a whitelist of |
|
2185 project names that may be included from site-packages. You can use globs to |
|
2186 specify the value. It defaults to a single value of '*', indicating that any |
|
2187 package may come from site-packages. |
|
2188 |
|
2189 This option interacts with include-site-packages in the following ways. |
|
2190 |
|
2191 If include-site-packages is true, then allowed-eggs-from-site-packages filters |
|
2192 what eggs from site-packages may be chosen. If allowed-eggs-from-site-packages |
|
2193 is an empty list, then no eggs from site-packages are chosen, but site-packages |
|
2194 will still be included at the end of path lists. |
|
2195 |
|
2196 If include-site-packages is false, allowed-eggs-from-site-packages is |
|
2197 irrelevant. |
|
2198 |
|
2199 This test shows the interaction with the zc.buildout.easy_install API. Another |
|
2200 test below (allow_site_package_eggs_option) shows using it with a buildout.cfg. |
|
2201 |
|
2202 Our "py_path" has the "demoneeded" and "demo" packages available. We'll |
|
2203 simply be asking for "demoneeded" here. |
|
2204 |
|
2205 >>> py_path, site_packages_path = make_py() |
|
2206 >>> create_sample_sys_install(site_packages_path) |
|
2207 |
|
2208 >>> example_dest = tmpdir('site-packages-example-install') |
|
2209 >>> workingset = zc.buildout.easy_install.install( |
|
2210 ... ['demoneeded'], example_dest, links=[], executable=py_path, |
|
2211 ... index=None, |
|
2212 ... allowed_eggs_from_site_packages=['demoneeded', 'other']) |
|
2213 >>> [dist.project_name for dist in workingset] |
|
2214 ['demoneeded'] |
|
2215 |
|
2216 That worked fine. It would work fine for a glob too. |
|
2217 |
|
2218 >>> zc.buildout.easy_install.clear_index_cache() |
|
2219 >>> rmdir(example_dest) |
|
2220 >>> example_dest = tmpdir('site-packages-example-install') |
|
2221 >>> workingset = zc.buildout.easy_install.install( |
|
2222 ... ['demoneeded'], example_dest, links=[], executable=py_path, |
|
2223 ... index=None, |
|
2224 ... allowed_eggs_from_site_packages=['?emon*', 'other']) |
|
2225 >>> [dist.project_name for dist in workingset] |
|
2226 ['demoneeded'] |
|
2227 |
|
2228 But now let's try again with 'demoneeded' not allowed. |
|
2229 |
|
2230 >>> zc.buildout.easy_install.clear_index_cache() |
|
2231 >>> rmdir(example_dest) |
|
2232 >>> example_dest = tmpdir('site-packages-example-install') |
|
2233 >>> workingset = zc.buildout.easy_install.install( |
|
2234 ... ['demoneeded'], example_dest, links=[], executable=py_path, |
|
2235 ... index=None, |
|
2236 ... allowed_eggs_from_site_packages=['demo']) |
|
2237 Traceback (most recent call last): |
|
2238 ... |
|
2239 MissingDistribution: Couldn't find a distribution for 'demoneeded'. |
|
2240 |
|
2241 Here's the same, but with an empty list. |
|
2242 |
|
2243 >>> zc.buildout.easy_install.clear_index_cache() |
|
2244 >>> rmdir(example_dest) |
|
2245 >>> example_dest = tmpdir('site-packages-example-install') |
|
2246 >>> workingset = zc.buildout.easy_install.install( |
|
2247 ... ['demoneeded'], example_dest, links=[], executable=py_path, |
|
2248 ... index=None, |
|
2249 ... allowed_eggs_from_site_packages=[]) |
|
2250 Traceback (most recent call last): |
|
2251 ... |
|
2252 MissingDistribution: Couldn't find a distribution for 'demoneeded'. |
|
2253 |
|
2254 Of course, this doesn't stop us from getting a package from elsewhere. Here, |
|
2255 we add a link server. |
|
2256 |
|
2257 >>> zc.buildout.easy_install.clear_index_cache() |
|
2258 >>> rmdir(example_dest) |
|
2259 >>> example_dest = tmpdir('site-packages-example-install') |
|
2260 >>> workingset = zc.buildout.easy_install.install( |
|
2261 ... ['demoneeded'], example_dest, executable=py_path, |
|
2262 ... links=[link_server], index=link_server+'index/', |
|
2263 ... allowed_eggs_from_site_packages=['other']) |
|
2264 >>> [dist.project_name for dist in workingset] |
|
2265 ['demoneeded'] |
|
2266 >>> [dist.location for dist in workingset] |
|
2267 ['/site-packages-example-install/demoneeded-1.1-py2.6.egg'] |
|
2268 |
|
2269 Finally, here's an example of an interaction: we say that it is OK to |
|
2270 allow the "demoneeded" egg to come from site-packages, but we don't |
|
2271 include-site-packages. |
|
2272 |
|
2273 >>> zc.buildout.easy_install.clear_index_cache() |
|
2274 >>> rmdir(example_dest) |
|
2275 >>> example_dest = tmpdir('site-packages-example-install') |
|
2276 >>> workingset = zc.buildout.easy_install.install( |
|
2277 ... ['demoneeded'], example_dest, links=[], executable=py_path, |
|
2278 ... index=None, include_site_packages=False, |
|
2279 ... allowed_eggs_from_site_packages=['demoneeded']) |
|
2280 Traceback (most recent call last): |
|
2281 ... |
|
2282 MissingDistribution: Couldn't find a distribution for 'demoneeded'. |
|
2283 |
|
2284 """ |
|
2285 |
|
2286 def allowed_eggs_from_site_packages_dependencies_bugfix(): |
|
2287 """ |
|
2288 If you specify that a package with a dependency may come from site-packages, |
|
2289 that doesn't mean that the dependency may come from site-packages. This |
|
2290 is a test for a bug fix to verify that this is true. |
|
2291 |
|
2292 >>> py_path, site_packages_path = make_py() |
|
2293 >>> create_sample_sys_install(site_packages_path) |
|
2294 >>> interpreter_dir = tmpdir('interpreter') |
|
2295 >>> interpreter_parts_dir = os.path.join( |
|
2296 ... interpreter_dir, 'parts', 'interpreter') |
|
2297 >>> interpreter_bin_dir = os.path.join(interpreter_dir, 'bin') |
|
2298 >>> mkdir(interpreter_bin_dir) |
|
2299 >>> mkdir(interpreter_dir, 'eggs') |
|
2300 >>> mkdir(interpreter_dir, 'parts') |
|
2301 >>> mkdir(interpreter_parts_dir) |
|
2302 >>> ws = zc.buildout.easy_install.install( |
|
2303 ... ['demo'], join(interpreter_dir, 'eggs'), executable=py_path, |
|
2304 ... links=[link_server], index=link_server+'index/', |
|
2305 ... allowed_eggs_from_site_packages=['demo']) |
|
2306 >>> [dist.project_name for dist in ws] |
|
2307 ['demo', 'demoneeded'] |
|
2308 >>> from pprint import pprint |
|
2309 >>> pprint([dist.location for dist in ws]) |
|
2310 ['/executable_buildout/site-packages', |
|
2311 '/interpreter/eggs/demoneeded-1.1-pyN.N.egg'] |
|
2312 |
|
2313 """ |
|
2314 |
|
2315 def allowed_eggs_from_site_packages_bug_592524(): |
|
2316 """ |
|
2317 When we use allowed_eggs_from_site_packages, we need to make sure that the |
|
2318 site-packages paths are not inserted with the normal egg paths. They already |
|
2319 included at the end, and including them along with the normal egg paths will |
|
2320 possibly mask subsequent egg paths. This affects interpreters and scripts |
|
2321 generated by sitepackage_safe_scripts. |
|
2322 |
|
2323 Our "py_path" has the "demoneeded" and "demo" packages available. |
|
2324 |
|
2325 >>> py_path, site_packages_path = make_py() |
|
2326 >>> create_sample_sys_install(site_packages_path) |
|
2327 >>> interpreter_dir = tmpdir('interpreter') |
|
2328 >>> interpreter_parts_dir = os.path.join( |
|
2329 ... interpreter_dir, 'parts', 'interpreter') |
|
2330 >>> interpreter_bin_dir = os.path.join(interpreter_dir, 'bin') |
|
2331 >>> mkdir(interpreter_bin_dir) |
|
2332 >>> mkdir(interpreter_dir, 'eggs') |
|
2333 >>> mkdir(interpreter_dir, 'parts') |
|
2334 >>> mkdir(interpreter_parts_dir) |
|
2335 >>> ws = zc.buildout.easy_install.install( |
|
2336 ... ['demo', 'other'], join(interpreter_dir, 'eggs'), executable=py_path, |
|
2337 ... links=[link_server], index=link_server+'index/', |
|
2338 ... allowed_eggs_from_site_packages=['demo']) |
|
2339 >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts( |
|
2340 ... interpreter_bin_dir, ws, py_path, interpreter_parts_dir, |
|
2341 ... interpreter='py', include_site_packages=True) |
|
2342 |
|
2343 Now we will look at the paths in the site.py we generated. Notice that the |
|
2344 site-packages are at the end. They were not before this bugfix. |
|
2345 |
|
2346 >>> test = 'import pprint, sys; pprint.pprint(sys.path[-4:])' |
|
2347 >>> print call_py(join(interpreter_bin_dir, 'py'), test) |
|
2348 ['/interpreter/eggs/other-1.0-pyN.N.egg', |
|
2349 '/interpreter/eggs/demoneeded-1.1-pyN.N.egg', |
|
2350 '/executable_buildout/eggs/setuptools-0.0-pyN.N.egg', |
|
2351 '/executable_buildout/site-packages'] |
|
2352 <BLANKLINE> |
|
2353 """ |
|
2354 |
|
2355 def subprocesses_have_same_environment_by_default(): |
|
2356 """ |
|
2357 The scripts generated by sitepackage_safe_scripts set the PYTHONPATH so that, |
|
2358 if the environment is maintained (the default behavior), subprocesses get |
|
2359 the same Python packages. |
|
2360 |
|
2361 First, we set up a script and an interpreter. |
|
2362 |
|
2363 >>> interpreter_dir = tmpdir('interpreter') |
|
2364 >>> interpreter_parts_dir = os.path.join( |
|
2365 ... interpreter_dir, 'parts', 'interpreter') |
|
2366 >>> interpreter_bin_dir = os.path.join(interpreter_dir, 'bin') |
|
2367 >>> mkdir(interpreter_bin_dir) |
|
2368 >>> mkdir(interpreter_dir, 'eggs') |
|
2369 >>> mkdir(interpreter_dir, 'parts') |
|
2370 >>> mkdir(interpreter_parts_dir) |
|
2371 >>> ws = zc.buildout.easy_install.install( |
|
2372 ... ['demo'], join(interpreter_dir, 'eggs'), links=[link_server], |
|
2373 ... index=link_server+'index/') |
|
2374 >>> test = ( |
|
2375 ... "import subprocess, sys; subprocess.call(" |
|
2376 ... "[sys.executable, '-c', " |
|
2377 ... "'import eggrecipedemo; print eggrecipedemo.x'])") |
|
2378 >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts( |
|
2379 ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, |
|
2380 ... reqs=['demo'], interpreter='py', |
|
2381 ... script_initialization=test + '; sys.exit(0)') |
|
2382 |
|
2383 This works for the script. |
|
2384 |
|
2385 >>> print system(join(interpreter_bin_dir, 'demo')) |
|
2386 3 |
|
2387 <BLANKLINE> |
|
2388 |
|
2389 This also works for the generated interpreter. |
|
2390 |
|
2391 >>> print call_py(join(interpreter_bin_dir, 'py'), test) |
|
2392 3 |
|
2393 <BLANKLINE> |
|
2394 |
|
2395 If you have a PYTHONPATH in your environment, it will be honored, after |
|
2396 the buildout-generated path. |
|
2397 |
|
2398 >>> original_pythonpath = os.environ.get('PYTHONPATH') |
|
2399 >>> os.environ['PYTHONPATH'] = 'foo' |
|
2400 >>> test = ( |
|
2401 ... "import subprocess, sys; subprocess.call(" |
|
2402 ... "[sys.executable, '-c', " |
|
2403 ... "'import sys, pprint; pprint.pprint(sys.path)'])") |
|
2404 >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts( |
|
2405 ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, |
|
2406 ... reqs=['demo'], interpreter='py', |
|
2407 ... script_initialization=test + '; sys.exit(0)') |
|
2408 |
|
2409 This works for the script. As you can see, /sample_buildout/foo is included |
|
2410 right after the "parts" directory that contains site.py and sitecustomize.py. |
|
2411 You can also see, actually more easily than in the other example, that we |
|
2412 have the desired eggs available. |
|
2413 |
|
2414 >>> print system(join(interpreter_bin_dir, 'demo')), # doctest: +ELLIPSIS |
|
2415 ['', |
|
2416 '/interpreter/parts/interpreter', |
|
2417 '/sample-buildout/foo', |
|
2418 ... |
|
2419 '/interpreter/eggs/demo-0.3-pyN.N.egg', |
|
2420 '/interpreter/eggs/demoneeded-1.1-pyN.N.egg'] |
|
2421 |
|
2422 This also works for the generated interpreter, with identical results. |
|
2423 |
|
2424 >>> print call_py(join(interpreter_bin_dir, 'py'), test), |
|
2425 ... # doctest: +ELLIPSIS |
|
2426 ['', |
|
2427 '/interpreter/parts/interpreter', |
|
2428 '/sample-buildout/foo', |
|
2429 ... |
|
2430 '/interpreter/eggs/demo-0.3-pyN.N.egg', |
|
2431 '/interpreter/eggs/demoneeded-1.1-pyN.N.egg'] |
|
2432 |
|
2433 >>> # Cleanup |
|
2434 >>> if original_pythonpath: |
|
2435 ... os.environ['PYTHONPATH'] = original_pythonpath |
|
2436 ... else: |
|
2437 ... del os.environ['PYTHONPATH'] |
|
2438 ... |
|
2439 |
|
2440 """ |
|
2441 |
|
2442 def bootstrap_makes_buildout_that_works_with_system_python(): |
|
2443 r""" |
|
2444 In order to work smoothly with a system Python, bootstrapping creates |
|
2445 the buildout script with |
|
2446 zc.buildout.easy_install.sitepackage_safe_scripts. If it did not, a |
|
2447 variety of problems might happen. For instance, if another version of |
|
2448 buildout or setuptools is installed in the site-packages than is |
|
2449 desired, it may cause a problem. |
|
2450 |
|
2451 A problem actually experienced in the field is when |
|
2452 a recipe wants a different version of a dependency that is installed in |
|
2453 site-packages. We will create a similar situation, and show that it is now |
|
2454 handled. |
|
2455 |
|
2456 First let's write a dummy recipe. |
|
2457 |
|
2458 >>> mkdir(sample_buildout, 'recipes') |
|
2459 >>> write(sample_buildout, 'recipes', 'dummy.py', |
|
2460 ... ''' |
|
2461 ... import logging, os, zc.buildout |
|
2462 ... class Dummy: |
|
2463 ... def __init__(self, buildout, name, options): |
|
2464 ... pass |
|
2465 ... def install(self): |
|
2466 ... return () |
|
2467 ... def update(self): |
|
2468 ... pass |
|
2469 ... ''') |
|
2470 >>> write(sample_buildout, 'recipes', 'setup.py', |
|
2471 ... ''' |
|
2472 ... from setuptools import setup |
|
2473 ... |
|
2474 ... setup( |
|
2475 ... name = "recipes", |
|
2476 ... entry_points = {'zc.buildout': ['dummy = dummy:Dummy']}, |
|
2477 ... install_requires = 'demoneeded==1.2c1', |
|
2478 ... ) |
|
2479 ... ''') |
|
2480 >>> write(sample_buildout, 'recipes', 'README.txt', " ") |
|
2481 |
|
2482 Now we'll try to use it with a Python that has a different version of |
|
2483 demoneeded installed. |
|
2484 |
|
2485 >>> py_path, site_packages_path = make_py() |
|
2486 >>> create_sample_sys_install(site_packages_path) |
|
2487 >>> rmdir('develop-eggs') |
|
2488 >>> from zc.buildout.testing import make_buildout |
|
2489 >>> make_buildout(executable=py_path) |
|
2490 >>> write(sample_buildout, 'buildout.cfg', |
|
2491 ... ''' |
|
2492 ... [buildout] |
|
2493 ... develop = recipes |
|
2494 ... parts = dummy |
|
2495 ... find-links = %(link_server)s |
|
2496 ... executable = %(py_path)s |
|
2497 ... |
|
2498 ... [dummy] |
|
2499 ... recipe = recipes:dummy |
|
2500 ... ''' % globals()) |
|
2501 |
|
2502 Now we actually run the buildout. Before the change, we got the following |
|
2503 error: |
|
2504 |
|
2505 Develop: '/sample-buildout/recipes' |
|
2506 While: |
|
2507 Installing. |
|
2508 Getting section dummy. |
|
2509 Initializing section dummy. |
|
2510 Installing recipe recipes. |
|
2511 Error: There is a version conflict. |
|
2512 We already have: demoneeded 1.1 |
|
2513 but recipes 0.0.0 requires 'demoneeded==1.2c1'. |
|
2514 |
|
2515 Now, it is handled smoothly. |
|
2516 |
|
2517 >>> print system(buildout) |
|
2518 Develop: '/sample-buildout/recipes' |
|
2519 Getting distribution for 'demoneeded==1.2c1'. |
|
2520 Got demoneeded 1.2c1. |
|
2521 Installing dummy. |
|
2522 <BLANKLINE> |
|
2523 |
|
2524 Here's the same story with a namespace package, which has some additional |
|
2525 complications behind the scenes. First, a recipe, in the "tellmy" namespace. |
|
2526 |
|
2527 >>> mkdir(sample_buildout, 'ns') |
|
2528 >>> mkdir(sample_buildout, 'ns', 'tellmy') |
|
2529 >>> write(sample_buildout, 'ns', 'tellmy', '__init__.py', |
|
2530 ... "__import__('pkg_resources').declare_namespace(__name__)\n") |
|
2531 >>> mkdir(sample_buildout, 'ns', 'tellmy', 'recipes') |
|
2532 >>> write(sample_buildout, 'ns', 'tellmy', 'recipes', '__init__.py', ' ') |
|
2533 >>> write(sample_buildout, 'ns', 'tellmy', 'recipes', 'dummy.py', |
|
2534 ... ''' |
|
2535 ... import logging, os, zc.buildout |
|
2536 ... class Dummy: |
|
2537 ... def __init__(self, buildout, name, options): |
|
2538 ... pass |
|
2539 ... def install(self): |
|
2540 ... return () |
|
2541 ... def update(self): |
|
2542 ... pass |
|
2543 ... ''') |
|
2544 >>> write(sample_buildout, 'ns', 'setup.py', |
|
2545 ... ''' |
|
2546 ... from setuptools import setup |
|
2547 ... setup( |
|
2548 ... name="tellmy.recipes", |
|
2549 ... packages=['tellmy', 'tellmy.recipes'], |
|
2550 ... install_requires=['setuptools'], |
|
2551 ... namespace_packages=['tellmy'], |
|
2552 ... entry_points = {'zc.buildout': |
|
2553 ... ['dummy = tellmy.recipes.dummy:Dummy']}, |
|
2554 ... ) |
|
2555 ... ''') |
|
2556 |
|
2557 Now, a buildout that uses it. |
|
2558 |
|
2559 >>> create_sample_namespace_eggs(sample_eggs, site_packages_path) |
|
2560 >>> rmdir('develop-eggs') |
|
2561 >>> from zc.buildout.testing import make_buildout |
|
2562 >>> make_buildout(executable=py_path) |
|
2563 >>> write(sample_buildout, 'buildout.cfg', |
|
2564 ... ''' |
|
2565 ... [buildout] |
|
2566 ... develop = ns |
|
2567 ... recipes |
|
2568 ... parts = dummy |
|
2569 ... find-links = %(link_server)s |
|
2570 ... executable = %(py_path)s |
|
2571 ... |
|
2572 ... [dummy] |
|
2573 ... recipe = tellmy.recipes:dummy |
|
2574 ... ''' % globals()) |
|
2575 |
|
2576 Now we actually run the buildout. |
|
2577 |
|
2578 >>> print system(buildout) |
|
2579 Develop: '/sample-buildout/ns' |
|
2580 Develop: '/sample-buildout/recipes' |
|
2581 Uninstalling dummy. |
|
2582 Installing dummy. |
|
2583 <BLANKLINE> |
|
2584 |
|
2585 """ |
|
2586 |
|
2587 if sys.version_info > (2, 4): |
|
2588 def test_exit_codes(): |
|
2589 """ |
|
2590 >>> import subprocess |
|
2591 >>> def call(s): |
|
2592 ... p = subprocess.Popen(s, stdin=subprocess.PIPE, |
|
2593 ... stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
|
2594 ... p.stdin.close() |
|
2595 ... print p.stdout.read() |
|
2596 ... print 'Exit:', bool(p.wait()) |
|
2597 |
|
2598 >>> call(buildout) |
|
2599 <BLANKLINE> |
|
2600 Exit: False |
|
2601 |
|
2602 >>> write('buildout.cfg', |
|
2603 ... ''' |
|
2604 ... [buildout] |
|
2605 ... parts = x |
|
2606 ... ''') |
|
2607 |
|
2608 >>> call(buildout) # doctest: +NORMALIZE_WHITESPACE |
|
2609 While: |
|
2610 Installing. |
|
2611 Getting section x. |
|
2612 Error: The referenced section, 'x', was not defined. |
|
2613 <BLANKLINE> |
|
2614 Exit: True |
|
2615 |
|
2616 >>> write('setup.py', |
|
2617 ... ''' |
|
2618 ... from setuptools import setup |
|
2619 ... setup(name='zc.buildout.testexit', entry_points={ |
|
2620 ... 'zc.buildout': ['default = testexitrecipe:x']}) |
|
2621 ... ''') |
|
2622 |
|
2623 >>> write('testexitrecipe.py', |
|
2624 ... ''' |
|
2625 ... x y |
|
2626 ... ''') |
|
2627 |
|
2628 >>> write('buildout.cfg', |
|
2629 ... ''' |
|
2630 ... [buildout] |
|
2631 ... parts = x |
|
2632 ... develop = . |
|
2633 ... |
|
2634 ... [x] |
|
2635 ... recipe = zc.buildout.testexit |
|
2636 ... ''') |
|
2637 |
|
2638 >>> call(buildout) # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS |
|
2639 Develop: '/sample-buildout/.' |
|
2640 While: |
|
2641 Installing. |
|
2642 Getting section x. |
|
2643 Initializing section x. |
|
2644 Loading zc.buildout recipe entry zc.buildout.testexit:default. |
|
2645 <BLANKLINE> |
|
2646 An internal error occurred due to a bug in either zc.buildout or in a |
|
2647 recipe being used: |
|
2648 Traceback (most recent call last): |
|
2649 ... |
|
2650 x y |
|
2651 ^ |
|
2652 SyntaxError: invalid syntax |
|
2653 <BLANKLINE> |
|
2654 Exit: True |
|
2655 """ |
|
2656 |
|
2657 def bug_59270_recipes_always_start_in_buildout_dir(): |
|
2658 """ |
|
2659 Recipes can rely on running from buildout directory |
|
2660 |
|
2661 >>> mkdir('bad_start') |
|
2662 >>> write('bad_recipe.py', |
|
2663 ... ''' |
|
2664 ... import os |
|
2665 ... class Bad: |
|
2666 ... def __init__(self, *_): |
|
2667 ... print os.getcwd() |
|
2668 ... def install(self): |
|
2669 ... print os.getcwd() |
|
2670 ... os.chdir('bad_start') |
|
2671 ... print os.getcwd() |
|
2672 ... return () |
|
2673 ... ''') |
|
2674 |
|
2675 >>> write('setup.py', |
|
2676 ... ''' |
|
2677 ... from setuptools import setup |
|
2678 ... setup(name='bad.test', |
|
2679 ... entry_points={'zc.buildout': ['default=bad_recipe:Bad']},) |
|
2680 ... ''') |
|
2681 |
|
2682 >>> write('buildout.cfg', |
|
2683 ... ''' |
|
2684 ... [buildout] |
|
2685 ... develop = . |
|
2686 ... parts = b1 b2 |
|
2687 ... [b1] |
|
2688 ... recipe = bad.test |
|
2689 ... [b2] |
|
2690 ... recipe = bad.test |
|
2691 ... ''') |
|
2692 |
|
2693 >>> os.chdir('bad_start') |
|
2694 >>> print system(join(sample_buildout, 'bin', 'buildout') |
|
2695 ... +' -c '+join(sample_buildout, 'buildout.cfg')), |
|
2696 Develop: '/sample-buildout/.' |
|
2697 /sample-buildout |
|
2698 /sample-buildout |
|
2699 Installing b1. |
|
2700 /sample-buildout |
|
2701 /sample-buildout/bad_start |
|
2702 Installing b2. |
|
2703 /sample-buildout |
|
2704 /sample-buildout/bad_start |
|
2705 |
|
2706 """ |
|
2707 |
|
2708 def bug_61890_file_urls_dont_seem_to_work_in_find_dash_links(): |
|
2709 """ |
|
2710 |
|
2711 This bug arises from the fact that setuptools is overly restrictive |
|
2712 about file urls, requiring that file urls pointing at directories |
|
2713 must end in a slash. |
|
2714 |
|
2715 >>> dest = tmpdir('sample-install') |
|
2716 >>> import zc.buildout.easy_install |
|
2717 >>> sample_eggs = sample_eggs.replace(os.path.sep, '/') |
|
2718 >>> ws = zc.buildout.easy_install.install( |
|
2719 ... ['demo==0.2'], dest, |
|
2720 ... links=['file://'+sample_eggs], index=link_server+'index/') |
|
2721 |
|
2722 |
|
2723 >>> for dist in ws: |
|
2724 ... print dist |
|
2725 demo 0.2 |
|
2726 demoneeded 1.1 |
|
2727 |
|
2728 >>> ls(dest) |
|
2729 - demo-0.2-py2.4.egg |
|
2730 - demoneeded-1.1-py2.4.egg |
|
2731 |
|
2732 """ |
|
2733 |
|
2734 def bug_75607_buildout_should_not_run_if_it_creates_an_empty_buildout_cfg(): |
|
2735 """ |
|
2736 >>> remove('buildout.cfg') |
|
2737 >>> print system(buildout), |
|
2738 While: |
|
2739 Initializing. |
|
2740 Error: Couldn't open /sample-buildout/buildout.cfg |
|
2741 |
|
2742 |
|
2743 |
|
2744 """ |
|
2745 |
|
2746 def dealing_with_extremely_insane_dependencies(): |
|
2747 r""" |
|
2748 |
|
2749 There was a problem with analysis of dependencies taking a long |
|
2750 time, in part because the analysis would get repeated every time a |
|
2751 package was encountered in a dependency list. Now, we don't do |
|
2752 the analysis any more: |
|
2753 |
|
2754 >>> import os |
|
2755 >>> for i in range(5): |
|
2756 ... p = 'pack%s' % i |
|
2757 ... deps = [('pack%s' % j) for j in range(5) if j is not i] |
|
2758 ... if i == 4: |
|
2759 ... deps.append('pack5') |
|
2760 ... mkdir(p) |
|
2761 ... write(p, 'setup.py', |
|
2762 ... 'from setuptools import setup\n' |
|
2763 ... 'setup(name=%r, install_requires=%r,\n' |
|
2764 ... ' url="u", author="a", author_email="e")\n' |
|
2765 ... % (p, deps)) |
|
2766 |
|
2767 >>> write('buildout.cfg', |
|
2768 ... ''' |
|
2769 ... [buildout] |
|
2770 ... develop = pack0 pack1 pack2 pack3 pack4 |
|
2771 ... parts = pack1 |
|
2772 ... |
|
2773 ... [pack1] |
|
2774 ... recipe = zc.recipe.egg:eggs |
|
2775 ... eggs = pack0 |
|
2776 ... ''') |
|
2777 |
|
2778 >>> print system(buildout), |
|
2779 Develop: '/sample-buildout/pack0' |
|
2780 Develop: '/sample-buildout/pack1' |
|
2781 Develop: '/sample-buildout/pack2' |
|
2782 Develop: '/sample-buildout/pack3' |
|
2783 Develop: '/sample-buildout/pack4' |
|
2784 Installing pack1. |
|
2785 Couldn't find index page for 'pack5' (maybe misspelled?) |
|
2786 Getting distribution for 'pack5'. |
|
2787 While: |
|
2788 Installing pack1. |
|
2789 Getting distribution for 'pack5'. |
|
2790 Error: Couldn't find a distribution for 'pack5'. |
|
2791 |
|
2792 However, if we run in verbose mode, we can see why packages were included: |
|
2793 |
|
2794 >>> print system(buildout+' -v'), # doctest: +ELLIPSIS |
|
2795 Installing 'zc.buildout', 'setuptools'. |
|
2796 We have a develop egg: zc.buildout 1.0.0 |
|
2797 We have the best distribution that satisfies 'setuptools'. |
|
2798 Picked: setuptools = 0.6 |
|
2799 Develop: '/sample-buildout/pack0' |
|
2800 Develop: '/sample-buildout/pack1' |
|
2801 Develop: '/sample-buildout/pack2' |
|
2802 Develop: '/sample-buildout/pack3' |
|
2803 Develop: '/sample-buildout/pack4' |
|
2804 ...Installing pack1. |
|
2805 Installing 'pack0'. |
|
2806 We have a develop egg: pack0 0.0.0 |
|
2807 Getting required 'pack4' |
|
2808 required by pack0 0.0.0. |
|
2809 We have a develop egg: pack4 0.0.0 |
|
2810 Getting required 'pack3' |
|
2811 required by pack0 0.0.0. |
|
2812 required by pack4 0.0.0. |
|
2813 We have a develop egg: pack3 0.0.0 |
|
2814 Getting required 'pack2' |
|
2815 required by pack0 0.0.0. |
|
2816 required by pack3 0.0.0. |
|
2817 required by pack4 0.0.0. |
|
2818 We have a develop egg: pack2 0.0.0 |
|
2819 Getting required 'pack1' |
|
2820 required by pack0 0.0.0. |
|
2821 required by pack2 0.0.0. |
|
2822 required by pack3 0.0.0. |
|
2823 required by pack4 0.0.0. |
|
2824 We have a develop egg: pack1 0.0.0 |
|
2825 Getting required 'pack5' |
|
2826 required by pack4 0.0.0. |
|
2827 We have no distributions for pack5 that satisfies 'pack5'. |
|
2828 Couldn't find index page for 'pack5' (maybe misspelled?) |
|
2829 Getting distribution for 'pack5'. |
|
2830 While: |
|
2831 Installing pack1. |
|
2832 Getting distribution for 'pack5'. |
|
2833 Error: Couldn't find a distribution for 'pack5'. |
|
2834 """ |
|
2835 |
|
2836 def read_find_links_to_load_extensions(): |
|
2837 """ |
|
2838 We'll create a wacky buildout extension that is just another name for http: |
|
2839 |
|
2840 >>> src = tmpdir('src') |
|
2841 >>> write(src, 'wacky_handler.py', |
|
2842 ... ''' |
|
2843 ... import urllib2 |
|
2844 ... class Wacky(urllib2.HTTPHandler): |
|
2845 ... wacky_open = urllib2.HTTPHandler.http_open |
|
2846 ... def install(buildout=None): |
|
2847 ... urllib2.install_opener(urllib2.build_opener(Wacky)) |
|
2848 ... ''') |
|
2849 >>> write(src, 'setup.py', |
|
2850 ... ''' |
|
2851 ... from setuptools import setup |
|
2852 ... setup(name='wackyextension', version='1', |
|
2853 ... py_modules=['wacky_handler'], |
|
2854 ... entry_points = {'zc.buildout.extension': |
|
2855 ... ['default = wacky_handler:install'] |
|
2856 ... }, |
|
2857 ... ) |
|
2858 ... ''') |
|
2859 >>> print system(buildout+' setup '+src+' bdist_egg'), |
|
2860 ... # doctest: +ELLIPSIS |
|
2861 Running setup ... |
|
2862 creating 'dist/wackyextension-1-... |
|
2863 |
|
2864 Now we'll create a buildout that uses this extension to load other packages: |
|
2865 |
|
2866 >>> wacky_server = link_server.replace('http', 'wacky') |
|
2867 >>> dist = 'file://' + join(src, 'dist').replace(os.path.sep, '/') |
|
2868 >>> write('buildout.cfg', |
|
2869 ... ''' |
|
2870 ... [buildout] |
|
2871 ... parts = demo |
|
2872 ... extensions = wackyextension |
|
2873 ... find-links = %(wacky_server)s/demoneeded-1.0.zip |
|
2874 ... %(dist)s |
|
2875 ... [demo] |
|
2876 ... recipe = zc.recipe.egg |
|
2877 ... eggs = demoneeded |
|
2878 ... ''' % globals()) |
|
2879 |
|
2880 When we run the buildout. it will load the extension from the dist |
|
2881 directory and then use the wacky extension to load the demo package |
|
2882 |
|
2883 >>> print system(buildout), |
|
2884 Getting distribution for 'wackyextension'. |
|
2885 Got wackyextension 1. |
|
2886 Installing demo. |
|
2887 Getting distribution for 'demoneeded'. |
|
2888 Got demoneeded 1.0. |
|
2889 |
|
2890 """ |
|
2891 |
|
2892 def distributions_from_local_find_links_make_it_to_download_cache(): |
|
2893 """ |
|
2894 |
|
2895 If we specify a local directory in find links, distors found there |
|
2896 need to make it to the download cache. |
|
2897 |
|
2898 >>> mkdir('test') |
|
2899 >>> write('test', 'setup.py', |
|
2900 ... ''' |
|
2901 ... from setuptools import setup |
|
2902 ... setup(name='foo') |
|
2903 ... ''') |
|
2904 |
|
2905 >>> print system(buildout+' setup test bdist_egg'), # doctest: +ELLIPSIS |
|
2906 Running setup script 'test/setup.py'. |
|
2907 ... |
|
2908 |
|
2909 |
|
2910 >>> mkdir('cache') |
|
2911 >>> old_cache = zc.buildout.easy_install.download_cache('cache') |
|
2912 >>> list(zc.buildout.easy_install.install(['foo'], 'eggs', |
|
2913 ... links=[join('test', 'dist')])) # doctest: +ELLIPSIS |
|
2914 [foo 0.0.0 ... |
|
2915 |
|
2916 >>> ls('cache') |
|
2917 - foo-0.0.0-py2.4.egg |
|
2918 |
|
2919 >>> _ = zc.buildout.easy_install.download_cache(old_cache) |
|
2920 |
|
2921 """ |
|
2922 |
|
2923 def create_egg(name, version, dest, install_requires=None, |
|
2924 dependency_links=None): |
|
2925 d = tempfile.mkdtemp() |
|
2926 if dest=='available': |
|
2927 extras = dict(x=['x']) |
|
2928 else: |
|
2929 extras = {} |
|
2930 if dependency_links: |
|
2931 links = 'dependency_links = %s, ' % dependency_links |
|
2932 else: |
|
2933 links = '' |
|
2934 if install_requires: |
|
2935 requires = 'install_requires = %s, ' % install_requires |
|
2936 else: |
|
2937 requires = '' |
|
2938 try: |
|
2939 open(os.path.join(d, 'setup.py'), 'w').write( |
|
2940 'from setuptools import setup\n' |
|
2941 'setup(name=%r, version=%r, extras_require=%r, zip_safe=True,\n' |
|
2942 ' %s %s py_modules=["setup"]\n)' |
|
2943 % (name, str(version), extras, requires, links) |
|
2944 ) |
|
2945 zc.buildout.testing.bdist_egg(d, sys.executable, os.path.abspath(dest)) |
|
2946 finally: |
|
2947 shutil.rmtree(d) |
|
2948 |
|
2949 def prefer_final_permutation(existing, available): |
|
2950 for d in ('existing', 'available'): |
|
2951 if os.path.exists(d): |
|
2952 shutil.rmtree(d) |
|
2953 os.mkdir(d) |
|
2954 for version in existing: |
|
2955 create_egg('spam', version, 'existing') |
|
2956 for version in available: |
|
2957 create_egg('spam', version, 'available') |
|
2958 |
|
2959 zc.buildout.easy_install.clear_index_cache() |
|
2960 [dist] = list( |
|
2961 zc.buildout.easy_install.install(['spam'], 'existing', ['available'], |
|
2962 always_unzip=True) |
|
2963 ) |
|
2964 |
|
2965 if dist.extras: |
|
2966 print 'downloaded', dist.version |
|
2967 else: |
|
2968 print 'had', dist.version |
|
2969 sys.path_importer_cache.clear() |
|
2970 |
|
2971 def prefer_final(): |
|
2972 """ |
|
2973 This test tests several permutations: |
|
2974 |
|
2975 Using different version numbers to work around zip importer cache problems. :( |
|
2976 |
|
2977 - With prefer final: |
|
2978 |
|
2979 - no existing and newer dev available |
|
2980 >>> prefer_final_permutation((), [1, '2a1']) |
|
2981 downloaded 1 |
|
2982 |
|
2983 - no existing and only dev available |
|
2984 >>> prefer_final_permutation((), ['3a1']) |
|
2985 downloaded 3a1 |
|
2986 |
|
2987 - final existing and only dev acailable |
|
2988 >>> prefer_final_permutation([4], ['5a1']) |
|
2989 had 4 |
|
2990 |
|
2991 - final existing and newer final available |
|
2992 >>> prefer_final_permutation([6], [7]) |
|
2993 downloaded 7 |
|
2994 |
|
2995 - final existing and same final available |
|
2996 >>> prefer_final_permutation([8], [8]) |
|
2997 had 8 |
|
2998 |
|
2999 - final existing and older final available |
|
3000 >>> prefer_final_permutation([10], [9]) |
|
3001 had 10 |
|
3002 |
|
3003 - only dev existing and final available |
|
3004 >>> prefer_final_permutation(['12a1'], [11]) |
|
3005 downloaded 11 |
|
3006 |
|
3007 - only dev existing and no final available newer dev available |
|
3008 >>> prefer_final_permutation(['13a1'], ['13a2']) |
|
3009 downloaded 13a2 |
|
3010 |
|
3011 - only dev existing and no final available older dev available |
|
3012 >>> prefer_final_permutation(['15a1'], ['14a1']) |
|
3013 had 15a1 |
|
3014 |
|
3015 - only dev existing and no final available same dev available |
|
3016 >>> prefer_final_permutation(['16a1'], ['16a1']) |
|
3017 had 16a1 |
|
3018 |
|
3019 - Without prefer final: |
|
3020 |
|
3021 >>> _ = zc.buildout.easy_install.prefer_final(False) |
|
3022 |
|
3023 - no existing and newer dev available |
|
3024 >>> prefer_final_permutation((), [18, '19a1']) |
|
3025 downloaded 19a1 |
|
3026 |
|
3027 - no existing and only dev available |
|
3028 >>> prefer_final_permutation((), ['20a1']) |
|
3029 downloaded 20a1 |
|
3030 |
|
3031 - final existing and only dev acailable |
|
3032 >>> prefer_final_permutation([21], ['22a1']) |
|
3033 downloaded 22a1 |
|
3034 |
|
3035 - final existing and newer final available |
|
3036 >>> prefer_final_permutation([23], [24]) |
|
3037 downloaded 24 |
|
3038 |
|
3039 - final existing and same final available |
|
3040 >>> prefer_final_permutation([25], [25]) |
|
3041 had 25 |
|
3042 |
|
3043 - final existing and older final available |
|
3044 >>> prefer_final_permutation([27], [26]) |
|
3045 had 27 |
|
3046 |
|
3047 - only dev existing and final available |
|
3048 >>> prefer_final_permutation(['29a1'], [28]) |
|
3049 had 29a1 |
|
3050 |
|
3051 - only dev existing and no final available newer dev available |
|
3052 >>> prefer_final_permutation(['30a1'], ['30a2']) |
|
3053 downloaded 30a2 |
|
3054 |
|
3055 - only dev existing and no final available older dev available |
|
3056 >>> prefer_final_permutation(['32a1'], ['31a1']) |
|
3057 had 32a1 |
|
3058 |
|
3059 - only dev existing and no final available same dev available |
|
3060 >>> prefer_final_permutation(['33a1'], ['33a1']) |
|
3061 had 33a1 |
|
3062 |
|
3063 >>> _ = zc.buildout.easy_install.prefer_final(True) |
|
3064 |
|
3065 """ |
|
3066 |
|
3067 def buildout_prefer_final_option(): |
|
3068 """ |
|
3069 The prefer-final buildout option can be used for override the default |
|
3070 preference for newer distributions. |
|
3071 |
|
3072 The default is prefer-final = false: |
|
3073 |
|
3074 >>> write('buildout.cfg', |
|
3075 ... ''' |
|
3076 ... [buildout] |
|
3077 ... parts = eggs |
|
3078 ... find-links = %(link_server)s |
|
3079 ... |
|
3080 ... [eggs] |
|
3081 ... recipe = zc.recipe.egg:eggs |
|
3082 ... eggs = demo |
|
3083 ... ''' % globals()) |
|
3084 |
|
3085 >>> print system(buildout+' -v'), # doctest: +ELLIPSIS |
|
3086 Installing 'zc.buildout', 'setuptools'. |
|
3087 ... |
|
3088 Picked: demo = 0.4c1 |
|
3089 ... |
|
3090 Picked: demoneeded = 1.2c1 |
|
3091 |
|
3092 Here we see that the final versions of demo and demoneeded are used. |
|
3093 We get the same behavior if we add prefer-final = false |
|
3094 |
|
3095 >>> write('buildout.cfg', |
|
3096 ... ''' |
|
3097 ... [buildout] |
|
3098 ... parts = eggs |
|
3099 ... find-links = %(link_server)s |
|
3100 ... prefer-final = false |
|
3101 ... |
|
3102 ... [eggs] |
|
3103 ... recipe = zc.recipe.egg:eggs |
|
3104 ... eggs = demo |
|
3105 ... ''' % globals()) |
|
3106 |
|
3107 >>> print system(buildout+' -v'), # doctest: +ELLIPSIS |
|
3108 Installing 'zc.buildout', 'setuptools'. |
|
3109 ... |
|
3110 Picked: demo = 0.4c1 |
|
3111 ... |
|
3112 Picked: demoneeded = 1.2c1 |
|
3113 |
|
3114 If we specify prefer-final = true, we'll get the newest |
|
3115 distributions: |
|
3116 |
|
3117 >>> write('buildout.cfg', |
|
3118 ... ''' |
|
3119 ... [buildout] |
|
3120 ... parts = eggs |
|
3121 ... find-links = %(link_server)s |
|
3122 ... prefer-final = true |
|
3123 ... |
|
3124 ... [eggs] |
|
3125 ... recipe = zc.recipe.egg:eggs |
|
3126 ... eggs = demo |
|
3127 ... ''' % globals()) |
|
3128 |
|
3129 >>> print system(buildout+' -v'), # doctest: +ELLIPSIS |
|
3130 Installing 'zc.buildout', 'setuptools'. |
|
3131 ... |
|
3132 Picked: demo = 0.3 |
|
3133 ... |
|
3134 Picked: demoneeded = 1.1 |
|
3135 |
|
3136 We get an error if we specify anything but true or false: |
|
3137 |
|
3138 >>> write('buildout.cfg', |
|
3139 ... ''' |
|
3140 ... [buildout] |
|
3141 ... parts = eggs |
|
3142 ... find-links = %(link_server)s |
|
3143 ... prefer-final = no |
|
3144 ... |
|
3145 ... [eggs] |
|
3146 ... recipe = zc.recipe.egg:eggs |
|
3147 ... eggs = demo |
|
3148 ... ''' % globals()) |
|
3149 |
|
3150 >>> print system(buildout+' -v'), # doctest: +ELLIPSIS |
|
3151 While: |
|
3152 Initializing. |
|
3153 Error: Invalid value for prefer-final option: no |
|
3154 |
|
3155 """ |
|
3156 |
|
3157 def buildout_prefer_final_build_system_option(): |
|
3158 """ |
|
3159 The accept-buildout-test-releases buildout option can be used for overriding |
|
3160 the default preference for final distributions for recipes, buildout |
|
3161 extensions, and buildout itself. It is usually controlled via the bootstrap |
|
3162 script rather than in the configuration file, but we will test the machinery |
|
3163 using the file. |
|
3164 |
|
3165 Set up. This creates sdists for demorecipe 1.0 and 1.1b1, and for |
|
3166 demoextension 1.0 and 1.1b1. |
|
3167 |
|
3168 >>> create_sample_recipe_sdists(sample_eggs) |
|
3169 >>> create_sample_extension_sdists(sample_eggs) |
|
3170 |
|
3171 The default is accept-buildout-test-releases = false: |
|
3172 |
|
3173 >>> write('buildout.cfg', |
|
3174 ... ''' |
|
3175 ... [buildout] |
|
3176 ... parts = demo |
|
3177 ... find-links = %(link_server)s |
|
3178 ... extensions = demoextension |
|
3179 ... |
|
3180 ... [demo] |
|
3181 ... recipe = demorecipe |
|
3182 ... ''' % globals()) |
|
3183 |
|
3184 >>> print system(buildout+' -v'), # doctest: +ELLIPSIS |
|
3185 Installing ... |
|
3186 Picked: demoextension = 1.0 |
|
3187 ... |
|
3188 Picked: demorecipe = 1.0 |
|
3189 ... |
|
3190 |
|
3191 Here we see that the final versions of demorecipe and demoextension were used. |
|
3192 |
|
3193 We get the same behavior if we explicitly state that |
|
3194 accept-buildout-test-releases = false. |
|
3195 |
|
3196 >>> write('buildout.cfg', |
|
3197 ... ''' |
|
3198 ... [buildout] |
|
3199 ... parts = demo |
|
3200 ... find-links = %(link_server)s |
|
3201 ... extensions = demoextension |
|
3202 ... accept-buildout-test-releases = false |
|
3203 ... |
|
3204 ... [demo] |
|
3205 ... recipe = demorecipe |
|
3206 ... ''' % globals()) |
|
3207 |
|
3208 >>> print system(buildout+' -v'), # doctest: +ELLIPSIS |
|
3209 Installing ... |
|
3210 Picked: demoextension = 1.0 |
|
3211 ... |
|
3212 Picked: demorecipe = 1.0 |
|
3213 ... |
|
3214 |
|
3215 If we specify accept-buildout-test-releases = true, we'll get the newest |
|
3216 distributions in the build system: |
|
3217 |
|
3218 >>> write('buildout.cfg', |
|
3219 ... ''' |
|
3220 ... [buildout] |
|
3221 ... parts = demo |
|
3222 ... find-links = %(link_server)s |
|
3223 ... extensions = demoextension |
|
3224 ... accept-buildout-test-releases = true |
|
3225 ... |
|
3226 ... [demo] |
|
3227 ... recipe = demorecipe |
|
3228 ... ''' % globals()) |
|
3229 |
|
3230 >>> print system(buildout+' -v'), # doctest: +ELLIPSIS |
|
3231 Installing ... |
|
3232 Picked: demoextension = 1.1b1 |
|
3233 ... |
|
3234 Picked: demorecipe = 1.1b1 |
|
3235 ... |
|
3236 |
|
3237 We get an error if we specify anything but true or false: |
|
3238 |
|
3239 >>> write('buildout.cfg', |
|
3240 ... ''' |
|
3241 ... [buildout] |
|
3242 ... parts = demo |
|
3243 ... find-links = %(link_server)s |
|
3244 ... extensions = demoextension |
|
3245 ... accept-buildout-test-releases = no |
|
3246 ... |
|
3247 ... [demo] |
|
3248 ... recipe = demorecipe |
|
3249 ... ''' % globals()) |
|
3250 |
|
3251 >>> print system(buildout+' -v'), # doctest: +ELLIPSIS |
|
3252 While: |
|
3253 Initializing. |
|
3254 Error: Invalid value for accept-buildout-test-releases option: no |
|
3255 |
|
3256 """ |
|
3257 |
|
3258 def develop_with_modules(): |
|
3259 """ |
|
3260 Distribution setup scripts can import modules in the distribution directory: |
|
3261 |
|
3262 >>> mkdir('foo') |
|
3263 >>> write('foo', 'bar.py', |
|
3264 ... '''# empty |
|
3265 ... ''') |
|
3266 |
|
3267 >>> write('foo', 'setup.py', |
|
3268 ... ''' |
|
3269 ... import bar |
|
3270 ... from setuptools import setup |
|
3271 ... setup(name="foo") |
|
3272 ... ''') |
|
3273 |
|
3274 >>> write('buildout.cfg', |
|
3275 ... ''' |
|
3276 ... [buildout] |
|
3277 ... develop = foo |
|
3278 ... parts = |
|
3279 ... ''') |
|
3280 |
|
3281 >>> print system(join('bin', 'buildout')), |
|
3282 Develop: '/sample-buildout/foo' |
|
3283 |
|
3284 >>> ls('develop-eggs') |
|
3285 - foo.egg-link |
|
3286 - z3c.recipe.scripts.egg-link |
|
3287 - zc.recipe.egg.egg-link |
|
3288 |
|
3289 """ |
|
3290 |
|
3291 def dont_pick_setuptools_if_version_is_specified_when_required_by_src_dist(): |
|
3292 """ |
|
3293 When installing a source distribution, we got setuptools without |
|
3294 honoring our version specification. |
|
3295 |
|
3296 >>> mkdir('dist') |
|
3297 >>> write('setup.py', |
|
3298 ... ''' |
|
3299 ... from setuptools import setup |
|
3300 ... setup(name='foo', version='1', py_modules=['foo'], zip_safe=True) |
|
3301 ... ''') |
|
3302 >>> write('foo.py', '') |
|
3303 >>> _ = system(buildout+' setup . sdist') |
|
3304 |
|
3305 >>> if zc.buildout.easy_install.is_distribute: |
|
3306 ... distribute_version = 'distribute = %s' % ( |
|
3307 ... pkg_resources.working_set.find( |
|
3308 ... pkg_resources.Requirement.parse('distribute')).version,) |
|
3309 ... else: |
|
3310 ... distribute_version = '' |
|
3311 ... |
|
3312 >>> write('buildout.cfg', |
|
3313 ... ''' |
|
3314 ... [buildout] |
|
3315 ... parts = foo |
|
3316 ... find-links = dist |
|
3317 ... versions = versions |
|
3318 ... allow-picked-versions = false |
|
3319 ... |
|
3320 ... [versions] |
|
3321 ... setuptools = %s |
|
3322 ... foo = 1 |
|
3323 ... %s |
|
3324 ... |
|
3325 ... [foo] |
|
3326 ... recipe = zc.recipe.egg |
|
3327 ... eggs = foo |
|
3328 ... ''' % (pkg_resources.working_set.find( |
|
3329 ... pkg_resources.Requirement.parse('setuptools')).version, |
|
3330 ... distribute_version)) |
|
3331 |
|
3332 >>> print system(buildout), |
|
3333 Installing foo. |
|
3334 Getting distribution for 'foo==1'. |
|
3335 Got foo 1. |
|
3336 |
|
3337 """ |
|
3338 |
|
3339 def pyc_and_pyo_files_have_correct_paths(): |
|
3340 r""" |
|
3341 |
|
3342 >>> write('buildout.cfg', |
|
3343 ... ''' |
|
3344 ... [buildout] |
|
3345 ... parts = eggs |
|
3346 ... find-links = %(link_server)s |
|
3347 ... unzip = true |
|
3348 ... |
|
3349 ... [eggs] |
|
3350 ... recipe = zc.recipe.egg |
|
3351 ... eggs = demo |
|
3352 ... interpreter = py |
|
3353 ... ''' % globals()) |
|
3354 |
|
3355 >>> _ = system(buildout) |
|
3356 |
|
3357 >>> write('t.py', |
|
3358 ... ''' |
|
3359 ... import eggrecipedemo, eggrecipedemoneeded |
|
3360 ... print eggrecipedemo.main.func_code.co_filename |
|
3361 ... print eggrecipedemoneeded.f.func_code.co_filename |
|
3362 ... ''') |
|
3363 |
|
3364 >>> print system(join('bin', 'py')+ ' t.py'), |
|
3365 /sample-buildout/eggs/demo-0.4c1-py2.4.egg/eggrecipedemo.py |
|
3366 /sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg/eggrecipedemoneeded.py |
|
3367 |
|
3368 >>> import os |
|
3369 >>> for name in os.listdir('eggs'): |
|
3370 ... if name.startswith('demoneeded'): |
|
3371 ... ls('eggs', name) |
|
3372 d EGG-INFO |
|
3373 - eggrecipedemoneeded.py |
|
3374 - eggrecipedemoneeded.pyc |
|
3375 - eggrecipedemoneeded.pyo |
|
3376 |
|
3377 """ |
|
3378 |
|
3379 def dont_mess_with_standard_dirs_with_variable_refs(): |
|
3380 """ |
|
3381 >>> write('buildout.cfg', |
|
3382 ... ''' |
|
3383 ... [buildout] |
|
3384 ... eggs-directory = ${buildout:directory}/develop-eggs |
|
3385 ... parts = |
|
3386 ... ''' % globals()) |
|
3387 >>> print system(buildout), |
|
3388 |
|
3389 """ |
|
3390 |
|
3391 def expand_shell_patterns_in_develop_paths(): |
|
3392 """ |
|
3393 Sometimes we want to include a number of eggs in some directory as |
|
3394 develop eggs, without explicitly listing all of them in our |
|
3395 buildout.cfg |
|
3396 |
|
3397 >>> make_dist_that_requires(sample_buildout, 'sampley') |
|
3398 >>> make_dist_that_requires(sample_buildout, 'samplez') |
|
3399 |
|
3400 Now, let's create a buildout that has a shell pattern that matches |
|
3401 both: |
|
3402 |
|
3403 >>> write('buildout.cfg', |
|
3404 ... ''' |
|
3405 ... [buildout] |
|
3406 ... parts = eggs |
|
3407 ... develop = sample* |
|
3408 ... find-links = %(link_server)s |
|
3409 ... |
|
3410 ... [eggs] |
|
3411 ... recipe = zc.recipe.egg |
|
3412 ... eggs = sampley |
|
3413 ... samplez |
|
3414 ... ''' % globals()) |
|
3415 |
|
3416 We can see that both eggs were found: |
|
3417 |
|
3418 >>> print system(buildout), |
|
3419 Develop: '/sample-buildout/sampley' |
|
3420 Develop: '/sample-buildout/samplez' |
|
3421 Installing eggs. |
|
3422 |
|
3423 """ |
|
3424 |
|
3425 def warn_users_when_expanding_shell_patterns_yields_no_results(): |
|
3426 """ |
|
3427 Sometimes shell patterns do not match anything, so we want to warn |
|
3428 our users about it... |
|
3429 |
|
3430 >>> make_dist_that_requires(sample_buildout, 'samplea') |
|
3431 |
|
3432 So if we have 2 patterns, one that has a matching directory, and |
|
3433 another one that does not |
|
3434 |
|
3435 >>> write('buildout.cfg', |
|
3436 ... ''' |
|
3437 ... [buildout] |
|
3438 ... parts = eggs |
|
3439 ... develop = samplea grumble* |
|
3440 ... find-links = %(link_server)s |
|
3441 ... |
|
3442 ... [eggs] |
|
3443 ... recipe = zc.recipe.egg |
|
3444 ... eggs = samplea |
|
3445 ... ''' % globals()) |
|
3446 |
|
3447 We should get one of the eggs, and a warning for the pattern that |
|
3448 did not match anything. |
|
3449 |
|
3450 >>> print system(buildout), |
|
3451 Develop: '/sample-buildout/samplea' |
|
3452 Couldn't develop '/sample-buildout/grumble*' (not found) |
|
3453 Installing eggs. |
|
3454 |
|
3455 """ |
|
3456 |
|
3457 def make_sure_versions_dont_cancel_extras(): |
|
3458 """ |
|
3459 There was a bug that caused extras in requirements to be lost. |
|
3460 |
|
3461 >>> open('setup.py', 'w').write(''' |
|
3462 ... from setuptools import setup |
|
3463 ... setup(name='extraversiondemo', version='1.0', |
|
3464 ... url='x', author='x', author_email='x', |
|
3465 ... extras_require=dict(foo=['demo']), py_modules=['t']) |
|
3466 ... ''') |
|
3467 >>> open('README', 'w').close() |
|
3468 >>> open('t.py', 'w').close() |
|
3469 |
|
3470 >>> sdist('.', sample_eggs) |
|
3471 >>> mkdir('dest') |
|
3472 >>> ws = zc.buildout.easy_install.install( |
|
3473 ... ['extraversiondemo[foo]'], 'dest', links=[sample_eggs], |
|
3474 ... versions = dict(extraversiondemo='1.0') |
|
3475 ... ) |
|
3476 >>> sorted(dist.key for dist in ws) |
|
3477 ['demo', 'demoneeded', 'extraversiondemo'] |
|
3478 """ |
|
3479 |
|
3480 def increment_buildout_options(): |
|
3481 r""" |
|
3482 >>> write('b1.cfg', ''' |
|
3483 ... [buildout] |
|
3484 ... parts = p1 |
|
3485 ... x = 1 |
|
3486 ... y = a |
|
3487 ... b |
|
3488 ... |
|
3489 ... [p1] |
|
3490 ... recipe = zc.buildout:debug |
|
3491 ... foo = ${buildout:x} ${buildout:y} |
|
3492 ... ''') |
|
3493 |
|
3494 >>> write('buildout.cfg', ''' |
|
3495 ... [buildout] |
|
3496 ... extends = b1.cfg |
|
3497 ... parts += p2 |
|
3498 ... x += 2 |
|
3499 ... y -= a |
|
3500 ... |
|
3501 ... [p2] |
|
3502 ... <= p1 |
|
3503 ... ''') |
|
3504 |
|
3505 >>> print system(buildout), |
|
3506 Installing p1. |
|
3507 foo='1\n2 b' |
|
3508 recipe='zc.buildout:debug' |
|
3509 Installing p2. |
|
3510 foo='1\n2 b' |
|
3511 recipe='zc.buildout:debug' |
|
3512 """ |
|
3513 |
|
3514 def increment_buildout_with_multiple_extended_files_421022(): |
|
3515 r""" |
|
3516 >>> write('foo.cfg', ''' |
|
3517 ... [buildout] |
|
3518 ... foo-option = foo |
|
3519 ... [other] |
|
3520 ... foo-option = foo |
|
3521 ... ''') |
|
3522 >>> write('bar.cfg', ''' |
|
3523 ... [buildout] |
|
3524 ... bar-option = bar |
|
3525 ... [other] |
|
3526 ... bar-option = bar |
|
3527 ... ''') |
|
3528 >>> write('buildout.cfg', ''' |
|
3529 ... [buildout] |
|
3530 ... parts = p other |
|
3531 ... extends = bar.cfg foo.cfg |
|
3532 ... bar-option += baz |
|
3533 ... foo-option += ham |
|
3534 ... |
|
3535 ... [other] |
|
3536 ... recipe = zc.buildout:debug |
|
3537 ... bar-option += baz |
|
3538 ... foo-option += ham |
|
3539 ... |
|
3540 ... [p] |
|
3541 ... recipe = zc.buildout:debug |
|
3542 ... x = ${buildout:bar-option} ${buildout:foo-option} |
|
3543 ... ''') |
|
3544 |
|
3545 >>> print system(buildout), |
|
3546 Installing p. |
|
3547 recipe='zc.buildout:debug' |
|
3548 x='bar\nbaz foo\nham' |
|
3549 Installing other. |
|
3550 bar-option='bar\nbaz' |
|
3551 foo-option='foo\nham' |
|
3552 recipe='zc.buildout:debug' |
|
3553 """ |
|
3554 |
|
3555 def increment_on_command_line(): |
|
3556 r""" |
|
3557 >>> write('buildout.cfg', ''' |
|
3558 ... [buildout] |
|
3559 ... parts = p1 |
|
3560 ... x = 1 |
|
3561 ... y = a |
|
3562 ... b |
|
3563 ... |
|
3564 ... [p1] |
|
3565 ... recipe = zc.buildout:debug |
|
3566 ... foo = ${buildout:x} ${buildout:y} |
|
3567 ... |
|
3568 ... [p2] |
|
3569 ... <= p1 |
|
3570 ... ''') |
|
3571 |
|
3572 >>> print system(buildout+' buildout:parts+=p2 p1:foo+=bar'), |
|
3573 Installing p1. |
|
3574 foo='1 a\nb\nbar' |
|
3575 recipe='zc.buildout:debug' |
|
3576 Installing p2. |
|
3577 foo='1 a\nb\nbar' |
|
3578 recipe='zc.buildout:debug' |
|
3579 """ |
|
3580 |
|
3581 ###################################################################### |
|
3582 |
|
3583 def make_py_with_system_install(make_py, sample_eggs): |
|
3584 py_path, site_packages_path = make_py() |
|
3585 create_sample_namespace_eggs(sample_eggs, site_packages_path) |
|
3586 return py_path |
|
3587 |
|
3588 def create_sample_namespace_eggs(dest, site_packages_path=None): |
|
3589 from zc.buildout.testing import write, mkdir |
|
3590 for pkg, version in (('version', '1.0'), ('version', '1.1'), |
|
3591 ('fortune', '1.0')): |
|
3592 tmp = tempfile.mkdtemp() |
|
3593 try: |
|
3594 write(tmp, 'README.txt', '') |
|
3595 mkdir(tmp, 'src') |
|
3596 mkdir(tmp, 'src', 'tellmy') |
|
3597 write(tmp, 'src', 'tellmy', '__init__.py', |
|
3598 "__import__(" |
|
3599 "'pkg_resources').declare_namespace(__name__)\n") |
|
3600 mkdir(tmp, 'src', 'tellmy', pkg) |
|
3601 write(tmp, 'src', 'tellmy', pkg, |
|
3602 '__init__.py', '__version__=%r\n' % version) |
|
3603 write( |
|
3604 tmp, 'setup.py', |
|
3605 "from setuptools import setup\n" |
|
3606 "setup(\n" |
|
3607 " name='tellmy.%(pkg)s',\n" |
|
3608 " package_dir = {'': 'src'},\n" |
|
3609 " packages = ['tellmy', 'tellmy.%(pkg)s'],\n" |
|
3610 " install_requires = ['setuptools'],\n" |
|
3611 " namespace_packages=['tellmy'],\n" |
|
3612 " zip_safe=True, version=%(version)r,\n" |
|
3613 " author='bob', url='bob', author_email='bob')\n" |
|
3614 % locals() |
|
3615 ) |
|
3616 zc.buildout.testing.sdist(tmp, dest) |
|
3617 if (site_packages_path and pkg == 'version' and version == '1.1'): |
|
3618 # We install the 1.1 version in site packages the way a |
|
3619 # system packaging system (debs, rpms) would do it. |
|
3620 zc.buildout.testing.sys_install(tmp, site_packages_path) |
|
3621 finally: |
|
3622 shutil.rmtree(tmp) |
|
3623 |
|
3624 def create_sample_extension_sdists(dest): |
|
3625 from zc.buildout.testing import write, mkdir |
|
3626 name = 'demoextension' |
|
3627 for version in ('1.0', '1.1b1'): |
|
3628 tmp = tempfile.mkdtemp() |
|
3629 try: |
|
3630 write(tmp, 'README.txt', '') |
|
3631 write(tmp, name + '.py', |
|
3632 "def ext(buildout):\n" |
|
3633 " pass\n" |
|
3634 "def unload(buildout):\n" |
|
3635 " pass\n" |
|
3636 % locals()) |
|
3637 write(tmp, 'setup.py', |
|
3638 "from setuptools import setup\n" |
|
3639 "setup(\n" |
|
3640 " name = %(name)r,\n" |
|
3641 " py_modules = [%(name)r],\n" |
|
3642 " entry_points = {\n" |
|
3643 " 'zc.buildout.extension': " |
|
3644 "['ext = %(name)s:ext'],\n" |
|
3645 " 'zc.buildout.unloadextension': " |
|
3646 "['ext = %(name)s:unload'],\n" |
|
3647 " },\n" |
|
3648 " zip_safe=True, version=%(version)r,\n" |
|
3649 " author='bob', url='bob', author_email='bob')\n" |
|
3650 % locals()) |
|
3651 zc.buildout.testing.sdist(tmp, dest) |
|
3652 finally: |
|
3653 shutil.rmtree(tmp) |
|
3654 |
|
3655 def create_sample_recipe_sdists(dest): |
|
3656 from zc.buildout.testing import write, mkdir |
|
3657 name = 'demorecipe' |
|
3658 for version in ('1.0', '1.1b1'): |
|
3659 tmp = tempfile.mkdtemp() |
|
3660 try: |
|
3661 write(tmp, 'README.txt', '') |
|
3662 write(tmp, name + '.py', |
|
3663 "import logging, os, zc.buildout\n" |
|
3664 "class Demorecipe:\n" |
|
3665 " def __init__(self, buildout, name, options):\n" |
|
3666 " self.name, self.options = name, options\n" |
|
3667 " def install(self):\n" |
|
3668 " return ()\n" |
|
3669 " def update(self):\n" |
|
3670 " pass\n" |
|
3671 % locals()) |
|
3672 write(tmp, 'setup.py', |
|
3673 "from setuptools import setup\n" |
|
3674 "setup(\n" |
|
3675 " name = %(name)r,\n" |
|
3676 " py_modules = [%(name)r],\n" |
|
3677 " entry_points = {'zc.buildout': " |
|
3678 "['default = %(name)s:Demorecipe']},\n" |
|
3679 " zip_safe=True, version=%(version)r,\n" |
|
3680 " author='bob', url='bob', author_email='bob')\n" |
|
3681 % locals()) |
|
3682 zc.buildout.testing.sdist(tmp, dest) |
|
3683 finally: |
|
3684 shutil.rmtree(tmp) |
|
3685 |
|
3686 def _write_eggrecipedemoneeded(tmp, minor_version, suffix=''): |
|
3687 from zc.buildout.testing import write |
|
3688 write(tmp, 'README.txt', '') |
|
3689 write(tmp, 'eggrecipedemoneeded.py', |
|
3690 'y=%s\ndef f():\n pass' % minor_version) |
|
3691 write( |
|
3692 tmp, 'setup.py', |
|
3693 "from setuptools import setup\n" |
|
3694 "setup(name='demoneeded', py_modules=['eggrecipedemoneeded']," |
|
3695 " zip_safe=True, version='1.%s%s', author='bob', url='bob', " |
|
3696 "author_email='bob')\n" |
|
3697 % (minor_version, suffix) |
|
3698 ) |
|
3699 |
|
3700 def _write_eggrecipedemo(tmp, minor_version, suffix=''): |
|
3701 from zc.buildout.testing import write |
|
3702 write(tmp, 'README.txt', '') |
|
3703 write( |
|
3704 tmp, 'eggrecipedemo.py', |
|
3705 'import eggrecipedemoneeded\n' |
|
3706 'x=%s\n' |
|
3707 'def main(): print x, eggrecipedemoneeded.y\n' |
|
3708 % minor_version) |
|
3709 write( |
|
3710 tmp, 'setup.py', |
|
3711 "from setuptools import setup\n" |
|
3712 "setup(name='demo', py_modules=['eggrecipedemo']," |
|
3713 " install_requires = 'demoneeded'," |
|
3714 " entry_points={'console_scripts': " |
|
3715 "['demo = eggrecipedemo:main']}," |
|
3716 " zip_safe=True, version='0.%s%s')\n" % (minor_version, suffix) |
|
3717 ) |
|
3718 |
|
3719 def create_sample_sys_install(site_packages_path): |
|
3720 for creator, minor_version in ( |
|
3721 (_write_eggrecipedemoneeded, 1), |
|
3722 (_write_eggrecipedemo, 3)): |
|
3723 # Write the files and install in site_packages_path. |
|
3724 tmp = tempfile.mkdtemp() |
|
3725 try: |
|
3726 creator(tmp, minor_version) |
|
3727 zc.buildout.testing.sys_install(tmp, site_packages_path) |
|
3728 finally: |
|
3729 shutil.rmtree(tmp) |
|
3730 |
|
3731 def create_sample_eggs(test, executable=sys.executable): |
|
3732 from zc.buildout.testing import write |
|
3733 dest = test.globs['sample_eggs'] |
|
3734 tmp = tempfile.mkdtemp() |
|
3735 try: |
|
3736 for i in (0, 1, 2): |
|
3737 suffix = i==2 and 'c1' or '' |
|
3738 _write_eggrecipedemoneeded(tmp, i, suffix) |
|
3739 zc.buildout.testing.sdist(tmp, dest) |
|
3740 |
|
3741 write( |
|
3742 tmp, 'setup.py', |
|
3743 "from setuptools import setup\n" |
|
3744 "setup(name='other', zip_safe=False, version='1.0', " |
|
3745 "py_modules=['eggrecipedemoneeded'])\n" |
|
3746 ) |
|
3747 zc.buildout.testing.bdist_egg(tmp, executable, dest) |
|
3748 |
|
3749 os.remove(os.path.join(tmp, 'eggrecipedemoneeded.py')) |
|
3750 |
|
3751 for i in (1, 2, 3, 4): |
|
3752 suffix = i==4 and 'c1' or '' |
|
3753 _write_eggrecipedemo(tmp, i, suffix) |
|
3754 zc.buildout.testing.bdist_egg(tmp, executable, dest) |
|
3755 |
|
3756 write(tmp, 'eggrecipebigdemo.py', 'import eggrecipedemo') |
|
3757 write( |
|
3758 tmp, 'setup.py', |
|
3759 "from setuptools import setup\n" |
|
3760 "setup(name='bigdemo', " |
|
3761 " install_requires = 'demo'," |
|
3762 " py_modules=['eggrecipebigdemo'], " |
|
3763 " zip_safe=True, version='0.1')\n" |
|
3764 ) |
|
3765 zc.buildout.testing.bdist_egg(tmp, executable, dest) |
|
3766 |
|
3767 finally: |
|
3768 shutil.rmtree(tmp) |
|
3769 |
|
3770 extdemo_c = """ |
|
3771 #include <Python.h> |
|
3772 #include <extdemo.h> |
|
3773 |
|
3774 static PyMethodDef methods[] = {{NULL}}; |
|
3775 |
|
3776 PyMODINIT_FUNC |
|
3777 initextdemo(void) |
|
3778 { |
|
3779 PyObject *m; |
|
3780 m = Py_InitModule3("extdemo", methods, ""); |
|
3781 #ifdef TWO |
|
3782 PyModule_AddObject(m, "val", PyInt_FromLong(2)); |
|
3783 #else |
|
3784 PyModule_AddObject(m, "val", PyInt_FromLong(EXTDEMO)); |
|
3785 #endif |
|
3786 } |
|
3787 """ |
|
3788 |
|
3789 extdemo_setup_py = """ |
|
3790 import os |
|
3791 from distutils.core import setup, Extension |
|
3792 |
|
3793 if os.environ.get('test-variable'): |
|
3794 print "Have environment test-variable:", os.environ['test-variable'] |
|
3795 |
|
3796 setup(name = "extdemo", version = "%s", url="http://www.zope.org", |
|
3797 author="Demo", author_email="demo@demo.com", |
|
3798 ext_modules = [Extension('extdemo', ['extdemo.c'])], |
|
3799 ) |
|
3800 """ |
|
3801 |
|
3802 def add_source_dist(test, version=1.4): |
|
3803 |
|
3804 if 'extdemo' not in test.globs: |
|
3805 test.globs['extdemo'] = test.globs['tmpdir']('extdemo') |
|
3806 |
|
3807 tmp = test.globs['extdemo'] |
|
3808 write = test.globs['write'] |
|
3809 try: |
|
3810 write(tmp, 'extdemo.c', extdemo_c); |
|
3811 write(tmp, 'setup.py', extdemo_setup_py % version); |
|
3812 write(tmp, 'README', ""); |
|
3813 write(tmp, 'MANIFEST.in', "include *.c\n"); |
|
3814 test.globs['sdist'](tmp, test.globs['sample_eggs']) |
|
3815 except: |
|
3816 shutil.rmtree(tmp) |
|
3817 |
|
3818 def easy_install_SetUp(test): |
|
3819 zc.buildout.testing.buildoutSetUp(test) |
|
3820 sample_eggs = test.globs['tmpdir']('sample_eggs') |
|
3821 test.globs['sample_eggs'] = sample_eggs |
|
3822 os.mkdir(os.path.join(sample_eggs, 'index')) |
|
3823 create_sample_eggs(test) |
|
3824 add_source_dist(test) |
|
3825 test.globs['link_server'] = test.globs['start_server']( |
|
3826 test.globs['sample_eggs']) |
|
3827 test.globs['update_extdemo'] = lambda : add_source_dist(test, 1.5) |
|
3828 zc.buildout.testing.install_develop('zc.recipe.egg', test) |
|
3829 zc.buildout.testing.install_develop('z3c.recipe.scripts', test) |
|
3830 |
|
3831 egg_parse = re.compile('([0-9a-zA-Z_.]+)-([0-9a-zA-Z_.]+)-py(\d[.]\d).egg$' |
|
3832 ).match |
|
3833 def makeNewRelease(project, ws, dest, version='99.99'): |
|
3834 dist = ws.find(pkg_resources.Requirement.parse(project)) |
|
3835 eggname, oldver, pyver = egg_parse( |
|
3836 os.path.basename(dist.location) |
|
3837 ).groups() |
|
3838 dest = os.path.join(dest, "%s-%s-py%s.egg" % (eggname, version, pyver)) |
|
3839 if os.path.isfile(dist.location): |
|
3840 shutil.copy(dist.location, dest) |
|
3841 zip = zipfile.ZipFile(dest, 'a') |
|
3842 zip.writestr( |
|
3843 'EGG-INFO/PKG-INFO', |
|
3844 zip.read('EGG-INFO/PKG-INFO').replace("Version: %s" % oldver, |
|
3845 "Version: %s" % version) |
|
3846 ) |
|
3847 zip.close() |
|
3848 else: |
|
3849 shutil.copytree(dist.location, dest) |
|
3850 info_path = os.path.join(dest, 'EGG-INFO', 'PKG-INFO') |
|
3851 info = open(info_path).read().replace("Version: %s" % oldver, |
|
3852 "Version: %s" % version) |
|
3853 open(info_path, 'w').write(info) |
|
3854 |
|
3855 def getWorkingSetWithBuildoutEgg(test): |
|
3856 sample_buildout = test.globs['sample_buildout'] |
|
3857 eggs = os.path.join(sample_buildout, 'eggs') |
|
3858 |
|
3859 # If the zc.buildout dist is a develop dist, convert it to a |
|
3860 # regular egg in the sample buildout |
|
3861 req = pkg_resources.Requirement.parse('zc.buildout') |
|
3862 dist = pkg_resources.working_set.find(req) |
|
3863 if dist.precedence == pkg_resources.DEVELOP_DIST: |
|
3864 # We have a develop egg, create a real egg for it: |
|
3865 here = os.getcwd() |
|
3866 os.chdir(os.path.dirname(dist.location)) |
|
3867 assert os.spawnle( |
|
3868 os.P_WAIT, sys.executable, |
|
3869 zc.buildout.easy_install._safe_arg(sys.executable), |
|
3870 os.path.join(os.path.dirname(dist.location), 'setup.py'), |
|
3871 '-q', 'bdist_egg', '-d', eggs, |
|
3872 dict(os.environ, |
|
3873 PYTHONPATH=pkg_resources.working_set.find( |
|
3874 pkg_resources.Requirement.parse('setuptools') |
|
3875 ).location, |
|
3876 ), |
|
3877 ) == 0 |
|
3878 os.chdir(here) |
|
3879 os.remove(os.path.join(eggs, 'zc.buildout.egg-link')) |
|
3880 |
|
3881 # Rebuild the buildout script |
|
3882 ws = pkg_resources.WorkingSet([eggs]) |
|
3883 ws.require('zc.buildout') |
|
3884 zc.buildout.easy_install.scripts( |
|
3885 ['zc.buildout'], ws, sys.executable, |
|
3886 os.path.join(sample_buildout, 'bin')) |
|
3887 else: |
|
3888 ws = pkg_resources.working_set |
|
3889 return ws |
|
3890 |
|
3891 def updateSetup(test): |
|
3892 zc.buildout.testing.buildoutSetUp(test) |
|
3893 new_releases = test.globs['tmpdir']('new_releases') |
|
3894 test.globs['new_releases'] = new_releases |
|
3895 ws = getWorkingSetWithBuildoutEgg(test) |
|
3896 # now let's make the new releases |
|
3897 makeNewRelease('zc.buildout', ws, new_releases) |
|
3898 makeNewRelease('zc.buildout', ws, new_releases, '100.0b1') |
|
3899 os.mkdir(os.path.join(new_releases, 'zc.buildout')) |
|
3900 if zc.buildout.easy_install.is_distribute: |
|
3901 makeNewRelease('distribute', ws, new_releases) |
|
3902 os.mkdir(os.path.join(new_releases, 'distribute')) |
|
3903 else: |
|
3904 makeNewRelease('setuptools', ws, new_releases) |
|
3905 os.mkdir(os.path.join(new_releases, 'setuptools')) |
|
3906 |
|
3907 def bootstrapSetup(test): |
|
3908 easy_install_SetUp(test) |
|
3909 sample_eggs = test.globs['sample_eggs'] |
|
3910 ws = getWorkingSetWithBuildoutEgg(test) |
|
3911 makeNewRelease('zc.buildout', ws, sample_eggs) |
|
3912 makeNewRelease('zc.buildout', ws, sample_eggs, '100.0b1') |
|
3913 os.environ['bootstrap-testing-find-links'] = test.globs['link_server'] |
|
3914 |
|
3915 normalize_bang = ( |
|
3916 re.compile(re.escape('#!'+ |
|
3917 zc.buildout.easy_install._safe_arg(sys.executable))), |
|
3918 '#!/usr/local/bin/python2.4', |
|
3919 ) |
|
3920 |
|
3921 hide_distribute_additions = (re.compile('install_dir .+\n'), '') |
|
3922 hide_zip_safe_message = ( |
|
3923 # This comes in a different place in the output in Python 2.7. It's not |
|
3924 # important to our tests. Hide it. |
|
3925 re.compile( |
|
3926 '((?<=\n)\n)?zip_safe flag not set; analyzing archive contents...\n'), |
|
3927 '') |
|
3928 hide_first_index_page_message = ( |
|
3929 # This comes in a different place in the output in Python 2.7. It's not |
|
3930 # important to our tests. Hide it. |
|
3931 re.compile( |
|
3932 "Couldn't find index page for '[^']+' \(maybe misspelled\?\)\n"), |
|
3933 '') |
|
3934 def test_suite(): |
|
3935 test_suite = [ |
|
3936 doctest.DocFileSuite( |
|
3937 'buildout.txt', 'runsetup.txt', 'repeatable.txt', 'setup.txt', |
|
3938 setUp=zc.buildout.testing.buildoutSetUp, |
|
3939 tearDown=zc.buildout.testing.buildoutTearDown, |
|
3940 checker=renormalizing.RENormalizing([ |
|
3941 zc.buildout.testing.normalize_path, |
|
3942 zc.buildout.testing.normalize_endings, |
|
3943 zc.buildout.testing.normalize_script, |
|
3944 zc.buildout.testing.normalize_egg_py, |
|
3945 zc.buildout.tests.hide_distribute_additions, |
|
3946 hide_zip_safe_message, |
|
3947 (re.compile('__buildout_signature__ = recipes-\S+'), |
|
3948 '__buildout_signature__ = recipes-SSSSSSSSSSS'), |
|
3949 (re.compile('executable = [\S ]+python\S*', re.I), |
|
3950 'executable = python'), |
|
3951 (re.compile('[-d] (setuptools|distribute)-\S+[.]egg'), |
|
3952 'setuptools.egg'), |
|
3953 (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'), |
|
3954 'zc.buildout.egg'), |
|
3955 (re.compile('creating \S*setup.cfg'), 'creating setup.cfg'), |
|
3956 (re.compile('hello\%ssetup' % os.path.sep), 'hello/setup'), |
|
3957 (re.compile('Picked: (\S+) = \S+'), |
|
3958 'Picked: \\1 = V.V'), |
|
3959 (re.compile(r'We have a develop egg: zc.buildout (\S+)'), |
|
3960 'We have a develop egg: zc.buildout X.X.'), |
|
3961 (re.compile(r'\\[\\]?'), '/'), |
|
3962 (re.compile('WindowsError'), 'OSError'), |
|
3963 (re.compile(r'\[Error \d+\] Cannot create a file ' |
|
3964 r'when that file already exists: '), |
|
3965 '[Errno 17] File exists: ' |
|
3966 ), |
|
3967 (re.compile('distribute'), 'setuptools'), |
|
3968 ]) |
|
3969 ), |
|
3970 doctest.DocFileSuite( |
|
3971 'debugging.txt', |
|
3972 setUp=zc.buildout.testing.buildoutSetUp, |
|
3973 tearDown=zc.buildout.testing.buildoutTearDown, |
|
3974 checker=renormalizing.RENormalizing([ |
|
3975 zc.buildout.testing.normalize_path, |
|
3976 zc.buildout.testing.normalize_endings, |
|
3977 zc.buildout.tests.hide_distribute_additions, |
|
3978 (re.compile(r'\S+buildout.py'), 'buildout.py'), |
|
3979 (re.compile(r'line \d+'), 'line NNN'), |
|
3980 (re.compile(r'py\(\d+\)'), 'py(NNN)'), |
|
3981 ]) |
|
3982 ), |
|
3983 |
|
3984 doctest.DocFileSuite( |
|
3985 'update.txt', |
|
3986 setUp=updateSetup, |
|
3987 tearDown=zc.buildout.testing.buildoutTearDown, |
|
3988 checker=renormalizing.RENormalizing([ |
|
3989 zc.buildout.testing.normalize_path, |
|
3990 zc.buildout.testing.normalize_endings, |
|
3991 zc.buildout.testing.normalize_script, |
|
3992 zc.buildout.testing.normalize_egg_py, |
|
3993 normalize_bang, |
|
3994 zc.buildout.tests.hide_distribute_additions, |
|
3995 (re.compile('99[.]99'), 'NINETYNINE.NINETYNINE'), |
|
3996 (re.compile('(zc.buildout|setuptools)-\d+[.]\d+\S*' |
|
3997 '-py\d.\d.egg'), |
|
3998 '\\1.egg'), |
|
3999 (re.compile('distribute-\d+[.]\d+\S*' |
|
4000 '-py\d.\d.egg'), |
|
4001 'setuptools.egg'), |
|
4002 (re.compile('(zc.buildout|setuptools)( version)? \d+[.]\d+\S*'), |
|
4003 '\\1 V.V'), |
|
4004 (re.compile('distribute( version)? \d+[.]\d+\S*'), |
|
4005 'setuptools V.V'), |
|
4006 (re.compile('[-d] (setuptools|distribute)'), '- setuptools'), |
|
4007 (re.compile('distribute'), 'setuptools'), |
|
4008 (re.compile("\nUnused options for buildout: " |
|
4009 "'(distribute|setuptools)\-version'\."), |
|
4010 '') |
|
4011 ]) |
|
4012 ), |
|
4013 |
|
4014 doctest.DocFileSuite( |
|
4015 'easy_install.txt', 'downloadcache.txt', 'dependencylinks.txt', |
|
4016 'allowhosts.txt', 'unzip.txt', 'upgrading_distribute.txt', |
|
4017 setUp=easy_install_SetUp, |
|
4018 tearDown=zc.buildout.testing.buildoutTearDown, |
|
4019 checker=renormalizing.RENormalizing([ |
|
4020 zc.buildout.testing.normalize_path, |
|
4021 zc.buildout.testing.normalize_endings, |
|
4022 zc.buildout.testing.normalize_script, |
|
4023 zc.buildout.testing.normalize_egg_py, |
|
4024 normalize_bang, |
|
4025 hide_first_index_page_message, |
|
4026 zc.buildout.tests.hide_distribute_additions, |
|
4027 (re.compile('extdemo[.]pyd'), 'extdemo.so'), |
|
4028 (re.compile('[-d] (setuptools|distribute)-\S+[.]egg'), |
|
4029 'setuptools.egg'), |
|
4030 (re.compile(r'\\[\\]?'), '/'), |
|
4031 (re.compile(r'\#!\S+\bpython\S*'), '#!/usr/bin/python'), |
|
4032 # Normalize generate_script's Windows interpreter to UNIX: |
|
4033 (re.compile(r'\nimport subprocess\n'), '\n'), |
|
4034 (re.compile('subprocess\\.call\\(argv, env=environ\\)'), |
|
4035 'os.execve(sys.executable, argv, environ)'), |
|
4036 (re.compile('distribute'), 'setuptools'), |
|
4037 # Distribute unzips eggs by default. |
|
4038 (re.compile('\- demoneeded'), 'd demoneeded'), |
|
4039 ]+(sys.version_info < (2, 5) and [ |
|
4040 (re.compile('.*No module named runpy.*', re.S), ''), |
|
4041 (re.compile('.*usage: pdb.py scriptfile .*', re.S), ''), |
|
4042 (re.compile('.*Error: what does not exist.*', re.S), ''), |
|
4043 ] or [])), |
|
4044 ), |
|
4045 |
|
4046 doctest.DocFileSuite( |
|
4047 'download.txt', 'extends-cache.txt', |
|
4048 setUp=easy_install_SetUp, |
|
4049 tearDown=zc.buildout.testing.buildoutTearDown, |
|
4050 optionflags=doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS, |
|
4051 checker=renormalizing.RENormalizing([ |
|
4052 (re.compile(' at -?0x[^>]+'), '<MEM ADDRESS>'), |
|
4053 (re.compile('http://localhost:[0-9]{4,5}/'), |
|
4054 'http://localhost/'), |
|
4055 (re.compile('[0-9a-f]{32}'), '<MD5 CHECKSUM>'), |
|
4056 zc.buildout.testing.normalize_path, |
|
4057 ]), |
|
4058 ), |
|
4059 |
|
4060 doctest.DocTestSuite( |
|
4061 setUp=easy_install_SetUp, |
|
4062 tearDown=zc.buildout.testing.buildoutTearDown, |
|
4063 checker=renormalizing.RENormalizing([ |
|
4064 zc.buildout.testing.normalize_path, |
|
4065 zc.buildout.testing.normalize_endings, |
|
4066 zc.buildout.testing.normalize_script, |
|
4067 zc.buildout.testing.normalize_egg_py, |
|
4068 zc.buildout.tests.hide_distribute_additions, |
|
4069 hide_first_index_page_message, |
|
4070 (re.compile("buildout: Running \S*setup.py"), |
|
4071 'buildout: Running setup.py'), |
|
4072 (re.compile('(setuptools|distribute)-\S+-'), |
|
4073 'setuptools.egg'), |
|
4074 (re.compile('zc.buildout-\S+-'), |
|
4075 'zc.buildout.egg'), |
|
4076 (re.compile('File "\S+one.py"'), |
|
4077 'File "one.py"'), |
|
4078 (re.compile(r'We have a develop egg: (\S+) (\S+)'), |
|
4079 r'We have a develop egg: \1 V'), |
|
4080 (re.compile('Picked: (setuptools|distribute) = \S+'), |
|
4081 'Picked: setuptools = V'), |
|
4082 (re.compile(r'\\[\\]?'), '/'), |
|
4083 (re.compile( |
|
4084 '-q develop -mxN -d "/sample-buildout/develop-eggs'), |
|
4085 '-q develop -mxN -d /sample-buildout/develop-eggs' |
|
4086 ), |
|
4087 (re.compile(r'^[*]...'), '...'), |
|
4088 # for bug_92891_bootstrap_crashes_with_egg_recipe_in_buildout_section |
|
4089 (re.compile(r"Unused options for buildout: 'eggs' 'scripts'\."), |
|
4090 "Unused options for buildout: 'scripts' 'eggs'."), |
|
4091 (re.compile('distribute'), 'setuptools'), |
|
4092 # Distribute unzips eggs by default. |
|
4093 (re.compile('\- demoneeded'), 'd demoneeded'), |
|
4094 ]), |
|
4095 ), |
|
4096 zc.buildout.testselectingpython.test_suite(), |
|
4097 zc.buildout.rmtree.test_suite(), |
|
4098 doctest.DocFileSuite( |
|
4099 'windows.txt', |
|
4100 setUp=zc.buildout.testing.buildoutSetUp, |
|
4101 tearDown=zc.buildout.testing.buildoutTearDown, |
|
4102 checker=renormalizing.RENormalizing([ |
|
4103 zc.buildout.testing.normalize_path, |
|
4104 zc.buildout.testing.normalize_endings, |
|
4105 zc.buildout.testing.normalize_script, |
|
4106 zc.buildout.testing.normalize_egg_py, |
|
4107 zc.buildout.tests.hide_distribute_additions, |
|
4108 (re.compile('__buildout_signature__ = recipes-\S+'), |
|
4109 '__buildout_signature__ = recipes-SSSSSSSSSSS'), |
|
4110 (re.compile('[-d] setuptools-\S+[.]egg'), 'setuptools.egg'), |
|
4111 (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'), |
|
4112 'zc.buildout.egg'), |
|
4113 (re.compile('creating \S*setup.cfg'), 'creating setup.cfg'), |
|
4114 (re.compile('hello\%ssetup' % os.path.sep), 'hello/setup'), |
|
4115 (re.compile('Picked: (\S+) = \S+'), |
|
4116 'Picked: \\1 = V.V'), |
|
4117 (re.compile(r'We have a develop egg: zc.buildout (\S+)'), |
|
4118 'We have a develop egg: zc.buildout X.X.'), |
|
4119 (re.compile(r'\\[\\]?'), '/'), |
|
4120 (re.compile('WindowsError'), 'OSError'), |
|
4121 (re.compile(r'\[Error 17\] Cannot create a file ' |
|
4122 r'when that file already exists: '), |
|
4123 '[Errno 17] File exists: ' |
|
4124 ), |
|
4125 ]) |
|
4126 ), |
|
4127 doctest.DocFileSuite( |
|
4128 'testing_bugfix.txt', |
|
4129 checker=renormalizing.RENormalizing([ |
|
4130 # Python 2.7 |
|
4131 (re.compile( |
|
4132 re.escape( |
|
4133 'testrunner.logsupport.NullHandler instance at')), |
|
4134 'testrunner.logsupport.NullHandler object at'), |
|
4135 (re.compile(re.escape('logging.StreamHandler instance at')), |
|
4136 'logging.StreamHandler object at'), |
|
4137 ]) |
|
4138 ), |
|
4139 ] |
|
4140 |
|
4141 # adding bootstrap.txt doctest to the suite |
|
4142 # only if bootstrap.py is present |
|
4143 bootstrap_py = os.path.join( |
|
4144 os.path.dirname( |
|
4145 os.path.dirname( |
|
4146 os.path.dirname( |
|
4147 os.path.dirname(zc.buildout.__file__) |
|
4148 ) |
|
4149 ) |
|
4150 ), |
|
4151 'bootstrap', 'bootstrap.py') |
|
4152 |
|
4153 if os.path.exists(bootstrap_py): |
|
4154 test_suite.append(doctest.DocFileSuite( |
|
4155 'bootstrap.txt', |
|
4156 setUp=bootstrapSetup, |
|
4157 tearDown=zc.buildout.testing.buildoutTearDown, |
|
4158 checker=renormalizing.RENormalizing([ |
|
4159 zc.buildout.testing.normalize_path, |
|
4160 zc.buildout.testing.normalize_endings, |
|
4161 zc.buildout.testing.normalize_script, |
|
4162 zc.buildout.testing.normalize_egg_py, |
|
4163 normalize_bang, |
|
4164 (re.compile('Downloading.*setuptools.*egg\n'), ''), |
|
4165 (re.compile('options:'), 'Options:'), |
|
4166 (re.compile('usage:'), 'Usage:'), |
|
4167 ]), |
|
4168 )) |
|
4169 test_suite.append(doctest.DocFileSuite( |
|
4170 'virtualenv.txt', |
|
4171 setUp=easy_install_SetUp, |
|
4172 tearDown=zc.buildout.testing.buildoutTearDown, |
|
4173 checker=renormalizing.RENormalizing([ |
|
4174 zc.buildout.testing.normalize_path, |
|
4175 zc.buildout.testing.normalize_endings, |
|
4176 zc.buildout.testing.normalize_script, |
|
4177 zc.buildout.testing.normalize_egg_py, |
|
4178 zc.buildout.tests.hide_distribute_additions, |
|
4179 (re.compile('(setuptools|distribute)-\S+-'), |
|
4180 'setuptools.egg'), |
|
4181 (re.compile('zc.buildout-\S+-'), |
|
4182 'zc.buildout.egg'), |
|
4183 (re.compile(re.escape('#!"/executable_buildout/bin/py"')), |
|
4184 '#!/executable_buildout/bin/py'), # Windows. |
|
4185 (re.compile(re.escape('/broken_s/')), |
|
4186 '/broken_S/'), # Windows. |
|
4187 ]), |
|
4188 )) |
|
4189 |
|
4190 return unittest.TestSuite(test_suite) |