Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.buildout
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
6
Merge Requests
6
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
slapos.buildout
Commits
b288c4c1
Commit
b288c4c1
authored
Dec 18, 2009
by
Gary Poster
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
basic tests and implementation of stand-alone interpreter option
parent
dc34f555
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
324 additions
and
26 deletions
+324
-26
src/zc/buildout/easy_install.py
src/zc/buildout/easy_install.py
+2
-2
src/zc/buildout/testing.py
src/zc/buildout/testing.py
+52
-21
zc.recipe.egg_/setup.py
zc.recipe.egg_/setup.py
+1
-0
zc.recipe.egg_/src/zc/recipe/egg/README.txt
zc.recipe.egg_/src/zc/recipe/egg/README.txt
+217
-0
zc.recipe.egg_/src/zc/recipe/egg/__init__.py
zc.recipe.egg_/src/zc/recipe/egg/__init__.py
+1
-1
zc.recipe.egg_/src/zc/recipe/egg/egg.py
zc.recipe.egg_/src/zc/recipe/egg/egg.py
+51
-2
No files found.
src/zc/buildout/easy_install.py
View file @
b288c4c1
...
...
@@ -985,7 +985,7 @@ def interpreter(name, working_set, executable, dest, site_py_dest,
real_sitecustomize_path
=
_get_module_file
(
executable
,
'sitecustomize'
)
if
real_sitecustomize_path
:
sitecustomize
.
write
(
'execfile(%
s
)
\
n
'
%
(
real_sitecustomize_path
,))
sitecustomize
.
write
(
'execfile(%
r
)
\
n
'
%
(
real_sitecustomize_path
,))
sitecustomize
.
close
()
generated
.
append
(
sitecustomize_path
)
# Write site.py.
...
...
@@ -1031,7 +1031,7 @@ def interpreter(name, working_set, executable, dest, site_py_dest,
os
.
chmod
(
script_name
,
0755
)
except
(
AttributeError
,
os
.
error
):
pass
logger
.
info
(
"Generated interpreter %r."
,
name
)
logger
.
info
(
"Generated interpreter %r."
,
full_
name
)
generated
.
append
(
script_name
)
return
generated
...
...
src/zc/buildout/testing.py
View file @
b288c4c1
...
...
@@ -28,6 +28,7 @@ import socket
import
subprocess
import
sys
import
tempfile
import
textwrap
import
threading
import
time
import
urllib2
...
...
@@ -202,6 +203,24 @@ def wait_until(label, func, *args, **kw):
time
.
sleep
(
0.01
)
raise
ValueError
(
'Timed out waiting for: '
+
label
)
def
make_buildout
():
# Create a basic buildout.cfg to avoid a warning from buildout:
open
(
'buildout.cfg'
,
'w'
).
write
(
"[buildout]
\
n
parts =
\
n
"
)
# Use the buildout bootstrap command to create a buildout
zc
.
buildout
.
buildout
.
Buildout
(
'buildout.cfg'
,
[(
'buildout'
,
'log-level'
,
'WARNING'
),
# trick bootstrap into putting the buildout develop egg
# in the eggs dir.
(
'buildout'
,
'develop-eggs-directory'
,
'eggs'
),
]
).
bootstrap
([])
# Create the develop-eggs dir, which didn't get created the usual
# way due to the trick above:
os
.
mkdir
(
'develop-eggs'
)
def
buildoutSetUp
(
test
):
test
.
globs
[
'__tear_downs'
]
=
__tear_downs
=
[]
...
...
@@ -255,27 +274,7 @@ def buildoutSetUp(test):
sample
=
tmpdir
(
'sample-buildout'
)
os
.
chdir
(
sample
)
# Create a basic buildout.cfg to avoid a warning from buildout:
open
(
'buildout.cfg'
,
'w'
).
write
(
"[buildout]
\
n
parts =
\
n
"
)
# Use the buildout bootstrap command to create a buildout
zc
.
buildout
.
buildout
.
Buildout
(
'buildout.cfg'
,
[(
'buildout'
,
'log-level'
,
'WARNING'
),
# trick bootstrap into putting the buildout develop egg
# in the eggs dir.
(
'buildout'
,
'develop-eggs-directory'
,
'eggs'
),
]
).
bootstrap
([])
# Create the develop-eggs dir, which didn't get created the usual
# way due to the trick above:
os
.
mkdir
(
'develop-eggs'
)
make_buildout
()
def
start_server
(
path
):
port
,
thread
=
_start_server
(
path
,
name
=
path
)
...
...
@@ -283,6 +282,37 @@ def buildoutSetUp(test):
register_teardown
(
lambda
:
stop_server
(
url
,
thread
))
return
url
def
make_py
(
initialization
=
''
,
site_packages_dir
=
None
):
"""Returns paths to new executable and to its site-packages.
"""
buildout
=
tmpdir
(
'executable_buildout'
)
if
site_packages_dir
is
None
:
site_packages_dir
=
mkdir
(
buildout
,
'site-packages'
)
old_wd
=
os
.
getcwd
()
os
.
chdir
(
buildout
)
make_buildout
()
initialization
=
'
\
n
'
.
join
(
' '
+
line
for
line
in
initialization
.
split
(
'
\
n
'
))
install_develop
(
'zc.recipe.egg'
,
os
.
path
.
join
(
buildout
,
'develop-eggs'
))
write
(
'buildout.cfg'
,
textwrap
.
dedent
(
'''
\
[buildout]
parts = py
[py]
recipe = zc.recipe.egg:interpreter
initialization =
%(initialization)s
extra-paths = %(site-packages)s
eggs = setuptools
'''
)
%
{
'initialization'
:
initialization
,
'site-packages'
:
site_packages_dir
})
system
(
os
.
path
.
join
(
buildout
,
'bin'
,
'buildout'
))
os
.
chdir
(
old_wd
)
return
(
os
.
path
.
join
(
buildout
,
'bin'
,
'py'
),
site_packages_dir
)
test
.
globs
.
update
(
dict
(
sample_buildout
=
sample
,
ls
=
ls
,
...
...
@@ -301,6 +331,7 @@ def buildoutSetUp(test):
start_server
=
start_server
,
buildout
=
os
.
path
.
join
(
sample
,
'bin'
,
'buildout'
),
wait_until
=
wait_until
,
make_py
=
make_py
))
zc
.
buildout
.
easy_install
.
prefer_final
(
prefer_final
)
...
...
zc.recipe.egg_/setup.py
View file @
b288c4c1
...
...
@@ -76,6 +76,7 @@ setup(
'eggs = %s:Eggs'
%
name
,
'custom = %s:Custom'
%
name
,
'develop = %s:Develop'
%
name
,
'interpreter = %s:Interpreter'
%
name
,
]
},
include_package_data
=
True
,
...
...
zc.recipe.egg_/src/zc/recipe/egg/README.txt
View file @
b288c4c1
...
...
@@ -154,6 +154,8 @@ dependent-scripts
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.
See the ``interpreter`` (or ``py``) recipe, below, for a more
full-featured interpreter.
extra-paths
Extra paths to include in a generated script.
...
...
@@ -750,3 +752,218 @@ be made to contact an index server:
Uninstalling bigdemo.
Installing demo.
Generated script '/sample-buildout/bin/foo'.
Interpreter generation
----------------------
What if you want a more full-featured interpreter than the one described
above? That one is a script that mimics an interpreter--it has support
for only a limited number of command-line options.
The interpreter recipe generates a full-fledged version. Here's an example.
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = py
...
... [py]
... recipe = zc.recipe.egg:interpreter
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)s/index
... """ % dict(server=link_server))
>>> print system(buildout),
Uninstalling demo.
Installing py.
Generated interpreter '/sample-buildout/bin/py'.
Notice that the recipe took the name of the recipe from the name of the
section.
The bin/py script now just restarts Python after specifying a special
path in PYTHONPATH.
>>> cat(sample_buildout, 'bin', 'py') # doctest: +NORMALIZE_WHITESPACE
#!/usr/bin/python2.4 -S
<BLANKLINE>
import os
import sys
<BLANKLINE>
argv = [sys.executable] + sys.argv[1:]
environ = os.environ.copy()
path = '/sample-buildout/parts/py'
if environ.get('PYTHONPATH'):
path = os.pathsep.join([path, environ['PYTHONPATH']])
environ['PYTHONPATH'] = path
os.execve(sys.executable, argv, environ)
The path is a directory that contains two files: our own site.py and
sitecustomize.py.
>>> ls(sample_buildout, 'parts', 'py')
- site.py
- sitecustomize.py
>>> cat(sample_buildout, 'parts', 'py', 'site.py')
... # doctest: +NORMALIZE_WHITESPACE
import sys
sys.path[0:0] = [
'/sample-buildout/eggs/demo-0.2-py2.4.egg',
'/sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg',
]
import sitecustomize
>>> cat(sample_buildout, 'parts', 'py', 'sitecustomize.py')
Here's an example of using the generated interpreter.
>>> print system(join(sample_buildout, 'bin', 'py') +
... ' -c "import sys, pprint; pprint.pprint(sys.path[:3])"')
['',
'/sample-buildout/eggs/demo-0.2-py2.4.egg',
'/sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg']
<BLANKLINE>
The interpreter recipe takes several options. First, here's the list of the
options that overlap from the scripts recipe. After this, we'll list the new
options and describe them.
* eggs
* find-links
* index
* python
* extra-paths
* initialization
* relative-paths
* include-site-packages
In addition to these, the interpreter script offers these three new options.
include-site-customization
Normally the Python's real sitecustomize module is not processed.
If you want it to be processed, set this value to 'true'. This will
be honored irrespective of the setting for include-site-paths.
extends
You can extend another section using this value. It is intended to be
used by extending a section that uses this package's scripts recipe.
In this manner, you can avoid repeating yourself.
name
If you do not want to have the interpreter have the same name as the
section, you can set it explicitly with this option.
Let's look at the ``extends`` option first.
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = demo python
...
... [demo]
... recipe = zc.recipe.egg
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)s/index
...
... [python]
... recipe = zc.recipe.egg:interpreter
... extends = demo
... """ % dict(server=link_server))
That's not quite as short as adding an "interpreter = py" option to the
[demo] section, but an improvement over what it could be.
Now let's put it in action.
>>> print system(buildout),
Uninstalling py.
Installing demo.
Generated script '/sample-buildout/bin/demo'.
Installing python.
Generated interpreter '/sample-buildout/bin/python'.
>>> print system(join(sample_buildout, 'bin', 'python') +
... ' -c "import sys, pprint; pprint.pprint(sys.path[:3])"')
['',
'/sample-buildout/eggs/demo-0.2-py2.4.egg',
'/sample-buildout/eggs/demoneeded-1.2c1-py2.4.egg']
<BLANKLINE>
Note that the parts/py directory has been cleaned up, and parts/python has
been created.
>>> ls(sample_buildout, 'parts')
d python
Now let's use the include-site-customization option. It simply lets Python's
underlying sitecustomize module, if it exists, be executed.
To show this, we need a Python executable guaranteed to have a sitecustomize
module. We'll make one. The os.environ change below will go into the
sitecustomize. We'll be able to use that as a flag.
>>> py_path, site_packages_path = make_py(initialization='''\
... import os
... os.environ['zc.buildout'] = 'foo bar baz shazam'
... ''')
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = py
... executable = %(py_path)s
...
... [py]
... recipe = zc.recipe.egg:interpreter
... include-site-customization = true
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)s/index
... """ % dict(server=link_server, py_path=py_path))
>>> print system(buildout),
Uninstalling python.
Uninstalling demo.
Installing py.
Generated interpreter '/sample-buildout/bin/py'.
>>> cat(sample_buildout, 'parts', 'py', 'sitecustomize.py')
... # doctest: +NORMALIZE_WHITESPACE
execfile('/executable_buildout/parts/py/sitecustomize.py')
>>> print system(join(sample_buildout, 'bin', 'py') +
... ''' -c "import os; print os.environ['zc.buildout']"''')
foo bar baz shazam
<BLANKLINE>
The last new option is ``name``. This simply changes the name of the
interpreter, so that you are not forced to use the name of the section.
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... parts = interpreter
...
... [interpreter]
... name = python2
... recipe = zc.recipe.egg:interpreter
... include-site-customization = true
... eggs = demo<0.3
... find-links = %(server)s
... index = %(server)s/index
... """ % dict(server=link_server))
>>> print system(buildout),
Uninstalling py.
Installing interpreter.
Generated interpreter '/sample-buildout/bin/python2'.
>>> print system(join(sample_buildout, 'bin', 'python2') +
... ' -c "print 42"')
42
<BLANKLINE>
The other options have been described before for the scripts recipe, and so
they will not be repeated here.
zc.recipe.egg_/src/zc/recipe/egg/__init__.py
View file @
b288c4c1
from
zc.recipe.egg.egg
import
Egg
,
Scripts
,
Eggs
from
zc.recipe.egg.egg
import
Egg
,
Scripts
,
Eggs
,
Interpreter
from
zc.recipe.egg.custom
import
Custom
,
Develop
zc.recipe.egg_/src/zc/recipe/egg/egg.py
View file @
b288c4c1
...
...
@@ -19,6 +19,7 @@ $Id$
import
logging
,
os
,
re
,
zipfile
import
zc.buildout.easy_install
class
Eggs
(
object
):
def
__init__
(
self
,
buildout
,
name
,
options
):
...
...
@@ -98,10 +99,11 @@ class Eggs(object):
update
=
install
class
Scripts
(
Eggs
):
class
ScriptBase
(
Eggs
):
def
__init__
(
self
,
buildout
,
name
,
options
):
super
(
Script
s
,
self
).
__init__
(
buildout
,
name
,
options
)
super
(
Script
Base
,
self
).
__init__
(
buildout
,
name
,
options
)
b_options
=
buildout
[
'buildout'
]
...
...
@@ -135,6 +137,9 @@ class Scripts(Eggs):
(
value
,))
self
.
include_site_packages
=
(
value
==
'true'
)
class
Scripts
(
ScriptBase
):
parse_entry_point
=
re
.
compile
(
'([^=]+)=(
\
w+(?:[.]
\
w+)*):(
\
w+(?:[.]
\
w+)*)$'
).
match
...
...
@@ -184,6 +189,50 @@ class Scripts(Eggs):
update
=
install
class
Interpreter
(
ScriptBase
):
def
__init__
(
self
,
buildout
,
name
,
options
):
if
'extends'
in
options
:
options
.
update
(
buildout
[
options
[
'extends'
]])
super
(
Interpreter
,
self
).
__init__
(
buildout
,
name
,
options
)
b_options
=
buildout
[
'buildout'
]
options
[
'parts-directory'
]
=
os
.
path
.
join
(
b_options
[
'parts-directory'
],
self
.
name
)
value
=
options
.
setdefault
(
'include-site-customization'
,
b_options
.
get
(
'include-site-customization'
,
'false'
))
if
value
not
in
(
'true'
,
'false'
):
raise
zc
.
buildout
.
UserError
(
"Invalid value for include-site-customization option: %s"
%
(
value
,))
self
.
include_site_customization
=
(
value
==
'true'
)
options
.
setdefault
(
'name'
,
name
)
def
install
(
self
):
reqs
,
ws
=
self
.
working_set
()
options
=
self
.
options
if
not
os
.
path
.
exists
(
options
[
'parts-directory'
]):
os
.
mkdir
(
options
[
'parts-directory'
])
dir_made
=
True
else
:
dir_made
=
False
generated
=
zc
.
buildout
.
easy_install
.
interpreter
(
options
[
'name'
],
ws
,
options
[
'executable'
],
options
[
'bin-directory'
],
options
[
'parts-directory'
],
extra_paths
=
self
.
extra_paths
,
initialization
=
options
.
get
(
'initialization'
,
''
),
relative_paths
=
self
.
_relative_paths
,
import_site
=
self
.
include_site_packages
,
import_sitecustomize
=
self
.
include_site_customization
,
)
if
dir_made
:
generated
.
append
(
options
[
'parts-directory'
])
return
generated
def
get_bool
(
options
,
name
,
default
=
False
):
value
=
options
.
get
(
name
)
if
not
value
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment