[Checkins] SVN: zc.buildout/branches/gary-2-bootstrap-changes/ change bootstrap to allow a bit more configuration and flexibility
Gary Poster
gary.poster at canonical.com
Thu Sep 24 16:10:31 EDT 2009
Log message for revision 104512:
change bootstrap to allow a bit more configuration and flexibility
Changed:
U zc.buildout/branches/gary-2-bootstrap-changes/bootstrap/bootstrap.py
U zc.buildout/branches/gary-2-bootstrap-changes/src/zc/buildout/bootstrap.txt
-=-
Modified: zc.buildout/branches/gary-2-bootstrap-changes/bootstrap/bootstrap.py
===================================================================
--- zc.buildout/branches/gary-2-bootstrap-changes/bootstrap/bootstrap.py 2009-09-24 20:08:34 UTC (rev 104511)
+++ zc.buildout/branches/gary-2-bootstrap-changes/bootstrap/bootstrap.py 2009-09-24 20:10:30 UTC (rev 104512)
@@ -20,21 +20,108 @@
$Id$
"""
-import os, shutil, sys, tempfile, urllib2
+import os, re, shutil, sys, tempfile, textwrap, urllib, urllib2
-tmpeggs = tempfile.mkdtemp()
+# We have to manually parse our options rather than using one of the stdlib
+# tools because we want to pass the ones we don't recognize along to
+# zc.buildout.buildout.main.
-is_jython = sys.platform.startswith('java')
+configuration = {
+ '--ez_setup-source': 'http://peak.telecommunity.com/dist/ez_setup.py',
+ '--version': '',
+ '--download-base': None,
+ '--eggs': None}
+helpstring = __doc__ + textwrap.dedent('''
+ This script recognizes the following options itself. The first option it
+ encounters that is not one of these will cause the script to stop parsing
+ options and pass the rest on to buildout. Therefore, if you want to use
+ any of the following options *and* buildout command-line options like
+ -c, first use the following options, and then use the buildout options.
+
+ Options:
+ --version=ZC_BUILDOUT_VERSION
+ Specify a version number of the zc.buildout to use
+ --ez_setup-source=URL_OR_FILE
+ Specify a URL or file location for the ez_setup file.
+ Defaults to
+ %(--ez_setup-source)s
+ --download-base=URL_OR_DIRECTORY
+ Specify a URL or directory for downloading setuptools and
+ zc.buildout. Defaults to PyPI.
+ --eggs=DIRECTORY
+ Specify a directory for storing eggs. Defaults to a temporary
+ directory that is deleted when the bootstrap script completes.
+
+ By using --ez_setup-source and --download-base to point to local resources,
+ you can keep this script from going over the network.
+ ''' % configuration)
+match_equals = re.compile(r'(%s)=(.*)' % ('|'.join(configuration),)).match
+args = sys.argv[1:]
+if args == ['--help']:
+ print helpstring
+ sys.exit(0)
+
+# If we end up using a temporary directory for storing our eggs, this will
+# hold the path of that directory. On the other hand, if an explicit directory
+# is specified in the argv, this will remain None.
+tmpeggs = None
+
+while args:
+ val = args[0]
+ if val in configuration:
+ del args[0]
+ if not args or args[0].startswith('-'):
+ print "ERROR: %s requires an argument."
+ print helpstring
+ sys.exit(1)
+ configuration[val] = args[0]
+ else:
+ match = match_equals(val)
+ if match and match.group(1) in configuration:
+ configuration[match.group(1)] = match.group(2)
+ else:
+ break
+ del args[0]
+
+for name in ('--ez_setup-source', '--download-base'):
+ val = configuration[name]
+ if val is not None and '://' not in val: # We're being lazy.
+ configuration[name] = 'file://%s' % (
+ urllib.pathname2url(os.path.abspath(os.path.expanduser(val))),)
+
+if (configuration['--download-base'] and
+ not configuration['--download-base'].endswith('/')):
+ # Download base needs a trailing slash to make the world happy.
+ configuration['--download-base'] += '/'
+
+if not configuration['--eggs']:
+ configuration['--eggs'] = tmpeggs = tempfile.mkdtemp()
+else:
+ configuration['--eggs'] = os.path.abspath(
+ os.path.expanduser(configuration['--eggs']))
+
+# The requirement is what we will pass to setuptools to specify zc.buildout.
+requirement = 'zc.buildout'
+if configuration['--version']:
+ requirement += '==' + configuration['--version']
+
try:
+ import setuptools # A flag. Sometimes pkg_resources is installed alone.
import pkg_resources
except ImportError:
ez = {}
- exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
- ).read() in ez
- ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
-
+ exec urllib2.urlopen(configuration['--ez_setup-source']).read() in ez
+ setuptools_args = dict(to_dir=configuration['--eggs'], download_delay=0)
+ if configuration['--download-base']:
+ setuptools_args['download_base'] = configuration['--download-base']
+ ez['use_setuptools'](**setuptools_args)
import pkg_resources
+ # This does not (always?) update the default working set. We will
+ # do it.
+ for path in sys.path:
+ if path not in pkg_resources.working_set.entries:
+ pkg_resources.working_set.add_entry(path)
if sys.platform == 'win32':
def quote(c):
@@ -45,40 +132,40 @@
else:
def quote (c):
return c
+cmd = [quote(sys.executable),
+ '-c',
+ quote('from setuptools.command.easy_install import main; main()'),
+ '-mqNxd',
+ quote(configuration['--eggs'])]
-cmd = 'from setuptools.command.easy_install import main; main()'
-ws = pkg_resources.working_set
+if configuration['--download-base']:
+ cmd.extend(['-f', quote(configuration['--download-base'])])
-if len(sys.argv) > 2 and sys.argv[1] == '--version':
- VERSION = '==%s' % sys.argv[2]
- args = sys.argv[3:] + ['bootstrap']
-else:
- VERSION = ''
- args = sys.argv[1:] + ['bootstrap']
+cmd.append(requirement)
+ws = pkg_resources.working_set
+env = dict(
+ os.environ,
+ PYTHONPATH=ws.find(pkg_resources.Requirement.parse('setuptools')).location)
+
+is_jython = sys.platform.startswith('java')
if is_jython:
import subprocess
+ exitcode = subprocess.Popen(cmd, env=env).wait()
+else: # Windows needs this, apparently; otherwise we would prefer subprocess
+ exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
+if exitcode != 0:
+ sys.stdout.flush()
+ sys.stderr.flush()
+ print ("An error occured when trying to install zc.buildout. "
+ "Look above this message for any errors that "
+ "were output by easy_install.")
+ sys.exit(exitcode)
- assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd',
- quote(tmpeggs), 'zc.buildout' + VERSION],
- env=dict(os.environ,
- PYTHONPATH=
- ws.find(pkg_resources.Requirement.parse('setuptools')).location
- ),
- ).wait() == 0
-
-else:
- assert os.spawnle(
- os.P_WAIT, sys.executable, quote (sys.executable),
- '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION,
- dict(os.environ,
- PYTHONPATH=
- ws.find(pkg_resources.Requirement.parse('setuptools')).location
- ),
- ) == 0
-
-ws.add_entry(tmpeggs)
-ws.require('zc.buildout' + VERSION)
+ws.add_entry(configuration['--eggs'])
+ws.require(requirement)
import zc.buildout.buildout
+args.append('bootstrap')
zc.buildout.buildout.main(args)
-shutil.rmtree(tmpeggs)
+if tmpeggs is not None:
+ shutil.rmtree(tmpeggs)
Modified: zc.buildout/branches/gary-2-bootstrap-changes/src/zc/buildout/bootstrap.txt
===================================================================
--- zc.buildout/branches/gary-2-bootstrap-changes/src/zc/buildout/bootstrap.txt 2009-09-24 20:08:34 UTC (rev 104511)
+++ zc.buildout/branches/gary-2-bootstrap-changes/src/zc/buildout/bootstrap.txt 2009-09-24 20:10:30 UTC (rev 104512)
@@ -57,7 +57,7 @@
... 'bootstrap.py --version UNKNOWN'); print 'X' # doctest: +ELLIPSIS
...
X
- No local packages or download links found for zc.buildout==UNKNOWN
+ No local packages or download links found for zc.buildout==UNKNOWN...
error: Could not find suitable distribution for Requirement.parse('zc.buildout==UNKNOWN')
...
@@ -120,4 +120,71 @@
zc.buildout.buildout.main()
<BLANKLINE>
+You can specify a location of ez_setup.py, so you can rely on a local or remote
+location. We'll write our own ez_setup.py that we will also use to test some
+other bootstrap options.
+ >>> write('ez_setup.py', '''\
+ ... def use_setuptools(**kwargs):
+ ... import sys, pprint
+ ... pprint.pprint(kwargs, width=40)
+ ... sys.exit()
+ ... ''')
+ >>> print system(
+ ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+ ... 'bootstrap.py --ez_setup-source=./ez_setup.py')
+ ... # doctest: +ELLIPSIS
+ {'download_delay': 0,
+ 'to_dir': '...'}
+ <BLANKLINE>
+
+You can also pass a download-cache, and a place in which eggs should be stored
+(they are normally stored in a temporary directory).
+
+ >>> print system(
+ ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+ ... 'bootstrap.py --ez_setup-source=./ez_setup.py '+
+ ... '--download-base=./download-cache --eggs=eggs')
+ ... # doctest: +ELLIPSIS
+ {'download_base': '/sample/download-cache/',
+ 'download_delay': 0,
+ 'to_dir': '/sample/eggs'}
+ <BLANKLINE>
+
+Here's the entire help text.
+
+ >>> print system(
+ ... zc.buildout.easy_install._safe_arg(sys.executable)+' '+
+ ... 'bootstrap.py --help'),
+ ... # doctest: +ELLIPSIS
+ Bootstrap a buildout-based project
+ <BLANKLINE>
+ Simply run this script in a directory containing a buildout.cfg.
+ The script accepts buildout command-line options, so you can
+ use the -c option to specify an alternate configuration file.
+ <BLANKLINE>
+ ...
+ <BLANKLINE>
+ This script recognizes the following options itself. The first option it
+ encounters that is not one of these will cause the script to stop parsing
+ options and pass the rest on to buildout. Therefore, if you want to use
+ any of the following options *and* buildout command-line options like
+ -c, first use the following options, and then use the buildout options.
+ <BLANKLINE>
+ Options:
+ --version=ZC_BUILDOUT_VERSION
+ Specify a version number of the zc.buildout to use
+ --ez_setup-source=URL_OR_FILE
+ Specify a URL or file location for the ez_setup file.
+ Defaults to
+ http://peak.telecommunity.com/dist/ez_setup.py
+ --download-base=URL_OR_DIRECTORY
+ Specify a URL or directory for downloading setuptools and
+ zc.buildout. Defaults to PyPI.
+ --eggs=DIRECTORY
+ Specify a directory for storing eggs. Defaults to a temporary
+ directory that is deleted when the bootstrap script completes.
+ <BLANKLINE>
+ By using --ez_setup-source and --download-base to point to local resources,
+ you can keep this script from going over the network.
+ <BLANKLINE>
More information about the checkins
mailing list