summaryrefslogtreecommitdiff
path: root/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/buildout.py
diff options
context:
space:
mode:
authorNishanth Amuluru2011-01-08 11:20:57 +0530
committerNishanth Amuluru2011-01-08 11:20:57 +0530
commit65411d01d448ff0cd4abd14eee14cf60b5f8fc20 (patch)
treeb4c404363c4c63a61d6e2f8bd26c5b057c1fb09d /eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/buildout.py
parent2e35094d43b4cc6974172e1febf76abb50f086ec (diff)
downloadpytask-65411d01d448ff0cd4abd14eee14cf60b5f8fc20.tar.gz
pytask-65411d01d448ff0cd4abd14eee14cf60b5f8fc20.tar.bz2
pytask-65411d01d448ff0cd4abd14eee14cf60b5f8fc20.zip
Added buildout stuff and made changes accordingly
--HG-- rename : profile/management/__init__.py => eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/infrae.subversion-1.4.5-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/infrae.subversion-1.4.5-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/py-1.4.0-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/py-1.4.0-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/zc.buildout-1.5.2-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/zc.buildout-1.5.2-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/zc.recipe.egg-1.3.2-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/zc.recipe.egg-1.3.2-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => parts/django/Django.egg-info/dependency_links.txt rename : taskapp/models.py => parts/django/django/conf/app_template/models.py rename : taskapp/tests.py => parts/django/django/conf/app_template/tests.py rename : taskapp/views.py => parts/django/django/conf/app_template/views.py rename : taskapp/views.py => parts/django/django/contrib/gis/tests/geo3d/views.py rename : profile/management/__init__.py => parts/django/tests/modeltests/delete/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/files/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/invalid_models/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/m2m_signals/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/model_package/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/management/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/management/commands/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/models.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/delete_regress/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/file_storage/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/max_lengths/__init__.py rename : profile/forms.py => pytask/profile/forms.py rename : profile/management/__init__.py => pytask/profile/management/__init__.py rename : profile/management/commands/seed_db.py => pytask/profile/management/commands/seed_db.py rename : profile/models.py => pytask/profile/models.py rename : profile/templatetags/user_tags.py => pytask/profile/templatetags/user_tags.py rename : taskapp/tests.py => pytask/profile/tests.py rename : profile/urls.py => pytask/profile/urls.py rename : profile/utils.py => pytask/profile/utils.py rename : profile/views.py => pytask/profile/views.py rename : static/css/base.css => pytask/static/css/base.css rename : taskapp/tests.py => pytask/taskapp/tests.py rename : taskapp/views.py => pytask/taskapp/views.py rename : templates/base.html => pytask/templates/base.html rename : templates/profile/browse_notifications.html => pytask/templates/profile/browse_notifications.html rename : templates/profile/edit.html => pytask/templates/profile/edit.html rename : templates/profile/view.html => pytask/templates/profile/view.html rename : templates/profile/view_notification.html => pytask/templates/profile/view_notification.html rename : templates/registration/activate.html => pytask/templates/registration/activate.html rename : templates/registration/activation_email.txt => pytask/templates/registration/activation_email.txt rename : templates/registration/activation_email_subject.txt => pytask/templates/registration/activation_email_subject.txt rename : templates/registration/logged_out.html => pytask/templates/registration/logged_out.html rename : templates/registration/login.html => pytask/templates/registration/login.html rename : templates/registration/logout.html => pytask/templates/registration/logout.html rename : templates/registration/password_change_done.html => pytask/templates/registration/password_change_done.html rename : templates/registration/password_change_form.html => pytask/templates/registration/password_change_form.html rename : templates/registration/password_reset_complete.html => pytask/templates/registration/password_reset_complete.html rename : templates/registration/password_reset_confirm.html => pytask/templates/registration/password_reset_confirm.html rename : templates/registration/password_reset_done.html => pytask/templates/registration/password_reset_done.html rename : templates/registration/password_reset_email.html => pytask/templates/registration/password_reset_email.html rename : templates/registration/password_reset_form.html => pytask/templates/registration/password_reset_form.html rename : templates/registration/registration_complete.html => pytask/templates/registration/registration_complete.html rename : templates/registration/registration_form.html => pytask/templates/registration/registration_form.html rename : utils.py => pytask/utils.py
Diffstat (limited to 'eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/buildout.py')
-rw-r--r--eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/buildout.py1835
1 files changed, 1835 insertions, 0 deletions
diff --git a/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/buildout.py b/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/buildout.py
new file mode 100644
index 0000000..6fe4e8b
--- /dev/null
+++ b/eggs/zc.buildout-1.5.2-py2.6.egg/zc/buildout/buildout.py
@@ -0,0 +1,1835 @@
+##############################################################################
+#
+# Copyright (c) 2005-2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Buildout main script
+"""
+
+from rmtree import rmtree
+try:
+ from hashlib import md5
+except ImportError:
+ # Python 2.4 and older
+ from md5 import md5
+
+import ConfigParser
+import copy
+import distutils.errors
+import glob
+import itertools
+import logging
+import os
+import pkg_resources
+import re
+import shutil
+import sys
+import tempfile
+import UserDict
+import warnings
+import zc.buildout
+import zc.buildout.download
+import zc.buildout.easy_install
+
+
+realpath = zc.buildout.easy_install.realpath
+
+pkg_resources_loc = pkg_resources.working_set.find(
+ pkg_resources.Requirement.parse('setuptools')).location
+
+_isurl = re.compile('([a-zA-Z0-9+.-]+)://').match
+
+is_jython = sys.platform.startswith('java')
+
+if is_jython:
+ import subprocess
+
+_sys_executable_has_broken_dash_S = (
+ zc.buildout.easy_install._has_broken_dash_S(sys.executable))
+
+class MissingOption(zc.buildout.UserError, KeyError):
+ """A required option was missing.
+ """
+
+class MissingSection(zc.buildout.UserError, KeyError):
+ """A required section is missing.
+ """
+
+ def __str__(self):
+ return "The referenced section, %r, was not defined." % self[0]
+
+
+def _annotate_section(section, note):
+ for key in section:
+ section[key] = (section[key], note)
+ return section
+
+def _annotate(data, note):
+ for key in data:
+ data[key] = _annotate_section(data[key], note)
+ return data
+
+def _print_annotate(data):
+ sections = data.keys()
+ sections.sort()
+ print
+ print "Annotated sections"
+ print "="*len("Annotated sections")
+ for section in sections:
+ print
+ print '[%s]' % section
+ keys = data[section].keys()
+ keys.sort()
+ for key in keys:
+ value, notes = data[section][key]
+ keyvalue = "%s= %s" % (key, value)
+ print keyvalue
+ line = ' '
+ for note in notes.split():
+ if note == '[+]':
+ line = '+= '
+ elif note == '[-]':
+ line = '-= '
+ else:
+ print line, note
+ line = ' '
+ print
+
+
+def _unannotate_section(section):
+ for key in section:
+ value, note = section[key]
+ section[key] = value
+ return section
+
+def _unannotate(data):
+ for key in data:
+ data[key] = _unannotate_section(data[key])
+ return data
+
+_buildout_default_options = _annotate_section({
+ 'accept-buildout-test-releases': 'false',
+ 'allow-hosts': '*',
+ 'allow-picked-versions': 'true',
+ 'allowed-eggs-from-site-packages': '*',
+ 'bin-directory': 'bin',
+ 'develop-eggs-directory': 'develop-eggs',
+ 'eggs-directory': 'eggs',
+ 'executable': sys.executable,
+ 'exec-sitecustomize': 'true',
+ 'find-links': '',
+ 'include-site-packages': 'true',
+ 'install-from-cache': 'false',
+ 'installed': '.installed.cfg',
+ 'log-format': '',
+ 'log-level': 'INFO',
+ 'newest': 'true',
+ 'offline': 'false',
+ 'parts-directory': 'parts',
+ 'prefer-final': 'false',
+ 'python': 'buildout',
+ 'relative-paths': 'false',
+ 'socket-timeout': '',
+ 'unzip': 'false',
+ 'use-dependency-links': 'true',
+ }, 'DEFAULT_VALUE')
+
+
+class Buildout(UserDict.DictMixin):
+
+ def __init__(self, config_file, cloptions,
+ user_defaults=True, windows_restart=False, command=None):
+
+ __doing__ = 'Initializing.'
+
+ self.__windows_restart = windows_restart
+
+ # default options
+ data = dict(buildout=_buildout_default_options.copy())
+ self._buildout_dir = os.getcwd()
+
+ if not _isurl(config_file):
+ config_file = os.path.abspath(config_file)
+ base = os.path.dirname(config_file)
+ if not os.path.exists(config_file):
+ if command == 'init':
+ print 'Creating %r.' % config_file
+ open(config_file, 'w').write('[buildout]\nparts = \n')
+ elif command == 'setup':
+ # Sigh. This model of a buildout instance
+ # with methods is breaking down. :(
+ config_file = None
+ data['buildout']['directory'] = ('.', 'COMPUTED_VALUE')
+ else:
+ raise zc.buildout.UserError(
+ "Couldn't open %s" % config_file)
+
+ if config_file:
+ data['buildout']['directory'] = (os.path.dirname(config_file),
+ 'COMPUTED_VALUE')
+ else:
+ base = None
+
+
+ cloptions = dict(
+ (section, dict((option, (value, 'COMMAND_LINE_VALUE'))
+ for (_, option, value) in v))
+ for (section, v) in itertools.groupby(sorted(cloptions),
+ lambda v: v[0])
+ )
+ override = cloptions.get('buildout', {}).copy()
+
+ # load user defaults, which override defaults
+ if user_defaults:
+ user_config = os.path.join(os.path.expanduser('~'),
+ '.buildout', 'default.cfg')
+ if os.path.exists(user_config):
+ _update(data, _open(os.path.dirname(user_config), user_config,
+ [], data['buildout'].copy(), override))
+
+ # load configuration files
+ if config_file:
+ _update(data, _open(os.path.dirname(config_file), config_file, [],
+ data['buildout'].copy(), override))
+
+ # apply command-line options
+ _update(data, cloptions)
+
+ self._annotated = copy.deepcopy(data)
+ self._raw = _unannotate(data)
+ self._data = {}
+ self._parts = []
+ # provide some defaults before options are parsed
+ # because while parsing options those attributes might be
+ # used already (Gottfried Ganssauge)
+ buildout_section = data['buildout']
+
+ # Try to make sure we have absolute paths for standard
+ # directories. We do this before doing substitutions, in case
+ # a one of these gets read by another section. If any
+ # variable references are used though, we leave it as is in
+ # _buildout_path.
+ if 'directory' in buildout_section:
+ self._buildout_dir = buildout_section['directory']
+ for name in ('bin', 'parts', 'eggs', 'develop-eggs'):
+ d = self._buildout_path(buildout_section[name+'-directory'])
+ buildout_section[name+'-directory'] = d
+
+ # Attributes on this buildout object shouldn't be used by
+ # recipes in their __init__. It can cause bugs, because the
+ # recipes will be instantiated below (``options = self['buildout']``)
+ # before this has completed initializing. These attributes are
+ # left behind for legacy support but recipe authors should
+ # beware of using them. A better practice is for a recipe to
+ # use the buildout['buildout'] options.
+ links = buildout_section['find-links']
+ self._links = links and links.split() or ()
+ allow_hosts = buildout_section['allow-hosts'].split('\n')
+ self._allow_hosts = tuple([host.strip() for host in allow_hosts
+ if host.strip() != ''])
+ self._logger = logging.getLogger('zc.buildout')
+ self.offline = (buildout_section['offline'] == 'true')
+ self.newest = (buildout_section['newest'] == 'true')
+ self.accept_buildout_test_releases = (
+ buildout_section['accept-buildout-test-releases'] == 'true')
+
+ ##################################################################
+ ## WARNING!!!
+ ## ALL ATTRIBUTES MUST HAVE REASONABLE DEFAULTS AT THIS POINT
+ ## OTHERWISE ATTRIBUTEERRORS MIGHT HAPPEN ANY TIME FROM RECIPES.
+ ## RECIPES SHOULD GENERALLY USE buildout['buildout'] OPTIONS, NOT
+ ## BUILDOUT ATTRIBUTES.
+ ##################################################################
+ # initialize some attrs and buildout directories.
+ options = self['buildout']
+
+ # now reinitialize
+ links = options.get('find-links', '')
+ self._links = links and links.split() or ()
+
+ allow_hosts = options['allow-hosts'].split('\n')
+ self._allow_hosts = tuple([host.strip() for host in allow_hosts
+ if host.strip() != ''])
+
+ self._buildout_dir = options['directory']
+
+ # Make sure we have absolute paths for standard directories. We do this
+ # a second time here in case someone overrode these in their configs.
+ for name in ('bin', 'parts', 'eggs', 'develop-eggs'):
+ d = self._buildout_path(options[name+'-directory'])
+ options[name+'-directory'] = d
+
+ if options['installed']:
+ options['installed'] = os.path.join(options['directory'],
+ options['installed'])
+
+ self._setup_logging()
+
+ versions = options.get('versions')
+ if versions:
+ zc.buildout.easy_install.default_versions(dict(self[versions]))
+
+
+ self.offline = options.get_bool('offline')
+ if self.offline:
+ options['newest'] = 'false'
+ self.newest = options.get_bool('newest')
+ zc.buildout.easy_install.prefer_final(
+ options.get_bool('prefer-final'))
+ self.accept_buildout_test_releases = options.get_bool(
+ 'accept-buildout-test-releases')
+ zc.buildout.easy_install.use_dependency_links(
+ options.get_bool('use-dependency-links'))
+ zc.buildout.easy_install.allow_picked_versions(
+ options.get_bool('allow-picked-versions'))
+ zc.buildout.easy_install.install_from_cache(
+ options.get_bool('install-from-cache'))
+ zc.buildout.easy_install.always_unzip(options.get_bool('unzip'))
+ allowed_eggs = tuple(name.strip() for name in options[
+ 'allowed-eggs-from-site-packages'].split('\n'))
+ self.include_site_packages = options.get_bool('include-site-packages')
+ self.exec_sitecustomize = options.get_bool('exec-sitecustomize')
+ if (_sys_executable_has_broken_dash_S and
+ (not self.include_site_packages or allowed_eggs != ('*',))):
+ # We can't do this if the executable has a broken -S.
+ warnings.warn(zc.buildout.easy_install.BROKEN_DASH_S_WARNING)
+ self.include_site_packages = True
+ zc.buildout.easy_install.allowed_eggs_from_site_packages(allowed_eggs)
+ zc.buildout.easy_install.include_site_packages(
+ self.include_site_packages)
+
+ download_cache = options.get('download-cache')
+ if download_cache:
+ download_cache = os.path.join(options['directory'], download_cache)
+ if not os.path.isdir(download_cache):
+ raise zc.buildout.UserError(
+ 'The specified download cache:\n'
+ '%r\n'
+ "Doesn't exist.\n"
+ % download_cache)
+ download_cache = os.path.join(download_cache, 'dist')
+ if not os.path.isdir(download_cache):
+ os.mkdir(download_cache)
+
+ zc.buildout.easy_install.download_cache(download_cache)
+
+ # "Use" each of the defaults so they aren't reported as unused options.
+ for name in _buildout_default_options:
+ options[name]
+
+ # Do the same for extends-cache which is not among the defaults but
+ # wasn't recognized as having been used since it was used before
+ # tracking was turned on.
+ options.get('extends-cache')
+
+ os.chdir(options['directory'])
+
+ def _buildout_path(self, name):
+ if '${' in name:
+ return name
+ return os.path.join(self._buildout_dir, name)
+
+ def bootstrap(self, args):
+ __doing__ = 'Bootstrapping.'
+
+ self._setup_directories()
+
+ options = self['buildout']
+
+ # Get a base working set for our distributions that corresponds to the
+ # stated desires in the configuration.
+ distributions = ['setuptools', 'zc.buildout']
+ if options.get('offline') == 'true':
+ ws = zc.buildout.easy_install.working_set(
+ distributions, options['executable'],
+ [options['develop-eggs-directory'],
+ options['eggs-directory']],
+ prefer_final=not self.accept_buildout_test_releases,
+ )
+ else:
+ ws = zc.buildout.easy_install.install(
+ distributions, options['eggs-directory'],
+ links=self._links,
+ index=options.get('index'),
+ executable=options['executable'],
+ path=[options['develop-eggs-directory']],
+ newest=self.newest,
+ allow_hosts=self._allow_hosts,
+ prefer_final=not self.accept_buildout_test_releases,
+ )
+
+ # Now copy buildout and setuptools eggs, and record destination eggs:
+ entries = []
+ for name in 'setuptools', 'zc.buildout':
+ r = pkg_resources.Requirement.parse(name)
+ dist = ws.find(r)
+ if dist.precedence == pkg_resources.DEVELOP_DIST:
+ dest = os.path.join(self['buildout']['develop-eggs-directory'],
+ name+'.egg-link')
+ open(dest, 'w').write(dist.location)
+ entries.append(dist.location)
+ else:
+ dest = os.path.join(self['buildout']['eggs-directory'],
+ os.path.basename(dist.location))
+ entries.append(dest)
+ if not os.path.exists(dest):
+ if os.path.isdir(dist.location):
+ shutil.copytree(dist.location, dest)
+ else:
+ shutil.copy2(dist.location, dest)
+
+ # Create buildout script.
+ # Ideally the (possibly) new version of buildout would get a
+ # chance to write the script. Not sure how to do that.
+ ws = pkg_resources.WorkingSet(entries)
+ ws.require('zc.buildout')
+ partsdir = os.path.join(options['parts-directory'], 'buildout')
+ if not os.path.exists(partsdir):
+ os.mkdir(partsdir)
+ # (Honor the relative-paths option.)
+ relative_paths = options.get('relative-paths', 'false')
+ if relative_paths == 'true':
+ relative_paths = options['directory']
+ else:
+ assert relative_paths == 'false'
+ relative_paths = ''
+ if (self.accept_buildout_test_releases and
+ self._annotated['buildout']['accept-buildout-test-releases'][1] ==
+ 'COMMAND_LINE_VALUE'):
+ # Bootstrap was called with '--accept-buildout-test-releases'.
+ # Continue to honor that setting.
+ script_initialization = _early_release_initialization_code
+ else:
+ script_initialization = ''
+ zc.buildout.easy_install.sitepackage_safe_scripts(
+ options['bin-directory'], ws, options['executable'], partsdir,
+ reqs=['zc.buildout'], relative_paths=relative_paths,
+ include_site_packages=self.include_site_packages,
+ script_initialization=script_initialization,
+ exec_sitecustomize=self.exec_sitecustomize,
+ )
+
+ init = bootstrap
+
+ def install(self, install_args):
+ __doing__ = 'Installing.'
+
+ self._load_extensions()
+ self._setup_directories()
+
+ # Add develop-eggs directory to path so that it gets searched
+ # for eggs:
+ sys.path.insert(0, self['buildout']['develop-eggs-directory'])
+
+ # Check for updates. This could cause the process to be restarted.
+ self._maybe_upgrade()
+
+ # load installed data
+ (installed_part_options, installed_exists
+ )= self._read_installed_part_options()
+
+ # Remove old develop eggs
+ self._uninstall(
+ installed_part_options['buildout'].get(
+ 'installed_develop_eggs', '')
+ )
+
+ # Build develop eggs
+ installed_develop_eggs = self._develop()
+ installed_part_options['buildout']['installed_develop_eggs'
+ ] = installed_develop_eggs
+
+ if installed_exists:
+ self._update_installed(
+ installed_develop_eggs=installed_develop_eggs)
+
+ # get configured and installed part lists
+ conf_parts = self['buildout']['parts']
+ conf_parts = conf_parts and conf_parts.split() or []
+ installed_parts = installed_part_options['buildout']['parts']
+ installed_parts = installed_parts and installed_parts.split() or []
+
+ if install_args:
+ install_parts = install_args
+ uninstall_missing = False
+ else:
+ install_parts = conf_parts
+ uninstall_missing = True
+
+ # load and initialize recipes
+ [self[part]['recipe'] for part in install_parts]
+ if not install_args:
+ install_parts = self._parts
+
+ if self._log_level < logging.DEBUG:
+ sections = list(self)
+ sections.sort()
+ print
+ print 'Configuration data:'
+ for section in self._data:
+ _save_options(section, self[section], sys.stdout)
+ print
+
+
+ # compute new part recipe signatures
+ self._compute_part_signatures(install_parts)
+
+ # uninstall parts that are no-longer used or whose configs
+ # have changed
+ for part in reversed(installed_parts):
+ if part in install_parts:
+ old_options = installed_part_options[part].copy()
+ installed_files = old_options.pop('__buildout_installed__')
+ new_options = self.get(part)
+ if old_options == new_options:
+ # The options are the same, but are all of the
+ # installed files still there? If not, we should
+ # reinstall.
+ if not installed_files:
+ continue
+ for f in installed_files.split('\n'):
+ if not os.path.exists(self._buildout_path(f)):
+ break
+ else:
+ continue
+
+ # output debugging info
+ if self._logger.getEffectiveLevel() < logging.DEBUG:
+ for k in old_options:
+ if k not in new_options:
+ self._logger.debug("Part %s, dropped option %s.",
+ part, k)
+ elif old_options[k] != new_options[k]:
+ self._logger.debug(
+ "Part %s, option %s changed:\n%r != %r",
+ part, k, new_options[k], old_options[k],
+ )
+ for k in new_options:
+ if k not in old_options:
+ self._logger.debug("Part %s, new option %s.",
+ part, k)
+
+ elif not uninstall_missing:
+ continue
+
+ self._uninstall_part(part, installed_part_options)
+ installed_parts = [p for p in installed_parts if p != part]
+
+ if installed_exists:
+ self._update_installed(parts=' '.join(installed_parts))
+
+ # Check for unused buildout options:
+ _check_for_unused_options_in_section(self, 'buildout')
+
+ # install new parts
+ for part in install_parts:
+ signature = self[part].pop('__buildout_signature__')
+ saved_options = self[part].copy()
+ recipe = self[part].recipe
+ if part in installed_parts: # update
+ need_to_save_installed = False
+ __doing__ = 'Updating %s.', part
+ self._logger.info(*__doing__)
+ old_options = installed_part_options[part]
+ old_installed_files = old_options['__buildout_installed__']
+
+ try:
+ update = recipe.update
+ except AttributeError:
+ update = recipe.install
+ self._logger.warning(
+ "The recipe for %s doesn't define an update "
+ "method. Using its install method.",
+ part)
+
+ try:
+ installed_files = self[part]._call(update)
+ except:
+ installed_parts.remove(part)
+ self._uninstall(old_installed_files)
+ if installed_exists:
+ self._update_installed(
+ parts=' '.join(installed_parts))
+ raise
+
+ old_installed_files = old_installed_files.split('\n')
+ if installed_files is None:
+ installed_files = old_installed_files
+ else:
+ if isinstance(installed_files, str):
+ installed_files = [installed_files]
+ else:
+ installed_files = list(installed_files)
+
+ need_to_save_installed = [
+ p for p in installed_files
+ if p not in old_installed_files]
+
+ if need_to_save_installed:
+ installed_files = (old_installed_files
+ + need_to_save_installed)
+
+ else: # install
+ need_to_save_installed = True
+ __doing__ = 'Installing %s.', part
+ self._logger.info(*__doing__)
+ installed_files = self[part]._call(recipe.install)
+ if installed_files is None:
+ self._logger.warning(
+ "The %s install returned None. A path or "
+ "iterable of paths should be returned.",
+ part)
+ installed_files = ()
+ elif isinstance(installed_files, str):
+ installed_files = [installed_files]
+ else:
+ installed_files = list(installed_files)
+
+ installed_part_options[part] = saved_options
+ saved_options['__buildout_installed__'
+ ] = '\n'.join(installed_files)
+ saved_options['__buildout_signature__'] = signature
+
+ installed_parts = [p for p in installed_parts if p != part]
+ installed_parts.append(part)
+ _check_for_unused_options_in_section(self, part)
+
+ if need_to_save_installed:
+ installed_part_options['buildout']['parts'] = (
+ ' '.join(installed_parts))
+ self._save_installed_options(installed_part_options)
+ installed_exists = True
+ else:
+ assert installed_exists
+ self._update_installed(parts=' '.join(installed_parts))
+
+ if installed_develop_eggs:
+ if not installed_exists:
+ self._save_installed_options(installed_part_options)
+ elif (not installed_parts) and installed_exists:
+ os.remove(self['buildout']['installed'])
+
+ self._unload_extensions()
+
+ def _update_installed(self, **buildout_options):
+ installed = self['buildout']['installed']
+ f = open(installed, 'a')
+ f.write('\n[buildout]\n')
+ for option, value in buildout_options.items():
+ _save_option(option, value, f)
+ f.close()
+
+ def _uninstall_part(self, part, installed_part_options):
+ # uninstall part
+ __doing__ = 'Uninstalling %s.', part
+ self._logger.info(*__doing__)
+
+ # run uninstall recipe
+ recipe, entry = _recipe(installed_part_options[part])
+ try:
+ uninstaller = _install_and_load(
+ recipe, 'zc.buildout.uninstall', entry, self)
+ self._logger.info('Running uninstall recipe.')
+ uninstaller(part, installed_part_options[part])
+ except (ImportError, pkg_resources.DistributionNotFound), v:
+ pass
+
+ # remove created files and directories
+ self._uninstall(
+ installed_part_options[part]['__buildout_installed__'])
+
+ def _setup_directories(self):
+ __doing__ = 'Setting up buildout directories'
+
+ # Create buildout directories
+ for name in ('bin', 'parts', 'eggs', 'develop-eggs'):
+ d = self['buildout'][name+'-directory']
+ if not os.path.exists(d):
+ self._logger.info('Creating directory %r.', d)
+ os.mkdir(d)
+
+ def _develop(self):
+ """Install sources by running setup.py develop on them
+ """
+ __doing__ = 'Processing directories listed in the develop option'
+
+ develop = self['buildout'].get('develop')
+ if not develop:
+ return ''
+
+ dest = self['buildout']['develop-eggs-directory']
+ old_files = os.listdir(dest)
+
+ env = dict(os.environ, PYTHONPATH=pkg_resources_loc)
+ here = os.getcwd()
+ try:
+ try:
+ for setup in develop.split():
+ setup = self._buildout_path(setup)
+ files = glob.glob(setup)
+ if not files:
+ self._logger.warn("Couldn't develop %r (not found)",
+ setup)
+ else:
+ files.sort()
+ for setup in files:
+ self._logger.info("Develop: %r", setup)
+ __doing__ = 'Processing develop directory %r.', setup
+ zc.buildout.easy_install.develop(setup, dest)
+ except:
+ # if we had an error, we need to roll back changes, by
+ # removing any files we created.
+ self._sanity_check_develop_eggs_files(dest, old_files)
+ self._uninstall('\n'.join(
+ [os.path.join(dest, f)
+ for f in os.listdir(dest)
+ if f not in old_files
+ ]))
+ raise
+
+ else:
+ self._sanity_check_develop_eggs_files(dest, old_files)
+ return '\n'.join([os.path.join(dest, f)
+ for f in os.listdir(dest)
+ if f not in old_files
+ ])
+
+ finally:
+ os.chdir(here)
+
+
+ def _sanity_check_develop_eggs_files(self, dest, old_files):
+ for f in os.listdir(dest):
+ if f in old_files:
+ continue
+ if not (os.path.isfile(os.path.join(dest, f))
+ and f.endswith('.egg-link')):
+ self._logger.warning(
+ "Unexpected entry, %r, in develop-eggs directory.", f)
+
+ def _compute_part_signatures(self, parts):
+ # Compute recipe signature and add to options
+ for part in parts:
+ options = self.get(part)
+ if options is None:
+ options = self[part] = {}
+ recipe, entry = _recipe(options)
+ req = pkg_resources.Requirement.parse(recipe)
+ sig = _dists_sig(pkg_resources.working_set.resolve([req]))
+ options['__buildout_signature__'] = ' '.join(sig)
+
+ def _read_installed_part_options(self):
+ old = self['buildout']['installed']
+ if old and os.path.isfile(old):
+ parser = ConfigParser.RawConfigParser()
+ parser.optionxform = lambda s: s
+ parser.read(old)
+ result = {}
+ for section in parser.sections():
+ options = {}
+ for option, value in parser.items(section):
+ if '%(' in value:
+ for k, v in _spacey_defaults:
+ value = value.replace(k, v)
+ options[option] = value
+ result[section] = Options(self, section, options)
+
+ return result, True
+ else:
+ return ({'buildout': Options(self, 'buildout', {'parts': ''})},
+ False,
+ )
+
+ def _uninstall(self, installed):
+ for f in installed.split('\n'):
+ if not f:
+ continue
+ f = self._buildout_path(f)
+ if os.path.isdir(f):
+ rmtree(f)
+ elif os.path.isfile(f):
+ try:
+ os.remove(f)
+ except OSError:
+ if not (
+ sys.platform == 'win32' and
+ (realpath(os.path.join(os.path.dirname(sys.argv[0]),
+ 'buildout.exe'))
+ ==
+ realpath(f)
+ )
+ # Sigh. This is the exectable used to run the buildout
+ # and, of course, it's in use. Leave it.
+ ):
+ raise
+
+ def _install(self, part):
+ options = self[part]
+ recipe, entry = _recipe(options)
+ recipe_class = pkg_resources.load_entry_point(
+ recipe, 'zc.buildout', entry)
+ installed = recipe_class(self, part, options).install()
+ if installed is None:
+ installed = []
+ elif isinstance(installed, basestring):
+ installed = [installed]
+ base = self._buildout_path('')
+ installed = [d.startswith(base) and d[len(base):] or d
+ for d in installed]
+ return ' '.join(installed)
+
+
+ def _save_installed_options(self, installed_options):
+ installed = self['buildout']['installed']
+ if not installed:
+ return
+ f = open(installed, 'w')
+ _save_options('buildout', installed_options['buildout'], f)
+ for part in installed_options['buildout']['parts'].split():
+ print >>f
+ _save_options(part, installed_options[part], f)
+ f.close()
+
+ def _error(self, message, *args):
+ raise zc.buildout.UserError(message % args)
+
+ def _setup_logging(self):
+ root_logger = logging.getLogger()
+ self._logger = logging.getLogger('zc.buildout')
+ handler = logging.StreamHandler(sys.stdout)
+ log_format = self['buildout']['log-format']
+ if not log_format:
+ # No format specified. Use different formatter for buildout
+ # and other modules, showing logger name except for buildout
+ log_format = '%(name)s: %(message)s'
+ buildout_handler = logging.StreamHandler(sys.stdout)
+ buildout_handler.setFormatter(logging.Formatter('%(message)s'))
+ self._logger.propagate = False
+ self._logger.addHandler(buildout_handler)
+
+ handler.setFormatter(logging.Formatter(log_format))
+ root_logger.addHandler(handler)
+
+ level = self['buildout']['log-level']
+ if level in ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'):
+ level = getattr(logging, level)
+ else:
+ try:
+ level = int(level)
+ except ValueError:
+ self._error("Invalid logging level %s", level)
+ verbosity = self['buildout'].get('verbosity', 0)
+ try:
+ verbosity = int(verbosity)
+ except ValueError:
+ self._error("Invalid verbosity %s", verbosity)
+
+ level -= verbosity
+ root_logger.setLevel(level)
+ self._log_level = level
+
+ def _maybe_upgrade(self):
+ # See if buildout or setuptools need to be upgraded.
+ # If they do, do the upgrade and restart the buildout process.
+ __doing__ = 'Checking for upgrades.'
+
+ if not self.newest:
+ return
+
+ options = self['buildout']
+
+ specs = ['zc.buildout']
+ if zc.buildout.easy_install.is_distribute:
+ specs.append('distribute')
+ else:
+ specs.append('setuptools')
+ ws = zc.buildout.easy_install.install(
+ [
+ (spec + ' ' + options.get(spec+'-version', '')).strip()
+ for spec in specs
+ ],
+ options['eggs-directory'],
+ links = options.get('find-links', '').split(),
+ index = options.get('index'),
+ path = [options['develop-eggs-directory']],
+ allow_hosts = self._allow_hosts,
+ prefer_final=not self.accept_buildout_test_releases,
+ )
+
+ upgraded = []
+ for project in 'zc.buildout', 'setuptools':
+ req = pkg_resources.Requirement.parse(project)
+ project_location = pkg_resources.working_set.find(req).location
+ if ws.find(req).location != project_location:
+ upgraded.append(ws.find(req))
+
+ if not upgraded:
+ return
+
+ __doing__ = 'Upgrading.'
+
+ should_run = realpath(
+ os.path.join(os.path.abspath(options['bin-directory']),
+ 'buildout')
+ )
+ if sys.platform == 'win32':
+ should_run += '-script.py'
+
+ if (realpath(os.path.abspath(sys.argv[0])) != should_run):
+ self._logger.debug("Running %r.", realpath(sys.argv[0]))
+ self._logger.debug("Local buildout is %r.", should_run)
+ self._logger.warn("Not upgrading because not running a local "
+ "buildout command.")
+ return
+
+ if sys.platform == 'win32' and not self.__windows_restart:
+ args = map(zc.buildout.easy_install._safe_arg, sys.argv)
+ args.insert(1, '-W')
+ if not __debug__:
+ args.insert(0, '-O')
+ args.insert(0, zc.buildout.easy_install._safe_arg (sys.executable))
+ os.execv(sys.executable, args)
+
+ self._logger.info("Upgraded:\n %s;\nrestarting.",
+ ",\n ".join([("%s version %s"
+ % (dist.project_name, dist.version)
+ )
+ for dist in upgraded
+ ]
+ ),
+ )
+
+ # the new dist is different, so we've upgraded.
+ # Update the scripts and return True
+ # Ideally the new version of buildout would get a chance to write the
+ # script. Not sure how to do that.
+ partsdir = os.path.join(options['parts-directory'], 'buildout')
+ if os.path.exists(partsdir):
+ # This is primarily for unit tests, in which .py files change too
+ # fast for Python to know to regenerate the .pyc/.pyo files.
+ shutil.rmtree(partsdir)
+ os.mkdir(partsdir)
+ if (self.accept_buildout_test_releases and
+ self._annotated['buildout']['accept-buildout-test-releases'][1] ==
+ 'COMMAND_LINE_VALUE'):
+ # Bootstrap was called with '--accept-buildout-test-releases'.
+ # Continue to honor that setting.
+ script_initialization = _early_release_initialization_code
+ else:
+ script_initialization = ''
+ # (Honor the relative-paths option.)
+ relative_paths = options.get('relative-paths', 'false')
+ if relative_paths == 'true':
+ relative_paths = options['directory']
+ else:
+ assert relative_paths == 'false'
+ relative_paths = ''
+ zc.buildout.easy_install.sitepackage_safe_scripts(
+ options['bin-directory'], ws, options['executable'], partsdir,
+ reqs=['zc.buildout'], relative_paths=relative_paths,
+ include_site_packages=self.include_site_packages,
+ script_initialization=script_initialization,
+ exec_sitecustomize=self.exec_sitecustomize,
+ )
+
+ # Restart
+ args = map(zc.buildout.easy_install._safe_arg, sys.argv)
+ if not __debug__:
+ args.insert(0, '-O')
+ args.insert(0, zc.buildout.easy_install._safe_arg(sys.executable))
+ # We want to make sure that our new site.py is used for rerunning
+ # buildout, so we put the partsdir in PYTHONPATH for our restart.
+ # This overrides any set PYTHONPATH, but since we generally are
+ # trying to run with a completely "clean" python (only the standard
+ # library) then that should be fine.
+ env = os.environ.copy()
+ env['PYTHONPATH'] = partsdir
+ if is_jython:
+ sys.exit(
+ subprocess.Popen(
+ [sys.executable] + list(args), env=env).wait())
+ else:
+ sys.exit(os.spawnve(os.P_WAIT, sys.executable, args, env))
+
+ def _load_extensions(self):
+ __doing__ = 'Loading extensions.'
+ specs = self['buildout'].get('extensions', '').split()
+ if specs:
+ path = [self['buildout']['develop-eggs-directory']]
+ if self.offline:
+ dest = None
+ path.append(self['buildout']['eggs-directory'])
+ else:
+ dest = self['buildout']['eggs-directory']
+ if not os.path.exists(dest):
+ self._logger.info('Creating directory %r.', dest)
+ os.mkdir(dest)
+
+ zc.buildout.easy_install.install(
+ specs, dest, path=path,
+ working_set=pkg_resources.working_set,
+ links = self['buildout'].get('find-links', '').split(),
+ index = self['buildout'].get('index'),
+ newest=self.newest, allow_hosts=self._allow_hosts,
+ prefer_final=not self.accept_buildout_test_releases)
+
+ # Clear cache because extensions might now let us read pages we
+ # couldn't read before.
+ zc.buildout.easy_install.clear_index_cache()
+
+ for ep in pkg_resources.iter_entry_points('zc.buildout.extension'):
+ ep.load()(self)
+
+ def _unload_extensions(self):
+ __doing__ = 'Unloading extensions.'
+ specs = self['buildout'].get('extensions', '').split()
+ if specs:
+ for ep in pkg_resources.iter_entry_points(
+ 'zc.buildout.unloadextension'):
+ ep.load()(self)
+
+ def setup(self, args):
+ if not args:
+ raise zc.buildout.UserError(
+ "The setup command requires the path to a setup script or \n"
+ "directory containing a setup script, and its arguments."
+ )
+ setup = args.pop(0)
+ if os.path.isdir(setup):
+ setup = os.path.join(setup, 'setup.py')
+
+ self._logger.info("Running setup script %r.", setup)
+ setup = os.path.abspath(setup)
+
+ fd, tsetup = tempfile.mkstemp()
+ exe = zc.buildout.easy_install._safe_arg(sys.executable)
+ try:
+ os.write(fd, zc.buildout.easy_install.runsetup_template % dict(
+ setuptools=pkg_resources_loc,
+ setupdir=os.path.dirname(setup),
+ setup=setup,
+ __file__ = setup,
+ ))
+ if is_jython:
+ arg_list = list()
+
+ for a in args:
+ arg_list.append(zc.buildout.easy_install._safe_arg(a))
+
+ subprocess.Popen([exe] + list(tsetup) + arg_list).wait()
+
+ else:
+ os.spawnl(os.P_WAIT, sys.executable, exe, tsetup,
+ *[zc.buildout.easy_install._safe_arg(a)
+ for a in args])
+ finally:
+ os.close(fd)
+ os.remove(tsetup)
+
+ runsetup = setup # backward compat.
+
+ def annotate(self, args):
+ _print_annotate(self._annotated)
+
+ def __getitem__(self, section):
+ __doing__ = 'Getting section %s.', section
+ try:
+ return self._data[section]
+ except KeyError:
+ pass
+
+ try:
+ data = self._raw[section]
+ except KeyError:
+ raise MissingSection(section)
+
+ options = Options(self, section, data)
+ self._data[section] = options
+ options._initialize()
+ return options
+
+ def __setitem__(self, key, value):
+ raise NotImplementedError('__setitem__')
+
+ def __delitem__(self, key):
+ raise NotImplementedError('__delitem__')
+
+ def keys(self):
+ return self._raw.keys()
+
+ def __iter__(self):
+ return iter(self._raw)
+
+
+def _install_and_load(spec, group, entry, buildout):
+ __doing__ = 'Loading recipe %r.', spec
+ try:
+ req = pkg_resources.Requirement.parse(spec)
+
+ buildout_options = buildout['buildout']
+ if pkg_resources.working_set.find(req) is None:
+ __doing__ = 'Installing recipe %s.', spec
+ if buildout.offline:
+ dest = None
+ path = [buildout_options['develop-eggs-directory'],
+ buildout_options['eggs-directory'],
+ ]
+ else:
+ dest = buildout_options['eggs-directory']
+ path = [buildout_options['develop-eggs-directory']]
+
+ zc.buildout.easy_install.install(
+ [spec], dest,
+ links=buildout._links,
+ index=buildout_options.get('index'),
+ path=path,
+ working_set=pkg_resources.working_set,
+ newest=buildout.newest,
+ allow_hosts=buildout._allow_hosts,
+ prefer_final=not buildout.accept_buildout_test_releases)
+
+ __doing__ = 'Loading %s recipe entry %s:%s.', group, spec, entry
+ return pkg_resources.load_entry_point(
+ req.project_name, group, entry)
+
+ except Exception, v:
+ buildout._logger.log(
+ 1,
+ "Could't load %s entry point %s\nfrom %s:\n%s.",
+ group, entry, spec, v)
+ raise
+
+
+class Options(UserDict.DictMixin):
+
+ def __init__(self, buildout, section, data):
+ self.buildout = buildout
+ self.name = section
+ self._raw = data
+ self._cooked = {}
+ self._data = {}
+
+ def _initialize(self):
+ name = self.name
+ __doing__ = 'Initializing section %s.', name
+
+ if '<' in self._raw:
+ self._raw = self._do_extend_raw(name, self._raw, [])
+
+ # force substitutions
+ for k, v in self._raw.items():
+ if '${' in v:
+ self._dosub(k, v)
+
+ if self.name == 'buildout':
+ return # buildout section can never be a part
+
+ recipe = self.get('recipe')
+ if not recipe:
+ return
+
+ reqs, entry = _recipe(self._data)
+ buildout = self.buildout
+ recipe_class = _install_and_load(reqs, 'zc.buildout', entry, buildout)
+
+ __doing__ = 'Initializing part %s.', name
+ self.recipe = recipe_class(buildout, name, self)
+ buildout._parts.append(name)
+
+ def _do_extend_raw(self, name, data, doing):
+ if name == 'buildout':
+ return data
+ if name in doing:
+ raise zc.buildout.UserError("Infinite extending loop %r" % name)
+ doing.append(name)
+ try:
+ to_do = data.pop('<', None)
+ if to_do is None:
+ return data
+ __doing__ = 'Loading input sections for %r', name
+
+ result = {}
+ for iname in to_do.split('\n'):
+ iname = iname.strip()
+ if not iname:
+ continue
+ raw = self.buildout._raw.get(iname)
+ if raw is None:
+ raise zc.buildout.UserError("No section named %r" % iname)
+ result.update(self._do_extend_raw(iname, raw, doing))
+
+ result.update(data)
+ return result
+ finally:
+ assert doing.pop() == name
+
+ def _dosub(self, option, v):
+ __doing__ = 'Getting option %s:%s.', self.name, option
+ seen = [(self.name, option)]
+ v = '$$'.join([self._sub(s, seen) for s in v.split('$$')])
+ self._cooked[option] = v
+
+ def get(self, option, default=None, seen=None):
+ try:
+ return self._data[option]
+ except KeyError:
+ pass
+
+ v = self._cooked.get(option)
+ if v is None:
+ v = self._raw.get(option)
+ if v is None:
+ return default
+
+ __doing__ = 'Getting option %s:%s.', self.name, option
+
+ if '${' in v:
+ key = self.name, option
+ if seen is None:
+ seen = [key]
+ elif key in seen:
+ raise zc.buildout.UserError(
+ "Circular reference in substitutions.\n"
+ )
+ else:
+ seen.append(key)
+ v = '$$'.join([self._sub(s, seen) for s in v.split('$$')])
+ seen.pop()
+
+ self._data[option] = v
+ return v
+
+ _template_split = re.compile('([$]{[^}]*})').split
+ _simple = re.compile('[-a-zA-Z0-9 ._]+$').match
+ _valid = re.compile('\${[-a-zA-Z0-9 ._]*:[-a-zA-Z0-9 ._]+}$').match
+ def _sub(self, template, seen):
+ value = self._template_split(template)
+ subs = []
+ for ref in value[1::2]:
+ s = tuple(ref[2:-1].split(':'))
+ if not self._valid(ref):
+ if len(s) < 2:
+ raise zc.buildout.UserError("The substitution, %s,\n"
+ "doesn't contain a colon."
+ % ref)
+ if len(s) > 2:
+ raise zc.buildout.UserError("The substitution, %s,\n"
+ "has too many colons."
+ % ref)
+ if not self._simple(s[0]):
+ raise zc.buildout.UserError(
+ "The section name in substitution, %s,\n"
+ "has invalid characters."
+ % ref)
+ if not self._simple(s[1]):
+ raise zc.buildout.UserError(
+ "The option name in substitution, %s,\n"
+ "has invalid characters."
+ % ref)
+
+ section, option = s
+ if not section:
+ section = self.name
+ v = self.buildout[section].get(option, None, seen)
+ if v is None:
+ if option == '_buildout_section_name_':
+ v = self.name
+ else:
+ raise MissingOption("Referenced option does not exist:",
+ section, option)
+ subs.append(v)
+ subs.append('')
+
+ return ''.join([''.join(v) for v in zip(value[::2], subs)])
+
+ def __getitem__(self, key):
+ try:
+ return self._data[key]
+ except KeyError:
+ pass
+
+ v = self.get(key)
+ if v is None:
+ raise MissingOption("Missing option: %s:%s" % (self.name, key))
+ return v
+
+ def __setitem__(self, option, value):
+ if not isinstance(value, str):
+ raise TypeError('Option values must be strings', value)
+ self._data[option] = value
+
+ def __delitem__(self, key):
+ if key in self._raw:
+ del self._raw[key]
+ if key in self._data:
+ del self._data[key]
+ if key in self._cooked:
+ del self._cooked[key]
+ elif key in self._data:
+ del self._data[key]
+ else:
+ raise KeyError, key
+
+ def keys(self):
+ raw = self._raw
+ return list(self._raw) + [k for k in self._data if k not in raw]
+
+ def copy(self):
+ result = self._raw.copy()
+ result.update(self._cooked)
+ result.update(self._data)
+ return result
+
+ def _call(self, f):
+ buildout_directory = self.buildout['buildout']['directory']
+ self._created = []
+ try:
+ try:
+ os.chdir(buildout_directory)
+ return f()
+ except:
+ for p in self._created:
+ if os.path.isdir(p):
+ rmtree(p)
+ elif os.path.isfile(p):
+ os.remove(p)
+ else:
+ self.buildout._logger.warn("Couldn't clean up %r.", p)
+ raise
+ finally:
+ self._created = None
+ os.chdir(buildout_directory)
+
+ def created(self, *paths):
+ try:
+ self._created.extend(paths)
+ except AttributeError:
+ raise TypeError(
+ "Attempt to register a created path while not installing",
+ self.name)
+ return self._created
+
+ def query_bool(self, name, default=None):
+ """Given a name, return a boolean value for that name.
+
+ ``default``, if given, should be 'true', 'false', or None.
+ """
+ if default is not None:
+ value = self.setdefault(name, default=default)
+ else:
+ value = self.get(name)
+ if value is None:
+ return value
+ return _convert_bool(name, value)
+
+ def get_bool(self, name):
+ """Given a name, return a boolean value for that name.
+ """
+ return _convert_bool(name, self[name])
+
+
+def _convert_bool(name, value):
+ if value not in ('true', 'false'):
+ raise zc.buildout.UserError(
+ 'Invalid value for %s option: %s' % (name, value))
+ else:
+ return value == 'true'
+
+_spacey_nl = re.compile('[ \t\r\f\v]*\n[ \t\r\f\v\n]*'
+ '|'
+ '^[ \t\r\f\v]+'
+ '|'
+ '[ \t\r\f\v]+$'
+ )
+
+_spacey_defaults = [
+ ('%(__buildout_space__)s', ' '),
+ ('%(__buildout_space_n__)s', '\n'),
+ ('%(__buildout_space_r__)s', '\r'),
+ ('%(__buildout_space_f__)s', '\f'),
+ ('%(__buildout_space_v__)s', '\v'),
+ ]
+
+def _quote_spacey_nl(match):
+ match = match.group(0).split('\n', 1)
+ result = '\n\t'.join(
+ [(s
+ .replace(' ', '%(__buildout_space__)s')
+ .replace('\r', '%(__buildout_space_r__)s')
+ .replace('\f', '%(__buildout_space_f__)s')
+ .replace('\v', '%(__buildout_space_v__)s')
+ .replace('\n', '%(__buildout_space_n__)s')
+ )
+ for s in match]
+ )
+ return result
+
+def _save_option(option, value, f):
+ value = _spacey_nl.sub(_quote_spacey_nl, value)
+ if value.startswith('\n\t'):
+ value = '%(__buildout_space_n__)s' + value[2:]
+ if value.endswith('\n\t'):
+ value = value[:-2] + '%(__buildout_space_n__)s'
+ print >>f, option, '=', value
+
+def _save_options(section, options, f):
+ print >>f, '[%s]' % section
+ items = options.items()
+ items.sort()
+ for option, value in items:
+ _save_option(option, value, f)
+
+def _open(base, filename, seen, dl_options, override):
+ """Open a configuration file and return the result as a dictionary,
+
+ Recursively open other files based on buildout options found.
+ """
+ _update_section(dl_options, override)
+ _dl_options = _unannotate_section(dl_options.copy())
+ is_temp = False
+ download = zc.buildout.download.Download(
+ _dl_options, cache=_dl_options.get('extends-cache'), fallback=True,
+ hash_name=True)
+ if _isurl(filename):
+ path, is_temp = download(filename)
+ fp = open(path)
+ base = filename[:filename.rfind('/')]
+ elif _isurl(base):
+ if os.path.isabs(filename):
+ fp = open(filename)
+ base = os.path.dirname(filename)
+ else:
+ filename = base + '/' + filename
+ path, is_temp = download(filename)
+ fp = open(path)
+ base = filename[:filename.rfind('/')]
+ else:
+ filename = os.path.join(base, filename)
+ fp = open(filename)
+ base = os.path.dirname(filename)
+
+ if filename in seen:
+ if is_temp:
+ fp.close()
+ os.remove(path)
+ raise zc.buildout.UserError("Recursive file include", seen, filename)
+
+ root_config_file = not seen
+ seen.append(filename)
+
+ result = {}
+
+ parser = ConfigParser.RawConfigParser()
+ parser.optionxform = lambda s: s
+ parser.readfp(fp)
+ if is_temp:
+ fp.close()
+ os.remove(path)
+
+ extends = extended_by = None
+ for section in parser.sections():
+ options = dict(parser.items(section))
+ if section == 'buildout':
+ extends = options.pop('extends', extends)
+ extended_by = options.pop('extended-by', extended_by)
+ result[section] = options
+
+ result = _annotate(result, filename)
+
+ if root_config_file and 'buildout' in result:
+ dl_options = _update_section(dl_options, result['buildout'])
+
+ if extends:
+ extends = extends.split()
+ eresult = _open(base, extends.pop(0), seen, dl_options, override)
+ for fname in extends:
+ _update(eresult, _open(base, fname, seen, dl_options, override))
+ result = _update(eresult, result)
+
+ if extended_by:
+ self._logger.warn(
+ "The extendedBy option is deprecated. Stop using it."
+ )
+ for fname in extended_by.split():
+ result = _update(result,
+ _open(base, fname, seen, dl_options, override))
+
+ seen.pop()
+ return result
+
+
+ignore_directories = '.svn', 'CVS'
+def _dir_hash(dir):
+ hash = md5()
+ for (dirpath, dirnames, filenames) in os.walk(dir):
+ dirnames[:] = [n for n in dirnames if n not in ignore_directories]
+ filenames[:] = [f for f in filenames
+ if (not (f.endswith('pyc') or f.endswith('pyo'))
+ and os.path.exists(os.path.join(dirpath, f)))
+ ]
+ hash.update(' '.join(dirnames))
+ hash.update(' '.join(filenames))
+ for name in filenames:
+ hash.update(open(os.path.join(dirpath, name)).read())
+ return hash.digest().encode('base64').strip()
+
+def _dists_sig(dists):
+ result = []
+ for dist in dists:
+ location = dist.location
+ if dist.precedence == pkg_resources.DEVELOP_DIST:
+ result.append(dist.project_name + '-' + _dir_hash(location))
+ else:
+ result.append(os.path.basename(location))
+ return result
+
+def _update_section(s1, s2):
+ s2 = s2.copy() # avoid mutating the second argument, which is unexpected
+ for k, v in s2.items():
+ v2, note2 = v
+ if k.endswith('+'):
+ key = k.rstrip(' +')
+ v1, note1 = s1.get(key, ("", ""))
+ newnote = ' [+] '.join((note1, note2)).strip()
+ s2[key] = "\n".join((v1).split('\n') +
+ v2.split('\n')), newnote
+ del s2[k]
+ elif k.endswith('-'):
+ key = k.rstrip(' -')
+ v1, note1 = s1.get(key, ("", ""))
+ newnote = ' [-] '.join((note1, note2)).strip()
+ s2[key] = ("\n".join(
+ [v for v in v1.split('\n')
+ if v not in v2.split('\n')]), newnote)
+ del s2[k]
+
+ s1.update(s2)
+ return s1
+
+def _update(d1, d2):
+ for section in d2:
+ if section in d1:
+ d1[section] = _update_section(d1[section], d2[section])
+ else:
+ d1[section] = d2[section]
+ return d1
+
+def _recipe(options):
+ recipe = options['recipe']
+ if ':' in recipe:
+ recipe, entry = recipe.split(':')
+ else:
+ entry = 'default'
+
+ return recipe, entry
+
+def _doing():
+ _, v, tb = sys.exc_info()
+ message = str(v)
+ doing = []
+ while tb is not None:
+ d = tb.tb_frame.f_locals.get('__doing__')
+ if d:
+ doing.append(d)
+ tb = tb.tb_next
+
+ if doing:
+ sys.stderr.write('While:\n')
+ for d in doing:
+ if not isinstance(d, str):
+ d = d[0] % d[1:]
+ sys.stderr.write(' %s\n' % d)
+
+def _error(*message):
+ sys.stderr.write('Error: ' + ' '.join(message) +'\n')
+ sys.exit(1)
+
+_internal_error_template = """
+An internal error occurred due to a bug in either zc.buildout or in a
+recipe being used:
+"""
+
+def _check_for_unused_options_in_section(buildout, section):
+ options = buildout[section]
+ unused = [option for option in options._raw if option not in options._data]
+ if unused:
+ buildout._logger.warn("Unused options for %s: %s."
+ % (section, ' '.join(map(repr, unused)))
+ )
+
+_early_release_initialization_code = """\
+sys.argv.insert(1, 'buildout:accept-buildout-test-releases=true')
+print ('NOTE: Accepting early releases of build system packages. Rerun '
+ 'bootstrap without --accept-buildout-test-releases (-t) to return to '
+ 'default behavior.')
+"""
+
+_usage = """\
+Usage: buildout [options] [assignments] [command [command arguments]]
+
+Options:
+
+ -h, --help
+
+ Print this message and exit.
+
+ -v
+
+ Increase the level of verbosity. This option can be used multiple times.
+
+ -q
+
+ Decrease the level of verbosity. This option can be used multiple times.
+
+ -c config_file
+
+ Specify the path to the buildout configuration file to be used.
+ This defaults to the file named "buildout.cfg" in the current
+ working directory.
+
+ -t socket_timeout
+
+ Specify the socket timeout in seconds.
+
+ -U
+
+ 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.
+
+ -D
+
+ Debug errors. If an error occurs, then the post-mortem debugger
+ will be started. This is especially useful for debuging recipe
+ problems.
+
+ -s
+
+ Squelch warnings about using an executable with a broken -S
+ implementation.
+
+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,
+use buildout:offline=true.
+
+Options and assignments can be interspersed.
+
+Commands:
+
+ install [parts]
+
+ Install parts. If no command arguments are given, then the parts
+ definition from the configuration file is used. Otherwise, the
+ arguments specify the parts to be installed.
+
+ Note that the semantics differ depending on whether any parts are
+ specified. If parts are specified, then only those parts will be
+ installed. If no parts are specified, then the parts specified by
+ the buildout parts option will be installed along with all of
+ their dependencies.
+
+ bootstrap
+
+ Create a new buildout in the current working directory, copying
+ the buildout and setuptools eggs and, creating a basic directory
+ structure and a buildout-local buildout script.
+
+ init
+
+ Initialize a buildout, creating a buildout.cfg file if it doesn't
+ exist and then performing the same actions as for the buildout
+ command.
+
+ setup script [setup command and options]
+
+ Run a given setup script arranging that setuptools is in the
+ script's path and and that it has been imported so that
+ setuptools-provided commands (like bdist_egg) can be used even if
+ the setup script doesn't import setuptools itself.
+
+ The script can be given either as a script path or a path to a
+ directory containing a setup.py script.
+
+ annotate
+
+ Display annotated sections. All sections are displayed, sorted
+ alphabetically. For each section, all key-value pairs are displayed,
+ sorted alphabetically, along with the origin of the value (file name or
+ COMPUTED_VALUE, DEFAULT_VALUE, COMMAND_LINE_VALUE).
+
+"""
+def _help():
+ print _usage
+ sys.exit(0)
+
+def main(args=None):
+ if args is None:
+ args = sys.argv[1:]
+
+ config_file = 'buildout.cfg'
+ verbosity = 0
+ options = []
+ windows_restart = False
+ user_defaults = True
+ debug = False
+ ignore_broken_dash_s = False
+ while args:
+ if args[0][0] == '-':
+ op = orig_op = args.pop(0)
+ op = op[1:]
+ while op and op[0] in 'vqhWUoOnNDAs':
+ if op[0] == 'v':
+ verbosity += 10
+ elif op[0] == 'q':
+ verbosity -= 10
+ elif op[0] == 'W':
+ windows_restart = True
+ elif op[0] == 'U':
+ 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'))
+ elif op[0] == 'D':
+ debug = True
+ elif op[0] == 's':
+ ignore_broken_dash_s = True
+ else:
+ _help()
+ op = op[1:]
+
+ if op[:1] in ('c', 't'):
+ op_ = op[:1]
+ op = op[1:]
+
+ if op_ == 'c':
+ if op:
+ config_file = op
+ else:
+ if args:
+ config_file = args.pop(0)
+ else:
+ _error("No file name specified for option", orig_op)
+ elif op_ == 't':
+ try:
+ timeout = int(args.pop(0))
+ except IndexError:
+ _error("No timeout value specified for option", orig_op)
+ except ValueError:
+ _error("No timeout value must be numeric", orig_op)
+
+ import socket
+ print 'Setting socket time out to %d seconds' % timeout
+ socket.setdefaulttimeout(timeout)
+
+ elif op:
+ if orig_op == '--help':
+ _help()
+ _error("Invalid option", '-'+op[0])
+ elif '=' in args[0]:
+ option, value = args.pop(0).split('=', 1)
+ if len(option.split(':')) != 2:
+ _error('Invalid option:', option)
+ section, option = option.split(':')
+ options.append((section.strip(), option.strip(), value.strip()))
+ else:
+ # We've run out of command-line options and option assignnemnts
+ # The rest should be commands, so we'll stop here
+ break
+
+ if verbosity < 0 or ignore_broken_dash_s:
+ broken_dash_S_filter_action = 'ignore'
+ elif verbosity == 0: # This is the default.
+ broken_dash_S_filter_action = 'once'
+ else:
+ broken_dash_S_filter_action = 'default'
+ warnings.filterwarnings(
+ broken_dash_S_filter_action,
+ re.escape(
+ zc.buildout.easy_install.BROKEN_DASH_S_WARNING),
+ UserWarning)
+ if verbosity:
+ options.append(('buildout', 'verbosity', str(verbosity)))
+
+ if args:
+ command = args.pop(0)
+ if command not in (
+ 'install', 'bootstrap', 'runsetup', 'setup', 'init',
+ 'annotate',
+ ):
+ _error('invalid command:', command)
+ else:
+ command = 'install'
+
+ try:
+ try:
+ buildout = Buildout(config_file, options,
+ user_defaults, windows_restart, command)
+ getattr(buildout, command)(args)
+ except SystemExit:
+ pass
+ except Exception, v:
+ _doing()
+ exc_info = sys.exc_info()
+ import pdb, traceback
+ if debug:
+ traceback.print_exception(*exc_info)
+ sys.stderr.write('\nStarting pdb:\n')
+ pdb.post_mortem(exc_info[2])
+ else:
+ if isinstance(v, (zc.buildout.UserError,
+ distutils.errors.DistutilsError,
+ )
+ ):
+ _error(str(v))
+ else:
+ sys.stderr.write(_internal_error_template)
+ traceback.print_exception(*exc_info)
+ sys.exit(1)
+
+
+ finally:
+ logging.shutdown()
+
+if sys.version_info[:2] < (2, 4):
+ def reversed(iterable):
+ result = list(iterable);
+ result.reverse()
+ return result