[Checkins] SVN: zc.buildout/branches/amos-dependency-links/ Added use-dependency-links option to buildout. This option lets you

Amos Latteier amos at latteier.com
Thu Oct 18 13:14:35 EDT 2007


Log message for revision 80924:
  Added use-dependency-links option to buildout. This option lets you 
  ignore dependency_links setup metadata if you wish. The default behavior 
  of buildout is not changed.
  

Changed:
  U   zc.buildout/branches/amos-dependency-links/CHANGES.txt
  U   zc.buildout/branches/amos-dependency-links/src/zc/buildout/buildout.py
  U   zc.buildout/branches/amos-dependency-links/src/zc/buildout/buildout.txt
  U   zc.buildout/branches/amos-dependency-links/src/zc/buildout/easy_install.py
  U   zc.buildout/branches/amos-dependency-links/src/zc/buildout/easy_install.txt
  U   zc.buildout/branches/amos-dependency-links/src/zc/buildout/testing.txt
  U   zc.buildout/branches/amos-dependency-links/src/zc/buildout/tests.py

-=-
Modified: zc.buildout/branches/amos-dependency-links/CHANGES.txt
===================================================================
--- zc.buildout/branches/amos-dependency-links/CHANGES.txt	2007-10-18 15:52:08 UTC (rev 80923)
+++ zc.buildout/branches/amos-dependency-links/CHANGES.txt	2007-10-18 17:14:35 UTC (rev 80924)
@@ -11,6 +11,26 @@
 Change History
 **************
 
+Unreleased Version
+==================
+
+Feature Changes
+---------------
+
+- Added a configuration option that allows buildouts to ignore
+  dependency_links metadata specified in setup. By default
+  dependency_links in setup are used in preference to buildout
+  specified find-links. This can make it hard to control where eggs
+  come from. Here's how to tell buildout to ignore URLs in
+  dependency_links::
+
+    [buildout]
+    use-dependency-links = false
+
+  By default use-dependency-links is true, which matches the behavior
+  of previous versions of buildout.
+
+
 1.0.0b30 (2007-08-20)
 =====================
 

Modified: zc.buildout/branches/amos-dependency-links/src/zc/buildout/buildout.py
===================================================================
--- zc.buildout/branches/amos-dependency-links/src/zc/buildout/buildout.py	2007-10-18 15:52:08 UTC (rev 80923)
+++ zc.buildout/branches/amos-dependency-links/src/zc/buildout/buildout.py	2007-10-18 17:14:35 UTC (rev 80924)
@@ -158,6 +158,12 @@
                         prefer_final)
         zc.buildout.easy_install.prefer_final(prefer_final=='true')
         
+        use_dependency_links = options.get('use-dependency-links', 'true')
+        if use_dependency_links not in ('true', 'false'):
+            self._error('Invalid value for use-dependency-links option: %s',
+                        use_dependency_links)
+        zc.buildout.easy_install.use_dependency_links(
+            use_dependency_links == 'true')
 
         download_cache = options.get('download-cache')
         if download_cache:
@@ -637,7 +643,7 @@
             self['buildout']['eggs-directory'],
             links = self['buildout'].get('find-links', '').split(),
             index = self['buildout'].get('index'),
-            path = [self['buildout']['develop-eggs-directory']],
+            path = [self['buildout']['develop-eggs-directory']]
             )
 
         upgraded = []

Modified: zc.buildout/branches/amos-dependency-links/src/zc/buildout/buildout.txt
===================================================================
--- zc.buildout/branches/amos-dependency-links/src/zc/buildout/buildout.txt	2007-10-18 15:52:08 UTC (rev 80923)
+++ zc.buildout/branches/amos-dependency-links/src/zc/buildout/buildout.txt	2007-10-18 17:14:35 UTC (rev 80924)
@@ -2083,6 +2083,21 @@
 You will then need to use a false value for prefer-final to get the
 newset releases.
 
