Commit 067d194d authored by Jim Fulton's avatar Jim Fulton

Added support for extra paths in generated scripts.

Added an option to supply entry points directly. This is useful for
packages that don't declare their entry points.

No longer generate "py-" scripts implicitly.  Added a new option,
interpreter, to request such scripts and specifu their names.

Increased default buildout logging.
parent 91fa83b0
......@@ -29,6 +29,13 @@ python
Python executable is found in the executable option of the named
section.
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
......@@ -37,6 +44,10 @@ scripts
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.
......@@ -69,7 +80,7 @@ install the demo package.
... index = %(server)s/index
... """ % dict(server=link_server))
In this example, we limited ourself to revisions before 0.3. We also
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:
......@@ -78,6 +89,11 @@ Let's run the buildout:
>>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout),
buildout: Installing demo
zc.buildout.easy_install: Getting new distribution for demo<0.3
zc.buildout.easy_install: Got demo 0.2
zc.buildout.easy_install: Getting new distribution for demoneeded
zc.buildout.easy_install: Got demoneeded 1.1
Now, if we look at the buildout eggs directory:
......@@ -93,20 +109,48 @@ link for the recipe. 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 also defined a script and we see that the script was
installed as well:
>>> ls(sample_buildout, 'bin')
- buildout
- demo
- py-demo
- py-zc.buildout
Here, in addition to the buildout script, we see the demo script,
demo, and we see a script, py-demo, for giving us a Python prompt with
demo.
Let's add an interpreter option:
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = zc.recipe.egg
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)s/index
... interpreter = py-demo
... """ % dict(server=link_server))
>>> print system(buildout),
buildout: Uninstalling demo
buildout: Installing 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(os.path.join(sample_buildout, 'bin', 'demo')),
......@@ -144,6 +188,10 @@ specification. For example, We remove the restriction on demo:
... """ % dict(server=link_server))
>>> print system(buildout),
buildout: Uninstalling demo
buildout: Installing demo
zc.buildout.easy_install: Getting new distribution for demo
zc.buildout.easy_install: Got demo 0.3
Then we'll get a new demo egg:
......@@ -162,11 +210,13 @@ The script is updated too:
>>> print system(os.path.join(sample_buildout, 'bin', 'demo')),
3 1
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]
......@@ -181,10 +231,11 @@ arguments:
>>> print system(buildout),
buildout: Uninstalling demo
buildout: Installing demo
>>> ls(sample_buildout, 'bin')
- buildout
- py-zc.buildout
You can also control the name used for scripts:
......@@ -201,11 +252,15 @@ You can also control the name used for scripts:
... """ % dict(server=link_server))
>>> print system(buildout),
buildout: Uninstalling demo
buildout: Installing demo
>>> ls(sample_buildout, 'bin')
- buildout
- foo
- py-zc.buildout
Specifying extra script paths
-----------------------------
If we need to include extra paths in a script, we can use the
extra-paths option:
......@@ -226,6 +281,8 @@ extra-paths option:
... """ % dict(server=link_server))
>>> print system(buildout),
buildout: Uninstalling demo
buildout: Installing demo
Let's look at the script that was generated:
......@@ -237,7 +294,7 @@ Let's look at the script that was generated:
'/tmp/xyzsample-install/demo-0.3-py2.3.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg',
'/foo/bar',
'/spam/eggs'
'/spam/eggs',
]
<BLANKLINE>
import eggrecipedemo
......@@ -245,8 +302,54 @@ Let's look at the script that was generated:
if __name__ == '__main__':
eggrecipedemo.main()
Specifying entry points
-----------------------
Scripts can be generated for entry points declared explcitly. We can
declate entry points using the entry-points option:
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo
...
... [demo]
... recipe = zc.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),
buildout: Uninstalling demo
buildout: Installing demo
>>> ls(sample_buildout, 'bin')
- alt
- buildout
- demo
- other
>>> cat(sample_buildout, 'bin', 'other')
#!/usr/local/bin/python2.3
<BLANKLINE>
import sys
sys.path[0:0] = [
'/private/tmp/tmp88gKbfsample-buildout/eggs/demo-0.3-py2.3.egg',
'/private/tmp/tmp88gKbfsample-buildout/eggs/demoneeded-1.1-py2.3.egg',
'/foo/bar',
'/spam/eggs',
]
<BLANKLINE>
import foo.bar
<BLANKLINE>
if __name__ == '__main__':
foo.bar.a.b.c()
Offline mode
------------
......@@ -267,3 +370,5 @@ be made to contact an index server:
... """ % dict(server=link_server))
>>> print system(buildout),
buildout: Uninstalling demo
buildout: Installing demo
......@@ -6,10 +6,10 @@ 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, 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.
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:
......@@ -37,6 +37,7 @@ around the egg recipe:
... print 'Working set:'
... for d in ws:
... print d
... print 'extra paths:', self.egg.extra_paths
... """)
Here we instantiated the egg recipe in the constructor, saving it in
......@@ -77,7 +78,7 @@ of extra requirements to be included in the working set.
>>> import os
>>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout),
>>> print system(buildout + ' -q'),
Part: sample-part
Egg requirements:
demo<0.3
......@@ -85,6 +86,7 @@ of extra requirements to be included in the working set.
demo 0.2
other 1.0
demoneeded 1.1
extra paths: []
We can see that the options were augmented with additionl data
computed by the egg recipe by looking at .installed.cfg:
......@@ -108,3 +110,35 @@ computed by the egg recipe by looking at .installed.cfg:
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.1
extra paths: ['/foo/bar', '/spam/eggs']
......@@ -95,6 +95,7 @@ the egg:
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout),
buildout: Installing extdemo
zip_safe flag not set; analyzing archive contents...
We got the zip_safe warning because the source distribution we used
......
......@@ -16,7 +16,7 @@
$Id$
"""
import os, re, zipfile
import logging, os, re, zipfile
import zc.buildout.easy_install
class Egg:
......@@ -87,8 +87,11 @@ class Egg:
return orig_distributions, ws
parse_entry_point = re.compile(
'([^=]+)=(\w+(?:[.]\w+)*):(\w+(?:[.]\w+)*)$'
).match
def install(self):
distributions, ws = self.working_set()
reqs, ws = self.working_set()
options = self.options
scripts = options.get('scripts')
......@@ -99,9 +102,20 @@ class Egg:
('=' 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 zc.buildout.easy_install.scripts(
distributions, ws, options['executable'],
reqs, ws, options['executable'],
options['_b'],
scripts=scripts,
extra_paths=self.extra_paths)
extra_paths=self.extra_paths,
interpreter=options.get('interpreter'),
)
......@@ -46,6 +46,7 @@ install the demo package using Python 2.3.
... find-links = %(server)s
... index = %(server)s/index
... python = python2.3
... interpreter = py-demo
... """ % dict(server=link_server, python23=python2_3_executable))
Now, if we run the buildout:
......@@ -54,6 +55,11 @@ Now, if we run the buildout:
>>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout),
buildout: Installing demo
zc.buildout.easy_install: Getting new distribution for demo<0.3
zc.buildout.easy_install: Got demo 0.2
zc.buildout.easy_install: Getting new distribution for demoneeded
zc.buildout.easy_install: Got demoneeded 1.1
we'll get the Python 2.3 eggs for demo and demoneeded:
......@@ -78,7 +84,7 @@ And the generated scripts invoke Python 2.3:
import sys
sys.path[0:0] = [
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demo-0.2-py2.3.egg',
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demoneeded-1.1-py2.3.egg'
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demoneeded-1.1-py2.3.egg',
]
<BLANKLINE>
import eggrecipedemo
......@@ -97,7 +103,7 @@ And the generated scripts invoke Python 2.3:
<BLANKLINE>
sys.path[0:0] = [
'/tmp/tmp5zS2Afsample-buildout/eggs/demo-0.2-py2.3.egg',
'/tmp/tmp5zS2Afsample-buildout/eggs/demoneeded-1.1-py2.3.egg'
'/tmp/tmp5zS2Afsample-buildout/eggs/demoneeded-1.1-py2.3.egg',
]
<BLANKLINE>
_interactive = True
......@@ -135,6 +141,7 @@ If we change the Python version to 2.4, we'll use Python 2.4 eggs:
... find-links = %(server)s
... index = %(server)s/index
... python = python2.4
... interpreter = py-demo
...
... [python2.4]
... executable = %(python24)s
......@@ -142,6 +149,12 @@ If we change the Python version to 2.4, we'll use Python 2.4 eggs:
... """ % dict(server=link_server, python24=python2_4_executable))
>>> print system(buildout),
buildout: Uninstalling demo
buildout: Installing demo
zc.buildout.easy_install: Getting new distribution for demo<0.3
zc.buildout.easy_install: Got demo 0.2
zc.buildout.easy_install: Getting new distribution for demoneeded
zc.buildout.easy_install: Got demoneeded 1.1
>>> ls(sample_buildout, 'eggs')
- demo-0.2-py2.3.egg
......@@ -162,7 +175,7 @@ If we change the Python version to 2.4, we'll use Python 2.4 eggs:
import sys
sys.path[0:0] = [
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demo-0.2-py2.4.egg',
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demoneeded-1.1-py2.4.egg'
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demoneeded-1.1-py2.4.egg',
]
<BLANKLINE>
import eggrecipedemo
......@@ -183,7 +196,7 @@ If we change the Python version to 2.4, we'll use Python 2.4 eggs:
<BLANKLINE>
sys.path[0:0] = [
'/tmp/tmp5zS2Afsample-buildout/eggs/demo-0.2-py2.4.egg',
'/tmp/tmp5zS2Afsample-buildout/eggs/demoneeded-1.1-py2.4.egg'
'/tmp/tmp5zS2Afsample-buildout/eggs/demoneeded-1.1-py2.4.egg',
]
<BLANKLINE>
_interactive = True
......
......@@ -122,7 +122,7 @@ def test_suite():
setUp=setUpCustom, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
(re.compile("(d ((ext)?demo(needed)?|other)"
"-\d[.]\d-py)\d[.]\d(-[^. \t\n]+)?[.]egg"),
"-\d[.]\d-py)\d[.]\d(-\S+)?[.]egg"),
'\\1V.V.egg'),
(re.compile('extdemo.c\n.+\\extdemo.exp\n'), ''),
]),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment