1818use the -c option to specify an alternate configuration file.
1919"""
2020
21- import os , shutil , sys , tempfile , textwrap , urllib , urllib2 , subprocess
22- from optparse import OptionParser
23-
24- if sys .platform == 'win32' :
25- def quote (c ):
26- if ' ' in c :
27- return '"%s"' % c # work around spawn lamosity on windows
28- else :
29- return c
30- else :
31- quote = str
32-
33- # See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
34- stdout , stderr = subprocess .Popen (
35- [sys .executable , '-Sc' ,
36- 'try:\n '
37- ' import ConfigParser\n '
38- 'except ImportError:\n '
39- ' print 1\n '
40- 'else:\n '
41- ' print 0\n ' ],
42- stdout = subprocess .PIPE , stderr = subprocess .PIPE ).communicate ()
43- has_broken_dash_S = bool (int (stdout .strip ()))
21+ import os
22+ import shutil
23+ import sys
24+ import tempfile
4425
45- # In order to be more robust in the face of system Pythons, we want to
46- # run without site-packages loaded. This is somewhat tricky, in
47- # particular because Python 2.6's distutils imports site, so starting
48- # with the -S flag is not sufficient. However, we'll start with that:
49- if not has_broken_dash_S and 'site' in sys .modules :
50- # We will restart with python -S.
51- args = sys .argv [:]
52- args [0 :0 ] = [sys .executable , '-S' ]
53- args = map (quote , args )
54- os .execv (sys .executable , args )
55- # Now we are running with -S. We'll get the clean sys.path, import site
56- # because distutils will do it later, and then reset the path and clean
57- # out any namespace packages from site-packages that might have been
58- # loaded by .pth files.
59- clean_path = sys .path [:]
60- import site
61- sys .path [:] = clean_path
62- for k , v in sys .modules .items ():
63- if k in ('setuptools' , 'pkg_resources' ) or (
64- hasattr (v , '__path__' ) and
65- len (v .__path__ )== 1 and
66- not os .path .exists (os .path .join (v .__path__ [0 ],'__init__.py' ))):
67- # This is a namespace package. Remove it.
68- sys .modules .pop (k )
69-
70- is_jython = sys .platform .startswith ('java' )
71-
72- setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
73- distribute_source = 'http://python-distribute.org/distribute_setup.py'
26+ from optparse import OptionParser
7427
75- # parsing arguments
76- def normalize_to_url (option , opt_str , value , parser ):
77- if value :
78- if '://' not in value : # It doesn't smell like a URL.
79- value = 'file://%s' % (
80- urllib .pathname2url (
81- os .path .abspath (os .path .expanduser (value ))),)
82- if opt_str == '--download-base' and not value .endswith ('/' ):
83- # Download base needs a trailing slash to make the world happy.
84- value += '/'
85- else :
86- value = None
87- name = opt_str [2 :].replace ('-' , '_' )
88- setattr (parser .values , name , value )
28+ tmpeggs = tempfile .mkdtemp ()
8929
9030usage = '''\
9131 [DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
@@ -95,31 +35,13 @@ def normalize_to_url(option, opt_str, value, parser):
9535Simply run this script in a directory containing a buildout.cfg, using the
9636Python that you want bin/buildout to use.
9737
98- Note that by using --setup-source and --download-base to point to
99- local resources, you can keep this script from going over the network.
38+ Note that by using --find-links to point to local resources, you can keep
39+ this script from going over the network.
10040'''
10141
10242parser = OptionParser (usage = usage )
103- parser .add_option ("-v" , "--version" , dest = "version" ,
104- help = "use a specific zc.buildout version" )
105- parser .add_option ("-d" , "--distribute" ,
106- action = "store_true" , dest = "use_distribute" , default = False ,
107- help = "Use Distribute rather than Setuptools." )
108- parser .add_option ("--setup-source" , action = "callback" , dest = "setup_source" ,
109- callback = normalize_to_url , nargs = 1 , type = "string" ,
110- help = ("Specify a URL or file location for the setup file. "
111- "If you use Setuptools, this will default to " +
112- setuptools_source + "; if you use Distribute, this "
113- "will default to " + distribute_source + "." ))
114- parser .add_option ("--download-base" , action = "callback" , dest = "download_base" ,
115- callback = normalize_to_url , nargs = 1 , type = "string" ,
116- help = ("Specify a URL or directory for downloading "
117- "zc.buildout and either Setuptools or Distribute. "
118- "Defaults to PyPI." ))
119- parser .add_option ("--eggs" ,
120- help = ("Specify a directory for storing eggs. Defaults to "
121- "a temporary directory that is deleted when the "
122- "bootstrap script completes." ))
43+ parser .add_option ("-v" , "--version" , help = "use a specific zc.buildout version" )
44+
12345parser .add_option ("-t" , "--accept-buildout-test-releases" ,
12446 dest = 'accept_buildout_test_releases' ,
12547 action = "store_true" , default = False ,
@@ -129,101 +51,89 @@ def normalize_to_url(option, opt_str, value, parser):
12951 "extensions for you. If you use this flag, "
13052 "bootstrap and buildout will get the newest releases "
13153 "even if they are alphas or betas." ))
132- parser .add_option ("-c" , None , action = "store" , dest = "config_file" ,
133- help = ("Specify the path to the buildout configuration "
134- "file to be used." ))
135- parser .add_option ("-e" , "--distribute-version" , action = "store" , dest = "distribute_version" ,
136- help = ("Specify the version for distribute." ))
54+ parser .add_option ("-c" , "--config-file" ,
55+ help = ("Specify the path to the buildout configuration "
56+ "file to be used." ))
57+ parser .add_option ("-f" , "--find-links" ,
58+ help = ("Specify a URL to search for buildout releases" ))
59+ parser .add_option ("--allow-site-packages" ,
60+ action = "store_true" , default = False ,
61+ help = ("Let bootstrap.py use existing site packages" ))
13762
13863
13964options , args = parser .parse_args ()
14065
141- # if -c was provided, we push it back into args for buildout's main function
142- if options .config_file is not None :
143- args += ['-c' , options .config_file ]
144-
145- if options .eggs :
146- eggs_dir = os .path .abspath (os .path .expanduser (options .eggs ))
147- else :
148- eggs_dir = tempfile .mkdtemp ()
149-
150- if options .setup_source is None :
151- if options .use_distribute :
152- options .setup_source = distribute_source
153- else :
154- options .setup_source = setuptools_source
155-
156- if options .accept_buildout_test_releases :
157- args .append ('buildout:accept-buildout-test-releases=true' )
158- args .append ('bootstrap' )
159-
66+ ######################################################################
67+ # load/install setuptools
16068
16169try :
162- import pkg_resources
163- import setuptools # A flag. Sometimes pkg_resources is installed alone.
164- if not hasattr ( pkg_resources , '_distribute' ):
165- raise ImportError
70+ if options . allow_site_packages :
71+ import setuptools
72+ import pkg_resources
73+ from urllib . request import urlopen
16674except ImportError :
167- ez_code = urllib2 .urlopen (
168- options .setup_source ).read ().replace ('\r \n ' , '\n ' )
169- ez = {}
170- exec ez_code in ez
171- setup_args = dict (to_dir = eggs_dir , download_delay = 0 )
172- if options .distribute_version :
173- setup_args ['version' ] = options .distribute_version
174- if options .download_base :
175- setup_args ['download_base' ] = options .download_base
176- if options .use_distribute :
177- setup_args ['no_fake' ] = True
178- ez ['use_setuptools' ](** setup_args )
179- if 'pkg_resources' in sys .modules :
180- reload (sys .modules ['pkg_resources' ])
181- import pkg_resources
182- # This does not (always?) update the default working set. We will
183- # do it.
184- for path in sys .path :
185- if path not in pkg_resources .working_set .entries :
186- pkg_resources .working_set .add_entry (path )
75+ from urllib2 import urlopen
76+
77+ ez = {}
78+ exec (urlopen ('https://bootstrap.pypa.io/ez_setup.py' ).read (), ez )
79+
80+ if not options .allow_site_packages :
81+ # ez_setup imports site, which adds site packages
82+ # this will remove them from the path to ensure that incompatible versions
83+ # of setuptools are not in the path
84+ import site
85+ # inside a virtualenv, there is no 'getsitepackages'.
86+ # We can't remove these reliably
87+ if hasattr (site , 'getsitepackages' ):
88+ for sitepackage_path in site .getsitepackages ():
89+ sys .path [:] = [x for x in sys .path if sitepackage_path not in x ]
90+
91+ setup_args = dict (to_dir = tmpeggs , download_delay = 0 )
92+ ez ['use_setuptools' ](** setup_args )
93+ import setuptools
94+ import pkg_resources
95+
96+ # This does not (always?) update the default working set. We will
97+ # do it.
98+ for path in sys .path :
99+ if path not in pkg_resources .working_set .entries :
100+ pkg_resources .working_set .add_entry (path )
101+
102+ ######################################################################
103+ # Install buildout
187104
188- cmd = [quote (sys .executable ),
189- '-c' ,
190- quote ('from setuptools.command.easy_install import main; main()' ),
191- '-mqNxd' ,
192- quote (eggs_dir )]
105+ ws = pkg_resources .working_set
193106
194- if not has_broken_dash_S :
195- cmd .insert (1 , '-S' )
107+ cmd = [sys .executable , '-c' ,
108+ 'from setuptools.command.easy_install import main; main()' ,
109+ '-mZqNxd' , tmpeggs ]
196110
197- find_links = options .download_base
198- if not find_links :
199- find_links = os .environ .get ('bootstrap-testing-find-links' )
111+ find_links = os .environ .get (
112+ 'bootstrap-testing-find-links' ,
113+ options .find_links or
114+ ('http://downloads.buildout.org/'
115+ if options .accept_buildout_test_releases else None )
116+ )
200117if find_links :
201- cmd .extend (['-f' , quote ( find_links ) ])
118+ cmd .extend (['-f' , find_links ])
202119
203- if options .use_distribute :
204- setup_requirement = 'distribute'
205- else :
206- setup_requirement = 'setuptools'
207- ws = pkg_resources .working_set
208- setup_requirement_path = ws .find (
209- pkg_resources .Requirement .parse (setup_requirement )).location
210- env = dict (
211- os .environ ,
212- PYTHONPATH = setup_requirement_path )
120+ setuptools_path = ws .find (
121+ pkg_resources .Requirement .parse ('setuptools' )).location
213122
214123requirement = 'zc.buildout'
215124version = options .version
216125if version is None and not options .accept_buildout_test_releases :
217126 # Figure out the most recent final version of zc.buildout.
218127 import setuptools .package_index
219128 _final_parts = '*final-' , '*final'
129+
220130 def _final_version (parsed_version ):
221131 for part in parsed_version :
222132 if (part [:1 ] == '*' ) and (part not in _final_parts ):
223133 return False
224134 return True
225135 index = setuptools .package_index .PackageIndex (
226- search_path = [setup_requirement_path ])
136+ search_path = [setuptools_path ])
227137 if find_links :
228138 index .add_find_links ((find_links ,))
229139 req = pkg_resources .Requirement .parse (requirement )
@@ -245,22 +155,24 @@ def _final_version(parsed_version):
245155 requirement = '==' .join ((requirement , version ))
246156cmd .append (requirement )
247157
248- if is_jython :
249- import subprocess
250- exitcode = subprocess .Popen (cmd , env = env ).wait ()
251- else : # Windows prefers this, apparently; otherwise we would prefer subprocess
252- exitcode = os .spawnle (* ([os .P_WAIT , sys .executable ] + cmd + [env ]))
253- if exitcode != 0 :
254- sys .stdout .flush ()
255- sys .stderr .flush ()
256- print ("An error occurred when trying to install zc.buildout. "
257- "Look above this message for any errors that "
258- "were output by easy_install." )
259- sys .exit (exitcode )
158+ import subprocess
159+ if subprocess .call (cmd , env = dict (os .environ , PYTHONPATH = setuptools_path )) != 0 :
160+ raise Exception (
161+ "Failed to execute command:\n %s" % repr (cmd )[1 :- 1 ])
260162
261- ws .add_entry (eggs_dir )
163+ ######################################################################
164+ # Import and run buildout
165+
166+ ws .add_entry (tmpeggs )
262167ws .require (requirement )
263168import zc .buildout .buildout
169+
170+ if not [a for a in args if '=' not in a ]:
171+ args .append ('bootstrap' )
172+
173+ # if -c was provided, we push it back into args for buildout' main function
174+ if options .config_file is not None :
175+ args [0 :0 ] = ['-c' , options .config_file ]
176+
264177zc .buildout .buildout .main (args )
265- if not options .eggs : # clean up temporary egg directory
266- shutil .rmtree (eggs_dir )
178+ shutil .rmtree (tmpeggs )
0 commit comments