PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/zc/buildout/tests.py

https://github.com/koodaamo/buildout
Python | 3306 lines | 3265 code | 21 blank | 20 comment | 10 complexity | 17f211f52168eb2f48e7f7461bf54ebf MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. ##############################################################################
  2. #
  3. # Copyright (c) 2004-2009 Zope Foundation and Contributors.
  4. # All Rights Reserved.
  5. #
  6. # This software is subject to the provisions of the Zope Public License,
  7. # Version 2.1 (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. from zc.buildout.buildout import print_
  15. from zope.testing import renormalizing
  16. import doctest
  17. import manuel.capture
  18. import manuel.doctest
  19. import manuel.testing
  20. import os
  21. import pkg_resources
  22. import re
  23. import shutil
  24. import sys
  25. import tempfile
  26. import unittest
  27. import zc.buildout.easy_install
  28. import zc.buildout.testing
  29. import zipfile
  30. os_path_sep = os.path.sep
  31. if os_path_sep == '\\':
  32. os_path_sep *= 2
  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. >>> mkdir('foo')
  37. >>> write('foo', 'setup.py',
  38. ... '''
  39. ... from distutils.core import setup
  40. ... setup(name="foo")
  41. ... ''')
  42. >>> write('buildout.cfg',
  43. ... '''
  44. ... [buildout]
  45. ... develop = foo
  46. ... parts =
  47. ... ''')
  48. >>> print_(system(join('bin', 'buildout')), end='')
  49. Develop: '/sample-buildout/foo'
  50. >>> ls('develop-eggs')
  51. - foo.egg-link
  52. - zc.recipe.egg.egg-link
  53. """
  54. def develop_verbose():
  55. """
  56. We should be able to deal with setup scripts that aren't setuptools based.
  57. >>> mkdir('foo')
  58. >>> write('foo', 'setup.py',
  59. ... '''
  60. ... from setuptools import setup
  61. ... setup(name="foo")
  62. ... ''')
  63. >>> write('buildout.cfg',
  64. ... '''
  65. ... [buildout]
  66. ... develop = foo
  67. ... parts =
  68. ... ''')
  69. >>> print_(system(join('bin', 'buildout')+' -vv'), end='')
  70. ... # doctest: +ELLIPSIS
  71. Installing...
  72. Develop: '/sample-buildout/foo'
  73. ...
  74. Installed /sample-buildout/foo
  75. ...
  76. >>> ls('develop-eggs')
  77. - foo.egg-link
  78. - zc.recipe.egg.egg-link
  79. >>> print_(system(join('bin', 'buildout')+' -vvv'), end='')
  80. ... # doctest: +ELLIPSIS
  81. Installing...
  82. Develop: '/sample-buildout/foo'
  83. in: '/sample-buildout/foo'
  84. ... -q develop -mxN -d /sample-buildout/develop-eggs/...
  85. """
  86. def buildout_error_handling():
  87. r"""Buildout error handling
  88. Asking for a section that doesn't exist, yields a missing section error:
  89. >>> import os
  90. >>> os.chdir(sample_buildout)
  91. >>> import zc.buildout.buildout
  92. >>> buildout = zc.buildout.buildout.Buildout('buildout.cfg', [])
  93. >>> buildout['eek']
  94. Traceback (most recent call last):
  95. ...
  96. MissingSection: The referenced section, 'eek', was not defined.
  97. Asking for an option that doesn't exist, a MissingOption error is raised:
  98. >>> buildout['buildout']['eek']
  99. Traceback (most recent call last):
  100. ...
  101. MissingOption: Missing option: buildout:eek
  102. It is an error to create a variable-reference cycle:
  103. >>> write(sample_buildout, 'buildout.cfg',
  104. ... '''
  105. ... [buildout]
  106. ... parts =
  107. ... x = ${buildout:y}
  108. ... y = ${buildout:z}
  109. ... z = ${buildout:x}
  110. ... ''')
  111. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')),
  112. ... end='')
  113. ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
  114. While:
  115. Initializing.
  116. Getting section buildout.
  117. Initializing section buildout.
  118. Getting option buildout:x.
  119. Getting option buildout:y.
  120. Getting option buildout:z.
  121. Getting option buildout:x.
  122. Error: Circular reference in substitutions.
  123. It is an error to use funny characters in variable refereces:
  124. >>> write(sample_buildout, 'buildout.cfg',
  125. ... '''
  126. ... [buildout]
  127. ... develop = recipes
  128. ... parts = data_dir debug
  129. ... x = ${bui$ldout:y}
  130. ... ''')
  131. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')),
  132. ... end='')
  133. While:
  134. Initializing.
  135. Getting section buildout.
  136. Initializing section buildout.
  137. Getting option buildout:x.
  138. Error: The section name in substitution, ${bui$ldout:y},
  139. has invalid characters.
  140. >>> write(sample_buildout, 'buildout.cfg',
  141. ... '''
  142. ... [buildout]
  143. ... develop = recipes
  144. ... parts = data_dir debug
  145. ... x = ${buildout:y{z}
  146. ... ''')
  147. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')),
  148. ... end='')
  149. While:
  150. Initializing.
  151. Getting section buildout.
  152. Initializing section buildout.
  153. Getting option buildout:x.
  154. Error: The option name in substitution, ${buildout:y{z},
  155. has invalid characters.
  156. and too have too many or too few colons:
  157. >>> write(sample_buildout, 'buildout.cfg',
  158. ... '''
  159. ... [buildout]
  160. ... develop = recipes
  161. ... parts = data_dir debug
  162. ... x = ${parts}
  163. ... ''')
  164. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')),
  165. ... end='')
  166. While:
  167. Initializing.
  168. Getting section buildout.
  169. Initializing section buildout.
  170. Getting option buildout:x.
  171. Error: The substitution, ${parts},
  172. doesn't contain a colon.
  173. >>> write(sample_buildout, 'buildout.cfg',
  174. ... '''
  175. ... [buildout]
  176. ... develop = recipes
  177. ... parts = data_dir debug
  178. ... x = ${buildout:y:z}
  179. ... ''')
  180. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')),
  181. ... end='')
  182. While:
  183. Initializing.
  184. Getting section buildout.
  185. Initializing section buildout.
  186. Getting option buildout:x.
  187. Error: The substitution, ${buildout:y:z},
  188. has too many colons.
  189. Al parts have to have a section:
  190. >>> write(sample_buildout, 'buildout.cfg',
  191. ... '''
  192. ... [buildout]
  193. ... parts = x
  194. ... ''')
  195. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')),
  196. ... end='')
  197. While:
  198. Installing.
  199. Getting section x.
  200. Error: The referenced section, 'x', was not defined.
  201. and all parts have to have a specified recipe:
  202. >>> write(sample_buildout, 'buildout.cfg',
  203. ... '''
  204. ... [buildout]
  205. ... parts = x
  206. ...
  207. ... [x]
  208. ... foo = 1
  209. ... ''')
  210. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')),
  211. ... end='')
  212. While:
  213. Installing.
  214. Error: Missing option: x:recipe
  215. """
  216. make_dist_that_requires_setup_py_template = """
  217. from setuptools import setup
  218. setup(name=%r, version=%r,
  219. install_requires=%r,
  220. )
  221. """
  222. def make_dist_that_requires(dest, name, requires=[], version=1, egg=''):
  223. os.mkdir(os.path.join(dest, name))
  224. open(os.path.join(dest, name, 'setup.py'), 'w').write(
  225. make_dist_that_requires_setup_py_template
  226. % (name, version, requires)
  227. )
  228. def show_who_requires_when_there_is_a_conflict():
  229. """
  230. It's a pain when we require eggs that have requirements that are
  231. incompatible. We want the error we get to tell us what is missing.
  232. Let's make a few develop distros, some of which have incompatible
  233. requirements.
  234. >>> make_dist_that_requires(sample_buildout, 'sampley',
  235. ... ['demoneeded ==1.0'])
  236. >>> make_dist_that_requires(sample_buildout, 'samplez',
  237. ... ['demoneeded ==1.1'])
  238. Now, let's create a buildout that requires y and z:
  239. >>> write('buildout.cfg',
  240. ... '''
  241. ... [buildout]
  242. ... parts = eggs
  243. ... develop = sampley samplez
  244. ... find-links = %(link_server)s
  245. ...
  246. ... [eggs]
  247. ... recipe = zc.recipe.egg
  248. ... eggs = sampley
  249. ... samplez
  250. ... ''' % globals())
  251. >>> print_(system(buildout), end='')
  252. Develop: '/sample-buildout/sampley'
  253. Develop: '/sample-buildout/samplez'
  254. Installing eggs.
  255. Getting distribution for 'demoneeded==1.1'.
  256. Got demoneeded 1.1.
  257. While:
  258. Installing eggs.
  259. Error: There is a version conflict.
  260. We already have: demoneeded 1.1
  261. but sampley 1 requires 'demoneeded==1.0'.
  262. Here, we see that sampley required an older version of demoneeded. What
  263. if we hadn't required sampley ourselves:
  264. >>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb'])
  265. >>> make_dist_that_requires(sample_buildout, 'sampleb',
  266. ... ['sampley', 'samplea'])
  267. >>> write('buildout.cfg',
  268. ... '''
  269. ... [buildout]
  270. ... parts = eggs
  271. ... develop = sampley samplez samplea sampleb
  272. ... find-links = %(link_server)s
  273. ...
  274. ... [eggs]
  275. ... recipe = zc.recipe.egg
  276. ... eggs = samplea
  277. ... samplez
  278. ... ''' % globals())
  279. If we use the verbose switch, we can see where requirements are coming from:
  280. >>> print_(system(buildout+' -v'), end='') # doctest: +ELLIPSIS
  281. Installing 'zc.buildout >=1.99', 'distribute'.
  282. We have a develop egg: zc.buildout 1.0.0
  283. We have the best distribution that satisfies 'distribute'.
  284. Picked: distribute = 0.6
  285. Develop: '/sample-buildout/sampley'
  286. Develop: '/sample-buildout/samplez'
  287. Develop: '/sample-buildout/samplea'
  288. Develop: '/sample-buildout/sampleb'
  289. ...Installing eggs.
  290. Installing 'samplea', 'samplez'.
  291. We have a develop egg: samplea 1
  292. We have a develop egg: samplez 1
  293. Getting required 'demoneeded==1.1'
  294. required by samplez 1.
  295. We have the distribution that satisfies 'demoneeded==1.1'.
  296. Getting required 'sampleb'
  297. required by samplea 1.
  298. We have a develop egg: sampleb 1
  299. Getting required 'sampley'
  300. required by sampleb 1.
  301. We have a develop egg: sampley 1
  302. While:
  303. Installing eggs.
  304. Error: There is a version conflict.
  305. We already have: demoneeded 1.1
  306. but sampley 1 requires 'demoneeded==1.0'.
  307. """
  308. def show_who_requires_missing_distributions():
  309. """
  310. When working with a lot of eggs, which require eggs recursively, it
  311. can be hard to tell why we're requiring things we can't
  312. find. Fortunately, buildout will tell us who's asking for something
  313. that we can't find. when run in verbose mode
  314. >>> make_dist_that_requires(sample_buildout, 'sampley', ['demoneeded'])
  315. >>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb'])
  316. >>> make_dist_that_requires(sample_buildout, 'sampleb',
  317. ... ['sampley', 'samplea'])
  318. >>> write('buildout.cfg',
  319. ... '''
  320. ... [buildout]
  321. ... parts = eggs
  322. ... develop = sampley samplea sampleb
  323. ...
  324. ... [eggs]
  325. ... recipe = zc.recipe.egg
  326. ... eggs = samplea
  327. ... ''')
  328. >>> print_(system(buildout+' -v'), end='') # doctest: +ELLIPSIS
  329. Installing ...
  330. Installing 'samplea'.
  331. We have a develop egg: samplea 1
  332. Getting required 'sampleb'
  333. required by samplea 1.
  334. We have a develop egg: sampleb 1
  335. Getting required 'sampley'
  336. required by sampleb 1.
  337. We have a develop egg: sampley 1
  338. Getting required 'demoneeded'
  339. required by sampley 1.
  340. We have no distributions for demoneeded that satisfies 'demoneeded'.
  341. ...
  342. While:
  343. Installing eggs.
  344. Getting distribution for 'demoneeded'.
  345. Error: Couldn't find a distribution for 'demoneeded'.
  346. """
  347. def test_comparing_saved_options_with_funny_characters():
  348. """
  349. If an option has newlines, extra/odd spaces or a %, we need to make sure
  350. the comparison with the saved value works correctly.
  351. >>> mkdir(sample_buildout, 'recipes')
  352. >>> write(sample_buildout, 'recipes', 'debug.py',
  353. ... '''
  354. ... class Debug:
  355. ... def __init__(self, buildout, name, options):
  356. ... options['debug'] = \"\"\" <zodb>
  357. ...
  358. ... <filestorage>
  359. ... path foo
  360. ... </filestorage>
  361. ...
  362. ... </zodb>
  363. ... \"\"\"
  364. ... options['debug1'] = \"\"\"
  365. ... <zodb>
  366. ...
  367. ... <filestorage>
  368. ... path foo
  369. ... </filestorage>
  370. ...
  371. ... </zodb>
  372. ... \"\"\"
  373. ... options['debug2'] = ' x '
  374. ... options['debug3'] = '42'
  375. ... options['format'] = '%3d'
  376. ...
  377. ... def install(self):
  378. ... open('t', 'w').write('t')
  379. ... return 't'
  380. ...
  381. ... update = install
  382. ... ''')
  383. >>> write(sample_buildout, 'recipes', 'setup.py',
  384. ... '''
  385. ... from setuptools import setup
  386. ... setup(
  387. ... name = "recipes",
  388. ... entry_points = {'zc.buildout': ['default = debug:Debug']},
  389. ... )
  390. ... ''')
  391. >>> write(sample_buildout, 'recipes', 'README.txt', " ")
  392. >>> write(sample_buildout, 'buildout.cfg',
  393. ... '''
  394. ... [buildout]
  395. ... develop = recipes
  396. ... parts = debug
  397. ...
  398. ... [debug]
  399. ... recipe = recipes
  400. ... ''')
  401. >>> os.chdir(sample_buildout)
  402. >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
  403. >>> print_(system(buildout), end='')
  404. Develop: '/sample-buildout/recipes'
  405. Installing debug.
  406. If we run the buildout again, we shoudn't get a message about
  407. uninstalling anything because the configuration hasn't changed.
  408. >>> print_(system(buildout), end='')
  409. Develop: '/sample-buildout/recipes'
  410. Updating debug.
  411. """
  412. def finding_eggs_as_local_directories():
  413. r"""
  414. It is possible to set up find-links so that we could install from
  415. a local directory that may contained unzipped eggs.
  416. >>> src = tmpdir('src')
  417. >>> write(src, 'setup.py',
  418. ... '''
  419. ... from setuptools import setup
  420. ... setup(name='demo', py_modules=[''],
  421. ... zip_safe=False, version='1.0', author='bob', url='bob',
  422. ... author_email='bob')
  423. ... ''')
  424. >>> write(src, 't.py', '#\n')
  425. >>> write(src, 'README.txt', '')
  426. >>> _ = system(join('bin', 'buildout')+' setup ' + src + ' bdist_egg')
  427. Install it so it gets unzipped:
  428. >>> d1 = tmpdir('d1')
  429. >>> ws = zc.buildout.easy_install.install(
  430. ... ['demo'], d1, links=[join(src, 'dist')],
  431. ... )
  432. >>> ls(d1)
  433. d demo-1.0-py2.4.egg
  434. Then try to install it again:
  435. >>> d2 = tmpdir('d2')
  436. >>> ws = zc.buildout.easy_install.install(
  437. ... ['demo'], d2, links=[d1],
  438. ... )
  439. >>> ls(d2)
  440. d demo-1.0-py2.4.egg
  441. """
  442. def create_sections_on_command_line():
  443. """
  444. >>> write('buildout.cfg',
  445. ... '''
  446. ... [buildout]
  447. ... parts =
  448. ... x = ${foo:bar}
  449. ... ''')
  450. >>> print_(system(buildout + ' foo:bar=1 -vv'), end='')
  451. ... # doctest: +ELLIPSIS
  452. Installing 'zc.buildout >=1.99', 'distribute'.
  453. ...
  454. [foo]
  455. bar = 1
  456. ...
  457. """
  458. def test_help():
  459. """
  460. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')+' -h'))
  461. ... # doctest: +ELLIPSIS
  462. Usage: buildout [options] [assignments] [command [command arguments]]
  463. <BLANKLINE>
  464. Options:
  465. <BLANKLINE>
  466. -h, --help
  467. ...
  468. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')
  469. ... +' --help'))
  470. ... # doctest: +ELLIPSIS
  471. Usage: buildout [options] [assignments] [command [command arguments]]
  472. <BLANKLINE>
  473. Options:
  474. <BLANKLINE>
  475. -h, --help
  476. ...
  477. """
  478. def test_bootstrap_with_extension():
  479. """
  480. We had a problem running a bootstrap with an extension. Let's make
  481. sure it is fixed. Basically, we don't load extensions when
  482. bootstrapping.
  483. >>> d = tmpdir('sample-bootstrap')
  484. >>> write(d, 'buildout.cfg',
  485. ... '''
  486. ... [buildout]
  487. ... extensions = some_awsome_extension
  488. ... parts =
  489. ... ''')
  490. >>> os.chdir(d)
  491. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')
  492. ... + ' bootstrap'), end='')
  493. Creating directory '/sample-bootstrap/bin'.
  494. Creating directory '/sample-bootstrap/parts'.
  495. Creating directory '/sample-bootstrap/eggs'.
  496. Creating directory '/sample-bootstrap/develop-eggs'.
  497. Generated script '/sample-bootstrap/bin/buildout'.
  498. """
  499. def bug_92891_bootstrap_crashes_with_egg_recipe_in_buildout_section():
  500. """
  501. >>> d = tmpdir('sample-bootstrap')
  502. >>> write(d, 'buildout.cfg',
  503. ... '''
  504. ... [buildout]
  505. ... parts = buildout
  506. ... eggs-directory = eggs
  507. ...
  508. ... [buildout]
  509. ... recipe = zc.recipe.egg
  510. ... eggs = zc.buildout
  511. ... scripts = buildout=buildout
  512. ... ''')
  513. >>> os.chdir(d)
  514. >>> print_(system(os.path.join(sample_buildout, 'bin', 'buildout')
  515. ... + ' bootstrap'), end='')
  516. Creating directory '/sample-bootstrap/bin'.
  517. Creating directory '/sample-bootstrap/parts'.
  518. Creating directory '/sample-bootstrap/eggs'.
  519. Creating directory '/sample-bootstrap/develop-eggs'.
  520. Generated script '/sample-bootstrap/bin/buildout'.
  521. >>> print_(system(os.path.join('bin', 'buildout')), end='')
  522. Unused options for buildout: 'scripts' 'eggs'.
  523. """
  524. def removing_eggs_from_develop_section_causes_egg_link_to_be_removed():
  525. '''
  526. >>> cd(sample_buildout)
  527. Create a develop egg:
  528. >>> mkdir('foo')
  529. >>> write('foo', 'setup.py',
  530. ... """
  531. ... from setuptools import setup
  532. ... setup(name='foox')
  533. ... """)
  534. >>> write('buildout.cfg',
  535. ... """
  536. ... [buildout]
  537. ... develop = foo
  538. ... parts =
  539. ... """)
  540. >>> print_(system(join('bin', 'buildout')), end='')
  541. Develop: '/sample-buildout/foo'
  542. >>> ls('develop-eggs')
  543. - foox.egg-link
  544. - zc.recipe.egg.egg-link
  545. Create another:
  546. >>> mkdir('bar')
  547. >>> write('bar', 'setup.py',
  548. ... """
  549. ... from setuptools import setup
  550. ... setup(name='fooy')
  551. ... """)
  552. >>> write('buildout.cfg',
  553. ... """
  554. ... [buildout]
  555. ... develop = foo bar
  556. ... parts =
  557. ... """)
  558. >>> print_(system(join('bin', 'buildout')), end='')
  559. Develop: '/sample-buildout/foo'
  560. Develop: '/sample-buildout/bar'
  561. >>> ls('develop-eggs')
  562. - foox.egg-link
  563. - fooy.egg-link
  564. - zc.recipe.egg.egg-link
  565. Remove one:
  566. >>> write('buildout.cfg',
  567. ... """
  568. ... [buildout]
  569. ... develop = bar
  570. ... parts =
  571. ... """)
  572. >>> print_(system(join('bin', 'buildout')), end='')
  573. Develop: '/sample-buildout/bar'
  574. It is gone
  575. >>> ls('develop-eggs')
  576. - fooy.egg-link
  577. - zc.recipe.egg.egg-link
  578. Remove the other:
  579. >>> write('buildout.cfg',
  580. ... """
  581. ... [buildout]
  582. ... parts =
  583. ... """)
  584. >>> print_(system(join('bin', 'buildout')), end='')
  585. All gone
  586. >>> ls('develop-eggs')
  587. - zc.recipe.egg.egg-link
  588. '''
  589. def add_distribute_to_dependencies_when_namespace_packages():
  590. '''
  591. Often, a package depends on distribute soley by virtue of using
  592. namespace packages. In this situation, package authors often forget to
  593. declare distribute as a dependency. This is a mistake, but,
  594. unfortunately, a common one that we need to work around. If an egg
  595. uses namespace packages and does not include distribute as a depenency,
  596. we will still include distribute in the working set. If we see this for
  597. a devlop egg, we will also generate a warning.
  598. >>> mkdir('foo')
  599. >>> mkdir('foo', 'src')
  600. >>> mkdir('foo', 'src', 'stuff')
  601. >>> write('foo', 'src', 'stuff', '__init__.py',
  602. ... """__import__('pkg_resources').declare_namespace(__name__)
  603. ... """)
  604. >>> mkdir('foo', 'src', 'stuff', 'foox')
  605. >>> write('foo', 'src', 'stuff', 'foox', '__init__.py', '')
  606. >>> write('foo', 'setup.py',
  607. ... """
  608. ... from setuptools import setup
  609. ... setup(name='foox',
  610. ... namespace_packages = ['stuff'],
  611. ... package_dir = {'': 'src'},
  612. ... packages = ['stuff', 'stuff.foox'],
  613. ... )
  614. ... """)
  615. >>> write('foo', 'README.txt', '')
  616. >>> write('buildout.cfg',
  617. ... """
  618. ... [buildout]
  619. ... develop = foo
  620. ... parts =
  621. ... """)
  622. >>> print_(system(join('bin', 'buildout')), end='')
  623. Develop: '/sample-buildout/foo'
  624. Now, if we generate a working set using the egg link, we will get a warning
  625. and we will get distribute included in the working set.
  626. >>> import logging, zope.testing.loggingsupport
  627. >>> handler = zope.testing.loggingsupport.InstalledHandler(
  628. ... 'zc.buildout.easy_install', level=logging.WARNING)
  629. >>> logging.getLogger('zc.buildout.easy_install').propagate = False
  630. >>> [dist.project_name
  631. ... for dist in zc.buildout.easy_install.working_set(
  632. ... ['foox'], sys.executable,
  633. ... [join(sample_buildout, 'eggs'),
  634. ... join(sample_buildout, 'develop-eggs'),
  635. ... ])]
  636. ['foox', 'distribute']
  637. >>> print_(handler)
  638. zc.buildout.easy_install WARNING
  639. Develop distribution: foox 0.0.0
  640. uses namespace packages but the distribution does not require distribute.
  641. >>> handler.clear()
  642. On the other hand, if we have a regular egg, rather than a develop egg:
  643. >>> os.remove(join('develop-eggs', 'foox.egg-link'))
  644. >>> _ = system(join('bin', 'buildout') + ' setup foo bdist_egg -d'
  645. ... + join(sample_buildout, 'eggs'))
  646. >>> ls('develop-eggs')
  647. - zc.recipe.egg.egg-link
  648. >>> ls('eggs') # doctest: +ELLIPSIS
  649. - distribute.eggpyN.N.egg
  650. - foox-0.0.0-py2.4.egg
  651. ...
  652. We do not get a warning, but we do get distribute included in the working set:
  653. >>> [dist.project_name
  654. ... for dist in zc.buildout.easy_install.working_set(
  655. ... ['foox'], sys.executable,
  656. ... [join(sample_buildout, 'eggs'),
  657. ... join(sample_buildout, 'develop-eggs'),
  658. ... ])]
  659. ['foox', 'distribute']
  660. >>> print_(handler, end='')
  661. We get the same behavior if the it is a depedency that uses a
  662. namespace package.
  663. >>> mkdir('bar')
  664. >>> write('bar', 'setup.py',
  665. ... """
  666. ... from setuptools import setup
  667. ... setup(name='bar', install_requires = ['foox'])
  668. ... """)
  669. >>> write('bar', 'README.txt', '')
  670. >>> write('buildout.cfg',
  671. ... """
  672. ... [buildout]
  673. ... develop = foo bar
  674. ... parts =
  675. ... """)
  676. >>> print_(system(join('bin', 'buildout')), end='')
  677. Develop: '/sample-buildout/foo'
  678. Develop: '/sample-buildout/bar'
  679. >>> [dist.project_name
  680. ... for dist in zc.buildout.easy_install.working_set(
  681. ... ['bar'], sys.executable,
  682. ... [join(sample_buildout, 'eggs'),
  683. ... join(sample_buildout, 'develop-eggs'),
  684. ... ])]
  685. ['bar', 'foox', 'distribute']
  686. >>> print_(handler, end='')
  687. zc.buildout.easy_install WARNING
  688. Develop distribution: foox 0.0.0
  689. uses namespace packages but the distribution does not require distribute.
  690. >>> logging.getLogger('zc.buildout.easy_install').propagate = True
  691. >>> handler.uninstall()
  692. '''
  693. def develop_preserves_existing_setup_cfg():
  694. """
  695. See "Handling custom build options for extensions in develop eggs" in
  696. easy_install.txt. This will be very similar except that we'll have an
  697. existing setup.cfg:
  698. >>> write(extdemo, "setup.cfg",
  699. ... '''
  700. ... # sampe cfg file
  701. ...
  702. ... [foo]
  703. ... bar = 1
  704. ...
  705. ... [build_ext]
  706. ... define = X,Y
  707. ... ''')
  708. >>> mkdir('include')
  709. >>> write('include', 'extdemo.h',
  710. ... '''
  711. ... #define EXTDEMO 42
  712. ... ''')
  713. >>> dest = tmpdir('dest')
  714. >>> zc.buildout.easy_install.develop(
  715. ... extdemo, dest,
  716. ... {'include-dirs': os.path.join(sample_buildout, 'include')})
  717. '/dest/extdemo.egg-link'
  718. >>> ls(dest)
  719. - extdemo.egg-link
  720. >>> cat(extdemo, "setup.cfg")
  721. <BLANKLINE>
  722. # sampe cfg file
  723. <BLANKLINE>
  724. [foo]
  725. bar = 1
  726. <BLANKLINE>
  727. [build_ext]
  728. define = X,Y
  729. """
  730. def uninstall_recipes_used_for_removal():
  731. r"""
  732. Uninstall recipes need to be called when a part is removed too:
  733. >>> mkdir("recipes")
  734. >>> write("recipes", "setup.py",
  735. ... '''
  736. ... from setuptools import setup
  737. ... setup(name='recipes',
  738. ... entry_points={
  739. ... 'zc.buildout': ["demo=demo:Install"],
  740. ... 'zc.buildout.uninstall': ["demo=demo:uninstall"],
  741. ... })
  742. ... ''')
  743. >>> write("recipes", "demo.py",
  744. ... r'''
  745. ... import sys
  746. ... class Install:
  747. ... def __init__(*args): pass
  748. ... def install(self):
  749. ... sys.stdout.write('installing\n')
  750. ... return ()
  751. ... def uninstall(name, options):
  752. ... sys.stdout.write('uninstalling\n')
  753. ... ''')
  754. >>> write('buildout.cfg', '''
  755. ... [buildout]
  756. ... develop = recipes
  757. ... parts = demo
  758. ... [demo]
  759. ... recipe = recipes:demo
  760. ... ''')
  761. >>> print_(system(join('bin', 'buildout')), end='')
  762. Develop: '/sample-buildout/recipes'
  763. Installing demo.
  764. installing
  765. >>> write('buildout.cfg', '''
  766. ... [buildout]
  767. ... develop = recipes
  768. ... parts = demo
  769. ... [demo]
  770. ... recipe = recipes:demo
  771. ... x = 1
  772. ... ''')
  773. >>> print_(system(join('bin', 'buildout')), end='')
  774. Develop: '/sample-buildout/recipes'
  775. Uninstalling demo.
  776. Running uninstall recipe.
  777. uninstalling
  778. Installing demo.
  779. installing
  780. >>> write('buildout.cfg', '''
  781. ... [buildout]
  782. ... develop = recipes
  783. ... parts =
  784. ... ''')
  785. >>> print_(system(join('bin', 'buildout')), end='')
  786. Develop: '/sample-buildout/recipes'
  787. Uninstalling demo.
  788. Running uninstall recipe.
  789. uninstalling
  790. """
  791. def extensions_installed_as_eggs_work_in_offline_mode():
  792. '''
  793. >>> mkdir('demo')
  794. >>> write('demo', 'demo.py',
  795. ... r"""
  796. ... import sys
  797. ... def print_(*args):
  798. ... sys.stdout.write(' '.join(map(str, args)) + '\\n')
  799. ... def ext(buildout):
  800. ... print_('ext', list(buildout))
  801. ... """)
  802. >>> write('demo', 'setup.py',
  803. ... """
  804. ... from setuptools import setup
  805. ...
  806. ... setup(
  807. ... name = "demo",
  808. ... py_modules=['demo'],
  809. ... entry_points = {'zc.buildout.extension': ['ext = demo:ext']},
  810. ... )
  811. ... """)
  812. >>> bdist_egg(join(sample_buildout, "demo"), sys.executable,
  813. ... join(sample_buildout, "eggs"))
  814. >>> write(sample_buildout, 'buildout.cfg',
  815. ... """
  816. ... [buildout]
  817. ... extensions = demo
  818. ... parts =
  819. ... offline = true
  820. ... """)
  821. >>> print_(system(join(sample_buildout, 'bin', 'buildout')), end='')
  822. ext ['buildout']
  823. '''
  824. def changes_in_svn_or_CVS_dont_affect_sig():
  825. """
  826. If we have a develop recipe, it's signature shouldn't be affected to
  827. changes in .svn or CVS directories.
  828. >>> mkdir('recipe')
  829. >>> write('recipe', 'setup.py',
  830. ... '''
  831. ... from setuptools import setup
  832. ... setup(name='recipe',
  833. ... entry_points={'zc.buildout': ['default=foo:Foo']})
  834. ... ''')
  835. >>> write('recipe', 'foo.py',
  836. ... '''
  837. ... class Foo:
  838. ... def __init__(*args): pass
  839. ... def install(*args): return ()
  840. ... update = install
  841. ... ''')
  842. >>> write('buildout.cfg',
  843. ... '''
  844. ... [buildout]
  845. ... develop = recipe
  846. ... parts = foo
  847. ...
  848. ... [foo]
  849. ... recipe = recipe
  850. ... ''')
  851. >>> print_(system(join(sample_buildout, 'bin', 'buildout')), end='')
  852. Develop: '/sample-buildout/recipe'
  853. Installing foo.
  854. >>> mkdir('recipe', '.svn')
  855. >>> mkdir('recipe', 'CVS')
  856. >>> print_(system(join(sample_buildout, 'bin', 'buildout')), end='')
  857. Develop: '/sample-buildout/recipe'
  858. Updating foo.
  859. >>> write('recipe', '.svn', 'x', '1')
  860. >>> write('recipe', 'CVS', 'x', '1')
  861. >>> print_(system(join(sample_buildout, 'bin', 'buildout')), end='')
  862. Develop: '/sample-buildout/recipe'
  863. Updating foo.
  864. """
  865. if hasattr(os, 'symlink'):
  866. def bug_250537_broken_symlink_doesnt_affect_sig():
  867. """
  868. If we have a develop recipe, it's signature shouldn't be affected by
  869. broken symlinks, and better yet, computing the hash should not break
  870. because of the missing target file.
  871. >>> mkdir('recipe')
  872. >>> write('recipe', 'setup.py',
  873. ... '''
  874. ... from setuptools import setup
  875. ... setup(name='recipe',
  876. ... entry_points={'zc.buildout': ['default=foo:Foo']})
  877. ... ''')
  878. >>> write('recipe', 'foo.py',
  879. ... '''
  880. ... class Foo:
  881. ... def __init__(*args): pass
  882. ... def install(*args): return ()
  883. ... update = install
  884. ... ''')
  885. >>> write('buildout.cfg',
  886. ... '''
  887. ... [buildout]
  888. ... develop = recipe
  889. ... parts = foo
  890. ...
  891. ... [foo]
  892. ... recipe = recipe
  893. ... ''')
  894. >>> print_(system(join(sample_buildout, 'bin', 'buildout')), end='')
  895. Develop: '/sample-buildout/recipe'
  896. Installing foo.
  897. >>> write('recipe', 'some-file', '1')
  898. >>> os.symlink(join('recipe', 'some-file'),
  899. ... join('recipe', 'another-file'))
  900. >>> remove('recipe', 'some-file')
  901. >>> print_(system(join(sample_buildout, 'bin', 'buildout')), end='')
  902. Develop: '/sample-buildout/recipe'
  903. Updating foo.
  904. """
  905. def o_option_sets_offline():
  906. """
  907. >>> print_(system(join(sample_buildout, 'bin', 'buildout')+' -vvo'), end='')
  908. ... # doctest: +ELLIPSIS
  909. <BLANKLINE>
  910. ...
  911. offline = true
  912. ...
  913. """
  914. def recipe_upgrade():
  915. r"""
  916. The buildout will upgrade recipes in newest (and non-offline) mode.
  917. Let's create a recipe egg
  918. >>> mkdir('recipe')
  919. >>> write('recipe', 'recipe.py',
  920. ... r'''
  921. ... import sys
  922. ... class Recipe:
  923. ... def __init__(*a): pass
  924. ... def install(self):
  925. ... sys.stdout.write('recipe v1\n')
  926. ... return ()
  927. ... update = install
  928. ... ''')
  929. >>> write('recipe', 'setup.py',
  930. ... '''
  931. ... from setuptools import setup
  932. ... setup(name='recipe', version='1', py_modules=['recipe'],
  933. ... entry_points={'zc.buildout': ['default = recipe:Recipe']},
  934. ... )
  935. ... ''')
  936. >>> write('recipe', 'README', '')
  937. >>> print_(system(buildout+' setup recipe bdist_egg')) # doctest: +ELLIPSIS
  938. Running setup script 'recipe/setup.py'.
  939. ...
  940. >>> rmdir('recipe', 'build')
  941. And update our buildout to use it.
  942. >>> write('buildout.cfg',
  943. ... '''
  944. ... [buildout]
  945. ... parts = foo
  946. ... find-links = %s
  947. ...
  948. ... [foo]
  949. ... recipe = recipe
  950. ... ''' % join('recipe', 'dist'))
  951. >>> print_(system(buildout), end='')
  952. Getting distribution for 'recipe'.
  953. Got recipe 1.
  954. Installing foo.
  955. recipe v1
  956. Now, if we update the recipe egg:
  957. >>> write('recipe', 'recipe.py',
  958. ... r'''
  959. ... import sys
  960. ... class Recipe:
  961. ... def __init__(*a): pass
  962. ... def install(self):
  963. ... sys.stdout.write('recipe v2\n')
  964. ... return ()
  965. ... update = install
  966. ... ''')
  967. >>> write('recipe', 'setup.py',
  968. ... '''
  969. ... from setuptools import setup
  970. ... setup(name='recipe', version='2', py_modules=['recipe'],
  971. ... entry_points={'zc.buildout': ['default = recipe:Recipe']},
  972. ... )
  973. ... ''')
  974. >>> print_(system(buildout+' setup recipe bdist_egg')) # doctest: +ELLIPSIS
  975. Running setup script 'recipe/setup.py'.
  976. ...
  977. We won't get the update if we specify -N:
  978. >>> print_(system(buildout+' -N'), end='')
  979. Updating foo.
  980. recipe v1
  981. or if we use -o:
  982. >>> print_(system(buildout+' -o'), end='')
  983. Updating foo.
  984. recipe v1
  985. But we will if we use neither of these:
  986. >>> print_(system(buildout), end='')
  987. Getting distribution for 'recipe'.
  988. Got recipe 2.
  989. Uninstalling foo.
  990. Installing foo.
  991. recipe v2
  992. We can also select a particular recipe version:
  993. >>> write('buildout.cfg',
  994. ... '''
  995. ... [buildout]
  996. ... parts = foo
  997. ... find-links = %s
  998. ...
  999. ... [foo]
  1000. ... recipe = recipe ==1
  1001. ... ''' % join('recipe', 'dist'))
  1002. >>> print_(system(buildout), end='')
  1003. Uninstalling foo.
  1004. Installing foo.
  1005. recipe v1
  1006. """
  1007. def update_adds_to_uninstall_list():
  1008. """
  1009. Paths returned by the update method are added to the list of paths to
  1010. uninstall
  1011. >>> mkdir('recipe')
  1012. >>> write('recipe', 'setup.py',
  1013. ... '''
  1014. ... from setuptools import setup
  1015. ... setup(name='recipe',
  1016. ... entry_points={'zc.buildout': ['default = recipe:Recipe']},
  1017. ... )
  1018. ... ''')
  1019. >>> write('recipe', 'recipe.py',
  1020. ... '''
  1021. ... import os
  1022. ... class Recipe:
  1023. ... def __init__(*_): pass
  1024. ... def install(self):
  1025. ... r = ('a', 'b', 'c')
  1026. ... for p in r: os.mkdir(p)
  1027. ... return r
  1028. ... def update(self):
  1029. ... r = ('c', 'd', 'e')
  1030. ... for p in r:
  1031. ... if not os.path.exists(p):
  1032. ... os.mkdir(p)
  1033. ... return r
  1034. ... ''')
  1035. >>> write('buildout.cfg',
  1036. ... '''
  1037. ... [buildout]
  1038. ... develop = recipe
  1039. ... parts = foo
  1040. ...
  1041. ... [foo]
  1042. ... recipe = recipe
  1043. ... ''')
  1044. >>> print_(system(buildout), end='')
  1045. Develop: '/sample-buildout/recipe'
  1046. Installing foo.
  1047. >>> print_(system(buildout), end='')
  1048. Develop: '/sample-buildout/recipe'
  1049. Updating foo.
  1050. >>> cat('.installed.cfg') # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
  1051. [buildout]
  1052. ...
  1053. [foo]
  1054. __buildout_installed__ = a
  1055. b
  1056. c
  1057. d
  1058. e
  1059. __buildout_signature__ = ...
  1060. """
  1061. def log_when_there_are_not_local_distros():
  1062. """
  1063. >>> from zope.testing.loggingsupport import InstalledHandler
  1064. >>> handler = InstalledHandler('zc.buildout.easy_install')
  1065. >>> import logging
  1066. >>> logger = logging.getLogger('zc.buildout.easy_install')
  1067. >>> old_propogate = logger.propagate
  1068. >>> logger.propagate = False
  1069. >>> dest = tmpdir('sample-install')
  1070. >>> import zc.buildout.easy_install
  1071. >>> ws = zc.buildout.easy_install.install(
  1072. ... ['demo==0.2'], dest,
  1073. ... links=[link_server], index=link_server+'index/')
  1074. >>> print_(handler) # doctest: +ELLIPSIS
  1075. zc.buildout.easy_install DEBUG
  1076. Installing 'demo==0.2'.
  1077. zc.buildout.easy_install DEBUG
  1078. We have no distributions for demo that satisfies 'demo==0.2'.
  1079. ...
  1080. >>> handler.uninstall()
  1081. >>> logger.propagate = old_propogate
  1082. """
  1083. def internal_errors():
  1084. """Internal errors are clearly marked and don't generate tracebacks:
  1085. >>> mkdir(sample_buildout, 'recipes')
  1086. >>> write(sample_buildout, 'recipes', 'mkdir.py',
  1087. ... '''
  1088. ... class Mkdir:
  1089. ... def __init__(self, buildout, name, options):
  1090. ... self.name, self.options = name, options
  1091. ... options['path'] = os.path.join(
  1092. ... buildout['buildout']['directory'],
  1093. ... options['path'],
  1094. ... )
  1095. ... ''')
  1096. >>> write(sample_buildout, 'recipes', 'setup.py',
  1097. ... '''
  1098. ... from setuptools import setup
  1099. ... setup(name = "recipes",
  1100. ... entry_points = {'zc.buildout': ['mkdir = mkdir:Mkdir']},
  1101. ... )
  1102. ... ''')
  1103. >>> write(sample_buildout, 'buildout.cfg',
  1104. ... '''
  1105. ... [buildout]
  1106. ... develop = recipes
  1107. ... parts = data-dir
  1108. ...
  1109. ... [data-dir]
  1110. ... recipe = recipes:mkdir
  1111. ... ''')
  1112. >>> print_(system(buildout), end='') # doctest: +ELLIPSIS
  1113. Develop: '/sample-buildout/recipes'
  1114. While:
  1115. Installing.
  1116. Getting section data-dir.
  1117. Initializing part data-dir.
  1118. <BLANKLINE>
  1119. An internal error occured due to a bug in either zc.buildout or in a
  1120. recipe being used:
  1121. Traceback (most recent call last):
  1122. ...
  1123. NameError: global name 'os' is not defined
  1124. """
  1125. def whine_about_unused_options():
  1126. '''
  1127. >>> write('foo.py',
  1128. ... """
  1129. ... class Foo:
  1130. ...
  1131. ... def __init__(self, buildout, name, options):
  1132. ... self.name, self.options = name, options
  1133. ... options['x']
  1134. ...
  1135. ... def install(self):
  1136. ... self.options['y']
  1137. ... return ()
  1138. ... """)
  1139. >>> write('setup.py',
  1140. ... """
  1141. ... from setuptools import setup
  1142. ... setup(name = "foo",
  1143. ... entry_points = {'zc.buildout': ['default = foo:Foo']},
  1144. ... )
  1145. ... """)
  1146. >>> write('buildout.cfg',
  1147. ... """
  1148. ... [buildout]
  1149. ... develop = .
  1150. ... parts = foo
  1151. ... a = 1
  1152. ...
  1153. ... [foo]
  1154. ... recipe = foo
  1155. ... x = 1
  1156. ... y = 1
  1157. ... z = 1
  1158. ... """)
  1159. >>> print_(system(buildout), end='')
  1160. Develop: '/sample-buildout/.'
  1161. Unused options for buildout: 'a'.
  1162. Installing foo.
  1163. Unused options for foo: 'z'.
  1164. '''
  1165. def abnormal_exit():
  1166. """
  1167. People sometimes hit control-c while running a builout. We need to make
  1168. sure that the installed database Isn't corrupted. To test this, we'll create
  1169. some evil recipes that exit uncleanly:
  1170. >>> mkdir('recipes')
  1171. >>> write('recipes', 'recipes.py',
  1172. ... '''
  1173. ... import os
  1174. ...
  1175. ... class Clean:
  1176. ... def __init__(*_): pass
  1177. ... def install(_): return ()
  1178. ... def update(_): pass
  1179. ...
  1180. ... class EvilInstall(Clean):
  1181. ... def install(_): os._exit(1)
  1182. ...
  1183. ... class EvilUpdate(Clean):
  1184. ... def update(_): os._exit(1)
  1185. ... ''')
  1186. >>> write('recipes', 'setup.py',
  1187. ... '''
  1188. ... import setuptools
  1189. ... setuptools.setup(name='recipes',
  1190. ... entry_points = {
  1191. ... 'zc.buildout': [
  1192. ... 'clean = recipes:Clean',
  1193. ... 'evil_install = recipes:EvilInstall',
  1194. ... 'evil_update = recipes:EvilUpdate',
  1195. ... 'evil_uninstall = recipes:Clean',
  1196. ... ],
  1197. ... },
  1198. ... )
  1199. ... ''')
  1200. Now let's look at 3 cases:
  1201. 1. We exit during installation after installing some other parts:
  1202. >>> write('buildout.cfg',
  1203. ... '''
  1204. ... [buildout]
  1205. ... develop = recipes
  1206. ... parts = p1 p2 p3 p4
  1207. ...
  1208. ... [p1]
  1209. ... recipe = recipes:clean
  1210. ...
  1211. ... [p2]
  1212. ... recipe = recipes:clean
  1213. ...
  1214. ... [p3]
  1215. ... recipe = recipes:evil_install
  1216. ...
  1217. ... [p4]
  1218. ... recipe = recipes:clean
  1219. ... ''')
  1220. >>> print_(system(buildout), end='')
  1221. Develop: '/sample-buildout/recipes'
  1222. Installing p1.
  1223. Installing p2.
  1224. Installing p3.
  1225. >>> print_(system(buildout), end='')
  1226. Develop: '/sample-buildout/recipes'
  1227. Updating p1.
  1228. Updating p2.
  1229. Installing p3.
  1230. >>> print_(system(buildout+' buildout:parts='), end='')
  1231. Develop: '/sample-buildout/recipes'
  1232. Uninstalling p2.
  1233. Uninstalling p1.
  1234. 2. We exit while updating:
  1235. >>> write('buildout.cfg',
  1236. ... '''
  1237. ... [buildout]
  1238. ... develop = recipes
  1239. ... parts = p1 p2 p3 p4
  1240. ...
  1241. ... [p1]
  1242. ... recipe = recipes:clean
  1243. ...
  1244. ... [p2]
  1245. ... recipe = recipes:clean
  1246. ...
  1247. ... [p3]
  1248. ... recipe = recipes:evil_update
  1249. ...
  1250. ... [p4]
  1251. ... recipe = recipes:clean
  1252. ... ''')
  1253. >>> print_(system(buildout), end='')
  1254. Develop: '/sample-buildout/recipes'
  1255. Installing p1.
  1256. Installing p2.
  1257. Installing p3.
  1258. Installing p4.
  1259. >>> print_(system(buildout), end='')
  1260. Develop: '/sample-buildout/recipes'
  1261. Updating p1.
  1262. Updating p2.
  1263. Updating p3.
  1264. >>> print_(system(buildout+' buildout:parts='), end='')
  1265. Develop: '/sample-buildout/recipes'
  1266. Uninstalling p2.
  1267. Uninstalling p1.
  1268. Uninstalling p4.
  1269. Uninstalling p3.
  1270. 3. We exit while installing or updating after uninstalling:
  1271. >>> write('buildout.cfg',
  1272. ... '''
  1273. ... [buildout]
  1274. ... develop = recipes
  1275. ... parts = p1 p2 p3 p4
  1276. ...
  1277. ... [p1]
  1278. ... recipe = recipes:evil_update
  1279. ...
  1280. ... [p2]
  1281. ... recipe = recipes:clean
  1282. ...
  1283. ... [p3]
  1284. ... recipe = recipes:clean
  1285. ...
  1286. ... [p4]
  1287. ... recipe = recipes:clean
  1288. ... ''')
  1289. >>> print_(system(buildout), end='')
  1290. Develop: '/sample-buildout/recipes'
  1291. Installing p1.
  1292. Installing p2.
  1293. Installing p3.
  1294. Installing p4.
  1295. >>> write('buildout.cfg',
  1296. ... '''
  1297. ... [buildout]
  1298. ... develop = recipes
  1299. ... parts = p1 p2 p3 p4
  1300. ...
  1301. ... [p1]
  1302. ... recipe = recipes:evil_update
  1303. ...
  1304. ... [p2]
  1305. ... recipe = recipes:clean
  1306. ...
  1307. ... [p3]
  1308. ... recipe = recipes:clean
  1309. ...
  1310. ... [p4]
  1311. ... recipe = recipes:clean
  1312. ... x = 1
  1313. ... ''')
  1314. >>> print_(system(buildout), end='')
  1315. Develop: '/sample-buildout/recipes'
  1316. Uninstalling p4.
  1317. Updating p1.
  1318. >>> write('buildout.cfg',
  1319. ... '''
  1320. ... [buildout]
  1321. ... develop = recipes
  1322. ... parts = p1 p2 p3 p4
  1323. ...
  1324. ... [p1]
  1325. ... recipe = recipes:clean
  1326. ...
  1327. ... [p2]
  1328. ... recipe = recipes:clean
  1329. ...
  1330. ... [p3]
  1331. ... recipe = recipes:clean
  1332. ...
  1333. ... [p4]
  1334. ... recipe = recipes:clean
  1335. ... ''')
  1336. >>> print_(system(buildout), end='')
  1337. Develop: '/sample-buildout/recipes'
  1338. Uninstalling p1.
  1339. Installing p1.
  1340. Updating p2.
  1341. Updating p3.
  1342. Installing p4.
  1343. """
  1344. def install_source_dist_with_bad_py():
  1345. r"""
  1346. >>> mkdir('badegg')
  1347. >>> mkdir('badegg', 'badegg')
  1348. >>> write('badegg', 'badegg', '__init__.py', '#\\n')
  1349. >>> mkdir('badegg', 'badegg', 'scripts')
  1350. >>> write('badegg', 'badegg', 'scripts', '__init__.py', '#\\n')
  1351. >>> write('badegg', 'badegg', 'scripts', 'one.py',
  1352. ... '''
  1353. ... return 1
  1354. ... ''')
  1355. >>> write('badegg', 'setup.py',
  1356. ... '''
  1357. ... from setuptools import setup, find_packages
  1358. ... setup(
  1359. ... name='badegg',
  1360. ... version='1',
  1361. ... packages = find_packages('.'),
  1362. ... zip_safe=False)
  1363. ... ''')
  1364. >>> print_(system(buildout+' setup badegg sdist'), end='') # doctest: +ELLIPSIS
  1365. Running setup script 'badegg/setup.py'.
  1366. ...
  1367. >>> dist = join('badegg', 'dist')
  1368. >>> write('buildout.cfg',
  1369. ... '''
  1370. ... [buildout]
  1371. ... parts = eggs bo
  1372. ... find-links = %(dist)s
  1373. ...
  1374. ... [eggs]
  1375. ... recipe = zc.recipe.egg
  1376. ... eggs = badegg
  1377. ...
  1378. ... [bo]
  1379. ... recipe = zc.recipe.egg
  1380. ... eggs = zc.buildout
  1381. ... scripts = buildout=bo
  1382. ... ''' % globals())
  1383. >>> print_(system(buildout));print_('X') # doctest: +ELLIPSIS
  1384. Installing eggs.
  1385. Getting distribution for 'badegg'.
  1386. Got badegg 1.
  1387. Installing bo.
  1388. ...
  1389. SyntaxError: ...'return' outside function...
  1390. ...
  1391. SyntaxError: ...'return' outside function...
  1392. ...
  1393. >>> ls('eggs') # doctest: +ELLIPSIS
  1394. d badegg-1-py2.4.egg
  1395. ...
  1396. >>> ls('bin')
  1397. - bo
  1398. - buildout
  1399. """
  1400. def version_requirements_in_build_honored():
  1401. '''
  1402. >>> update_extdemo()
  1403. >>> dest = tmpdir('sample-install')
  1404. >>> mkdir('include')
  1405. >>> write('include', 'extdemo.h',
  1406. ... """
  1407. ... #define EXTDEMO 42
  1408. ... """)
  1409. >>> zc.buildout.easy_install.build(
  1410. ... 'extdemo ==1.4', dest,
  1411. ... {'include-dirs': os.path.join(sample_buildout, 'include')},
  1412. ... links=[link_server], index=link_server+'index/',
  1413. ... newest=False)
  1414. ['/sample-install/extdemo-1.4-py2.4-linux-i686.egg']
  1415. '''
  1416. def bug_105081_Specific_egg_versions_are_ignored_when_newer_eggs_are_around():
  1417. """
  1418. Buildout might ignore a specific egg requirement for a recipe:
  1419. - Have a newer version of an egg in your eggs directory
  1420. - Use 'recipe==olderversion' in your buildout.cfg to request an
  1421. older version
  1422. Buildout will go and fetch the older version, but it will *use*
  1423. the newer version when installing a part with this recipe.
  1424. >>> write('buildout.cfg',
  1425. ... '''
  1426. ... [buildout]
  1427. ... parts = x
  1428. ... find-links = %(sample_eggs)s
  1429. ...
  1430. ... [x]
  1431. ... recipe = zc.recipe.egg
  1432. ... eggs = demo
  1433. ... ''' % globals())
  1434. >>> print_(system(buildout), end='')
  1435. Installing x.
  1436. Getting distribution for 'demo'.
  1437. Got demo 0.3.
  1438. Getting distribution for 'demoneeded'.
  1439. Got demoneeded 1.1.
  1440. Generated script '/sample-buildout/bin/demo'.
  1441. >>> print_(system(join('bin', 'demo')), end='')
  1442. 3 1
  1443. >>> write('buildout.cfg',
  1444. ... '''
  1445. ... [buildout]
  1446. ... parts = x
  1447. ... find-links = %(sample_eggs)s
  1448. ...
  1449. ... [x]
  1450. ... recipe = zc.recipe.egg
  1451. ... eggs = demo ==0.1
  1452. ... ''' % globals())
  1453. >>> print_(system(buildout), end='')
  1454. Uninstalling x.
  1455. Installing x.
  1456. Getting distribution for 'demo==0.1'.
  1457. Got demo 0.1.
  1458. Generated script '/sample-buildout/bin/demo'.
  1459. >>> print_(system(join('bin', 'demo')), end='')
  1460. 1 1
  1461. """
  1462. if sys.version_info > (2, 4):
  1463. def test_exit_codes():
  1464. """
  1465. >>> import subprocess
  1466. >>> def call(s):
  1467. ... p = subprocess.Popen(s, stdin=subprocess.PIPE,
  1468. ... stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  1469. ... p.stdin.close()
  1470. ... print_(p.stdout.read().decode())
  1471. ... print_('Exit:', bool(p.wait()))
  1472. >>> call(buildout)
  1473. <BLANKLINE>
  1474. Exit: False
  1475. >>> write('buildout.cfg',
  1476. ... '''
  1477. ... [buildout]
  1478. ... parts = x
  1479. ... ''')
  1480. >>> call(buildout) # doctest: +NORMALIZE_WHITESPACE
  1481. While:
  1482. Installing.
  1483. Getting section x.
  1484. Error: The referenced section, 'x', was not defined.
  1485. <BLANKLINE>
  1486. Exit: True
  1487. >>> write('setup.py',
  1488. ... '''
  1489. ... from setuptools import setup
  1490. ... setup(name='zc.buildout.testexit', entry_points={
  1491. ... 'zc.buildout': ['default = testexitrecipe:x']})
  1492. ... ''')
  1493. >>> write('testexitrecipe.py',
  1494. ... '''
  1495. ... x y
  1496. ... ''')
  1497. >>> write('buildout.cfg',
  1498. ... '''
  1499. ... [buildout]
  1500. ... parts = x
  1501. ... develop = .
  1502. ...
  1503. ... [x]
  1504. ... recipe = zc.buildout.testexit
  1505. ... ''')
  1506. >>> call(buildout) # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
  1507. Develop: '/sample-buildout/.'
  1508. While:
  1509. Installing.
  1510. Getting section x.
  1511. Initializing section x.
  1512. Loading zc.buildout recipe entry zc.buildout.testexit:default.
  1513. <BLANKLINE>
  1514. An internal error occured due to a bug in either zc.buildout or in a
  1515. recipe being used:
  1516. Traceback (most recent call last):
  1517. ...
  1518. x y
  1519. ^
  1520. SyntaxError: invalid syntax
  1521. <BLANKLINE>
  1522. Exit: True
  1523. """
  1524. def bug_59270_recipes_always_start_in_buildout_dir():
  1525. r"""
  1526. Recipes can rely on running from buildout directory
  1527. >>> mkdir('bad_start')
  1528. >>> write('bad_recipe.py',
  1529. ... r'''
  1530. ... import os, sys
  1531. ... def print_(*args):
  1532. ... sys.stdout.write(' '.join(map(str, args)) + '\n')
  1533. ... class Bad:
  1534. ... def __init__(self, *_):
  1535. ... print_(os.getcwd())
  1536. ... def install(self):
  1537. ... sys.stdout.write(os.getcwd()+'\n')
  1538. ... os.chdir('bad_start')
  1539. ... sys.stdout.write(os.getcwd()+'\n')
  1540. ... return ()
  1541. ... ''')
  1542. >>> write('setup.py',
  1543. ... '''
  1544. ... from setuptools import setup
  1545. ... setup(name='bad.test',
  1546. ... entry_points={'zc.buildout': ['default=bad_recipe:Bad']},)
  1547. ... ''')
  1548. >>> write('buildout.cfg',
  1549. ... '''
  1550. ... [buildout]
  1551. ... develop = .
  1552. ... parts = b1 b2
  1553. ... [b1]
  1554. ... recipe = bad.test
  1555. ... [b2]
  1556. ... recipe = bad.test
  1557. ... ''')
  1558. >>> os.chdir('bad_start')
  1559. >>> print_(system(join(sample_buildout, 'bin', 'buildout')
  1560. ... +' -c '+join(sample_buildout, 'buildout.cfg')), end='')
  1561. Develop: '/sample-buildout/.'
  1562. /sample-buildout
  1563. /sample-buildout
  1564. Installing b1.
  1565. /sample-buildout
  1566. /sample-buildout/bad_start
  1567. Installing b2.
  1568. /sample-buildout
  1569. /sample-buildout/bad_start
  1570. """
  1571. def bug_61890_file_urls_dont_seem_to_work_in_find_dash_links():
  1572. """
  1573. This bug arises from the fact that setuptools is overly restrictive
  1574. about file urls, requiring that file urls pointing at directories
  1575. must end in a slash.
  1576. >>> dest = tmpdir('sample-install')
  1577. >>> import zc.buildout.easy_install
  1578. >>> sample_eggs = sample_eggs.replace(os.path.sep, '/')
  1579. >>> ws = zc.buildout.easy_install.install(
  1580. ... ['demo==0.2'], dest,
  1581. ... links=['file://'+sample_eggs], index=link_server+'index/')
  1582. >>> for dist in ws:
  1583. ... print_(dist)
  1584. demo 0.2
  1585. demoneeded 1.1
  1586. >>> ls(dest)
  1587. d demo-0.2-py2.4.egg
  1588. d demoneeded-1.1-py2.4.egg
  1589. """
  1590. def bug_75607_buildout_should_not_run_if_it_creates_an_empty_buildout_cfg():
  1591. """
  1592. >>> remove('buildout.cfg')
  1593. >>> print_(system(buildout), end='')
  1594. While:
  1595. Initializing.
  1596. Error: Couldn't open /sample-buildout/buildout.cfg
  1597. """
  1598. def dealing_with_extremely_insane_dependencies():
  1599. r"""
  1600. There was a problem with analysis of dependencies taking a long
  1601. time, in part because the analysis would get repeated every time a
  1602. package was encountered in a dependency list. Now, we don't do
  1603. the analysis any more:
  1604. >>> import os
  1605. >>> for i in range(5):
  1606. ... p = 'pack%s' % i
  1607. ... deps = [('pack%s' % j) for j in range(5) if j is not i]
  1608. ... if i == 4:
  1609. ... deps.append('pack5')
  1610. ... mkdir(p)
  1611. ... write(p, 'setup.py',
  1612. ... 'from setuptools import setup\n'
  1613. ... 'setup(name=%r, install_requires=%r,\n'
  1614. ... ' url="u", author="a", author_email="e")\n'
  1615. ... % (p, deps))
  1616. >>> write('buildout.cfg',
  1617. ... '''
  1618. ... [buildout]
  1619. ... develop = pack0 pack1 pack2 pack3 pack4
  1620. ... parts = pack1
  1621. ...
  1622. ... [pack1]
  1623. ... recipe = zc.recipe.egg:eggs
  1624. ... eggs = pack0
  1625. ... ''')
  1626. >>> print_(system(buildout), end='') # doctest: +ELLIPSIS
  1627. Develop: '/sample-buildout/pack0'
  1628. Develop: '/sample-buildout/pack1'
  1629. Develop: '/sample-buildout/pack2'
  1630. Develop: '/sample-buildout/pack3'
  1631. Develop: '/sample-buildout/pack4'
  1632. Installing pack1.
  1633. ...
  1634. While:
  1635. Installing pack1.
  1636. Getting distribution for 'pack5'.
  1637. Error: Couldn't find a distribution for 'pack5'.
  1638. However, if we run in verbose mode, we can see why packages were included:
  1639. >>> print_(system(buildout+' -v'), end='') # doctest: +ELLIPSIS
  1640. Installing 'zc.buildout >=1.99', 'dist…

Large files files are truncated, but you can click here to view the full file