[Checkins] SVN: zc.buildout/trunk/src/zc/buildout/ Added newest
keyword parameter to the install and build functions to
Jim Fulton
jim at zope.com
Mon Feb 5 18:03:46 EST 2007
Log message for revision 72383:
Added newest keyword parameter to the install and build functions to
allow for getting less than the newest but still getting what's
necessary.
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/tests.py
-=-
Modified: zc.buildout/trunk/src/zc/buildout/easy_install.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/easy_install.py 2007-02-05 22:03:49 UTC (rev 72382)
+++ zc.buildout/trunk/src/zc/buildout/easy_install.py 2007-02-05 23:03:44 UTC (rev 72383)
@@ -1,4 +1,4 @@
-##############################################################################
+#############################################################################
#
# Copyright (c) 2005 Zope Corporation and Contributors.
# All Rights Reserved.
@@ -85,381 +85,399 @@
_indexes[key] = index
return index
-def _satisfied(req, env, dest, executable, index, links):
- dists = [dist for dist in env[req.project_name] if dist in req]
- if not dists:
- logger.debug('We have no distributions for %s', req.project_name)
- return None
+clear_index_cache = _indexes.clear
- # Note that dists are sorted from best to worst, as promised by
- # env.__getitem__
+if sys.platform == 'win32':
+ # work around spawn lamosity on windows
+ # XXX need safe quoting (see the subproces.list2cmdline) and test
+ def _safe_arg(arg):
+ return '"%s"' % arg
+else:
+ _safe_arg = str
- for dist in dists:
- if (dist.precedence == pkg_resources.DEVELOP_DIST):
- logger.debug('We have a develop egg for %s', req)
- return dist
+_easy_install_cmd = _safe_arg(
+ 'from setuptools.command.easy_install import main; main()'
+ )
- # Find an upprt limit in the specs, if there is one:
- specs = [(pkg_resources.parse_version(v), op) for (op, v) in req.specs]
- specs.sort()
- maxv = None
- greater = False
- lastv = None
- for v, op in specs:
- if op == '==' and not greater:
- maxv = v
- elif op in ('>', '>=', '!='):
- maxv = None
- greater == True
- elif op == '<':
- maxv = None
- greater == False
- elif op == '<=':
- maxv = v
- greater == False
+class Installer:
- if v == lastv:
- # Repeated versions values are undefined, so
- # all bets are off
- maxv = None
- greater = True
- else:
- lastv = v
+ def __init__(self,
+ dest=None,
+ links=(),
+ index=None,
+ executable=sys.executable,
+ always_unzip=False,
+ path=None,
+ newest=True,
+ ):
+ self._dest = dest
+ self._links = list(links)
+ self._index_url = index
+ self._executable = executable
+ self._always_unzip = always_unzip
+ path = (path and path[:] or []) + buildout_and_setuptools_path
+ if dest is not None and dest not in path:
+ path.insert(0, dest)
+ self._path = path
+ self._newest = newest
+ self._env = pkg_resources.Environment(path,
+ python=_get_version(executable))
+ self._index = _get_index(executable, index, links)
- best_we_have = dists[0] # Because dists are sorted from best to worst
+ def _satisfied(self, req):
+ dists = [dist for dist in self._env[req.project_name] if dist in req]
+ if not dists:
+ logger.debug('We have no distributions for %s', req.project_name)
+ return None
- # Check if we have the upper limit
- if maxv is not None and best_we_have.version == maxv:
- logger.debug('We have the best distribution that satisfies\n%s',
- req)
- return best_we_have
+ # Note that dists are sorted from best to worst, as promised by
+ # env.__getitem__
- # We have some installed distros. There might, theoretically, be
- # newer ones. Let's find out which ones are available and see if
- # any are newer. We only do this if we're willing to install
- # something, which is only true if dest is not None:
+ for dist in dists:
+ if (dist.precedence == pkg_resources.DEVELOP_DIST):
+ logger.debug('We have a develop egg for %s', req)
+ return dist
- if dest is not None:
- best_available = _get_index(executable, index, links).obtain(req)
- else:
- best_available = None
+ if not self._newest:
+ # We don't need the newest, so we'll use the newest one we
+ # find, which is the first returned by
+ # Environment.__getitem__.
+ return dists[0]
- if best_available is None:
- # That's a bit odd. There aren't any distros available.
- # We should use the best one we have that meets the requirement.
- logger.debug(
- 'There are no distros available that meet %s. Using our best.', req)
- return best_we_have
- else:
- # Let's find out if we already have the best available:
- if best_we_have.parsed_version >= best_available.parsed_version:
- # Yup. Use it.
- logger.debug('We have the best distribution that satisfies\n%s', req)
+ # Find an upprt limit in the specs, if there is one:
+ specs = [(pkg_resources.parse_version(v), op) for (op, v) in req.specs]
+ specs.sort()
+ maxv = None
+ greater = False
+ lastv = None
+ for v, op in specs:
+ if op == '==' and not greater:
+ maxv = v
+ elif op in ('>', '>=', '!='):
+ maxv = None
+ greater == True
+ elif op == '<':
+ maxv = None
+ greater == False
+ elif op == '<=':
+ maxv = v
+ greater == False
+
+ if v == lastv:
+ # Repeated versions values are undefined, so
+ # all bets are off
+ maxv = None
+ greater = True
+ else:
+ lastv = v
+
+ best_we_have = dists[0] # Because dists are sorted from best to worst
+
+ # Check if we have the upper limit
+ if maxv is not None and best_we_have.version == maxv:
+ logger.debug('We have the best distribution that satisfies\n%s',
+ req)
return best_we_have
- return None
+ # We have some installed distros. There might, theoretically, be
+ # newer ones. Let's find out which ones are available and see if
+ # any are newer. We only do this if we're willing to install
+ # something, which is only true if dest is not None:
+
+ if self._dest is not None:
+ best_available = self._index.obtain(req)
+ else:
+ best_available = None
-if sys.platform == 'win32':
- # work around spawn lamosity on windows
- # XXX need safe quoting (see the subproces.list2cmdline) and test
- def _safe_arg(arg):
- return '"%s"' % arg
-else:
- _safe_arg = str
+ if best_available is None:
+ # That's a bit odd. There aren't any distros available.
+ # We should use the best one we have that meets the requirement.
+ logger.debug(
+ 'There are no distros available that meet %s. Using our best.',
+ req)
+ return best_we_have
+ else:
+ # Let's find out if we already have the best available:
+ if best_we_have.parsed_version >= best_available.parsed_version:
+ # Yup. Use it.
+ logger.debug(
+ 'We have the best distribution that satisfies\n%s',
+ req)
+ return best_we_have
-_easy_install_cmd = _safe_arg(
- 'from setuptools.command.easy_install import main; main()'
- )
+ return None
-def _call_easy_install(spec, env, ws, dest, links, index,
- executable, always_unzip):
+ def _call_easy_install(self, spec, ws, dest):
- path = _get_dist(pkg_resources.Requirement.parse('setuptools'),
- env, ws, dest, links, index, executable, False).location
-
- args = ('-c', _easy_install_cmd, '-mUNxd', _safe_arg(dest))
- if always_unzip:
- args += ('-Z', )
- level = logger.getEffectiveLevel()
- if level > logging.DEBUG:
- args += ('-q', )
- elif level < logging.DEBUG:
- args += ('-v', )
-
- args += (spec, )
+ path = self._get_dist(pkg_resources.Requirement.parse('setuptools'),
+ ws, False).location
- if level <= logging.DEBUG:
- logger.debug('Running easy_install:\n%s "%s"\npath=%s\n',
- executable, '" "'.join(args), path)
+ args = ('-c', _easy_install_cmd, '-mUNxd', _safe_arg(dest))
+ if self._always_unzip:
+ args += ('-Z', )
+ level = logger.getEffectiveLevel()
+ if level > logging.DEBUG:
+ args += ('-q', )
+ elif level < logging.DEBUG:
+ args += ('-v', )
- 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
+ args += (spec, )
+ if level <= logging.DEBUG:
+ logger.debug('Running easy_install:\n%s "%s"\npath=%s\n',
+ executable, '" "'.join(args), path)
-def _get_dist(requirement, env, ws,
- dest, links, index_url, executable, always_unzip):
-
- # Maybe an existing dist is already the best dist that satisfies the
- # requirement
- dist = _satisfied(requirement, env, dest, executable, index_url, links)
+ args += (dict(os.environ, PYTHONPATH=path), )
+ sys.stdout.flush() # We want any pending output first
+ exit_code = os.spawnle(os.P_WAIT, self._executable, self._executable,
+ *args)
+ assert exit_code == 0
- if dist is None:
- if dest is not None:
- logger.info("Getting new distribution for %s", requirement)
- # Retrieve the dist:
- index = _get_index(executable, index_url, links)
- dist = index.obtain(requirement)
- if dist is None:
- raise zc.buildout.UserError(
- "Couldn't find a distribution for %s."
- % requirement)
+ def _get_dist(self, requirement, ws, always_unzip):
- fname = dist.location
- if url_match(fname):
- fname = urlparse.urlparse(fname)[2]
-
- if fname.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)
+ # Maybe an existing dist is already the best dist that satisfies the
+ # requirement
+ dist = self._satisfied(requirement)
- newloc = os.path.join(
- dest, os.path.basename(dist.location))
+ if dist is None:
+ if self._dest is not None:
+ logger.info("Getting new distribution for %s", requirement)
- if os.path.isdir(dist.location):
- # we got a directory. It must have been
- # obtained locally. Jut copy it.
- shutil.copytree(dist.location, newloc)
- else:
+ # Retrieve the dist:
+ index = self._index
+ dist = index.obtain(requirement)
+ if dist is None:
+ raise zc.buildout.UserError(
+ "Couldn't find a distribution for %s."
+ % requirement)
- if always_unzip:
- should_unzip = True
- else:
- metadata = pkg_resources.EggMetadata(
- zipimport.zipimporter(dist.location)
- )
- should_unzip = (
- metadata.has_metadata('not-zip-safe')
- or not metadata.has_metadata('zip-safe')
- )
+ fname = dist.location
+ if url_match(fname):
+ fname = urlparse.urlparse(fname)[2]
- if should_unzip:
- setuptools.archive_util.unpack_archive(
- dist.location, newloc)
+ if fname.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)
+
+ newloc = os.path.join(
+ self._dest, os.path.basename(dist.location))
+
+ if os.path.isdir(dist.location):
+ # we got a directory. It must have been
+ # obtained locally. Jut copy it.
+ shutil.copytree(dist.location, newloc)
else:
- shutil.copyfile(dist.location, newloc)
-
- finally:
- shutil.rmtree(tmp)
- 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)
+ if self._always_unzip:
+ should_unzip = True
+ else:
+ metadata = pkg_resources.EggMetadata(
+ zipimport.zipimporter(dist.location)
+ )
+ should_unzip = (
+ metadata.has_metadata('not-zip-safe')
+ or not metadata.has_metadata('zip-safe')
+ )
- # May need a new one. Call easy_install
- _call_easy_install(
- dist.location, env, ws, dest, links, index_url,
- executable, always_unzip)
- finally:
- shutil.rmtree(tmp)
+ if should_unzip:
+ setuptools.archive_util.unpack_archive(
+ dist.location, newloc)
+ else:
+ shutil.copyfile(dist.location, newloc)
+ finally:
+ shutil.rmtree(tmp)
- # Because we have added a new egg, we need to rescan
- # the destination directory.
+ 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)
- # We may overwrite distributions, so clear importer
- # cache.
- sys.path_importer_cache.clear()
+ # May need a new one. Call easy_install
+ self._call_easy_install(dist.location, ws, self._dest)
+ finally:
+ shutil.rmtree(tmp)
- env.scan([dest])
- dist = env.best_match(requirement, ws)
- logger.info("Got %s", dist)
- else:
- dist = env.best_match(requirement, ws)
- if dist is None:
- raise ValueError("Couldn't find", requirement)
+ # Because we have added a new egg, we need to rescan
+ # the destination directory.
- # XXX Need test for this
- if dist.has_metadata('dependency_links.txt'):
- for link in dist.get_metadata_lines('dependency_links.txt'):
- link = link.strip()
- if link not in links:
- links.append(link)
-
- return dist
+ # We may overwrite distributions, so clear importer
+ # cache.
+ sys.path_importer_cache.clear()
-def _maybe_add_setuptools(ws, dist, env, dest, links, index, executable):
- if dist.has_metadata('namespace_packages.txt'):
- for r in dist.requires():
- if r.project_name == 'setuptools':
- break
- else:
- # We have a namespace package but no requirement for setuptools
- if dist.precedence == pkg_resources.DEVELOP_DIST:
- logger.warn(
- "Develop distribution for %s\n"
- "uses namespace packages but the distribution "
- "does not require setuptools.",
- dist)
- requirement = pkg_resources.Requirement.parse('setuptools')
- if ws.find(requirement) is None:
- dist = _get_dist(requirement, env, ws,
- dest, links, index, executable,
- False)
- ws.add(dist)
-
-
-def install(specs, dest,
- links=(), index=None,
- executable=sys.executable, always_unzip=False,
- path=None, working_set=None):
+ self._env.scan([self._dest])
+ dist = self._env.best_match(requirement, ws)
+ logger.info("Got %s", dist)
+ else:
+ dist = self._env.best_match(requirement, ws)
- logger.debug('Installing %r', specs)
+ if dist is None:
+ raise ValueError("Couldn't find", requirement)
- path = path and path[:] or []
- if dest is not None and dest not in path:
- path.insert(0, dest)
+ # XXX Need test for this
+ if dist.has_metadata('dependency_links.txt'):
+ for link in dist.get_metadata_lines('dependency_links.txt'):
+ link = link.strip()
+ if link not in self._links:
+ self._links.append(link)
+ self._index = _get_index(self._executable,
+ self._index_url, self._links)
- path += buildout_and_setuptools_path
+ return dist
- links = list(links) # make copy, because we may need to mutate
-
+ def _maybe_add_setuptools(self, ws, dist):
+ if dist.has_metadata('namespace_packages.txt'):
+ for r in dist.requires():
+ if r.project_name == 'setuptools':
+ break
+ else:
+ # We have a namespace package but no requirement for setuptools
+ if dist.precedence == pkg_resources.DEVELOP_DIST:
+ logger.warn(
+ "Develop distribution for %s\n"
+ "uses namespace packages but the distribution "
+ "does not require setuptools.",
+ dist)
+ requirement = pkg_resources.Requirement.parse('setuptools')
+ if ws.find(requirement) is None:
+ dist = self._get_dist(requirement, ws, False)
+ ws.add(dist)
- # For each spec, see if it is already installed. We create a working
- # set to keep track of what we've collected and to make sue than the
- # distributions assembled are consistent.
- env = pkg_resources.Environment(path, python=_get_version(executable))
- requirements = [pkg_resources.Requirement.parse(spec) for spec in specs]
- if working_set is None:
- ws = pkg_resources.WorkingSet([])
- else:
- ws = working_set
+ def install(self, specs, working_set=None):
- for requirement in requirements:
- dist = _get_dist(requirement, env, ws,
- dest, links, index, executable, always_unzip)
- ws.add(dist)
- _maybe_add_setuptools(ws, dist,
- env, dest, links, index, executable)
+ logger.debug('Installing %r', specs)
- # OK, we have the requested distributions and they're in the working
- # set, but they may have unmet requirements. We'll simply keep
- # trying to resolve requirements, adding missing requirements as they
- # are reported.
- #
- # Note that we don't pass in the environment, because we
- # want to look for new eggs unless what we have is the best that matches
- # the requirement.
- while 1:
- try:
- ws.resolve(requirements)
- except pkg_resources.DistributionNotFound, err:
- [requirement] = err
- if dest:
- logger.debug('Getting required %s', requirement)
- dist = _get_dist(requirement, env, ws,
- dest, links, index, executable, always_unzip)
- ws.add(dist)
- _maybe_add_setuptools(ws, dist,
- env, dest, links, index, executable)
+ path = self._path
+ dest = self._dest
+ if dest is not None and dest not in path:
+ path.insert(0, dest)
+
+ requirements = [pkg_resources.Requirement.parse(spec)
+ for spec in specs]
+
+ if working_set is None:
+ ws = pkg_resources.WorkingSet([])
else:
- break
-
- return ws
+ ws = working_set
-def build(spec, dest, build_ext,
- links=(), index=None,
- executable=sys.executable,
- path=None):
+ for requirement in requirements:
+ dist = self._get_dist(requirement, ws, self._always_unzip)
+ ws.add(dist)
+ self._maybe_add_setuptools(ws, dist)
- index_url = index
+ # OK, we have the requested distributions and they're in the working
+ # set, but they may have unmet requirements. We'll simply keep
+ # trying to resolve requirements, adding missing requirements as they
+ # are reported.
+ #
+ # Note that we don't pass in the environment, because we
+ # want to look for new eggs unless what we have is the best that matches
+ # the requirement.
+ while 1:
+ try:
+ ws.resolve(requirements)
+ except pkg_resources.DistributionNotFound, err:
+ [requirement] = err
+ if dest:
+ logger.debug('Getting required %s', requirement)
+ dist = self._get_dist(requirement, ws, self._always_unzip)
+ ws.add(dist)
+ self._maybe_add_setuptools(ws, dist)
+ else:
+ break
- logger.debug('Building %r', spec)
+ return ws
- path = path and path[:] or []
- if dest is not None:
- path.insert(0, dest)
+ def build(self, spec, build_ext):
+ logger.debug('Building %r', spec)
- path += buildout_and_setuptools_path
+ requirement = pkg_resources.Requirement.parse(spec)
- links = list(links) # make copy, because we may need to mutate
-
- # For each spec, see if it is already installed. We create a working
- # set to keep track of what we've collected and to make sue than the
- # distributions assembled are consistent.
- env = pkg_resources.Environment(path, python=_get_version(executable))
- requirement = pkg_resources.Requirement.parse(spec)
+ dist = self._satisfied(requirement)
+ if dist is not None:
+ return dist.location
- dist = _satisfied(requirement, env, dest, executable, index_url, links)
- if dist is not None:
- return [dist.location]
+ undo = []
+ try:
+ tmp = tempfile.mkdtemp('build')
+ undo.append(lambda : shutil.rmtree(tmp))
+ tmp2 = tempfile.mkdtemp('build')
+ undo.append(lambda : shutil.rmtree(tmp2))
- undo = []
- try:
- tmp = tempfile.mkdtemp('build')
- undo.append(lambda : shutil.rmtree(tmp))
- tmp2 = tempfile.mkdtemp('build')
- undo.append(lambda : shutil.rmtree(tmp2))
+ dist = self._index.fetch_distribution(
+ requirement, tmp2, False, True)
+ if dist is None:
+ raise zc.buildout.UserError(
+ "Couldn't find a source distribution for %s."
+ % requirement)
+ setuptools.archive_util.unpack_archive(dist.location, tmp)
- index = _get_index(executable, index_url, links)
- dist = index.fetch_distribution(requirement, tmp2, False, True)
- if dist is None:
- raise zc.buildout.UserError(
- "Couldn't find a source distribution for %s."
- % requirement)
- setuptools.archive_util.unpack_archive(dist.location, tmp)
+ 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])
- 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])
+ 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))
- 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))
+ tmp3 = tempfile.mkdtemp('build', dir=self._dest)
+ undo.append(lambda : shutil.rmtree(tmp3))
- tmp3 = tempfile.mkdtemp('build', dir=dest)
- undo.append(lambda : shutil.rmtree(tmp3))
+ self._call_easy_install(base, pkg_resources.WorkingSet(), tmp3)
- _call_easy_install(base, env, pkg_resources.WorkingSet(),
- tmp3, links, index_url, executable, True)
+ return _copyeggs(tmp3, self._dest, '.egg', undo)
- return _copyeggs(tmp3, dest, '.egg', undo)
+ finally:
+ undo.reverse()
+ [f() for f in undo]
+
+
+def install(specs, dest,
+ links=(), index=None,
+ executable=sys.executable, always_unzip=False,
+ path=None, working_set=None, newest=True):
+ installer = Installer(dest, links, index, executable, always_unzip, path,
+ newest)
+ return installer.install(specs, working_set)
+
+
+def build(spec, dest, build_ext,
+ links=(), index=None,
+ executable=sys.executable,
+ path=None, newest=True):
+ installer = Installer(dest, links, index, executable, True, path, newest)
+ return installer.build(spec, build_ext)
+
- finally:
- undo.reverse()
- [f() for f in undo]
-
def _rm(*paths):
for path in paths:
@@ -477,8 +495,8 @@
_rm(new)
os.rename(os.path.join(src, name), new)
result.append(new)
-
- assert len(result) == 1
+
+ assert len(result) == 1, str(result)
undo.pop()
return result[0]
Modified: zc.buildout/trunk/src/zc/buildout/easy_install.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/easy_install.txt 2007-02-05 22:03:49 UTC (rev 72382)
+++ zc.buildout/trunk/src/zc/buildout/easy_install.txt 2007-02-05 23:03:44 UTC (rev 72383)
@@ -21,7 +21,10 @@
- Distutils options for building extensions can be passed.
-The easy_install module provides a method, install, for installing one
+Distribution installation
+-------------------------
+
+The easy_install module provides a function, install, for installing one
or more packages and their dependencies. The install function takes 2
positional arguments:
@@ -68,6 +71,13 @@
you to call install multiple times, if necessary, to gather
multiple sets of requirements.
+newest
+ A boolian value indicating whether to search for new distributions
+ when already-installed distributions meet the requirement. When
+ this is true, the default, and when the destination directory is
+ not None, then the install function will search for the newest
+ distributions that satisfy the requirements.
+
The install method returns a working set containing the distributions
needed to meet the given requirements.
@@ -111,10 +121,19 @@
- demo-0.2-py2.4.egg
- demoneeded-1.1-py2.4.egg
-If we ask for the demo distribution without a version restriction,
-we'll get the newer version:
+If we remove the version restriction on demo, but specify a false
+value for newest, no new didstributions will be installed:
>>> ws = zc.buildout.easy_install.install(
+ ... ['demo'], dest, links=[link_server], index=link_server+'index/',
+ ... newest=False)
+ >>> ls(dest)
+ - demo-0.2-py2.4.egg
+ - demoneeded-1.1-py2.4.egg
+
+If we leave off the newst option, we'll get an update for demo:
+
+ >>> ws = zc.buildout.easy_install.install(
... ['demo'], dest, links=[link_server], index=link_server+'index/')
>>> ls(dest)
- demo-0.2-py2.4.egg
@@ -480,10 +499,14 @@
A list of additional directories to search for locally-installed
distributions.
-always_unzip
- A flag indicating that newly-downloaded distributions should be
- directories even if they could be installed as zip files.
+newest
+ A boolian value indicating whether to search for new distributions
+ when already-installed distributions meet the requirement. When
+ this is true, the default, and when the destination directory is
+ not None, then the install function will search for the newest
+ distributions that satisfy the requirements.
+
Our link server included a source distribution that includes a simple
extension, extdemo.c::
@@ -534,6 +557,57 @@
d demoneeded-1.1-py2.4.egg
d extdemo-1.4-py2.4-unix-i686.egg
+Let's update our link server with a new version of extdemo:
+
+ >>> update_extdemo()
+ >>> print get(link_server),
+ <html><body>
+ <a href="demo-0.1-py2.4.egg">demo-0.1-py2.4.egg</a><br>
+ <a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br>
+ <a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.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="extdemo-1.4.zip">extdemo-1.4.zip</a><br>
+ <a href="extdemo-1.5.zip">extdemo-1.5.zip</a><br>
+ <a href="index/">index/</a><br>
+ <a href="other-1.0-py2.4.egg">other-1.0-py2.4.egg</a><br>
+ </body></html>
+
+The easy_install caches information about servers to reduce network
+access. To see the update, we have to call the clear_index_cache
+function to clear the index cache:
+
+ >>> zc.buildout.easy_install.clear_index_cache()
+
+If we run build with newest set to False, we won't get an update:
+
+ >>> zc.buildout.easy_install.build(
+ ... 'extdemo', dest,
+ ... {'include-dirs': os.path.join(sample_buildout, 'include')},
+ ... links=[link_server], index=link_server+'index/',
+ ... newest=False)
+ '/sample-install/extdemo-1.4-py2.4-linux-i686.egg'
+
+ >>> ls(dest)
+ d demo-0.3-py2.4.egg
+ d demoneeded-1.1-py2.4.egg
+ d extdemo-1.4-py2.4-unix-i686.egg
+
+But if we run it with the default True setting for newest, then we'll
+get an updated egg:
+
+ >>> zc.buildout.easy_install.build(
+ ... 'extdemo', dest,
+ ... {'include-dirs': os.path.join(sample_buildout, 'include')},
+ ... links=[link_server], index=link_server+'index/')
+ '/sample-install/extdemo-1.5-py2.4-unix-i686.egg'
+
+ d demo-0.3-py2.4.egg
+ d demoneeded-1.1-py2.4.egg
+ d extdemo-1.4-py2.4-unix-i686.egg
+ d extdemo-1.5-py2.4-unix-i686.egg
+
+
Handling custom build options for extensions in develop eggs
------------------------------------------------------------
@@ -586,6 +660,7 @@
d demo-0.3-py2.4.egg
d demoneeded-1.1-py2.4.egg
d extdemo-1.4-py2.4-linux-i686.egg
+ d extdemo-1.5-py2.4-linux-i686.egg
- extdemo.egg-link
And that the source directory contains the compiled extension:
Modified: zc.buildout/trunk/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/tests.py 2007-02-05 22:03:49 UTC (rev 72382)
+++ zc.buildout/trunk/src/zc/buildout/tests.py 2007-02-05 23:03:44 UTC (rev 72383)
@@ -1047,19 +1047,22 @@
extdemo_setup_py = """
from distutils.core import setup, Extension
-setup(name = "extdemo", version = "1.4", url="http://www.zope.org",
+setup(name = "extdemo", version = "%s", url="http://www.zope.org",
author="Demo", author_email="demo at demo.com",
ext_modules = [Extension('extdemo', ['extdemo.c'])],
)
"""
-def add_source_dist(test):
-
- tmp = test.globs['extdemo'] = test.globs['tmpdir']('extdemo')
+def add_source_dist(test, version=1.4):
+
+ if 'extdemo' not in test.globs:
+ test.globs['extdemo'] = test.globs['tmpdir']('extdemo')
+
+ tmp = test.globs['extdemo']
write = test.globs['write']
try:
write(tmp, 'extdemo.c', extdemo_c);
- write(tmp, 'setup.py', extdemo_setup_py);
+ write(tmp, 'setup.py', extdemo_setup_py % version);
write(tmp, 'README', "");
write(tmp, 'MANIFEST.in', "include *.c\n");
test.globs['sdist'](tmp, test.globs['sample_eggs'])
@@ -1075,7 +1078,9 @@
add_source_dist(test)
test.globs['link_server'] = test.globs['start_server'](
test.globs['sample_eggs'])
+ test.globs['update_extdemo'] = lambda : add_source_dist(test, 1.5)
+
egg_parse = re.compile('([0-9a-zA-Z_.]+)-([0-9a-zA-Z_.]+)-py(\d[.]\d).egg$'
).match
def makeNewRelease(project, ws, dest):
More information about the Checkins
mailing list