+Dependency links
+----------------
+
+By default buildout will obey the setuptools dependency_links metadata
+when it looks for dependencies. This behavior can be controlled with
+the use-dependency-links buildout option.
+
+  [buildout]
+  ...
+  use-dependency-links = false
+
+The option defaults to true. If you set it to false, then dependency
+links are only looked for in the locations specified by find-links.
+
+
 Controlling the installation database
 -------------------------------------
 

Modified: zc.buildout/branches/amos-dependency-links/src/zc/buildout/easy_install.py
===================================================================
--- zc.buildout/branches/amos-dependency-links/src/zc/buildout/easy_install.py	2007-10-18 15:52:08 UTC (rev 80923)
+++ zc.buildout/branches/amos-dependency-links/src/zc/buildout/easy_install.py	2007-10-18 17:14:35 UTC (rev 80924)
@@ -115,7 +115,8 @@
     _download_cache = None
     _install_from_cache = False
     _prefer_final = True
-
+    _use_dependency_links = True
+    
     def __init__(self,
                  dest=None,
                  links=(),
@@ -125,6 +126,7 @@
                  path=None,
                  newest=True,
                  versions=None,
+                 use_dependency_links=None,
                  ):
         self._dest = dest
 
@@ -135,8 +137,8 @@
             links = ()
             index = 'file://' + self._download_cache
 
-        
-        
+        if use_dependency_links is not None:
+            self._use_dependency_links = use_dependency_links
         self._links = links = list(_fix_file_links(links))
         if self._download_cache and (self._download_cache not in links):
             links.insert(0, self._download_cache)
@@ -492,10 +494,10 @@
         else:
             dists = [dist]
 
-        # XXX Need test for this
         for dist in dists:
             if (dist.has_metadata('dependency_links.txt')
                 and not self._install_from_cache
+                and self._use_dependency_links
                 ):
                 for link in dist.get_metadata_lines('dependency_links.txt'):
                     link = link.strip()
@@ -702,12 +704,19 @@
         Installer._prefer_final = bool(setting)
     return old
 
+def use_dependency_links(setting=None):
+    old = Installer._use_dependency_links
+    if setting is not None:
+        Installer._use_dependency_links = bool(setting)
+    return old
+
 def install(specs, dest,
             links=(), index=None,
             executable=sys.executable, always_unzip=False,
-            path=None, working_set=None, newest=True, versions=None):
+            path=None, working_set=None, newest=True, versions=None,
+            use_dependency_links=None):
     installer = Installer(dest, links, index, executable, always_unzip, path,
-                          newest, versions)
+                          newest, versions, use_dependency_links)
     return installer.install(specs, working_set)
 
 

Modified: zc.buildout/branches/amos-dependency-links/src/zc/buildout/easy_install.txt
===================================================================
--- zc.buildout/branches/amos-dependency-links/src/zc/buildout/easy_install.txt	2007-10-18 15:52:08 UTC (rev 80923)
+++ zc.buildout/branches/amos-dependency-links/src/zc/buildout/easy_install.txt	2007-10-18 17:14:35 UTC (rev 80924)
@@ -34,11 +34,11 @@
 - A destination directory to install to and to satisfy requirements
   from.  The destination directory can be None, in which case, no new
   distributions are downloaded and there will be an error if the
-  needed distributions can't be found amoung those already installed.
+  needed distributions can't be found among those already installed.
 
 It supports a number of optional keyword arguments:
 
-find-links
+links
    A sequence of URLs, file names, or directories to look for
    links to distributions.
 
@@ -66,13 +66,13 @@
    directories even if they could be installed as zip files.
 
 working_set
-   An exsiting working set to be augmented with additional
+   An existing working set to be augmented with additional
    distributions, if necessary to satisfy requirements.  This allows
    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
+   A boolean 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
@@ -83,6 +83,12 @@
    when selecting distributions.  This can be used to specify a set of
    distribution versions independent of other requirements.
 
