[Checkins] SVN: zc.buildout/trunk/ Feature Changes

Jim Fulton jim at zope.com
Wed Feb 7 18:47:29 EST 2007


Log message for revision 72432:
  Feature Changes
  ---------------
  
  - Added a buildout newest option, to control whether the newest
    distributions should be sought to meet requirements.  This might
    also provide a hint to recipes that don't deal with
    distributions. For example, a recipe that manages subversion
    checkouts might not update a checkout if newest is set to "false".
  
  - The recipe-testing support setUp function now adds the name
    *buildout* to the test namespace with a value that is the path to
    the buildout script in the sample buildout.  This allows tests to
    use
  
  >>> print system(buildout),
  
  rather than:
  
  >>> print system(join('bin', 'buildout')),
  
  Bugs Fixed
  ----------
  
  - Paths returned from update methods replaced lists of installed files
    rather than augmenting them.
  

Changed:
  U   zc.buildout/trunk/CHANGES.txt
  U   zc.buildout/trunk/setup.py
  U   zc.buildout/trunk/src/zc/buildout/buildout.py
  U   zc.buildout/trunk/src/zc/buildout/buildout.txt
  U   zc.buildout/trunk/src/zc/buildout/testing.py
  U   zc.buildout/trunk/src/zc/buildout/tests.py
  U   zc.buildout/trunk/src/zc/buildout/update.txt

-=-
Modified: zc.buildout/trunk/CHANGES.txt
===================================================================
--- zc.buildout/trunk/CHANGES.txt	2007-02-07 23:43:36 UTC (rev 72431)
+++ zc.buildout/trunk/CHANGES.txt	2007-02-07 23:47:28 UTC (rev 72432)
@@ -20,6 +20,44 @@
 Change History
 **************
 
+1.0.0b20 (2007-02-??)
+=====================
+
+Feature Changes
+---------------
+
+- Added a buildout newest option, to control whether the newest
+  distributions should be sought to meet requirements.  This might
+  also provide a hint to recipes that don't deal with
+  distributions. For example, a recipe that manages subversion
+  checkouts might not update a checkout if newest is set to "false".
+
+- Added a *newest* keyword parameter to the
+  zc.buildout.easy_install.install and zc.buildout.easy_install.build
+  functions to control whether the newest distributions that meed
+  given requirements should be sought.  If a false value is provided
+  for this parameter and already installed eggs meet the given
+  requirements, then no attempt will be made to search for newer
+  distributions.
+ 
+- The recipe-testing support setUp function now adds the name
+  *buildout* to the test namespace with a value that is the path to
+  the buildout script in the sample buildout.  This allows tests to
+  use
+
+    >>> print system(buildout),
+
+  rather than:
+
+    >>> print system(join('bin', 'buildout')),
+
+
+Bugs Fixed
+----------
+
+- Paths returned from update methods replaced lists of installed files
+  rather than augmenting them.
+
 1.0.0b19 (2007-01-24)
 =====================
 

