Package: buildout.eggnest
buildout.eggnest=================This product is no longer supported.The problem------------It is very convenient to install functionality to a buildout with justa couple of lines, but for those used to Zope 2, one might missthe way of adding a piece of functionality by just dropping something(i.e. a product) into a folder. This could be good for people who want to tryout things without worrying about editing a configuration file withlots of directives in it.When wanting to install a new egg using buildout you currently have toedit the buildout configuration file(s) and add a couple of lines inthe right places. What if you could just drop a file in a folder instead?Solution--------Make a buildout extension so that the only thing you need to do in order toinstall an eggis to take a simple text file, and drop it in a certain directory. When yourerun buildout thecontents of that file is parsed, the specified egg is downloaded and added tothe instance.When ``buildout.eggnest`` is run it::1. If ``eggnest-src-directory`` is not given the default directory ``src``is scanned.2. Adds the egg to the ``eggs`` and ``zcml`` option to a set of given buildoutparts.This steps are done on the fly when running buildout. So I can add/delete/renamean egg and it will be picked up.NOTE: The extension does not write to the buildout's configuration file.buildout.eggnest options-------------------------eggnest-src-directory:Specified to the directory that your egg install files should be placed.Defaults to src. An idea could beto have a dedicated directory called "eggnest".eggnest-parts:What part of your buildout config that the eggs should be added to. *required*eggnest-verbose:Set this to ``true`` to get more information.Not really that much right now but a little bit more at least.How to use it-------------To use ``buildout.eggnest`` you need to add the following to your buildout.cfg::[buildout]extensions =buildout.eggnesteggnest-parts =instanceIn ``eggnest-parts`` you need to specify what buildout part that the eggs shouldbe added to.By default the ``src`` directory is scanned for egg specification files.eggs specification files for eggnest------------------------------------The egg install specification files should have this structure. This is the sameas the normal buildout config format.::[eggnest]egg =plone.introspectorzcml =plone.introspector``zcml`` can be multiple lines if additional slugs need to be specified.If the egg is in the ``Products`` namespace the zcml is not needed in thespecification file.::[eggnest]egg =Products.DocFinderTabbuildout.eggnest was created by Martin Lundwall <martin@webworks.se> after aninitial idea by Jorgen Modin <jorgen@webworks.se>Change history================0.2 (unreleased)----------------- Compatibility update for zc.buildout 1.4.0 (mlundwall)0.1 (2008-11-22)----------------- Initial release (mlundwall)Detailed Documentation======================Tests for buildout.eggnest buildout extension-------------------------------------------------Let's create a buildout configuration file::>>> data = """... [buildout]... parts = zope2 instance1 instance2 instance3... extensions =... eggs =... develop = %s... eggnest-parts = instance1 instance2... [instance1]... recipe = plone.recipe.zope2instance... zope2-location = ${zope2:location}... user = admin:admin... [instance2]... recipe = plone.recipe.zope2instance... zope2-location = ${zope2:location}... user = admin:admin... [instance3]... recipe = plone.recipe.zope2instance... zope2-location = ${zope2:location}... user = admin:admin... [zope2]... recipe = plone.recipe.zope2install... url = http://www.zope.org/Products/Zope/2.9.8/Zope-2.9.8-final.tgz... """ % egg_dir>>> rmdir(tempdir, 'buildout.test')>>> cd(tempdir)>>> sh('mkdir buildout.test')mkdir buildout.test<BLANKLINE>>>> cd('buildout.test')>>> touch('buildout.cfg', data=data)>>> ls('.')buildout.cfgrun the buildout first time so we get our zope instances::>>> sh('svn exportsvn://svn.zope.org/repos/main/zc.buildout/trunk/bootstrap/bootstrap.py')svn exportsvn://svn.zope.org/repos/main/zc.buildout/trunk/bootstrap/bootstrap.pyA    bootstrap.pyExport complete.<BLANKLINE>>>> sh('python2.4 bootstrap.py')python2.4 bootstrap.py...Creating directory '/private/tmp/buildout.test/bin'.Creating directory '/private/tmp/buildout.test/parts'.Creating directory '/private/tmp/buildout.test/develop-eggs'.Generated script '/private/tmp/buildout.test/bin/buildout'.<BLANKLINE>>>> sh('./bin/buildout')./bin/buildout...Installing instance1....Installing instance2....Installing instance3....<BLANKLINE><BLANKLINE>Now let's create a test products specification file and add the buildout.eggnestas an extension::>>> sh('mkdir src')mkdir src<BLANKLINE>>>> product = """... [eggnest]... egg =...     plone.portlet.static... zcml =...     plone.portlet.static... """>>> touch('src/product.txt', data=product)>>> ls('src')product.txt>>> data = data.replace('extensions =', 'extensions = buildout.eggnest')>>> touch('buildout.cfg', data=data)Ok, so now that we have an egg, lets run the buildout in offline mode. Weshould get a zcml slugs in parts/instance1/etc/package-includes andparts/instance2/etc/package-includesbut not in parts/instance3/etc/package-includes,and a line with the path to our egg in the bin/instance1 and bin/instance2but not in bin/instance3 files.First we check that there is nothing of the previous mentioned things::>>> ls('develop-eggs')buildout.eggnest.egg-link>>> ls('parts/instance1/etc/package-includes')No directory named parts/instance1/etc/package-includes>>> ls('parts/instance2/etc/package-includes')No directory named parts/instance2/etc/package-includes>>> ls('parts/instance3/etc/package-includes')No directory named parts/instance3/etc/package-includes>>> sh('grep plone.portlet.static bin/instance1')grep plone.portlet.static bin/instance1<BLANKLINE>>>> sh('grep plone.portlet.static bin/instance2')grep plone.portlet.static bin/instance2<BLANKLINE>>>> sh('grep plone.portlet.static bin/instance3')grep plone.portlet.static bin/instance3<BLANKLINE>OK, now run the buildout in offline mode::>>> sh('./bin/buildout')./bin/buildout...Check that we have a correct created buildout.Check that we have our zcml slugs in the package-includes::>>> ls('parts', 'instance1', 'etc', 'package-includes')001-plone.portlet.static-configure.zcml>>> ls('parts', 'instance2', 'etc', 'package-includes')001-plone.portlet.static-configure.zcml>>> ls('parts', 'instance3', 'etc', 'package-includes')No directory named parts/instance3/etc/package-includesand in the end check that there is a line in bin/instance1 and bin/instance1that includes our egg in the path::>>> code = cat('bin', 'instance1', returndata=True)>>> code.find('plone.portlet.static') == -1False>>> code = cat('bin', 'instance2', returndata=True)>>> code.find('plone.portlet.static') == -1False>>> code = cat('bin', 'instance3', returndata=True)>>> code.find('plone.portlet.static') == -1TrueLet's now try the ``eggnest-src-directory`` option. We create a new buildout.cfgfilewith an empty ``eggnest-src-directory``::>>> data = data.replace('eggs =', 'eggnest-src-directory = \neggs = ')>>> touch('buildout.cfg', data=data)>>> sh('./bin/buildout')./bin/buildout...No zcml slug in the instance 1,2 or 3::>>> ls('parts', 'instance1', 'etc', 'package-includes')No directory named parts/instance1/etc/package-includes>>> ls('parts', 'instance2', 'etc', 'package-includes')No directory named parts/instance2/etc/package-includes>>> ls('parts', 'instance3', 'etc', 'package-includes')No directory named parts/instance3/etc/package-includesNor a line in bin/instance1, bin/instance2 or bin/instance3 with our egg path::>>> code = cat('bin', 'instance1', returndata=True)>>> code.find('plone.portlet.static') == -1True>>> code = cat('bin', 'instance2', returndata=True)>>> code.find('plone.portlet.static') == -1True>>> code = cat('bin', 'instance3', returndata=True)>>> code.find('plone.portlet.static') == -1TrueBut if the ``eggnest-src-directory`` option is not empty::>>> data = data.replace('eggnest-src-directory =', 'eggnest-src-directory =auto')>>> touch('buildout.cfg', data=data)>>> sh('rm src/product.txt')rm src/product.txt>>> sh('mkdir auto')mkdir auto>>> touch('auto/product.txt', data=product)>>> ls('auto')product.txt>>> sh('./bin/buildout -o')./bin/buildout -o...and we get a zcml slug only in the specified target::>>> ls('parts', 'instance1', 'etc', 'package-includes')001-plone.portlet.static-configure.zcml>>> ls('parts', 'instance2', 'etc', 'package-includes')001-plone.portlet.static-configure.zcml>>> ls('parts', 'instance3', 'etc', 'package-includes')No directory named parts/instance3/etc/package-includesand only the specified target's control script is updated::>>> code = cat('bin', 'instance1', returndata=True)>>> code.find('plone.portlet.static') == -1False>>> code = cat('bin', 'instance2', returndata=True)>>> code.find('plone.portlet.static') == -1False>>> code = cat('bin', 'instance3', returndata=True)>>> code.find('plone.portlet.static') == -1True