~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to bootstrap.py

  • Committer: Gary Poster
  • Date: 2009-07-10 04:03:14 UTC
  • mto: (8697.27.2 zbuildout)
  • mto: This revision was merged to the branch mainline in revision 8912.
  • Revision ID: gary.poster@canonical.com-20090710040314-vpn4rg7a9jttbo1n
use experimental eggs for buildout and friends

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
# FOR A PARTICULAR PURPOSE.
12
12
#
13
13
##############################################################################
14
 
 
15
 
# NOTE TO LAUNCHPAD DEVELOPERS: This is a bootstrapping file from the
16
 
# zc.buildout project, which we have hacked slightly: look for the string
17
 
# "HACK" below.   See the docstring below for usage.
18
 
 
19
14
"""Bootstrap a buildout-based project
20
15
 
21
16
Simply run this script in a directory containing a buildout.cfg.
22
17
The script accepts buildout command-line options, so you can
23
18
use the -c option to specify an alternate configuration file.
24
19
 
25
 
$Id$
 
20
$Id: bootstrap.py 101778 2009-07-10 00:55:19Z gary $
26
21
"""
27
22
 
28
 
import os, shutil, sys, tempfile, urllib2
29
 
 
30
 
tmpeggs = tempfile.mkdtemp()
31
 
 
32
 
is_jython = sys.platform.startswith('java')
 
23
import os, re, shutil, sys, tempfile, textwrap, urllib, urllib2
 
24
 
 
25
# We have to manually parse our options rather than using one of the stdlib
 
26
# tools because we want to pass the ones we don't recognize along to
 
27
# zc.buildout.buildout.main.
 
28
 
 
29
configuration = {
 
30
    '--ez_setup-source': 'http://peak.telecommunity.com/dist/ez_setup.py',
 
31
    '--version': '',
 
32
    '--download-base': None,
 
33
    '--eggs': None}
 
34
 
 
35
helpstring = __doc__ + textwrap.dedent('''
 
36
    This script recognizes the following options itself.  The first option it
 
37
    encounters that is not one of these will cause the script to stop parsing
 
38
    options and pass the rest on to buildout.  Therefore, if you want to use
 
39
    any of the following options *and* buildout command-line options like
 
40
    -c, first use the following options, and then use the buildout options.
 
41
 
 
42
    Options: 
 
43
      --version=ZC_BUILDOUT_VERSION
 
44
                Specify a version number of the zc.buildout to use
 
45
      --ez_setup-source=URL_OR_FILE
 
46
                Specify a URL or file location for the ez_setup file.
 
47
                Defaults to
 
48
                %(--ez_setup-source)s
 
49
      --download-base=URL_OR_DIRECTORY
 
50
                Specify a URL or directory for downloading setuptools and
 
51
                zc.buildout.  Defaults to PyPI.
 
52
      --eggs=DIRECTORY
 
53
                Specify a directory for storing eggs.  Defaults to a temporary
 
54
                directory that is deleted when the bootstrap script completes.
 
55
 
 
56
    By using --ez_setup-source and --download-base to point to local resources,
 
57
    you can keep this script from going over the network.
 
58
    ''' % configuration)
 
59
match_equals = re.compile(r'(%s)=(\S*)' % ('|'.join(configuration),)).match
 
60
args = sys.argv[1:]
 
61
if args == ['--help']:
 
62
    print helpstring
 
63
    sys.exit(0)
 
64
 
 
65
# defaults
 
66
tmpeggs = None
 
67
 
 
68
while args:
 
69
    val = args[0]
 
70
    if val in configuration:
 
71
        del args[0]
 
72
        if not args or args[0].startswith('-'):
 
73
            print "ERROR: %s requires an argument."
 
74
            print helpstring
 
75
            sys.exit(1)
 
76
        configuration[val] = args[0]
 
77
    else:
 
78
        match = match_equals(val)
 
79
        if match and match.group(1) in configuration:
 
80
            configuration[match.group(1)] = match.group(2)
 
81
        else:
 
82
            break
 
83
    del args[0]
 
84
 
 
85
for name in ('--ez_setup-source', '--download-base'):
 
86
    val = configuration[name]
 
87
    if val is not None and '://' not in val: # we're being lazy.
 
88
        configuration[name] = 'file://%s' % (
 
89
            urllib.pathname2url(os.path.abspath(os.path.expanduser(val))),)
 