Modified: zc.buildout/trunk/setup.py
===================================================================
--- zc.buildout/trunk/setup.py	2007-02-07 23:43:36 UTC (rev 72431)
+++ zc.buildout/trunk/setup.py	2007-02-07 23:47:28 UTC (rev 72432)
@@ -7,7 +7,7 @@
 name = "zc.buildout"
 setup(
     name = name,
-    version = "1.0.0b19",
+    version = "1.0.0b20",
     author = "Jim Fulton",
     author_email = "jim at zope.com",
     description = "System for managing development buildouts",

Modified: zc.buildout/trunk/src/zc/buildout/buildout.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/buildout.py	2007-02-07 23:43:36 UTC (rev 72431)
+++ zc.buildout/trunk/src/zc/buildout/buildout.py	2007-02-07 23:47:28 UTC (rev 72432)
@@ -131,7 +131,16 @@
         if offline not in ('true', 'false'):
             self._error('Invalid value for offline option: %s', offline)
         options['offline'] = offline
+        self.offline = offline == 'true'
 
+        if self.offline:
+            newest = options['newest'] = 'false'
+        else:
+            newest = options.get('newest', 'true')
+            if newest not in ('true', 'false'):
+                self._error('Invalid value for newest option: %s', newest)
+            options['newest'] = newest
+        self.newest = newest == 'true'
 
     def _buildout_path(self, *names):
         return os.path.join(self._buildout_dir, *names)
@@ -303,7 +312,17 @@
                     
                     if installed_files is None:
                         installed_files = old_installed_files.split('\n')
+                    else:
+                        if isinstance(installed_files, str):
+                            installed_files = [installed_files]
+                        else:
+                            installed_files = list(installed_files)
+                            
 
+                        installed_files += [
+                            p for p in old_installed_files.split('\n')
+                            if p and p not in installed_files]
+
                 else:
                     self._logger.info('Installing %s', part)
                     installed_files = recipe.install()
@@ -491,8 +510,8 @@
         # See if buildout or setuptools need to be upgraded.
         # If they do, do the upgrade and restart the buildout process.
 
-        if self['buildout'].get('offline') == 'true':
-            return # skip upgrade in offline mode:
+        if not self.newest:
+            return
         
         ws = zc.buildout.easy_install.install(
             [
@@ -563,7 +582,7 @@
         specs = self['buildout'].get('extensions', '').split()
         if specs:
             path = [self['buildout']['develop-eggs-directory']]
-            if self['buildout'].get('offline') == 'true':
+            if self.offline:
                 dest = None
                 path.append(self['buildout']['eggs-directory'])
             else:
@@ -575,7 +594,7 @@
             zc.buildout.easy_install.install(
                 specs, dest, path=path,
                 working_set=pkg_resources.working_set,
-                )
+                newest=self.newest)
             for ep in pkg_resources.iter_entry_points('zc.buildout.extension'):
                 ep.load()(self)
 
@@ -640,7 +659,7 @@
 
         buildout_options = buildout['buildout']
         if pkg_resources.working_set.find(req) is None:
-            if buildout_options['offline'] == 'true':
+            if buildout.offline:
                 dest = None
                 path = [buildout_options['develop-eggs-directory'],
                         buildout_options['eggs-directory'],
@@ -655,6 +674,7 @@
                 index=buildout_options.get('index'),
                 path=path,
                 working_set=pkg_resources.working_set,
+                newest=buildout.newest,
                 )
 
         return pkg_resources.load_entry_point(
@@ -961,6 +981,32 @@
 
      Don't read user defaults.
 
+  -o
+  
+    Run in off-line mode.  This is equivalent to the assignment 
+    buildout:offline=true.
+
+  -O
+
+    Run in non-off-line mode.  This is equivalent to the assignment 
+    buildout:offline=false.  This is the default buildout mode.  The
+    -O option would normally be used to override a true offline
+    setting in a configuration file.
+
+  -n
+
+    Run in newest mode.  This is equivalent to the assignment
+    buildout:newest=true.  With this setting, which is the default,
+    buildout will try to find the newest versions of distributions
+    available that satisfy its requirements.
+
+  -N
+
+    Run in non-newest mode.  This is equivalent to the assignment 
+    buildout:newest=false.  With this setting, buildout will not seek
+    new distributions if installed distributions satisfy it's
+    requirements. 
+
 Assignments are of the form: section:option=value and are used to
 provide configuration options that override those given in the
 configuration file.  For example, to run the buildout in offline mode,
@@ -1000,7 +1046,7 @@
         if args[0][0] == '-':
             op = orig_op = args.pop(0)
             op = op[1:]
-            while op and op[0] in 'vqhWUo':
+            while op and op[0] in 'vqhWUoOnN':
                 if op[0] == 'v':
                     verbosity += 10
                 elif op[0] == 'q':
@@ -1011,6 +1057,12 @@
                     user_defaults = False
                 elif op[0] == 'o':
                     options.append(('buildout', 'offline', 'true'))
+                elif op[0] == 'O':
+                    options.append(('buildout', 'offline', 'false'))
+                elif op[0] == 'n':
+                    options.append(('buildout', 'newest', 'true'))
+                elif op[0] == 'N':
+                    options.append(('buildout', 'newest', 'false'))
                 else:
                     _help()
                 op = op[1:]

Modified: zc.buildout/trunk/src/zc/buildout/buildout.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/buildout.txt	2007-02-07 23:43:36 UTC (rev 72431)
+++ zc.buildout/trunk/src/zc/buildout/buildout.txt	2007-02-07 23:47:28 UTC (rev 72432)
@@ -205,7 +205,7 @@
 can't be updated.  An update method can return None, a string, or an
 iterable of strings.  If a string or iterable of strings is returned,
 then the saved list of paths to be uninstalled is updated with the new
-information. 
+information by adding any new files returned by the update method.
 
 We need to provide packaging information so that our recipe can be
 installed as a develop egg. The minimum information we need to specify
@@ -1186,6 +1186,24 @@
     Run in off-line mode.  This is equivalent to the assignment 
     buildout:offline=true.
 
+-O
+    Run in non-off-line mode.  This is equivalent to the assignment 
+    buildout:offline=false.  This is the default buildout mode.  The
+    -O option would normally be used to override a true offline
+    setting in a configuration file.
+
+-n
+    Run in newest mode.  This is equivalent to the assignment
+    buildout:newest=true.  With this setting, which is the default,
+    buildout will try to find the newest versions of distributions
+    available that satisfy its requirements.
+
+-N
+    Run in non-newest mode.  This is equivalent to the assignment 
+    buildout:newest=false.  With this setting, buildout will not seek
+    new distributions if installed distributions satisfy it's
+    requirements. 
+
 Assignments are of the form::
 
   section_name:option_name=value
@@ -1593,6 +1611,7 @@
     installed = /sample-buildout/.installed.cfg
     log-format = %(name)s: %(message)s
     log-level = INFO
+    newest = true
     offline = false
     parts = 
     parts-directory = /sample-buildout/parts
@@ -1705,16 +1724,25 @@
 Note that the buildout script was installed but not run.  To run
 the buildout, we'd have to run the installed buildout script.
 
-Offline mode
-------------
+Newest and Offline Modes
+------------------------
 
-If the buildout offline option is given a value of "true", the
-buildout and recipes that are aware of the option will avoid doing
-network access.  This is handy when running the buildout when not
-connected to the internet.  It also makes buildouts run much
-faster. This option is typically given as a command-line option
-``buildout:offline=true``.
+By default buildout and recipes will try to find the newest versions
+of distributions needed to satisfy requirements.  This can be very
+time consuming, especially when incrementally working on setting up a
+buildout or working on a recipe.  The buildout newest option can be
+used to to suppress this.  If the newest option is set to false, then
+new distributions won't be sought if an installed distribution meets
+requirements.  The newest option can be set to false using the -N
+command-line option.
 
+The offline option goes a bit further.  If the buildout offline option
+is given a value of "true", the buildout and recipes that are aware of
+the option will avoid doing network access.  This is handy when
+running the buildout when not connected to the internet.  It also
+makes buildouts run much faster. This option is typically set using
+the buildout -o option.
+
 Controlling the installation database
 -------------------------------------
 

Modified: zc.buildout/trunk/src/zc/buildout/testing.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/testing.py	2007-02-07 23:43:36 UTC (rev 72431)
+++ zc.buildout/trunk/src/zc/buildout/testing.py	2007-02-07 23:47:28 UTC (rev 72432)
@@ -204,6 +204,7 @@
         sdist = sdist,
         bdist_egg = bdist_egg,
         start_server = start_server,
+        buildout = os.path.join(sample, 'bin', 'buildout'),
         ))
 
 def buildoutTearDown(test):

Modified: zc.buildout/trunk/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/trunk/src/zc/buildout/tests.py	2007-02-07 23:43:36 UTC (rev 72431)
+++ zc.buildout/trunk/src/zc/buildout/tests.py	2007-02-07 23:47:28 UTC (rev 72432)
@@ -452,6 +452,32 @@
 <BLANKLINE>
      Don't read user defaults.
 <BLANKLINE>
+  -o
+<BLANKLINE>
+    Run in off-line mode.  This is equivalent to the assignment 
+    buildout:offline=true.
+<BLANKLINE>
+  -O
+<BLANKLINE>
+    Run in non-off-line mode.  This is equivalent to the assignment 
+    buildout:offline=false.  This is the default buildout mode.  The
+    -O option would normally be used to override a true offline
+    setting in a configuration file.
+<BLANKLINE>
+  -n
+<BLANKLINE>
+    Run in newest mode.  This is equivalent to the assignment
+    buildout:newest=true.  With this setting, which is the default,
+    buildout will try to find the newest versions of distributions
+    available that satisfy its requirements.
+<BLANKLINE>
+  -N
+<BLANKLINE>
+    Run in non-newest mode.  This is equivalent to the assignment 
+    buildout:newest=false.  With this setting, buildout will not seek
+    new distributions if installed distributions satisfy it's
+    requirements. 
+<BLANKLINE>
 Assignments are of the form: section:option=value and are used to
 provide configuration options that override those given in the
 configuration file.  For example, to run the buildout in offline mode,
@@ -503,6 +529,32 @@
 <BLANKLINE>
      Don't read user defaults.
 <BLANKLINE>
+  -o
+<BLANKLINE>
+    Run in off-line mode.  This is equivalent to the assignment 
+    buildout:offline=true.
+<BLANKLINE>
+  -O
+<BLANKLINE>
+    Run in non-off-line mode.  This is equivalent to the assignment 
+    buildout:offline=false.  This is the default buildout mode.  The
+    -O option would normally be used to override a true offline
+    setting in a configuration file.
+<BLANKLINE>
+  -n
+<BLANKLINE>
+    Run in newest mode.  This is equivalent to the assignment
+    buildout:newest=true.  With this setting, which is the default,
+    buildout will try to find the newest versions of distributions
+    available that satisfy its requirements.
+<BLANKLINE>
+  -N
+<BLANKLINE>
+    Run in non-newest mode.  This is equivalent to the assignment 
+    buildout:newest=false.  With this setting, buildout will not seek
+    new distributions if installed distributions satisfy it's
+    requirements. 
+<BLANKLINE>
 Assignments are of the form: section:option=value and are used to
 provide configuration options that override those given in the
 configuration file.  For example, to run the buildout in offline mode,
@@ -974,6 +1026,185 @@
     ...
     """
 
+def recipe_upgrade():
+    """
+
+The buildout will upgrade recipes in newest (and non-offline) mode.
+
+Let's create a recipe egg
+
+    >>> mkdir('recipe')
+    >>> write('recipe', 'recipe.py',
+    ... '''
+    ... class Recipe:
+    ...     def __init__(*a): pass
+    ...     def install(self):
+    ...         print 'recipe v1'
+    ...         return ()
+    ...     update = install
+    ... ''')
+
+    >>> write('recipe', 'setup.py',
+    ... '''
+    ... from setuptools import setup
+    ... setup(name='recipe', version='1', py_modules=['recipe'],
+    ...       entry_points={'zc.buildout': ['default = recipe:Recipe']},
+    ...       )
+    ... ''')
+
+    >>> write('recipe', 'README', '')
+
+    >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
+    buildout: Running setup script recipe/setup.py
+    ...
+
+And update our buildout to use it.
+
+    >>> write('buildout.cfg',
+    ... '''
+    ... [buildout]
+    ... parts = foo
+    ... find-links = %s
+    ...
+    ... [foo]
+    ... recipe = recipe
+    ... ''' % join('recipe', 'dist'))
+
+    >>> print system(buildout),
+    zc.buildout.easy_install: Getting new distribution for recipe
+    zc.buildout.easy_install: Got recipe 1
+    buildout: Installing foo
+    recipe v1
+
+Now, if we update the recipe egg:
+
+    >>> write('recipe', 'recipe.py',
+    ... '''
+    ... class Recipe:
+    ...     def __init__(*a): pass
+    ...     def install(self):
+    ...         print 'recipe v2'
+    ...         return ()
+    ...     update = install
+    ... ''')
+
+    >>> write('recipe', 'setup.py',
+    ... '''
+    ... from setuptools import setup
+    ... setup(name='recipe', version='2', py_modules=['recipe'],
+    ...       entry_points={'zc.buildout': ['default = recipe:Recipe']},
+    ...       )
+    ... ''')
+
+
+    >>> print system(buildout+' setup recipe bdist_egg'), # doctest: +ELLIPSIS
+    buildout: Running setup script recipe/setup.py
+    ...
+
+We won't get the update if we specify -N:
+
+    >>> print system(buildout+' -N'),
+    buildout: Updating foo
+    recipe v1
+
+or if we use -o:
+
+    >>> print system(buildout+' -o'),
+    buildout: Updating foo
+    recipe v1
+
+But we will if we use neither of these:
+
+    >>> print system(buildout),
+    zc.buildout.easy_install: Getting new distribution for recipe
+    zc.buildout.easy_install: Got recipe 2
+    buildout: Uninstalling foo
+    buildout: Installing foo
+    recipe v1
+
+We can also select a particular recipe version:
+
+    >>> write('buildout.cfg',
+    ... '''
+    ... [buildout]
+    ... parts = foo
+    ... find-links = %s
+    ...
+    ... [foo]
+    ... recipe = recipe ==1
+    ... ''' % join('recipe', 'dist'))
+
+    >>> print system(buildout),
+    buildout: Uninstalling foo
+    buildout: Installing foo
+    recipe v1
+    
+    """
+
+def update_adds_to_uninstall_list():
+    """
+
+Paths returned by the update method are added to the list of paths to
+uninstall
+
+    >>> mkdir('recipe')
+    >>> write('recipe', 'setup.py',
+    ... '''
+    ... from setuptools import setup
+    ... setup(name='recipe',
+    ...       entry_points={'zc.buildout': ['default = recipe:Recipe']},
+    ...       )
+    ... ''')
+
+    >>> write('recipe', 'recipe.py',
+    ... '''
+    ... import os
+    ... class Recipe:
+    ...     def __init__(*_): pass
+    ...     def install(self):
+    ...         r = ('a', 'b', 'c')
+    ...         for p in r: os.mkdir(p)
+    ...         return r
+    ...     def update(self):
+    ...         r = ('c', 'd', 'e')
+    ...         for p in r:
+    ...             if not os.path.exists(p):
+    ...                os.mkdir(p)
+    ...         return r
+    ... ''')
+
+    >>> write('buildout.cfg',
+    ... '''
+    ... [buildout]
+    ... develop = recipe
+    ... parts = foo
+    ...
+    ... [foo]
+    ... recipe = recipe
+    ... ''')
+
+    >>> print system(buildout),
+    buildout: Develop: /tmp/tmpbHOHnU/_TEST_/sample-buildout/recipe
+    buildout: Installing foo
+
+    >>> print system(buildout),
+    buildout: Develop: /tmp/tmpbHOHnU/_TEST_/sample-buildout/recipe
+    buildout: Updating foo
+
+    >>> cat('.installed.cfg') # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+    [buildout]
+    ...
+    [foo]
+    __buildout_installed__ = c
+    	d
+    	e
+    	a
+    	b
+    __buildout_signature__ = ...
+
+"""
+
+
 ######################################################################
     
 def create_sample_eggs(test, executable=sys.executable):

Modified: zc.buildout/trunk/src/zc/buildout/update.txt
===================================================================
--- zc.buildout/trunk/src/zc/buildout/update.txt	2007-02-07 23:43:36 UTC (rev 72431)
+++ zc.buildout/trunk/src/zc/buildout/update.txt	2007-02-07 23:47:28 UTC (rev 72432)
@@ -59,12 +59,10 @@
     ...     )
     ... """)
 
+
 Now if we run the buildout, the buildout will upgrade itself to the
 new versions found in new releases:
 
-    >>> import os
-    >>> os.chdir(sample_buildout)
-    >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
     >>> print system(buildout),
     zc.buildout.easy_install: Getting new distribution for zc.buildout
     zc.buildout.easy_install: Got zc.buildout 99.99
@@ -136,18 +134,25 @@
     ... index = %(new_releases)s
     ... parts = show-versions
     ... develop = showversions
-    ... offline = true
     ... 
     ... [show-versions]
     ... recipe = showversions
     ... """ % dict(new_releases=new_releases))
 
-    >>> print system(buildout),
+    >>> print system(buildout+' -o'),
     buildout: Develop: /sample-buildout/showversions
     buildout: Updating show-versions
     zc.buildout 1.0.0
     setuptools 0.6
- 
+
+Or in non-newest mode:
+
+    >>> print system(buildout+' -N'),
+    buildout: Develop: /sample-buildout/showversions
+    buildout: Updating show-versions
+    zc.buildout 1.0.0
+    setuptools 0.6
+
 We also won't upgrade if the buildout script bing run isn't in the
 buildouts bin directory.  To see this we'll create a new buildout
 directory:



More information about the Checkins mailing list