[Checkins] SVN: zc.buildout/trunk/ Refactored to do more work in
buildout and less work in easy_install.
Jim Fulton
jim at zope.com
Thu Sep 14 19:26:43 EDT 2006
Log message for revision 70184:
Refactored to do more work in buildout and less work in easy_install.
This makes things go a little faster, makes errors a little easier to
handle, and allows extensions (like the sftp extension) to influence
more of the process.
Changed:
U zc.buildout/trunk/src/zc/buildout/easy_install.py
U zc.buildout/trunk/src/zc/buildout/easy_install.txt
U zc.buildout/trunk/src/zc/buildout/testing.py
U zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/README.txt
U zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/selecting-python.txt
-=-
Modified: zc.buildout/trunk/src/zc/buildout/easy_install.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/easy_install.py 2006-09-14 23:26:39 UTC (rev 70183)
+++ zc.buildout/trunk/src/zc/buildout/easy_install.py 2006-09-14 23:26:41 UTC (rev 70184)
@@ -20,8 +20,12 @@
$Id$
"""
-import logging, os, re, tempfile, sys
-import pkg_resources, setuptools.command.setopt, setuptools.package_index
+import glob, logging, os, re, tempfile, shutil, sys, zipimport
+import distutils.errors
+import pkg_resources
+import setuptools.command.setopt
+import setuptools.package_index
+import setuptools.archive_util
import zc.buildout
default_index_url = os.environ.get('buildout-testing-index-url')
@@ -171,8 +175,7 @@
'from setuptools.command.easy_install import main; main()'
)
-def _call_easy_install(spec, dest, links=(),
- index=None,
+def _call_easy_install(spec, dest,
executable=sys.executable,
always_unzip=False,
):
@@ -180,10 +183,6 @@
path = os.pathsep.join([p for p in sys.path if not p.startswith(prefix)])
args = ('-c', _easy_install_cmd, '-mUNxd', _safe_arg(dest))
- if links:
- args += ('-f', _safe_arg(' '.join(links)))
- if index:
- args += ('-i', index)
if always_unzip:
args += ('-Z', )
level = logger.getEffectiveLevel()
@@ -220,15 +219,63 @@
if dest is not None:
logger.info("Getting new distribution for %s", requirement)
- # May need a new one. Call easy_install
- _call_easy_install(str(requirement), dest, links, index,
- executable, always_unzip)
+ # Retrieve the dist:
+ index = _get_index(executable, index, links)
+ dist = index.obtain(requirement)
+ if dist is None:
+ raise zc.buildout.UserError(
+ "Couln't find a distribution for %s."
+ % requirement)
+ if dist.location.endswith('.egg'):
+ # It's already an egg, just fetch it into the dest
+ tmp = tempfile.mkdtemp('get_dist')
+ try:
+ dist = index.fetch_distribution(requirement, tmp)
+ if dist is None:
+ raise zc.buildout.UserError(
+ "Couln't download a distribution for %s."
+ % requirement)
+
+ metadata = pkg_resources.EggMetadata(
+ zipimport.zipimporter(dist.location)
+ )
+ if (always_unzip
+ or
+ metadata.has_metadata('not-zip-safe')
+ or
+ not metadata.has_metadata('zip-safe')
+ ):
+ setuptools.archive_util.unpack_archive(
+ dist.location,
+ os.path.join(dest, os.path.basename(dist.location)
+ ),
+ )
+ else:
+ shutil.move(
+ dist.location,
+ os.path.join(dest, os.path.basename(dist.location)
+ ),
+ )
+
+ finally:
+ shutil.rmtree(tmp)
- # Because we may have added new eggs, we need to rescan
- # the destination directory. A possible optimization
- # is to get easy_install to recod the files installed
- # and either firgure out the distribution added, or
- # only rescan if any files have been added.
+ else:
+ # It's some other kind of dist. We'll download it to
+ # a temporary directory and let easy_install have it's
+ # way with it:
+ tmp = tempfile.mkdtemp('get_dist')
+ try:
+ dist = index.fetch_distribution(requirement, tmp)
+
+ # May need a new one. Call easy_install
+ _call_easy_install(dist.location, dest,
+ executable, always_unzip)
+ finally:
+ shutil.rmtree(tmp)
+
+ # Because we have added a new egg, we need to rescan
+ # the destination directory.
env.scan([dest])
dist = env.best_match(requirement, ws)
logger.info("Got %s", dist)
@@ -302,32 +349,6 @@
return ws
-
-def _editable(spec, dest, links=(), index = None, executable=sys.executable):
- prefix = sys.exec_prefix + os.path.sep
- path = os.pathsep.join([p for p in sys.path if not p.startswith(prefix)])
- args = ('-c', _easy_install_cmd, '-eb', _safe_arg(dest))
- if links:
- args += ('-f', ' '.join(links))
- if index:
- args += ('-i', index)
- level = logger.getEffectiveLevel()
- if level > logging.DEBUG:
- args += ('-q', )
- elif level < logging.DEBUG:
- args += ('-v', )
-
- args += (spec, )
-
- if level <= logging.DEBUG:
- logger.debug('Running easy_install:\n%s "%s"\npath=%s\n',
- executable, '" "'.join(args), path)
-
- args += (dict(os.environ, PYTHONPATH=path), )
- sys.stdout.flush() # We want any pending output first
- exit_code = os.spawnle(os.P_WAIT, executable, executable, *args)
- assert exit_code == 0
-
def build(spec, dest, build_ext,
links=(), index=None,
executable=sys.executable,
@@ -355,19 +376,46 @@
# Get an editable version of the package to a temporary directory:
tmp = tempfile.mkdtemp('editable')
- _editable(spec, tmp, links, index, executable)
+ tmp2 = tempfile.mkdtemp('editable')
+ try:
+ index = _get_index(executable, index, links)
+ dist = index.fetch_distribution(requirement, tmp2, False, True)
+ if dist is None:
+ raise zc.buildout.UserError(
+ "Couln't find a source distribution for %s."
+ % requirement)
+ setuptools.archive_util.unpack_archive(dist.location, tmp)
- setup_cfg = os.path.join(tmp, requirement.key, 'setup.cfg')
- if not os.path.exists(setup_cfg):
- f = open(setup_cfg, 'w')
- f.close()
- setuptools.command.setopt.edit_config(setup_cfg, dict(build_ext=build_ext))
+ if os.path.exists(os.path.join(tmp, 'setup.py')):
+ base = tmp
+ else:
+ setups = glob.glob(os.path.join(tmp, '*', 'setup.py'))
+ if not setups:
+ raise distutils.errors.DistutilsError(
+ "Couldn't find a setup script in %s"
+ % os.path.basename(dist.location)
+ )
+ if len(setups) > 1:
+ raise distutils.errors.DistutilsError(
+ "Multiple setup scripts in %s"
+ % os.path.basename(dist.location)
+ )
+ base = os.path.dirname(setups[0])
- # Now run easy_install for real:
- _call_easy_install(
- os.path.join(tmp, requirement.key),
- dest, links, index, executable, True)
+ setup_cfg = os.path.join(base, 'setup.cfg')
+ if not os.path.exists(setup_cfg):
+ f = open(setup_cfg, 'w')
+ f.close()
+ setuptools.command.setopt.edit_config(
+ setup_cfg, dict(build_ext=build_ext))
+
+ # Now run easy_install for real:
+ _call_easy_install(base, dest, executable, True)
+ finally:
+ shutil.rmtree(tmp)
+ shutil.rmtree(tmp2)
+
def working_set(specs, executable, path):
return install(specs, None, executable=executable, path=path)
Modified: zc.buildout/trunk/src/zc/buildout/easy_install.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/easy_install.txt 2006-09-14 23:26:39 UTC (rev 70183)
+++ zc.buildout/trunk/src/zc/buildout/easy_install.txt 2006-09-14 23:26:41 UTC (rev 70184)
@@ -75,10 +75,8 @@
<a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br>
<a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br>
<a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.egg</a><br>
- <a href="demoneeded-1.0-py2.3.egg">demoneeded-1.0-py2.3.egg</a><br>
- <a href="demoneeded-1.0-py2.4.egg">demoneeded-1.0-py2.4.egg</a><br>
- <a href="demoneeded-1.1-py2.3.egg">demoneeded-1.1-py2.3.egg</a><br>
- <a href="demoneeded-1.1-py2.4.egg">demoneeded-1.1-py2.4.egg</a><br>
+ <a href="demoneeded-1.0.tar.gz">demoneeded-1.0.tar.gz</a><br>
+ <a href="demoneeded-1.1.tar.gz">demoneeded-1.1.tar.gz</a><br>
<a href="extdemo-1.4.tar.gz">extdemo-1.4.tar.gz</a><br>
<a href="index/">index/</a><br>
<a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br>
Modified: zc.buildout/trunk/src/zc/buildout/testing.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/testing.py 2006-09-14 23:26:39 UTC (rev 70183)
+++ zc.buildout/trunk/src/zc/buildout/testing.py 2006-09-14 23:26:41 UTC (rev 70184)
@@ -125,16 +125,17 @@
sys.exit(load_entry_point('zc.buildout', 'console_scripts', 'buildout')())
'''
-def runsetup(d, executable):
+def runsetup(d, executable, type='bdist_egg'):
here = os.getcwd()
try:
os.chdir(d)
os.spawnle(
os.P_WAIT, executable, executable,
- 'setup.py', '-q', 'bdist_egg',
+ 'setup.py', '-q', type,
{'PYTHONPATH': os.path.dirname(pkg_resources.__file__)},
)
- shutil.rmtree('build')
+ if os.path.exists('build'):
+ shutil.rmtree('build')
finally:
os.chdir(here)
@@ -152,10 +153,11 @@
sample, 'setup.py',
"from setuptools import setup\n"
"setup(name='demoneeded', py_modules=['eggrecipedemobeeded'],"
- " zip_safe=True, version='1.%s')\n"
+ " zip_safe=True, version='1.%s', author='bob', url='bob', "
+ "author_email='bob')\n"
% i
)
- runsetup(sample, executable)
+ runsetup(sample, executable, 'sdist')
write(
sample, 'setup.py',
Modified: zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/README.txt
===================================================================
--- zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/README.txt 2006-09-14 23:26:39 UTC (rev 70183)
+++ zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/README.txt 2006-09-14 23:26:41 UTC (rev 70184)
@@ -58,8 +58,8 @@
<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="demoneeded-1.0-py2.3.egg">demoneeded-1.0-py2.3.egg</a><br>
- <a href="demoneeded-1.1-py2.3.egg">demoneeded-1.1-py2.3.egg</a><br>
+ <a href="demoneeded-1.0.tar.gz">demoneeded-1.0.tar.gz</a><br>
+ <a href="demoneeded-1.1.tar.gz">demoneeded-1.1.tar.gz</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>
Modified: zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/selecting-python.txt
===================================================================
--- zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/selecting-python.txt 2006-09-14 23:26:39 UTC (rev 70183)
+++ zc.buildout/trunk/zc.recipe.egg_/src/zc/recipe/egg/selecting-python.txt 2006-09-14 23:26:41 UTC (rev 70184)
@@ -19,10 +19,8 @@
<a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br>
<a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br>
<a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.egg</a><br>
- <a href="demoneeded-1.0-py2.3.egg">demoneeded-1.0-py2.3.egg</a><br>
- <a href="demoneeded-1.0-py2.4.egg">demoneeded-1.0-py2.4.egg</a><br>
- <a href="demoneeded-1.1-py2.3.egg">demoneeded-1.1-py2.3.egg</a><br>
- <a href="demoneeded-1.1-py2.4.egg">demoneeded-1.1-py2.4.egg</a><br>
+ <a href="demoneeded-1.0.tar.gz">demoneeded-1.0.tar.gz</a><br>
+ <a href="demoneeded-1.1.tar.gz">demoneeded-1.1.tar.gz</a><br>
<a href="index/">index/</a><br>
<a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br>
<a href="other-1.0-py2.4.egg">other-1.0-py2.4.egg</a><br>
More information about the Checkins
mailing list