90
 
 
91
if (configuration['--download-base'] and
 
92
    not configuration['--download-base'].endswith('/')):
 
93
    # download base needs a trailing slash to make the world happy
 
94
    configuration['--download-base'] += '/'
 
95
 
 
96
if not configuration['--eggs']:
 
97
    configuration['--eggs'] = tmpeggs = tempfile.mkdtemp()
 
98
else:
 
99
    configuration['--eggs'] = os.path.abspath(
 
100
        os.path.expanduser(configuration['--eggs']))
 
101
 
 
102
if configuration['--version']:
 
103
    configuration['--version'] = '==' + configuration['--version']
33
104
 
34
105
try:
35
106
    import pkg_resources
36
107
except ImportError:
37
108
    ez = {}
38
 
    # HACK: the next two logical lines have been hacked for Launchpad to make
39
 
    # bootstrapping not get any files over the network.  This is useful for
40
 
    # development because it speeds up the build and makes it possible to
41
 
    # make a new branch when you don't have network access.  It is essential
42
 
    # for deployment because we currently do not allow network access on PQM
43
 
    # or our deployment boxes.
44
 
    exec open('ez_setup.py').read() in ez
45
 
    ez['use_setuptools'](
46
 
        to_dir=tmpeggs,
47
 
        download_base='file://%s/download-cache/dist/' % (os.getcwd(),),
48
 
        download_delay=0)
 
109
    exec urllib2.urlopen(configuration['--ez_setup-source']).read() in ez
 
110
    setuptools_args = dict(to_dir=configuration['--eggs'], download_delay=0)
 
111
    if configuration['--download-base']:
 
112
        setuptools_args['download_base'] = configuration['--download-base']
 
113
    ez['use_setuptools'](**setuptools_args)
49
114
 
50
115
    import pkg_resources
51
116
 
58
123
else:
59
124
    def quote (c):
60
125
        return c
61
 
 
62
 
cmd = 'from setuptools.command.easy_install import main; main()'
63
 
ws  = pkg_resources.working_set
64
 
 
65
 
if is_jython:
 
126
cmd = [quote(sys.executable),
 
127
       '-c',
 
128
       quote('from setuptools.command.easy_install import main; main()'),
 
129
       '-mqNxd',
 
130
       quote(configuration['--eggs'])]
 
131
 
 
132
if configuration['--download-base']:
 
133
    cmd.extend(['-f', quote(configuration['--download-base'])])
 
134
 
 
135
cmd.append('zc.buildout' + configuration['--version'])
 
136
 
 
137
ws = pkg_resources.working_set
 
138
env = dict(
 
139
    os.environ,
 
140
    PYTHONPATH=ws.find(pkg_resources.Requirement.parse('setuptools')).location)
 
141
 
 
142
try:
66
143
    import subprocess
67
 
    
68
 
    assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd', 
69
 
           quote(tmpeggs), 'zc.buildout'], 
70
 
           env=dict(os.environ,
71
 
               PYTHONPATH=
72
 
               ws.find(pkg_resources.Requirement.parse('setuptools')).location
73
 
               ),
74
 
           ).wait() == 0
75
 
 
 
144
except ImportError:
 
145
    exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
76
146
else:
77
 
    assert os.spawnle(
78
 
        os.P_WAIT, sys.executable, quote (sys.executable),
79
 
        '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout',
80
 
        dict(os.environ,
81
 
            PYTHONPATH=
82
 
            ws.find(pkg_resources.Requirement.parse('setuptools')).location
83
 
            ),
84
 
        ) == 0
 
147
    # Jython can use subprocess but not spawn.  We prefer it generally.
 
148
    exitcode = subprocess.Popen(cmd, env=env).wait()
 
149
if exitcode != 0:
 
150
    # we shouldn't need an error message because a failure
 
151
    # should have generated a visible traceback in the subprocess.
 
152
    sys.exit(exitcode)
85
153
 
86
 
ws.add_entry(tmpeggs)
87
 
ws.require('zc.buildout')
 
154
ws.add_entry(configuration['--eggs'])
 
155
ws.require('zc.buildout' + configuration['--version'])
88
156
import zc.buildout.buildout
89
 
zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
90
 
shutil.rmtree(tmpeggs)
 
157
args.append('bootstrap')
 
158
zc.buildout.buildout.main(args)
 
159
if tmpeggs is not None:
 
160
    shutil.rmtree(tmpeggs)