Commit 1d8ffdd9 authored by Gary Poster's avatar Gary Poster

fixes for bootstrap and a system Python; changes based on learning what would...

fixes for bootstrap and a system Python; changes based on learning what would be necessary to be able to develop buildout with a system Python (zc.recipe.testing would also need to use sitepackage_safe_scripts)
parent 89cc72e5
...@@ -23,6 +23,35 @@ $Id$ ...@@ -23,6 +23,35 @@ $Id$
import os, shutil, sys, tempfile, textwrap, urllib, urllib2 import os, shutil, sys, tempfile, textwrap, urllib, urllib2
from optparse import OptionParser from optparse import OptionParser
if sys.platform == 'win32':
def quote(c):
if ' ' in c:
return '"%s"' % c # work around spawn lamosity on windows
else:
return c
else:
quote = str
# In order to be more robust in the face of system Pythons, we want to run
# with site-packages loaded. This is somewhat tricky, in particular because
# Python 2.6's distutils imports site, so starting with the -S flag is not
# sufficient.
if 'site' in sys.modules:
# We will restart with python -S.
args = sys.argv[:]
args[0:0] = [sys.executable, '-S']
args = map(quote, args)
os.execv(sys.executable, args)
clean_path = sys.path[:]
import site
sys.path[:] = clean_path
for k, v in sys.modules.items():
if (hasattr(v, '__path__') and
len(v.__path__)==1 and
not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
# This is a namespace package. Remove it.
sys.modules.pop(k)
is_jython = sys.platform.startswith('java') is_jython = sys.platform.startswith('java')
setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py' setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
...@@ -128,16 +157,6 @@ except ImportError: ...@@ -128,16 +157,6 @@ except ImportError:
if path not in pkg_resources.working_set.entries: if path not in pkg_resources.working_set.entries:
pkg_resources.working_set.add_entry(path) pkg_resources.working_set.add_entry(path)
if sys.platform == 'win32':
def quote(c):
if ' ' in c:
return '"%s"' % c # work around spawn lamosity on windows
else:
return c
else:
def quote (c):
return c
cmd = [quote(sys.executable), cmd = [quote(sys.executable),
'-c', '-c',
quote('from setuptools.command.easy_install import main; main()'), quote('from setuptools.command.easy_install import main; main()'),
......
...@@ -3,7 +3,7 @@ develop = zc.recipe.egg_ z3c.recipe.scripts_ . ...@@ -3,7 +3,7 @@ develop = zc.recipe.egg_ z3c.recipe.scripts_ .
parts = test oltest py parts = test oltest py
[py] [py]
recipe = zc.recipe.egg recipe = z3c.recipe.scripts
eggs = zc.buildout eggs = zc.buildout
zope.testing zope.testing
interpreter = py interpreter = py
......
...@@ -21,6 +21,35 @@ $Id$ ...@@ -21,6 +21,35 @@ $Id$
import os, shutil, sys, subprocess, urllib2 import os, shutil, sys, subprocess, urllib2
if sys.platform == 'win32':
def quote(c):
if ' ' in c:
return '"%s"' % c # work around spawn lamosity on windows
else:
return c
else:
quote = str
# In order to be more robust in the face of system Pythons, we want to run
# with site-packages loaded. This is somewhat tricky, in particular because
# Python 2.6's distutils imports site, so starting with the -S flag is not
# sufficient.
if 'site' in sys.modules:
# We will restart with python -S.
args = sys.argv[:]
args[0:0] = [sys.executable, '-S']
args = map(quote, args)
os.execv(sys.executable, args)
clean_path = sys.path[:]
import site
sys.path[:] = clean_path
for k, v in sys.modules.items():
if (hasattr(v, '__path__') and
len(v.__path__)==1 and
not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
# This is a namespace package. Remove it.
sys.modules.pop(k)
is_jython = sys.platform.startswith('java') is_jython = sys.platform.startswith('java')
for d in 'eggs', 'develop-eggs', 'bin': for d in 'eggs', 'develop-eggs', 'bin':
...@@ -49,14 +78,20 @@ env = os.environ.copy() # Windows needs yet-to-be-determined values from this. ...@@ -49,14 +78,20 @@ env = os.environ.copy() # Windows needs yet-to-be-determined values from this.
env['PYTHONPATH'] = os.path.dirname(pkg_resources.__file__) env['PYTHONPATH'] = os.path.dirname(pkg_resources.__file__)
subprocess.Popen( subprocess.Popen(
[sys.executable] + [sys.executable] +
['setup.py', '-q', 'develop', '-m', '-x', '-d', 'develop-eggs'], ['-S', 'setup.py', '-q', 'develop', '-m', '-x', '-d', 'develop-eggs'],
env=env).wait() env=env).wait()
pkg_resources.working_set.add_entry('src') pkg_resources.working_set.add_entry('src')
import zc.buildout.easy_install import zc.buildout.easy_install
zc.buildout.easy_install.scripts( if not os.path.exists('parts'):
['zc.buildout'], pkg_resources.working_set , sys.executable, 'bin') os.mkdir('parts')
partsdir = os.path.join('parts', 'buildout')
if not os.path.exists(partsdir):
os.mkdir(partsdir)
zc.buildout.easy_install.sitepackage_safe_scripts(
'bin', pkg_resources.working_set, sys.executable, partsdir,
reqs=['zc.buildout'])
bin_buildout = os.path.join('bin', 'buildout') bin_buildout = os.path.join('bin', 'buildout')
...@@ -64,4 +99,5 @@ if is_jython: ...@@ -64,4 +99,5 @@ if is_jython:
# Jython needs the script to be called twice via sys.executable # Jython needs the script to be called twice via sys.executable
assert subprocess.Popen([sys.executable] + [bin_buildout]).wait() == 0 assert subprocess.Popen([sys.executable] + [bin_buildout]).wait() == 0
sys.exit(subprocess.Popen(bin_buildout).wait()) sys.exit(subprocess.Popen(bin_buildout).wait())
...@@ -828,16 +828,19 @@ class Buildout(UserDict.DictMixin): ...@@ -828,16 +828,19 @@ class Buildout(UserDict.DictMixin):
if not self.newest: if not self.newest:
return return
options = self['buildout']
ws = zc.buildout.easy_install.install( ws = zc.buildout.easy_install.install(
[ [
(spec + ' ' + self['buildout'].get(spec+'-version', '')).strip() (spec + ' ' + options.get(spec+'-version', '')).strip()
for spec in ('zc.buildout', 'setuptools') for spec in ('zc.buildout', 'setuptools')
], ],
self['buildout']['eggs-directory'], options['eggs-directory'],
links = self['buildout'].get('find-links', '').split(), links = options.get('find-links', '').split(),
index = self['buildout'].get('index'), index = options.get('index'),
path = [self['buildout']['develop-eggs-directory']], path = [options['develop-eggs-directory']],
allow_hosts = self._allow_hosts allow_hosts = self._allow_hosts,
include_site_packages=False
) )
upgraded = [] upgraded = []
...@@ -853,7 +856,7 @@ class Buildout(UserDict.DictMixin): ...@@ -853,7 +856,7 @@ class Buildout(UserDict.DictMixin):
__doing__ = 'Upgrading.' __doing__ = 'Upgrading.'
should_run = realpath( should_run = realpath(
os.path.join(os.path.abspath(self['buildout']['bin-directory']), os.path.join(os.path.abspath(options['bin-directory']),
'buildout') 'buildout')
) )
if sys.platform == 'win32': if sys.platform == 'win32':
...@@ -885,21 +888,26 @@ class Buildout(UserDict.DictMixin): ...@@ -885,21 +888,26 @@ class Buildout(UserDict.DictMixin):
# the new dist is different, so we've upgraded. # the new dist is different, so we've upgraded.
# Update the scripts and return True # Update the scripts and return True
zc.buildout.easy_install.scripts( partsdir = os.path.join(options['parts-directory'], 'buildout')
['zc.buildout'], ws, sys.executable, if not os.path.exists(partsdir):
self['buildout']['bin-directory'], os.mkdir(partsdir)
) zc.buildout.easy_install.sitepackage_safe_scripts(
options['bin-directory'], ws, sys.executable, partsdir,
reqs=['zc.buildout'])
# Restart # Restart
args = map(zc.buildout.easy_install._safe_arg, sys.argv) args = map(zc.buildout.easy_install._safe_arg, sys.argv)
if not __debug__: if not __debug__:
args.insert(0, '-O') args.insert(0, '-O')
args.insert(0, zc.buildout.easy_install._safe_arg (sys.executable)) args.insert(0, zc.buildout.easy_install._safe_arg(sys.executable))
env = os.environ.copy()
env['PYTHONPATH'] = partsdir
if is_jython: if is_jython:
sys.exit(subprocess.Popen([sys.executable] + list(args)).wait()) sys.exit(
subprocess.Popen(
[sys.executable] + list(args), env=env).wait())
else: else:
sys.exit(os.spawnv(os.P_WAIT, sys.executable, args)) sys.exit(os.spawnve(os.P_WAIT, sys.executable, args, env))
def _load_extensions(self): def _load_extensions(self):
__doing__ = 'Loading extensions.' __doing__ = 'Loading extensions.'
...@@ -920,7 +928,8 @@ class Buildout(UserDict.DictMixin): ...@@ -920,7 +928,8 @@ class Buildout(UserDict.DictMixin):
working_set=pkg_resources.working_set, working_set=pkg_resources.working_set,
links = self['buildout'].get('find-links', '').split(), links = self['buildout'].get('find-links', '').split(),
index = self['buildout'].get('index'), index = self['buildout'].get('index'),
newest=self.newest, allow_hosts=self._allow_hosts) newest=self.newest, allow_hosts=self._allow_hosts,
include_site_packages=False)
# Clear cache because extensions might now let us read pages we # Clear cache because extensions might now let us read pages we
# couldn't read before. # couldn't read before.
......
...@@ -1486,8 +1486,10 @@ def _get_module_file(executable, name): ...@@ -1486,8 +1486,10 @@ def _get_module_file(executable, name):
"fp, path, desc = imp.find_module(%r); " "fp, path, desc = imp.find_module(%r); "
"fp.close; " "fp.close; "
"print path" % (name,)] "print path" % (name,)]
env = os.environ.copy()
env.pop('PYTHONPATH', None)
_proc = subprocess.Popen( _proc = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
stdout, stderr = _proc.communicate(); stdout, stderr = _proc.communicate();
if _proc.returncode: if _proc.returncode:
logger.info( logger.info(
...@@ -1583,7 +1585,9 @@ def _generate_site(dest, working_set, executable, extra_paths=(), ...@@ -1583,7 +1585,9 @@ def _generate_site(dest, working_set, executable, extra_paths=(),
site.close() site.close()
real_site.close() real_site.close()
if not successful_rewrite: if not successful_rewrite:
raise RuntimeError('Buildout did not successfully rewrite site.py') raise RuntimeError(
'Buildout did not successfully rewrite %s to %s' %
(real_site_path, site_path))
return site_path return site_path
namespace_include_site_packages_setup = ''' namespace_include_site_packages_setup = '''
......
...@@ -78,22 +78,26 @@ new versions found in new releases: ...@@ -78,22 +78,26 @@ new versions found in new releases:
zc.buildout 99.99 zc.buildout 99.99
setuptools 99.99 setuptools 99.99
Our buildout script has been updated to use the new eggs: Our buildout script's site.py has been updated to use the new eggs:
>>> cat(sample_buildout, 'bin', 'buildout') >>> cat(sample_buildout, 'parts', 'buildout', 'site.py')
... # doctest: +NORMALIZE_WHITESPACE ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
#!/usr/local/bin/python2.4 "...
def addsitepackages(known_paths):
"""Add site packages, as determined by zc.buildout.
<BLANKLINE> <BLANKLINE>
import sys See original_addsitepackages, below, for the original version."""
sys.path[0:0] = [ buildout_paths = [
'/sample-buildout/eggs/zc.buildout-99.99-py2.4.egg', '/sample-buildout/eggs/zc.buildout-99.99-pyN.N.egg',
'/sample-buildout/eggs/setuptools-99.99-py2.4.egg', '/sample-buildout/eggs/setuptools-99.99-pyN.N.egg'
] ]
<BLANKLINE> for path in buildout_paths:
import zc.buildout.buildout sitedir, sitedircase = makepath(path)
<BLANKLINE> if not sitedircase in known_paths and os.path.exists(sitedir):
if __name__ == '__main__': sys.path.append(sitedir)
zc.buildout.buildout.main() known_paths.add(sitedircase)
return known_paths
...
Now, let's recreate the sample buildout. If we specify constraints on Now, let's recreate the sample buildout. If we specify constraints on
the versions of zc.buildout and setuptools to use, running the the versions of zc.buildout and setuptools to use, running the
...@@ -120,7 +124,6 @@ Now we can see that we actually "upgrade" to an earlier version. ...@@ -120,7 +124,6 @@ Now we can see that we actually "upgrade" to an earlier version.
zc.buildout version 1.0.0, zc.buildout version 1.0.0,
setuptools version 0.6; setuptools version 0.6;
restarting. restarting.
Generated script '/sample-buildout/bin/buildout'.
Develop: '/sample-buildout/showversions' Develop: '/sample-buildout/showversions'
Updating show-versions. Updating show-versions.
zc.buildout 1.0.0 zc.buildout 1.0.0
......
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