+use_depenency_links
+   A flag indicating whether to search for dependencies using the
+   setup dependency_links metadata or not. If true, links are searched
+   for using dependency_links in preference to other
+   locations. Defaults to true.
+
 The install method returns a working set containing the distributions
 needed to meet the given requirements.
 
@@ -140,7 +146,7 @@
     -  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:
+If we leave off the newest option, we'll get an update for demo:
 
     >>> ws = zc.buildout.easy_install.install(
     ...     ['demo'], dest, links=[link_server], index=link_server+'index/')
@@ -150,8 +156,8 @@
     -  demoneeded-1.1-py2.4.egg
 
 Note that we didn't get the newest versions available.  There were
-release candidated for newer versions of both packages. By default,
-final releases are prefered.  We can change this behavior using the
+release candidates for newer versions of both packages. By default,
+final releases are preferred.  We can change this behavior using the
 prefer_final function:
 
     >>> zc.buildout.easy_install.prefer_final(False)
@@ -178,10 +184,9 @@
     >>> zc.buildout.easy_install.prefer_final(True)
     False
 
-
 We can supply additional distributions.  We can also supply
 specifications for distributions that would normally be found via
-dependencies.  We might do this to specify a sprcific version.
+dependencies.  We might do this to specify a specific version.
 
     >>> ws = zc.buildout.easy_install.install(
     ...     ['demo', 'other', 'demoneeded==1.0'], dest,
@@ -214,7 +219,6 @@
     >>> ls(dest)
     d  demo-0.3-py2.4.egg
     d  demoneeded-1.1-py2.4.egg
-
     
     >>> rmdir(dest)
     >>> dest = tmpdir('sample-install')
@@ -226,10 +230,10 @@
     d  demo-0.3-py2.4.egg
     d  demoneeded-1.1-py2.4.egg
 
-Specifying version information indepenent of requirements
+Specifying version information independent of requirements
 ---------------------------------------------------------
 
-Sometimes it's useful to specify version information indepenent of
+Sometimes it's useful to specify version information independent of
 normal requirements specifications.  For example, a buildout may need
 to lock down a set of versions, without having to put put version
 numbers in setup files or part definitions.  If a dictionary is passed
@@ -244,7 +248,7 @@
 
 In this example, we specified a version for demoneeded, even though we
 didn't define a requirement for it.  The versions specified apply to
-depenencies as well as the specified requirements.
+dependencies as well as the specified requirements.
 
 If we specify a version that's incompatible with a requirement, then
 we'll get an error:
@@ -332,8 +336,82 @@
 
     >>> [d.version for d in ws]
     ['0.3', '1.1']
+
+Depenency links
+---------------
+
+Setuptools allows metadata that descibes where to search for package
+dependencies. This option is called dependency_links. Buildout has its
+own notion of where to look for dependencies, but it also uses the
+setup tools dependency_links information if it's available.
+
+Let's demo this by creating an egg that specifies dependency_links. To
+begin, let's create a new egg repository. This repository uses the
+same sample eggs as the normal testing repository.
+
+    >>> link_server2 = start_server(sample_eggs)
+
+Turn on logging on this server so that we can see when eggs are pulled
+from it.
     
+    >>> get(link_server2 + 'enable_server_logging')
+    GET 200 /enable_server_logging
+    ''
 
+Now we can create an egg that specifies that its dependencies are
+found on this server.
+
+    >>> from zc.buildout.tests import create_egg
+    >>> repoloc = tmpdir('repo')
+    >>> create_egg('hasdeps', '1.0', repoloc, 
+    ...            install_requires = "'demoneeded'",
+    ...            dependency_links = [link_server2])
+
+Let's add the egg to another repository.
+
+    >>> link_server3 = start_server(repoloc)
+
+Now let's install the egg.
+
+    >>> example_dest = tmpdir('example-install')
+    >>> workingset = zc.buildout.easy_install.install(
+    ...     ['hasdeps'], example_dest,
+    ...     links=[link_server3], index=link_server3+'index/')
+    GET 200 /
+    GET 200 /demoneeded-1.1.zip
+
+The server logs show that the dependency was retrieved from the server
+specified in the dependency_links.
+
+Now let's see what happens if we provide two different ways to retrieve
+the dependencies.
+
+    >>> rmdir(example_dest)
+    >>> example_dest = tmpdir('example-install')
+    >>> workingset = zc.buildout.easy_install.install(
+    ...     ['hasdeps'], example_dest, index=link_server3+'index/',
+    ...     links=[link_server, link_server3]) #doctest: +ELLIPSIS
+    GET 200 /...
+
+
+Once again the dependency is fetched from the logging server even
+though it is also available from the non-logging server.
+
+If you wish to control where dependencies come from regardless of
+dependency_links setup metadata use the 'use_dependency_links' option
+to zc.buildout.easy_install.install.
+
+    >>> rmdir(example_dest)
+    >>> example_dest = tmpdir('example-install')
+    >>> workingset = zc.buildout.easy_install.install(
+    ...     ['hasdeps'], example_dest, index=link_server3+'index/',
+    ...     links=[link_server, link_server3],
+    ...     use_dependency_links=False)
+
+Notice that this time the dependency egg is not fetched from the
+logging server. When you specify not to use dependency_links, eggs
+will only be searched for using the links you explicitly provide.
+
 Script generation
 -----------------
 
@@ -426,7 +504,7 @@
 
   - An attribute expression for an entry point within the module.
 
-For example, we could have passed antry point information directly
+For example, we could have passed entry point information directly
 rather than passing a requirement:
 
     >>> scripts = zc.buildout.easy_install.scripts(
@@ -507,7 +585,7 @@
 
 If invoked with a script name and arguments, it will run that script, instead.
 
-An additional argumnet can be passed to define which scripts to install
+An additional argument can be passed to define which scripts to install
 and to provide script names. The argument is a dictionary mapping
 original script names to new script names.
 
@@ -530,7 +608,7 @@
 Including extra paths in scripts
 --------------------------------
 
-We can pass a keyword argument, extra paths, to caue additional paths
+We can pass a keyword argument, extra paths, to cause additional paths
 to be included in the a generated script:
 
     >>> scripts = zc.buildout.easy_install.scripts(
@@ -641,7 +719,7 @@
    will make our examples run a little bit faster.
 
 executable
-   A path to a Python executable.  Distributions will ne installed
+   A path to a Python executable.  Distributions will be installed
    using this executable and will be for the matching Python version.
 
 path
@@ -649,7 +727,7 @@
    distributions.
 
 newest
-   A boolian value indicating whether to search for new distributions
+   A boolean 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
@@ -772,7 +850,7 @@
 
 The versions option also influences the versions used.  For example,
 if we specify a version for extdemo, then that will be used, even
-though it isn't the newest.  Let's clean out the destimation directory
+though it isn't the newest.  Let's clean out the destination directory
 first:
 
     >>> import os
@@ -812,7 +890,7 @@
    command when building extensions.
 
 executable
-   A path to a Python executable.  Distributions will ne installed
+   A path to a Python executable.  Distributions will be installed
    using this executable and will be for the matching Python version.
 
 We have a local directory containing the extdemo source:
@@ -966,7 +1044,7 @@
     ...     always_unzip=True)
     GET 200 /demo-0.3-py2.4.egg
 
-Normally, the download cache is the prefered source of downloads, but
+Normally, the download cache is the preferred source of downloads, but
 not the only one.
 
 Installing solely from a download cache

Modified: zc.buildout/branches/amos-dependency-links/src/zc/buildout/testing.txt
===================================================================
--- zc.buildout/branches/amos-dependency-links/src/zc/buildout/testing.txt	2007-10-18 15:52:08 UTC (rev 80923)
+++ zc.buildout/branches/amos-dependency-links/src/zc/buildout/testing.txt	2007-10-18 17:14:35 UTC (rev 80924)
@@ -97,7 +97,7 @@
 
     and:
 
-       >>> get(server_url+'enable_server_logging')
+       >>> get(server_url+'disable_server_logging')
 
     This can be useful to see how buildout is interacting with a
     server.

Modified: zc.buildout/branches/amos-dependency-links/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/branches/amos-dependency-links/src/zc/buildout/tests.py	2007-10-18 15:52:08 UTC (rev 80923)
+++ zc.buildout/branches/amos-dependency-links/src/zc/buildout/tests.py	2007-10-18 17:14:35 UTC (rev 80924)
@@ -2057,19 +2057,27 @@
     """
 
 
-def create_egg(name, version, dest):
+def create_egg(name, version, dest, install_requires=None,
+               dependency_links=None):
     d = tempfile.mkdtemp()
     if dest=='available':
         extras = dict(x=['x'])
     else:
         extras = {}
-        
+    if dependency_links:
+        links = 'dependency_links = %s, ' % dependency_links
+    else:
+        links = ''
+    if install_requires:
+        requires = 'install_requires = %s, ' % install_requires
+    else:
+        requires = ''
     try:
         open(os.path.join(d, 'setup.py'), 'w').write(
             'from setuptools import setup\n'
             'setup(name=%r, version=%r, extras_require=%r, zip_safe=True,\n'
-            '      py_modules=["setup"]\n)'
-            % (name, str(version), extras)
+            '      %s %s py_modules=["setup"]\n)'
+            % (name, str(version), extras, requires, links)
             )
         zc.buildout.testing.bdist_egg(d, sys.executable, os.path.abspath(dest))
     finally:
@@ -2284,14 +2292,12 @@
     """
 
 
-# XXX Tests needed:
 
-# Link added from package meta data
 
 
 
 ######################################################################
-    
+
 def create_sample_eggs(test, executable=sys.executable):
     write = test.globs['write']
     dest = test.globs['sample_eggs']
@@ -2300,12 +2306,12 @@
         write(tmp, 'README.txt', '')
 
         for i in (0, 1, 2):
-            write(tmp, 'eggrecipedemobeeded.py', 'y=%s\n' % i)
+            write(tmp, 'eggrecipedemoneeded.py', 'y=%s\n' % i)
             c1 = i==2 and 'c1' or ''
             write(
                 tmp, 'setup.py',
                 "from setuptools import setup\n"
-                "setup(name='demoneeded', py_modules=['eggrecipedemobeeded'],"
+                "setup(name='demoneeded', py_modules=['eggrecipedemoneeded'],"
                 " zip_safe=True, version='1.%s%s', author='bob', url='bob', "
                 "author_email='bob')\n"
                 % (i, c1)
@@ -2316,18 +2322,18 @@
             tmp, 'setup.py',
             "from setuptools import setup\n"
             "setup(name='other', zip_safe=False, version='1.0', "
-            "py_modules=['eggrecipedemobeeded'])\n"
+            "py_modules=['eggrecipedemoneeded'])\n"
             )
         zc.buildout.testing.bdist_egg(tmp, executable, dest)
 
-        os.remove(os.path.join(tmp, 'eggrecipedemobeeded.py'))
+        os.remove(os.path.join(tmp, 'eggrecipedemoneeded.py'))
 
         for i in (1, 2, 3, 4):
             write(
                 tmp, 'eggrecipedemo.py',
-                'import eggrecipedemobeeded\n'
+                'import eggrecipedemoneeded\n'
                 'x=%s\n'
-                'def main(): print x, eggrecipedemobeeded.y\n'
+                'def main(): print x, eggrecipedemoneeded.y\n'
                 % i)
             c1 = i==4 and 'c1' or ''
             write(
@@ -2534,7 +2540,7 @@
             ),
         
         doctest.DocFileSuite(
-            'easy_install.txt', 'downloadcache.txt',
+            'easy_install.txt', 'downloadcache.txt', 'dependencylinks.txt',
             setUp=easy_install_SetUp,
             tearDown=zc.buildout.testing.buildoutTearDown,
 



More information about the Checkins mailing list