23 import sys |
23 import sys |
24 import tempfile |
24 import tempfile |
25 |
25 |
26 from optparse import OptionParser |
26 from optparse import OptionParser |
27 |
27 |
28 tmpeggs = tempfile.mkdtemp() |
28 __version__ = '2015-07-01' |
|
29 # See zc.buildout's changelog if this version is up to date. |
|
30 |
|
31 tmpeggs = tempfile.mkdtemp(prefix='bootstrap-') |
29 |
32 |
30 usage = '''\ |
33 usage = '''\ |
31 [DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] |
34 [DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] |
32 |
35 |
33 Bootstraps a buildout-based project. |
36 Bootstraps a buildout-based project. |
34 |
37 |
35 Simply run this script in a directory containing a buildout.cfg, using the |
38 Simply run this script in a directory containing a buildout.cfg, using the |
36 Python that you want bin/buildout to use. |
39 Python that you want bin/buildout to use. |
37 |
40 |
38 Note that by using --find-links to point to local resources, you can keep |
41 Note that by using --find-links to point to local resources, you can keep |
39 this script from going over the network. |
42 this script from going over the network. |
40 ''' |
43 ''' |
41 |
44 |
42 parser = OptionParser(usage=usage) |
45 parser = OptionParser(usage=usage) |
43 parser.add_option("-v", "--version", help="use a specific zc.buildout version") |
46 parser.add_option("--version", |
44 |
47 action="store_true", default=False, |
|
48 help=("Return bootstrap.py version.")) |
45 parser.add_option("-t", "--accept-buildout-test-releases", |
49 parser.add_option("-t", "--accept-buildout-test-releases", |
46 dest='accept_buildout_test_releases', |
50 dest='accept_buildout_test_releases', |
47 action="store_true", default=False, |
51 action="store_true", default=False, |
48 help=("Normally, if you do not specify a --version, the " |
52 help=("Normally, if you do not specify a --buildout-version, " |
49 "bootstrap script and buildout gets the newest " |
53 "the bootstrap script and buildout gets the newest " |
50 "*final* versions of zc.buildout and its recipes and " |
54 "*final* versions of zc.buildout and its recipes and " |
51 "extensions for you. If you use this flag, " |
55 "extensions for you. If you use this flag, " |
52 "bootstrap and buildout will get the newest releases " |
56 "bootstrap and buildout will get the newest releases " |
53 "even if they are alphas or betas.")) |
57 "even if they are alphas or betas.")) |
54 parser.add_option("-c", "--config-file", |
58 parser.add_option("-c", "--config-file", |
57 parser.add_option("-f", "--find-links", |
61 parser.add_option("-f", "--find-links", |
58 help=("Specify a URL to search for buildout releases")) |
62 help=("Specify a URL to search for buildout releases")) |
59 parser.add_option("--allow-site-packages", |
63 parser.add_option("--allow-site-packages", |
60 action="store_true", default=False, |
64 action="store_true", default=False, |
61 help=("Let bootstrap.py use existing site packages")) |
65 help=("Let bootstrap.py use existing site packages")) |
62 |
66 parser.add_option("--buildout-version", |
|
67 help="Use a specific zc.buildout version") |
|
68 parser.add_option("--setuptools-version", |
|
69 help="Use a specific setuptools version") |
|
70 parser.add_option("--setuptools-to-dir", |
|
71 help=("Allow for re-use of existing directory of " |
|
72 "setuptools versions")) |
63 |
73 |
64 options, args = parser.parse_args() |
74 options, args = parser.parse_args() |
|
75 if options.version: |
|
76 print("bootstrap.py version %s" % __version__) |
|
77 sys.exit(0) |
|
78 |
65 |
79 |
66 ###################################################################### |
80 ###################################################################### |
67 # load/install setuptools |
81 # load/install setuptools |
68 |
82 |
69 try: |
83 try: |
70 if options.allow_site_packages: |
|
71 import setuptools |
|
72 import pkg_resources |
|
73 from urllib.request import urlopen |
84 from urllib.request import urlopen |
74 except ImportError: |
85 except ImportError: |
75 from urllib2 import urlopen |
86 from urllib2 import urlopen |
76 |
87 |
77 ez = {} |
88 ez = {} |
78 exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez) |
89 if os.path.exists('ez_setup.py'): |
|
90 exec(open('ez_setup.py').read(), ez) |
|
91 else: |
|
92 exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez) |
79 |
93 |
80 if not options.allow_site_packages: |
94 if not options.allow_site_packages: |
81 # ez_setup imports site, which adds site packages |
95 # ez_setup imports site, which adds site packages |
82 # this will remove them from the path to ensure that incompatible versions |
96 # this will remove them from the path to ensure that incompatible versions |
83 # of setuptools are not in the path |
97 # of setuptools are not in the path |
84 import site |
98 import site |
85 # inside a virtualenv, there is no 'getsitepackages'. |
99 # inside a virtualenv, there is no 'getsitepackages'. |
86 # We can't remove these reliably |
100 # We can't remove these reliably |
87 if hasattr(site, 'getsitepackages'): |
101 if hasattr(site, 'getsitepackages'): |
88 for sitepackage_path in site.getsitepackages(): |
102 for sitepackage_path in site.getsitepackages(): |
89 sys.path[:] = [x for x in sys.path if sitepackage_path not in x] |
103 # Strip all site-packages directories from sys.path that |
|
104 # are not sys.prefix; this is because on Windows |
|
105 # sys.prefix is a site-package directory. |
|
106 if sitepackage_path != sys.prefix: |
|
107 sys.path[:] = [x for x in sys.path |
|
108 if sitepackage_path not in x] |
90 |
109 |
91 setup_args = dict(to_dir=tmpeggs, download_delay=0) |
110 setup_args = dict(to_dir=tmpeggs, download_delay=0) |
|
111 |
|
112 if options.setuptools_version is not None: |
|
113 setup_args['version'] = options.setuptools_version |
|
114 if options.setuptools_to_dir is not None: |
|
115 setup_args['to_dir'] = options.setuptools_to_dir |
|
116 |
92 ez['use_setuptools'](**setup_args) |
117 ez['use_setuptools'](**setup_args) |
93 import setuptools |
118 import setuptools |
94 import pkg_resources |
119 import pkg_resources |
95 |
120 |
96 # This does not (always?) update the default working set. We will |
121 # This does not (always?) update the default working set. We will |
102 ###################################################################### |
127 ###################################################################### |
103 # Install buildout |
128 # Install buildout |
104 |
129 |
105 ws = pkg_resources.working_set |
130 ws = pkg_resources.working_set |
106 |
131 |
|
132 setuptools_path = ws.find( |
|
133 pkg_resources.Requirement.parse('setuptools')).location |
|
134 |
|
135 # Fix sys.path here as easy_install.pth added before PYTHONPATH |
107 cmd = [sys.executable, '-c', |
136 cmd = [sys.executable, '-c', |
|
137 'import sys; sys.path[0:0] = [%r]; ' % setuptools_path + |
108 'from setuptools.command.easy_install import main; main()', |
138 'from setuptools.command.easy_install import main; main()', |
109 '-mZqNxd', tmpeggs] |
139 '-mZqNxd', tmpeggs] |
110 |
140 |
111 find_links = os.environ.get( |
141 find_links = os.environ.get( |
112 'bootstrap-testing-find-links', |
142 'bootstrap-testing-find-links', |
115 if options.accept_buildout_test_releases else None) |
145 if options.accept_buildout_test_releases else None) |
116 ) |
146 ) |
117 if find_links: |
147 if find_links: |
118 cmd.extend(['-f', find_links]) |
148 cmd.extend(['-f', find_links]) |
119 |
149 |
120 setuptools_path = ws.find( |
|
121 pkg_resources.Requirement.parse('setuptools')).location |
|
122 |
|
123 requirement = 'zc.buildout' |
150 requirement = 'zc.buildout' |
124 version = options.version |
151 version = options.buildout_version |
125 if version is None and not options.accept_buildout_test_releases: |
152 if version is None and not options.accept_buildout_test_releases: |
126 # Figure out the most recent final version of zc.buildout. |
153 # Figure out the most recent final version of zc.buildout. |
127 import setuptools.package_index |
154 import setuptools.package_index |
128 _final_parts = '*final-', '*final' |
155 _final_parts = '*final-', '*final' |
129 |
156 |
130 def _final_version(parsed_version): |
157 def _final_version(parsed_version): |
131 for part in parsed_version: |
158 try: |
132 if (part[:1] == '*') and (part not in _final_parts): |
159 return not parsed_version.is_prerelease |
133 return False |
160 except AttributeError: |
134 return True |
161 # Older setuptools |
|
162 for part in parsed_version: |
|
163 if (part[:1] == '*') and (part not in _final_parts): |
|
164 return False |
|
165 return True |
|
166 |
135 index = setuptools.package_index.PackageIndex( |
167 index = setuptools.package_index.PackageIndex( |
136 search_path=[setuptools_path]) |
168 search_path=[setuptools_path]) |
137 if find_links: |
169 if find_links: |
138 index.add_find_links((find_links,)) |
170 index.add_find_links((find_links,)) |
139 req = pkg_resources.Requirement.parse(requirement) |
171 req = pkg_resources.Requirement.parse(requirement) |