[Repoze-checkins] r755 - in repoze.recipe.egg: . trunk trunk/repoze trunk/repoze/recipe trunk/repoze/recipe/egg
Chris McDonough
chrism at agendaless.com
Sat Mar 1 07:04:51 UTC 2008
Author: Chris McDonough <chrism at agendaless.com>
Date: Sat Mar 1 02:04:50 2008
New Revision: 755
Log:
(Hopefully) temporary fork of zc.recipe.egg which is willing to install dependent egg scripts.
Added:
repoze.recipe.egg/
repoze.recipe.egg/trunk/
repoze.recipe.egg/trunk/CHANGES.txt
repoze.recipe.egg/trunk/README.txt
repoze.recipe.egg/trunk/repoze/
repoze.recipe.egg/trunk/repoze/__init__.py (contents, props changed)
repoze.recipe.egg/trunk/repoze/recipe/
repoze.recipe.egg/trunk/repoze/recipe/__init__.py (contents, props changed)
repoze.recipe.egg/trunk/repoze/recipe/egg/
repoze.recipe.egg/trunk/repoze/recipe/egg/README.txt
repoze.recipe.egg/trunk/repoze/recipe/egg/__init__.py (contents, props changed)
repoze.recipe.egg/trunk/repoze/recipe/egg/api.txt
repoze.recipe.egg/trunk/repoze/recipe/egg/custom.py (contents, props changed)
repoze.recipe.egg/trunk/repoze/recipe/egg/custom.txt
repoze.recipe.egg/trunk/repoze/recipe/egg/egg.py (contents, props changed)
repoze.recipe.egg/trunk/repoze/recipe/egg/selecting-python.txt
repoze.recipe.egg/trunk/repoze/recipe/egg/tests.py (contents, props changed)
repoze.recipe.egg/trunk/setup.py (contents, props changed)
Added: repoze.recipe.egg/trunk/CHANGES.txt
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/CHANGES.txt Sat Mar 1 02:04:50 2008
@@ -0,0 +1,15 @@
+To do
+*****
+
+- Some way to freeze the egg-versions used. This includes some way to
+ record which versions were selected dynamially and then a way to
+ require that the recorded versions be used in a later run.
+
+Change History
+**************
+
+Unreleased (2008-02-29)
+=======================
+
+- Fork of zc.recipe.egg 1.0.0 which will install dependent scripts by default.
+
Added: repoze.recipe.egg/trunk/README.txt
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/README.txt Sat Mar 1 02:04:50 2008
@@ -0,0 +1,11 @@
+********************************
+Buildout Egg-Installation Recipe
+********************************
+
+.. contents::
+
+The egg-installation recipe is a customization of zc.recipe.egg that
+allows for by-default installs of dependent scripts.
+
+
+
Added: repoze.recipe.egg/trunk/repoze/__init__.py
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/repoze/__init__.py Sat Mar 1 02:04:50 2008
@@ -0,0 +1 @@
+__import__('pkg_resources').declare_namespace(__name__)
Added: repoze.recipe.egg/trunk/repoze/recipe/__init__.py
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/repoze/recipe/__init__.py Sat Mar 1 02:04:50 2008
@@ -0,0 +1 @@
+__import__('pkg_resources').declare_namespace(__name__)
Added: repoze.recipe.egg/trunk/repoze/recipe/egg/README.txt
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/repoze/recipe/egg/README.txt Sat Mar 1 02:04:50 2008
@@ -0,0 +1,498 @@
+Installation of distributions as eggs
+=====================================
+
+The repoze.recipe.egg:eggs recipe can be used to install various types if
+distutils distributions as eggs. It takes a number of options:
+
+eggs
+ A list of eggs to install given as one or more setuptools
+ requirement strings. Each string must be given on a separate
+ line.
+
+find-links
+ A list of URLs, files, or directories to search for distributions.
+
+index
+ The URL of an index server, or almost any other valid URL. :)
+
+ If not specified, the Python Package Index,
+ http://cheeseshop.python.org/pypi, is used. You can specify an
+ alternate index with this option. If you use the links option and
+ if the links point to the needed distributions, then the index can
+ be anything and will be largely ignored. In the examples, here,
+ we'll just point to an empty directory on our link server. This
+ will make our examples run a little bit faster.
+
+python
+ The name of a section to get the Python executable from.
+ If not specified, then the buildout python option is used. The
+ Python executable is found in the executable option of the named
+ section.
+
+We have a link server that has a number of distributions:
+
+ >>> print get(link_server),
+ <html><body>
+ <a href="demo-0.1-py2.3.egg">demo-0.1-py2.3.egg</a><br>
+ <a href="demo-0.2-py2.3.egg">demo-0.2-py2.3.egg</a><br>
+ <a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br>
+ <a href="demo-0.4c1-py2.3.egg">demo-0.4c1-py2.3.egg</a><br>
+ <a href="demoneeded-1.0.zip">demoneeded-1.0.zip</a><br>
+ <a href="demoneeded-1.1.zip">demoneeded-1.1.zip</a><br>
+ <a href="demoneeded-1.2c1.zip">demoneeded-1.2c1.zip</a><br>
+ <a href="extdemo-1.4.zip">extdemo-1.4.zip</a><br>
+ <a href="index/">index/</a><br>
+ <a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br>
+ </body></html>
+
+We have a sample buildout. Let's update it's configuration file to
+install the demo package.
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg:eggs
+ ... eggs = demo<0.3
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... """ % dict(server=link_server))
+
+In this example, we limited ourselves to revisions before 0.3. We also
+specified where to find distributions using the find-links option.
+
+Let's run the buildout:
+
+ >>> import os
+ >>> print system(buildout),
+ Installing demo.
+ Getting distribution for 'demo<0.3'.
+ Got demo 0.2.
+ Getting distribution for 'demoneeded'.
+ Got demoneeded 1.2c1.
+
+Now, if we look at the buildout eggs directory:
+
+ >>> ls(sample_buildout, 'eggs')
+ - demo-0.2-py2.3.egg
+ - demoneeded-1.2c1-py2.3.egg
+ - setuptools-0.6-py2.3.egg
+ - zc.buildout-1.0-py2.3.egg
+
+We see that we got an egg for demo that met the requirement, as well
+as the egg for demoneeded, which demo requires. (We also see an egg
+link for the recipe in the develop-eggs directory. This egg link was
+actually created as part of the sample buildout setup. Normally, when
+using the recipe, you'll get a regular egg installation.)
+
+Script generation
+-----------------
+
+The demo egg defined a script, but we didn't get one installed:
+
+ >>> ls(sample_buildout, 'bin')
+ - buildout
+
+If we want scripts provided by eggs to be installed, we should use the
+scripts recipe:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg:scripts
+ ... eggs = demo<0.3
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... """ % dict(server=link_server))
+
+ >>> print system(buildout),
+ Uninstalling demo.
+ Installing demo.
+ Generated script '/sample-buildout/bin/demo'.
+
+Now we also see the script defined by the dmo script:
+
+ >>> ls(sample_buildout, 'bin')
+ - buildout
+ - demo
+
+The scripts recipe defines some additional options:
+
+entry-points
+ A list of entry-point identifiers of the form name=module#attrs,
+ name is a script name, module is a module name, and a attrs is a
+ (possibly dotted) name of an object wihin the module. This option
+ is useful when working with distributions that don't declare entry
+ points, such as distributions not written to work with setuptools.
+
+scripts
+ Control which scripts are generated. The value should be a list of
+ zero or more tokens. Each token is either a name, or a name
+ followed by an '=' and a new name. Only the named scripts are
+ generated. If no tokens are given, then script generation is
+ disabled. If the option isn't given at all, then all scripts
+ defined by the named eggs will be generated.
+
+interpreter
+ The name of a script to generate that allows access to a Python
+ interpreter that has the path set based on the eggs installed.
+
+extra-paths
+ Extra paths to include in a generates script.
+
+initialization
+ Specify some Python initialization code. This is very limited. In
+ particular, be aware that leading whitespace is stripped from the
+ code given.
+
+arguments
+ Specify some arguments to be passed to entry points as Python source.
+
+Let's add an interpreter option:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... eggs = demo<0.3
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... interpreter = py-demo
+ ... """ % dict(server=link_server))
+
+Note that we ommitted the entry point name from the recipe
+specification. We were able to do this because the scripts recipe if
+the default entry point for the repoze.recipe.egg egg.
+
+ >>> print system(buildout),
+ Uninstalling demo.
+ Installing demo.
+ Generated script '/sample-buildout/bin/demo'.
+ Generated interpreter '/sample-buildout/bin/py-demo'.
+
+Now we also get a py-demo script for giving us a Python prompt with
+the path for demo and any eggs it depends on included in sys.path.
+This is useful for debugging and testing.
+
+ >>> ls(sample_buildout, 'bin')
+ - buildout
+ - demo
+ - py-demo
+
+If we run the demo script, it prints out some minimal data:
+
+ >>> print system(join(sample_buildout, 'bin', 'demo')),
+ 2 2
+
+The value it prints out happens to be some values defined in the
+modules installed.
+
+We can also run the py-demo script. Here we'll just print out
+the bits if the path added to reflect the eggs:
+
+ >>> print system(join(sample_buildout, 'bin', 'py-demo'),
+ ... """import os, sys
+ ... for p in sys.path:
+ ... if 'demo' in p:
+ ... print os.path.basename(p)
+ ...
+ ... """).replace('>>> ', '').replace('... ', ''),
+ ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+ demo-0.2-py2.4.egg
+ demoneeded-1.2c1-py2.4.egg
+
+Egg updating
+------------
+
+The recipe normally gets the most recent distribution that satisfies the
+specification. It won't do this is the buildout is either in
+non-newest mode or in offline mode. To see how this works, we'll
+remove the restriction on demo:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... """ % dict(server=link_server))
+
+and run the buildout in non-newest mode:
+
+ >>> print system(buildout+' -N'),
+ Uninstalling demo.
+ Installing demo.
+ Generated script '/sample-buildout/bin/demo'.
+
+Note that we removed the eggs option, and the eggs defaulted to the
+part name. Because we removed the eggs option, the demo was
+reinstalled.
+
+We'll also run the buildout in off-line mode:
+
+ >>> print system(buildout+' -o'),
+ Updating demo.
+
+We didn't get an update for demo:
+
+ >>> ls(sample_buildout, 'eggs')
+ - demo-0.2-py2.3.egg
+ - demoneeded-1.2c1-py2.3.egg
+ - setuptools-0.6-py2.3.egg
+ - zc.buildout-1.0-py2.3.egg
+
+If we run the buildout on the default online and newest modes,
+we'll get an update for demo:
+
+ >>> print system(buildout),
+ Updating demo.
+ Getting distribution for 'demo'.
+ Got demo 0.4c1.
+ Generated script '/sample-buildout/bin/demo'.
+
+Then we'll get a new demo egg:
+
+ >>> ls(sample_buildout, 'eggs')
+ - demo-0.2-py2.3.egg
+ - demo-0.4c1-py2.3.egg
+ - demoneeded-1.2c1-py2.3.egg
+ - setuptools-0.6-py2.4.egg
+ - zc.buildout-1.0-py2.4.egg
+
+The script is updated too:
+
+ >>> print system(join(sample_buildout, 'bin', 'demo')),
+ 4 2
+
+Controlling script generation
+-----------------------------
+
+You can control which scripts get generated using the scripts option.
+For example, to suppress scripts, use the scripts option without any
+arguments:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... scripts =
+ ... """ % dict(server=link_server))
+
+
+ >>> print system(buildout),
+ Uninstalling demo.
+ Installing demo.
+
+ >>> ls(sample_buildout, 'bin')
+ - buildout
+
+You can also control the name used for scripts:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... scripts = demo=foo
+ ... """ % dict(server=link_server))
+
+ >>> print system(buildout),
+ Uninstalling demo.
+ Installing demo.
+ Generated script '/sample-buildout/bin/foo'.
+
+ >>> ls(sample_buildout, 'bin')
+ - buildout
+ - foo
+
+Specifying extra script paths
+-----------------------------
+
+If we need to include extra paths in a script, we can use the
+extra-paths option:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... scripts = demo=foo
+ ... extra-paths =
+ ... /foo/bar
+ ... /spam/eggs
+ ... """ % dict(server=link_server))
+
+ >>> print system(buildout),
+ Uninstalling demo.
+ Installing demo.
+ Generated script '/sample-buildout/bin/foo'.
+
+Let's look at the script that was generated:
+
+ >>> cat(sample_buildout, 'bin', 'foo') # doctest: +NORMALIZE_WHITESPACE
+ #!/usr/local/bin/python2.4
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ '/sample-buildout/eggs/demo-0.4c1-py2.4.egg',
+ '/sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg',
+ '/foo/bar',
+ '/spam/eggs',
+ ]
+ <BLANKLINE>
+ import eggrecipedemo
+ <BLANKLINE>
+ if __name__ == '__main__':
+ eggrecipedemo.main()
+
+Specifying initialialization code and arguments
+-----------------------------------------------
+
+Sometimes, we ned to do more than just calling entry points. We can
+use the initialialization and arguments options to specify extra code
+to be included in generated scripts:
+
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... scripts = demo=foo
+ ... extra-paths =
+ ... /foo/bar
+ ... /spam/eggs
+ ... initialization = a = (1, 2
+ ... 3, 4)
+ ... arguments = a, 2
+ ... """ % dict(server=link_server))
+
+ >>> print system(buildout),
+ Uninstalling demo.
+ Installing demo.
+ Generated script '/sample-buildout/bin/foo'.
+
+ >>> cat(sample_buildout, 'bin', 'foo') # doctest: +NORMALIZE_WHITESPACE
+ #!/usr/local/bin/python2.4
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ '/sample-buildout/eggs/demo-0.4c1-py2.4.egg',
+ '/sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg',
+ '/foo/bar',
+ '/spam/eggs',
+ ]
+ <BLANKLINE>
+ a = (1, 2
+ 3, 4)
+ <BLANKLINE>
+ import eggrecipedemo
+ <BLANKLINE>
+ if __name__ == '__main__':
+ eggrecipedemo.main(a, 2)
+
+Here we see that the initialization code we specified was added after
+setting the path. Note, as mentioennd above, that leading whitespace
+has been stripped. Similarly, the argument code we specified was
+added in the entry point call (to main).
+
+Specifying entry points
+-----------------------
+
+Scripts can be generated for entry points declared explicitly. We can
+declare entry points using the entry-points option:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... extra-paths =
+ ... /foo/bar
+ ... /spam/eggs
+ ... entry-points = alt=eggrecipedemo:alt other=foo.bar:a.b.c
+ ... """ % dict(server=link_server))
+
+ >>> print system(buildout),
+ Uninstalling demo.
+ Installing demo.
+ Generated script '/sample-buildout/bin/demo'.
+ Generated script '/sample-buildout/bin/alt'.
+ Generated script '/sample-buildout/bin/other'.
+
+ >>> ls(sample_buildout, 'bin')
+ - alt
+ - buildout
+ - demo
+ - other
+
+ >>> cat(sample_buildout, 'bin', 'other')
+ #!/usr/local/bin/python2.4
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ '/sample-buildout/eggs/demo-0.4c1-py2.4.egg',
+ '/sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg',
+ '/foo/bar',
+ '/spam/eggs',
+ ]
+ <BLANKLINE>
+ import foo.bar
+ <BLANKLINE>
+ if __name__ == '__main__':
+ foo.bar.a.b.c()
+
+Offline mode
+------------
+
+If the buildout offline option is set to "true", then no attempt will
+be made to contact an index server:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ... offline = true
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... index = eek!
+ ... scripts = demo=foo
+ ... """ % dict(server=link_server))
+
+ >>> print system(buildout),
+ Uninstalling demo.
+ Installing demo.
+ Generated script '/sample-buildout/bin/foo'.
Added: repoze.recipe.egg/trunk/repoze/recipe/egg/__init__.py
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/repoze/recipe/egg/__init__.py Sat Mar 1 02:04:50 2008
@@ -0,0 +1,2 @@
+from repoze.recipe.egg.egg import Egg, Scripts, Eggs
+from repoze.recipe.egg.custom import Custom, Develop
Added: repoze.recipe.egg/trunk/repoze/recipe/egg/api.txt
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/repoze/recipe/egg/api.txt Sat Mar 1 02:04:50 2008
@@ -0,0 +1,152 @@
+Egg Recipe API for other Recipes
+================================
+
+It is common for recipes to accept a collection of egg specifications
+and generate scripts based on the resulting working sets. The egg
+recipe provides an API that other recipes can use.
+
+A recipe can reuse the egg recipe, supporting the eggs, find-links,
+index, extra-paths, and python options. This is done by creating an
+egg recipe instance in a recipes's contructor. In the recipe's
+install script, the egg-recipe instance's working_set method is used
+to collect the requested eggs and working set.
+
+To illustrate, we create a sample recipe that is a very thin layer
+around the egg recipe:
+
+ >>> mkdir(sample_buildout, 'sample')
+ >>> write(sample_buildout, 'sample', 'sample.py',
+ ... """
+ ... import logging, os
+ ... import repoze.recipe.egg
+ ...
+ ... class Sample:
+ ...
+ ... def __init__(self, buildout, name, options):
+ ... self.egg = repoze.recipe.egg.Scripts(buildout, name, options)
+ ... self.name = name
+ ... self.options = options
+ ...
+ ... def install(self):
+ ... extras = self.options['extras'].split()
+ ... requirements, ws = self.egg.working_set(extras)
+ ... print 'Part:', self.name
+ ... print 'Egg requirements:'
+ ... for r in requirements:
+ ... print r
+ ... print 'Working set:'
+ ... for d in ws:
+ ... print d
+ ... print 'extra paths:', self.egg.extra_paths
+ ... return ()
+ ...
+ ... update = install
+ ... """)
+
+Here we instantiated the egg recipe in the constructor, saving it in
+an attribute. This also initialized the options dictionary.
+
+In our install method, we called the working_set method on the
+instance we saved. The working_set method takes an optional sequence
+of extra requirements to be included in the working set.
+
+ >>> write(sample_buildout, 'sample', 'setup.py',
+ ... """
+ ... from setuptools import setup
+ ...
+ ... setup(
+ ... name = "sample",
+ ... entry_points = {'zc.buildout': ['default = sample:Sample']},
+ ... install_requires = 'repoze.recipe.egg',
+ ... )
+ ... """)
+
+
+ >>> write(sample_buildout, 'sample', 'README.txt', " ")
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... develop = sample
+ ... parts = sample-part
+ ...
+ ... [sample-part]
+ ... recipe = sample
+ ... eggs = demo<0.3
+ ... find-links = %(server)s
+ ... index = %(server)sindex
+ ... extras = other
+ ... """ % dict(server=link_server))
+
+ >>> import os
+ >>> os.chdir(sample_buildout)
+ >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
+ >>> print system(buildout + ' -q'),
+ Part: sample-part
+ Egg requirements:
+ demo<0.3
+ Working set:
+ demo 0.2
+ other 1.0
+ demoneeded 1.2c1
+ extra paths: []
+
+We can see that the options were augmented with additionl data
+computed by the egg recipe by looking at .installed.cfg:
+
+ >>> cat(sample_buildout, '.installed.cfg')
+ [buildout]
+ installed_develop_eggs = /sample-buildout/develop-eggs/sample.egg-link
+ parts = sample-part
+ <BLANKLINE>
+ [sample-part]
+ __buildout_installed__ =
+ __buildout_signature__ = sample-6aWMvV2EJ9Ijq+bR8ugArQ==
+ repoze.recipe.egg-cAsnudgkduAa/Fd+WJIM6Q==
+ setuptools-0.6-py2.4.egg
+ zc.buildout-+rYeCcmFuD1K/aB77XTj5A==
+ _b = /sample-buildout/bin
+ _d = /sample-buildout/develop-eggs
+ _e = /sample-buildout/eggs
+ bin-directory = /sample-buildout/bin
+ develop-eggs-directory = /sample-buildout/develop-eggs
+ eggs = demo<0.3
+ eggs-directory = /sample-buildout/eggs
+ executable = /usr/local/bin/python2.3
+ extras = other
+ find-links = http://localhost:27071/
+ index = http://localhost:27071/index
+ recipe = sample
+
+If we use the extra-paths option:
+
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... develop = sample
+ ... parts = sample-part
+ ...
+ ... [sample-part]
+ ... recipe = sample
+ ... eggs = demo<0.3
+ ... find-links = %(server)s
+ ... index = %(server)sindex
+ ... extras = other
+ ... extra-paths = /foo/bar
+ ... /spam/eggs
+ ... """ % dict(server=link_server))
+
+Then we'll see that reflected in the extra_paths attribute in the egg
+recipe instance:
+
+ >>> print system(buildout + ' -q'),
+ Part: sample-part
+ Egg requirements:
+ demo<0.3
+ Working set:
+ demo 0.2
+ other 1.0
+ demoneeded 1.2c1
+ extra paths: ['/foo/bar', '/spam/eggs']
+
Added: repoze.recipe.egg/trunk/repoze/recipe/egg/custom.py
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/repoze/recipe/egg/custom.py Sat Mar 1 02:04:50 2008
@@ -0,0 +1,135 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Install packages as eggs
+
+$Id: custom.py 73397 2007-03-20 12:08:44Z jim $
+"""
+
+import logging
+import os
+import zc.buildout.easy_install
+
+logger = logging.getLogger(__name__)
+
+class Base:
+
+ def __init__(self, buildout, name, options):
+ self.name, self.options = name, options
+
+ options['_d'] = buildout['buildout']['develop-eggs-directory']
+
+ python = options.get('python', buildout['buildout']['python'])
+ options['executable'] = buildout[python]['executable']
+
+ self.build_ext = build_ext(buildout, options)
+
+
+ def update(self):
+ return self.install()
+
+class Custom(Base):
+
+ def __init__(self, buildout, name, options):
+ Base.__init__(self, buildout, name, options)
+
+ links = options.get('find-links',
+ buildout['buildout'].get('find-links'))
+ if links:
+ links = links.split()
+ options['find-links'] = '\n'.join(links)
+ else:
+ links = ()
+ self.links = links
+
+ index = options.get('index', buildout['buildout'].get('index'))
+ if index is not None:
+ options['index'] = index
+ self.index = index
+
+ options['_e'] = buildout['buildout']['eggs-directory']
+
+ assert options.get('unzip') in ('true', 'false', None)
+
+ if buildout['buildout'].get('offline') == 'true':
+ self.install = lambda: ()
+
+ self.newest = buildout['buildout'].get('newest') == 'true'
+
+ def install(self):
+ options = self.options
+ distribution = options.get('egg')
+ if distribution is None:
+ distribution = options.get('eggs')
+ if distribution is None:
+ distribution = self.name
+ else:
+ logger.warn("The eggs option is deprecated. Use egg instead")
+
+
+ distribution = options.get('egg', options.get('eggs', self.name)
+ ).strip()
+ return zc.buildout.easy_install.build(
+ distribution, options['_d'], self.build_ext,
+ self.links, self.index, options['executable'], [options['_e']],
+ newest=self.newest,
+ )
+
+class Develop(Base):
+
+ def __init__(self, buildout, name, options):
+ Base.__init__(self, buildout, name, options)
+ options['setup'] = os.path.join(buildout['buildout']['directory'],
+ options['setup'])
+
+ def install(self):
+ options = self.options
+ return zc.buildout.easy_install.develop(
+ options['setup'], options['_d'], self.build_ext,
+ options['executable'],
+ )
+
+
+def build_ext(buildout, options):
+ result = {}
+ for be_option in ('include-dirs', 'library-dirs', 'rpath'):
+ value = options.get(be_option)
+ if value is None:
+ continue
+ value = [
+ os.path.join(
+ buildout['buildout']['directory'],
+ v.strip()
+ )
+ for v in value.strip().split('\n')
+ if v.strip()
+ ]
+ result[be_option] = os.pathsep.join(value)
+ options[be_option] = os.pathsep.join(value)
+
+ swig = options.get('swig')
+ if swig:
+ options['swig'] = result['swig'] = os.path.join(
+ buildout['buildout']['directory'],
+ swig,
+ )
+
+ for be_option in ('define', 'undef', 'libraries', 'link-objects',
+ 'debug', 'force', 'compiler', 'swig-cpp', 'swig-opts',
+ ):
+ value = options.get(be_option)
+ if value is None:
+ continue
+ result[be_option] = value
+
+ return result
Added: repoze.recipe.egg/trunk/repoze/recipe/egg/custom.txt
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/repoze/recipe/egg/custom.txt Sat Mar 1 02:04:50 2008
@@ -0,0 +1,414 @@
+Creating eggs with extensions neededing custom build settings
+=============================================================
+
+Sometimes, It's necessary to provide extra control over how an egg is
+created. This is commonly true for eggs with extension modules that
+need to access libraries or include files.
+
+The repoze.recipe.egg:custom recipe can be used to define an egg with
+custom build parameters. The currently defined parameters are:
+
+include-dirs
+ A new-line separated list of directories to search for include
+ files.
+
+library-dirs
+ A new-line separated list of directories to search for libraries
+ to link with.
+
+rpath
+ A new-line separated list of directories to search for dynamic libraries
+ at run time.
+
+define
+ A comma-separated list of names of C preprocessor variables to
+ define.
+
+undef
+ A comman separated list of names of C preprocessor variables to
+ undefine.
+
+libraries
+ The name of an additional library to link with. Due to limitations
+ in distutils and desprite the option name, only a single library
+ can be specified.
+
+link-objects
+ The name of an link object to link afainst. Due to limitations
+ in distutils and desprite the option name, only a single link object
+ can be specified.
+
+debug
+ Compile/link with debugging information
+
+force
+ Forcibly build everything (ignore file timestamps)
+
+compiler
+ Specify the compiler type
+
+swig
+ The path to the swig executable
+
+swig-cpp
+ Make SWIG create C++ files (default is C)
+
+swig-opts
+ List of SWIG command line options
+
+In addition, the following options can be used to specify the egg:
+
+egg
+ An specification for the egg to be created, to install given as a
+ setuptools requirement string. This defaults to the part name.
+
+find-links
+ A list of URLs, files, or directories to search for distributions.
+
+index
+ The URL of an index server, or almost any other valid URL. :)
+
+ If not specified, the Python Package Index,
+ http://cheeseshop.python.org/pypi, is used. You can specify an
+ alternate index with this option. If you use the links option and
+ if the links point to the needed distributions, then the index can
+ be anything and will be largely ignored. In the examples, here,
+ we'll just point to an empty directory on our link server. This
+ will make our examples run a little bit faster.
+
+python
+ The name of a section to get the Python executable from.
+ If not specified, then the buildout python option is used. The
+ Python executable is found in the executable option of the named
+ section.
+
+To illustrate this, we'll define a buildout that builds an egg for a
+package that has a simple extension module::
+
+ #include <Python.h>
+ #include <extdemo.h>
+
+ static PyMethodDef methods[] = {};
+
+ PyMODINIT_FUNC
+ initextdemo(void)
+ {
+ PyObject *m;
+ m = Py_InitModule3("extdemo", methods, "");
+ #ifdef TWO
+ PyModule_AddObject(m, "val", PyInt_FromLong(2));
+ #else
+ PyModule_AddObject(m, "val", PyInt_FromLong(EXTDEMO));
+ #endif
+ }
+
+The extension depends on a system-dependnt include file, extdemo.h,
+that defines a constant, EXTDEMO, that is exposed by the extension.
+
+The extension module is available as a source distribution,
+extdemo-1.4.tar.gz, on a distribution server.
+
+We have a sample buildout that we'll add an include directory to with
+the necessary include file:
+
+ >>> mkdir('include')
+ >>> write('include', 'extdemo.h',
+ ... """
+ ... #define EXTDEMO 42
+ ... """)
+
+We'll also update the buildout configuration file to define a part for
+the egg:
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = extdemo
+ ...
+ ... [extdemo]
+ ... recipe = repoze.recipe.egg:custom
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... include-dirs = include
+ ... """ % dict(server=link_server))
+
+ >>> print system(buildout),
+ Installing extdemo.
+ zip_safe flag not set; analyzing archive contents...
+
+We got the zip_safe warning because the source distribution we used
+wasn't setuptools based and thus didn't set the option.
+
+The egg is created in the develop-eggs directory *not* the eggs
+directory because it depends on buildout-specific parameters and the
+eggs directory can be shared across multiple buildouts.
+
+ >>> ls(sample_buildout, 'develop-eggs')
+ d extdemo-1.4-py2.4-unix-i686.egg
+ - repoze.recipe.egg.egg-link
+
+Note that no scripts or dependencies are installed. To install
+dependencies or scripts for a custom egg, define another part and use
+the repoze.recipe.egg recipe, listing the custom egg as one of the eggs to
+be installed. The repoze.recipe.egg recipe will use the installed egg.
+
+Let's define a script that uses out ext demo:
+
+ >>> mkdir('demo')
+ >>> write('demo', 'demo.py',
+ ... """
+ ... import extdemo
+ ... def main():
+ ... print extdemo.val
+ ... """)
+
+ >>> write('demo', 'setup.py',
+ ... """
+ ... from setuptools import setup
+ ... setup(name='demo')
+ ... """)
+
+
+ >>> write('buildout.cfg',
+ ... """
+ ... [buildout]
+ ... develop = demo
+ ... parts = extdemo demo
+ ...
+ ... [extdemo]
+ ... recipe = repoze.recipe.egg:custom
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... include-dirs = include
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... eggs = demo
+ ... extdemo
+ ... entry-points = demo=demo:main
+ ... """ % dict(server=link_server))
+
+ >>> print system(buildout),
+ Develop: '/sample-buildout/demo'
+ Updating extdemo.
+ Installing demo.
+ Generated script '/sample-buildout/bin/demo'.
+
+When we run the script, we'll 42 printed:
+
+ >>> print system(join('bin', 'demo')),
+ 42
+
+Updating
+--------
+
+The custom recipe will normally check for new source distributions
+that meet the given specification. This can be suppressed using the
+buildout non-newest and offline modes. We'll generate a new source
+distribution for extdemo:
+
+ >>> update_extdemo()
+
+If we run the buildout in non-newest or offline modes:
+
+ >>> print system(buildout+' -N'),
+ Develop: '/sample-buildout/demo'
+ Updating extdemo.
+ Updating demo.
+
+ >>> print system(buildout+' -o'),
+ Develop: '/sample-buildout/demo'
+ Updating extdemo.
+ Updating demo.
+
+We won't get an update.
+
+ >>> ls(sample_buildout, 'develop-eggs')
+ - demo.egg-link
+ d extdemo-1.4-py2.4-unix-i686.egg
+ - repoze.recipe.egg.egg-link
+
+But if we run the buildout in the default on-line and newest modes, we
+will:
+
+ >>> print system(buildout),
+ Develop: '/sample-buildout/demo'
+ Updating extdemo.
+ zip_safe flag not set; analyzing archive contents...
+ Updating demo.
+ Generated script '/sample-buildout/bin/demo'.
+
+ >>> ls(sample_buildout, 'develop-eggs')
+ - demo.egg-link
+ d extdemo-1.4-py2.4-linux-i686.egg
+ d extdemo-1.5-py2.4-linux-i686.egg
+ - repoze.recipe.egg.egg-link
+
+Controlling the version used
+----------------------------
+
+We can specify a specific version using the egg option:
+
+ >>> write('buildout.cfg',
+ ... """
+ ... [buildout]
+ ... develop = demo
+ ... parts = extdemo demo
+ ...
+ ... [extdemo]
+ ... recipe = repoze.recipe.egg:custom
+ ... egg = extdemo ==1.4
+ ... find-links = %(server)s
+ ... index = %(server)s/index
+ ... include-dirs = include
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... eggs = demo
+ ... extdemo ==1.4
+ ... entry-points = demo=demo:main
+ ... """ % dict(server=link_server))
+
+ >>> print system(buildout+' -D'),
+ Develop: '/sample-buildout/demo'
+ Uninstalling demo.
+ Uninstalling extdemo.
+ Installing extdemo.
+ zip_safe flag not set; analyzing archive contents...
+ Installing demo.
+ Generated script '/sample-buildout/bin/demo'.
+
+ >>> ls(sample_buildout, 'develop-eggs')
+ - demo.egg-link
+ d extdemo-1.4-py2.4-linux-i686.egg
+ - repoze.recipe.egg.egg-link
+
+Controlling develop-egg generation
+==================================
+
+If you want to provide custom build options for a develop egg, you can
+use the develop recipe. The recipe has the following options:
+
+path
+ The path to a setup script or directory containing a startup
+ script. This is required.
+
+include-dirs
+ A new-line separated list of directories to search for include
+ files.
+
+library-dirs
+ A new-line separated list of directories to search for libraries
+ to link with.
+
+rpath
+ A new-line separated list of directories to search for dynamic libraries
+ at run time.
+
+define
+ A comma-separated list of names of C preprocessor variables to
+ define.
+
+undef
+ A comman separated list of names of C preprocessor variables to
+ undefine.
+
+libraries
+ The name of an additional library to link with. Due to limitations
+ in distutils and desprite the option name, only a single library
+ can be specified.
+
+link-objects
+ The name of an link object to link afainst. Due to limitations
+ in distutils and desprite the option name, only a single link object
+ can be specified.
+
+debug
+ Compile/link with debugging information
+
+force
+ Forcibly build everything (ignore file timestamps)
+
+compiler
+ Specify the compiler type
+
+swig
+ The path to the swig executable
+
+swig-cpp
+ Make SWIG create C++ files (default is C)
+
+swig-opts
+ List of SWIG command line options
+
+python
+ The name of a section to get the Python executable from.
+ If not specified, then the buildout python option is used. The
+ Python executable is found in the executable option of the named
+ section.
+
+To illustrate this, we'll use a directory containing the extdemo
+example from the earlier section:
+
+ >>> ls(extdemo)
+ - MANIFEST
+ - MANIFEST.in
+ - README
+ - extdemo.c
+ - setup.py
+
+ >>> write('buildout.cfg',
+ ... """
+ ... [buildout]
+ ... develop = demo
+ ... parts = extdemo demo
+ ...
+ ... [extdemo]
+ ... setup = %(extdemo)s
+ ... recipe = repoze.recipe.egg:develop
+ ... include-dirs = include
+ ... define = TWO
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... eggs = demo
+ ... extdemo
+ ... entry-points = demo=demo:main
+ ... """ % dict(extdemo=extdemo))
+
+Note that we added a define option to cause the preprocessor variable
+TWO to be defined. This will cause the module-variable, 'val', to be
+set with a value of 2.
+
+ >>> print system(buildout),
+ Develop: '/sample-buildout/demo'
+ Uninstalling demo.
+ Uninstalling extdemo.
+ Installing extdemo.
+ Installing demo.
+ Generated script '/sample-buildout/bin/demo'.
+
+Our develop-eggs now includes an egg link for extdemo:
+
+ >>> ls('develop-eggs')
+ - demo.egg-link
+ - extdemo.egg-link
+ - repoze.recipe.egg.egg-link
+
+and the extdemo now has a built extension:
+
+ >>> ls(extdemo)
+ - MANIFEST
+ - MANIFEST.in
+ - README
+ d build
+ - extdemo.c
+ d extdemo.egg-info
+ - extdemo.so
+ - setup.py
+
+Because develop eggs take precedence over non-develop eggs, the demo
+script will use the new develop egg:
+
+ >>> print system(join('bin', 'demo')),
+ 2
Added: repoze.recipe.egg/trunk/repoze/recipe/egg/egg.py
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/repoze/recipe/egg/egg.py Sat Mar 1 02:04:50 2008
@@ -0,0 +1,303 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Install packages as eggs
+
+$Id: egg.py 72431 2007-02-07 23:43:36Z jim $
+"""
+
+import logging
+import os
+import pkg_resources
+import re
+import sys
+
+import zc.buildout.easy_install
+
+class Eggs(object):
+
+ def __init__(self, buildout, name, options):
+ self.buildout = buildout
+ self.name = name
+ self.options = options
+ links = options.get('find-links',
+ buildout['buildout'].get('find-links'))
+ if links:
+ links = links.split()
+ options['find-links'] = '\n'.join(links)
+ else:
+ links = ()
+ self.links = links
+
+ index = options.get('index', buildout['buildout'].get('index'))
+ if index is not None:
+ options['index'] = index
+ self.index = index
+
+ options['eggs-directory'] = buildout['buildout']['eggs-directory']
+ options['_e'] = options['eggs-directory'] # backward compat.
+ options['develop-eggs-directory'
+ ] = buildout['buildout']['develop-eggs-directory']
+ options['_d'] = options['develop-eggs-directory'] # backward compat.
+
+ assert options.get('unzip') in ('true', 'false', None)
+
+ python = options.get('python', buildout['buildout']['python'])
+ options['executable'] = buildout[python]['executable']
+
+ def working_set(self, extra=()):
+ """Separate method to just get the working set
+
+ This is intended for reuse by similar recipes.
+ """
+ options = self.options
+
+ distributions = [
+ r.strip()
+ for r in options.get('eggs', self.name).split('\n')
+ if r.strip()]
+ orig_distributions = distributions[:]
+ distributions.extend(extra)
+
+ if self.buildout['buildout'].get('offline') == 'true':
+ ws = zc.buildout.easy_install.working_set(
+ distributions, options['executable'],
+ [options['develop-eggs-directory'], options['eggs-directory']]
+ )
+ else:
+ ws = zc.buildout.easy_install.install(
+ distributions, options['eggs-directory'],
+ links = self.links,
+ index = self.index,
+ executable = options['executable'],
+ always_unzip=options.get('unzip') == 'true',
+ path=[options['develop-eggs-directory']],
+ newest=self.buildout['buildout'].get('newest') == 'true',
+ )
+
+ return orig_distributions, ws
+
+ def install(self):
+ reqs, ws = self.working_set()
+ return ()
+
+ update = install
+
+class Scripts(Eggs):
+
+ def __init__(self, buildout, name, options):
+ super(Scripts, self).__init__(buildout, name, options)
+
+ options['bin-directory'] = buildout['buildout']['bin-directory']
+ options['_b'] = options['bin-directory'] # backward compat.
+
+ self.extra_paths = [
+ os.path.join(buildout['buildout']['directory'], p.strip())
+ for p in options.get('extra-paths', '').split('\n')
+ if p.strip()
+ ]
+ if self.extra_paths:
+ options['extra-paths'] = '\n'.join(self.extra_paths)
+
+ parse_entry_point = re.compile(
+ '([^=]+)=(\w+(?:[.]\w+)*):(\w+(?:[.]\w+)*)$'
+ ).match
+ def install(self):
+ reqs, ws = self.working_set()
+ options = self.options
+
+ scripts = options.get('scripts')
+ if scripts or scripts is None:
+ if scripts is not None:
+ scripts = scripts.split()
+ scripts = dict([
+ ('=' in s) and s.split('=', 1) or (s, s)
+ for s in scripts
+ ])
+
+ for s in options.get('entry-points', '').split():
+ parsed = self.parse_entry_point(s)
+ if not parsed:
+ logging.getLogger(self.name).error(
+ "Cannot parse the entry point %s.", s)
+ raise zc.buildout.UserError("Invalid entry point")
+ reqs.append(parsed.groups())
+
+ return scripts__(
+ reqs, ws, options['executable'],
+ options['bin-directory'],
+ scripts=scripts,
+ extra_paths=self.extra_paths,
+ interpreter=options.get('interpreter'),
+ initialization=options.get('initialization', ''),
+ arguments=options.get('arguments', ''),
+ dependent_scripts=asbool(options.get('dependent_scripts',True))
+ )
+
+ return ()
+
+ update = install
+
+Egg = Scripts
+
+def asbool(value):
+ value = str(value)
+ if value.strip().lower() in ['1','true']:
+ return True
+ elif value.strip().lower() in ['0','false']:
+ return False
+ else:
+ raise Exception("Unrecognised option %s for bool"% value)
+
+
+py_script_template = '''\
+#!%(python)s
+import sys, os
+
+sys.path[0:0] = [
+ %(path)s,
+ os.getcwd(),
+ ]
+
+_interactive = True
+if len(sys.argv) > 1:
+ import getopt
+ _options, _args = getopt.getopt(sys.argv[1:], 'ic:')
+ _interactive = False
+ for (_opt, _val) in _options:
+ if _opt == '-i':
+ _interactive = True
+ elif _opt == '-c':
+ exec _val
+
+ if _args:
+ sys.argv[:] = _args
+ execfile(sys.argv[0])
+
+if _interactive:
+ import code
+ code.interact(banner="", local=globals())
+'''
+
+def scripts__(reqs, working_set, executable, dest,
+ scripts=None,
+ extra_paths=(),
+ arguments='',
+ interpreter=None,
+ initialization='',
+ launcher=None,
+ dependent_scripts=False
+ ):
+ path = [dist.location for dist in working_set]
+ path.extend(extra_paths)
+ path = repr(path)[1:-1].replace(', ', ',\n ')
+ generated = []
+
+ if isinstance(reqs, str):
+ raise TypeError('Expected iterable of requirements or entry points,'
+ ' got string.')
+
+ if initialization:
+ initialization = '\n'+initialization+'\n'
+
+ entry_points = []
+ if dependent_scripts:
+ requirements = [x[1][0] for x in working_set.entry_keys.items()]
+ else:
+ requirements = []
+
+ for req in reqs:
+ if req not in requirements:
+ requirements.append(req)
+ for req in requirements:
+ if isinstance(req, str):
+ req = pkg_resources.Requirement.parse(req)
+ dist = working_set.find(req)
+ for name in pkg_resources.get_entry_map(dist, 'console_scripts'):
+ entry_point = dist.get_entry_info('console_scripts', name)
+ entry_points.append(
+ (name, entry_point.module_name,
+ '.'.join(entry_point.attrs))
+ )
+ else:
+ entry_points.append(req)
+
+ for name, module_name, attrs in entry_points:
+ if name.startswith('easy_install'):
+ continue
+ if scripts is not None:
+ sname = scripts.get(name)
+ if sname is None:
+ continue
+ else:
+ sname = name
+
+ sname = os.path.join(dest, sname)
+ generated.extend(
+ zc.buildout.easy_install._script(module_name, attrs, path,
+ sname, executable, arguments,
+ initialization)
+ )
+
+ if interpreter:
+ sname = os.path.join(dest, interpreter)
+ generated.extend(_pyscript(path, sname, executable, launcher))
+
+ return generated
+
+def _pyscript(path, dest, executable, launcher):
+ generated = []
+ script = dest
+ if sys.platform == 'win32':
+ script+='-script'
+ if launcher:
+ dest += '.buildout'
+
+ contents = py_script_template % dict(
+ python = executable,
+ path = path,
+ )
+ changed = not (os.path.exists(dest) and open(dest).read() == contents)
+
+ if sys.platform == 'win32':
+ # generate exe file and give the script a magic name:
+ exe = script + '.exe'
+ open(exe, 'wb').write(
+ pkg_resources.resource_string('setuptools', 'cli.exe')
+ )
+ generated.append(exe)
+ elif launcher:
+ exe = script
+ open(exe, 'wb').write(
+ open(launcher, 'rb').read()
+ )
+ generated.append(exe)
+ try:
+ os.chmod(exe,0755)
+ except (AttributeError, os.error):
+ pass
+ logging.getLogger('buildout').error(
+ "Generated launcher %r.", exe)
+
+
+ if changed:
+ open(dest, 'w').write(contents)
+ try:
+ os.chmod(dest,0755)
+ except (AttributeError, os.error):
+ pass
+ logging.getLogger('buildout').info(
+ "Generated interpreter %r.", script)
+
+ generated.append(dest)
+ return generated
Added: repoze.recipe.egg/trunk/repoze/recipe/egg/selecting-python.txt
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/repoze/recipe/egg/selecting-python.txt Sat Mar 1 02:04:50 2008
@@ -0,0 +1,128 @@
+Controlling which Python to use
+-------------------------------
+
+The following assumes that you have Python 2.3 installed.
+
+We can specify the python to use by specifying the name of a section
+to read the Python executable from. The default is the section
+defined by the python buildout option.
+
+We have a link server:
+
+ >>> print get(link_server),
+ <html><body>
+ <a href="demo-0.1-py2.3.egg">demo-0.1-py2.3.egg</a><br>
+ <a href="demo-0.2-py2.3.egg">demo-0.2-py2.3.egg</a><br>
+ <a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br>
+ <a href="demo-0.4c1-py2.3.egg">demo-0.4c1-py2.3.egg</a><br>
+ <a href="demoneeded-1.0.zip">demoneeded-1.0.zip</a><br>
+ <a href="demoneeded-1.1.zip">demoneeded-1.1.zip</a><br>
+ <a href="demoneeded-1.2c1.zip">demoneeded-1.2c1.zip</a><br>
+ <a href="extdemo-1.4.zip">extdemo-1.4.zip</a><br>
+ <a href="index/">index/</a><br>
+ <a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br>
+ </body></html>
+
+We have a sample buildout. Let's update it's configuration file to
+install the demo package using Python 2.3.
+
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... """
+ ... [buildout]
+ ... parts = demo
+ ... eggs-directory = eggs
+ ... index = http://www.python.org/pypi/
+ ...
+ ... [python2.3]
+ ... executable = %(python23)s
+ ...
+ ... [demo]
+ ... recipe = repoze.recipe.egg
+ ... eggs = demo <0.3
+ ... find-links = %(server)s
+ ... python = python2.3
+ ... interpreter = py-demo
+ ... """ % dict(server=link_server, python23=python2_3_executable))
+
+Now, if we run the buildout:
+
+ >>> import os
+ >>> os.chdir(sample_buildout)
+ >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
+ >>> print system(buildout),
+ Installing demo.
+ Getting distribution for 'demo<0.3'.
+ Got demo 0.2.
+ Getting distribution for 'demoneeded'.
+ Getting distribution for 'setuptools'.
+ Got setuptools 0.6.
+ Got demoneeded 1.2c1.
+ Generated script '/sample-buildout/bin/demo'.
+ Generated interpreter '/sample-buildout/bin/py-demo'.
+
+we'll get the Python 2.3 eggs for demo and demoneeded:
+
+ >>> ls(sample_buildout, 'eggs')
+ - demo-0.2-py2.3.egg
+ - demoneeded-1.2c1-py2.3.egg
+ d setuptools-0.6-py2.3.egg
+ d setuptools-0.6-py2.4.egg
+ - zc.buildout-1.0-py2.4.egg
+
+And the generated scripts invoke Python 2.3:
+
+ >>> import sys
+ >>> if sys.platform == 'win32':
+ ... script_name = 'demo-script.py'
+ ... else:
+ ... script_name = 'demo'
+ >>> f = open(os.path.join(sample_buildout, 'bin', script_name))
+ >>> f.readline().strip() == '#!' + python2_3_executable
+ True
+ >>> print f.read(), # doctest: +NORMALIZE_WHITESPACE
+ <BLANKLINE>
+ import sys
+ sys.path[0:0] = [
+ '/sample-buildout/eggs/demo-0.2-py2.3.egg',
+ '/sample-buildout/eggs/demoneeded-1.2c1-py2.3.egg',
+ ]
+ <BLANKLINE>
+ import eggrecipedemo
+ <BLANKLINE>
+ if __name__ == '__main__':
+ eggrecipedemo.main()
+
+ >>> if sys.platform == 'win32':
+ ... f = open(os.path.join(sample_buildout, 'bin', 'py-demo-script.py'))
+ ... else:
+ ... f = open(os.path.join(sample_buildout, 'bin', 'py-demo'))
+ >>> f.readline().strip() == '#!' + python2_3_executable
+ True
+ >>> print f.read(), # doctest: +NORMALIZE_WHITESPACE
+ import sys
+ <BLANKLINE>
+ sys.path[0:0] = [
+ '/sample-buildout/eggs/demo-0.2-py2.3.egg',
+ '/sample-buildout/eggs/demoneeded-1.2c1-py2.3.egg',
+ ]
+ <BLANKLINE>
+ _interactive = True
+ if len(sys.argv) > 1:
+ import getopt
+ _options, _args = getopt.getopt(sys.argv[1:], 'ic:')
+ _interactive = False
+ for (_opt, _val) in _options:
+ if _opt == '-i':
+ _interactive = True
+ elif _opt == '-c':
+ exec _val
+ <BLANKLINE>
+ if _args:
+ sys.argv[:] = _args
+ execfile(sys.argv[0])
+ <BLANKLINE>
+ if _interactive:
+ import code
+ code.interact(banner="", local=globals())
+
+ >>> f.close()
Added: repoze.recipe.egg/trunk/repoze/recipe/egg/tests.py
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/repoze/recipe/egg/tests.py Sat Mar 1 02:04:50 2008
@@ -0,0 +1,118 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import os, re, shutil, sys
+import zc.buildout.tests
+import zc.buildout.testselectingpython
+import zc.buildout.testing
+
+import unittest
+from zope.testing import doctest, renormalizing
+
+os_path_sep = os.path.sep
+if os_path_sep == '\\':
+ os_path_sep *= 2
+
+def dirname(d, level=1):
+ if level == 0:
+ return d
+ return dirname(os.path.dirname(d), level-1)
+
+def setUp(test):
+ zc.buildout.tests.easy_install_SetUp(test)
+ zc.buildout.testing.install_develop('repoze.recipe.egg', test)
+
+def setUpSelecting(test):
+ zc.buildout.testselectingpython.setup(test)
+ zc.buildout.testing.install_develop('repoze.recipe.egg', test)
+
+def test_suite():
+ suite = unittest.TestSuite((
+ doctest.DocFileSuite(
+ 'README.txt',
+ setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
+ checker=renormalizing.RENormalizing([
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_script,
+ zc.buildout.testing.normalize_egg_py,
+ zc.buildout.tests.normalize_bang,
+ (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
+ 'zc.buildout.egg'),
+ (re.compile('[-d] setuptools-[^-]+-'), 'setuptools-X-')
+ ])
+ ),
+ doctest.DocFileSuite(
+ 'api.txt',
+ setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
+ checker=renormalizing.RENormalizing([
+ zc.buildout.testing.normalize_path,
+ (re.compile('__buildout_signature__ = '
+ 'sample-\S+\s+'
+ 'repoze.recipe.egg-\S+\s+'
+ 'setuptools-\S+\s+'
+ 'zc.buildout-\S+\s*'
+ ),
+ '__buildout_signature__ = sample- repoze.recipe.egg-'),
+ (re.compile('executable = \S+python\S*'),
+ 'executable = python'),
+ (re.compile('index = \S+python\S+'),
+ 'executable = python'),
+ (re.compile('find-links = http://localhost:\d+/'),
+ 'find-links = http://localhost:8080/'),
+ (re.compile('index = http://localhost:\d+/index'),
+ 'index = http://localhost:8080/index'),
+ ])
+ ),
+ doctest.DocFileSuite(
+ 'custom.txt',
+ setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
+ checker=renormalizing.RENormalizing([
+ zc.buildout.testing.normalize_path,
+ (re.compile("(d ((ext)?demo(needed)?|other)"
+ "-\d[.]\d-py)\d[.]\d(-\S+)?[.]egg"),
+ '\\1V.V.egg'),
+ (re.compile('extdemo.c\n.+\\extdemo.exp\n'), ''),
+ (re.compile('extdemo[.]pyd'), 'extdemo.so')
+ ]),
+ ),
+
+ ))
+
+ if sys.version_info[:2] != (2, 3):
+ # Only run selecting python tests if not 2.3, since
+ # 2.3 is the alternate python used in the tests.
+ suite.addTest(
+ doctest.DocFileSuite(
+ 'selecting-python.txt',
+ setUp=setUpSelecting,
+ tearDown=zc.buildout.testing.buildoutTearDown,
+ checker=renormalizing.RENormalizing([
+ zc.buildout.testing.normalize_path,
+ zc.buildout.testing.normalize_script,
+ (re.compile('Got setuptools \S+'), 'Got setuptools V'),
+ (re.compile('([d-] )?setuptools-\S+-py'), 'setuptools-V-py'),
+ (re.compile('-py2[.][0-24-9][.]'), 'py2.4.'),
+ (re.compile('zc.buildout-\S+[.]egg'),
+ 'zc.buildout.egg'),
+ (re.compile('zc.buildout[.]egg-link'),
+ 'zc.buildout.egg'),
+ ]),
+ ),
+ )
+
+ return suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
+
Added: repoze.recipe.egg/trunk/setup.py
==============================================================================
--- (empty file)
+++ repoze.recipe.egg/trunk/setup.py Sat Mar 1 02:04:50 2008
@@ -0,0 +1,98 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Setup for repoze.recipe.egg package
+
+$Id: setup.py 81447 2007-11-03 19:14:30Z srichter $
+"""
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+def alltests():
+ import pdb; pdb.set_trace()
+ # use the zope.testing testrunner machinery to find all the
+ # test suites we've put under ourselves
+ from zope.testing.testrunner import get_options
+ from zope.testing.testrunner import find_suites
+ from zope.testing.testrunner import configure_logging
+ configure_logging()
+ from unittest import TestSuite
+ import sys
+ here = os.path.abspath(os.path.dirname(sys.argv[0]))
+ args = sys.argv[:]
+ defaults = ['--test-path', here]
+ options = get_options(args, defaults)
+ suites = list(find_suites(options))
+ return TestSuite(suites)
+
+name = "repoze.recipe.egg"
+setup(
+ name = name,
+ version = "0.1",
+ author = "Jim Fulton (forked by Chris McDonough)",
+ author_email = "chrism at plope.com",
+ description = "Recipe for installing Python package distributions as eggs",
+ long_description = (
+ read('README.txt')
+ + '\n' +
+ read('CHANGES.txt')
+ + '\n' +
+ 'Detailed Documentation\n'
+ '**********************\n'
+ + '\n' +
+ read('repoze', 'recipe', 'egg', 'README.txt')
+ + '\n' +
+ read('repoze', 'recipe', 'egg', 'selecting-python.txt')
+ + '\n' +
+ read('repoze', 'recipe', 'egg', 'custom.txt')
+ + '\n' +
+ read('repoze', 'recipe', 'egg', 'api.txt')
+ + '\n' +
+ 'Download\n'
+ '*********\n'
+ ),
+ keywords = "development build",
+ classifiers = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Framework :: Buildout',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Topic :: Software Development :: Build Tools',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ ],
+ url='http://dist.repoze.org/simple/repoze.recipe.egg',
+ license = "ZPL 2.1",
+
+ packages = find_packages(),
+ namespace_packages = ['repoze', 'repoze.recipe'],
+ install_requires = [
+ 'zc.buildout >=1.0.0b3',
+ 'setuptools',
+ 'virtualenv'],
+ tests_require = ['zope.testing', 'zc.buildout >=1.0.0b3'],
+ #test_suite = name+'.tests.test_suite',
+ test_suite = '__main__.alltests',
+ entry_points = {'zc.buildout': ['default = %s:Scripts' % name,
+ 'script = %s:Scripts' % name,
+ 'scripts = %s:Scripts' % name,
+ 'eggs = %s:Eggs' % name,
+ 'custom = %s:Custom' % name,
+ 'develop = %s:Develop' % name,
+ ]
+ },
+ include_package_data = True,
+ zip_safe=False,
+ )
More information about the Repoze-checkins
mailing list