Merge lp:~gary/zc.buildout/betafix3 into lp:zc.buildout

Proposed by Gary Poster
Status: Needs review
Proposed branch: lp:~gary/zc.buildout/betafix3
Merge into: lp:zc.buildout
Prerequisite: lp:~gary/zc.buildout/betafix2
Diff against target: 301 lines (+234/-5)
6 files modified
MANIFEST.in (+3/-0)
bootstrap/bootstrap.py (+216/-0)
src/zc/buildout/easy_install.py (+3/-2)
src/zc/buildout/easy_install.txt (+6/-3)
z3c.recipe.scripts_/MANIFEST.in (+3/-0)
zc.recipe.egg_/MANIFEST.in (+3/-0)
To merge this branch: bzr merge lp:~gary/zc.buildout/betafix3
Reviewer Review Type Date Requested Status
Francis J. Lacoste (community) Approve
Review via email: mp+27734@code.launchpad.net

Description of the change

This is the catch-all branch for three remaining small fixes.

1) I added MANIFEST.in files so that using non-svn branches/checkouts will produce workable distributions. See http://bazaar.launchpad.net/~gary/zc.buildout/betafix3/revision/556 .

2) I fixed bug 580563. I did not add a test. First, this is just a warning. Second, if at all possible, packages really should specify a dependency on setuptools, not distribute, since distribute can fulfill a setuptools dependency, but not the other way around. I didn't think it was worth the time. That said, I think it is doable (though distribute-related tests are sometimes tricky). See http://bazaar.launchpad.net/~gary/zc.buildout/betafix3/revision/557 .

3) I fixed bug 585188. Before this change buildout was more aggressive about processing .pth files than the standard site.py. This meant that it exposed a .pth problem that the Debian (or Ubuntu) packaging for repoze.what had with its plugins, when it was not visible in starting the system Python. I changed the zc.buildout-generated site.py to be more like the standard site.py. Tests show that the change is made, and that the script still works with the change. Tests do not show that the particular problem encountered with the repoze.what packaging is addressed: my brain rebelled when I tried to figure out a way to duplicate the nested .pth setup that would show the problem, but it would be fair to require me to try harder to do so. (See http://bazaar.launchpad.net/~gary/zc.buildout/betafix3/revision/558 and then http://bazaar.launchpad.net/~gary/zc.buildout/betafix3/revision/559 for the test adjustments.)

To post a comment you must log in.
Revision history for this message
Gary Poster (gary) wrote :

Um, bootstrap.py is magically added back in this diff. I have no idea why--as noted in an earlier branch, it's been there all along. That part is spurious.

Revision history for this message
Francis J. Lacoste (flacoste) wrote :

Fair enough, I won't ask for more corner cases test to show that we cope around broken behavior.

review: Approve

Unmerged revisions

559. By Gary Poster

fix tests for changes

558. By Gary Poster

mimic standard site.py behavior for inclusion of .pth files

557. By Gary Poster

eliminate spurious warning if you are using distribute.

556. By Gary Poster

add files so releases can be made from a non-SVN checkout

555. By Gary Poster

fix virtualenv interaction by identfying broken virtualenv characteristic and reverting to previous behavior in that case.

554. By Gary Poster

Fix some problems with allowed_eggs_from_site_packages

553. By Gary Poster

get a baseline of zc.buildout with passing tests

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'MANIFEST.in'
2--- MANIFEST.in 1970-01-01 00:00:00 +0000
3+++ MANIFEST.in 2010-06-16 15:38:24 +0000
4@@ -0,0 +1,3 @@
5+include *.txt
6+recursive-include src *.txt
7+exclude MANIFEST.in buildout.cfg .bzrignore
8
9=== added file 'bootstrap/bootstrap.py'
10--- bootstrap/bootstrap.py 1970-01-01 00:00:00 +0000
11+++ bootstrap/bootstrap.py 2010-06-16 15:38:24 +0000
12@@ -0,0 +1,216 @@
13+##############################################################################
14+#
15+# Copyright (c) 2006 Zope Foundation and Contributors.
16+# All Rights Reserved.
17+#
18+# This software is subject to the provisions of the Zope Public License,
19+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
20+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
21+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
23+# FOR A PARTICULAR PURPOSE.
24+#
25+##############################################################################
26+"""Bootstrap a buildout-based project
27+
28+Simply run this script in a directory containing a buildout.cfg.
29+The script accepts buildout command-line options, so you can
30+use the -c option to specify an alternate configuration file.
31+
32+$Id$
33+"""
34+
35+import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
36+from optparse import OptionParser
37+
38+if sys.platform == 'win32':
39+ def quote(c):
40+ if ' ' in c:
41+ return '"%s"' % c # work around spawn lamosity on windows
42+ else:
43+ return c
44+else:
45+ quote = str
46+
47+# Detect https://bugs.launchpad.net/virtualenv/+bug/572545 .
48+proc = subprocess.Popen(
49+ [sys.executable, '-Sc', 'import ConfigParser'],
50+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
51+proc.communicate()
52+has_broken_dash_S = bool(proc.returncode)
53+
54+# In order to be more robust in the face of system Pythons, we want to
55+# run without site-packages loaded. This is somewhat tricky, in
56+# particular because Python 2.6's distutils imports site, so starting
57+# with the -S flag is not sufficient. However, we'll start with that:
58+if not has_broken_dash_S and 'site' in sys.modules:
59+ # We will restart with python -S.
60+ args = sys.argv[:]
61+ args[0:0] = [sys.executable, '-S']
62+ args = map(quote, args)
63+ os.execv(sys.executable, args)
64+# Now we are running with -S. We'll get the clean sys.path, import site
65+# because distutils will do it later, and then reset the path and clean
66+# out any namespace packages from site-packages that might have been
67+# loaded by .pth files.
68+clean_path = sys.path[:]
69+import site
70+sys.path[:] = clean_path
71+for k, v in sys.modules.items():
72+ if (hasattr(v, '__path__') and
73+ len(v.__path__)==1 and
74+ not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
75+ # This is a namespace package. Remove it.
76+ sys.modules.pop(k)
77+
78+is_jython = sys.platform.startswith('java')
79+
80+setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
81+distribute_source = 'http://python-distribute.org/distribute_setup.py'
82+
83+# parsing arguments
84+def normalize_to_url(option, opt_str, value, parser):
85+ if value:
86+ if '://' not in value: # It doesn't smell like a URL.
87+ value = 'file://%s' % (
88+ urllib.pathname2url(
89+ os.path.abspath(os.path.expanduser(value))),)
90+ if opt_str == '--download-base' and not value.endswith('/'):
91+ # Download base needs a trailing slash to make the world happy.
92+ value += '/'
93+ else:
94+ value = None
95+ name = opt_str[2:].replace('-', '_')
96+ setattr(parser.values, name, value)
97+
98+usage = '''\
99+[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
100+
101+Bootstraps a buildout-based project.
102+
103+Simply run this script in a directory containing a buildout.cfg, using the
104+Python that you want bin/buildout to use.
105+
106+Note that by using --setup-source and --download-base to point to
107+local resources, you can keep this script from going over the network.
108+'''
109+
110+parser = OptionParser(usage=usage)
111+parser.add_option("-v", "--version", dest="version",
112+ help="use a specific zc.buildout version")
113+parser.add_option("-d", "--distribute",
114+ action="store_true", dest="use_distribute", default=False,
115+ help="Use Distribute rather than Setuptools.")
116+parser.add_option("--setup-source", action="callback", dest="setup_source",
117+ callback=normalize_to_url, nargs=1, type="string",
118+ help=("Specify a URL or file location for the setup file. "
119+ "If you use Setuptools, this will default to " +
120+ setuptools_source + "; if you use Distribute, this "
121+ "will default to " + distribute_source +"."))
122+parser.add_option("--download-base", action="callback", dest="download_base",
123+ callback=normalize_to_url, nargs=1, type="string",
124+ help=("Specify a URL or directory for downloading "
125+ "zc.buildout and either Setuptools or Distribute. "
126+ "Defaults to PyPI."))
127+parser.add_option("--eggs",
128+ help=("Specify a directory for storing eggs. Defaults to "
129+ "a temporary directory that is deleted when the "
130+ "bootstrap script completes."))
131+parser.add_option("-c", None, action="store", dest="config_file",
132+ help=("Specify the path to the buildout configuration "
133+ "file to be used."))
134+
135+options, args = parser.parse_args()
136+
137+# if -c was provided, we push it back into args for buildout's main function
138+if options.config_file is not None:
139+ args += ['-c', options.config_file]
140+
141+if options.eggs:
142+ eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
143+else:
144+ eggs_dir = tempfile.mkdtemp()
145+
146+if options.setup_source is None:
147+ if options.use_distribute:
148+ options.setup_source = distribute_source
149+ else:
150+ options.setup_source = setuptools_source
151+
152+args = args + ['bootstrap']
153+
154+
155+try:
156+ to_reload = False
157+ import pkg_resources
158+ to_reload = True
159+ if not hasattr(pkg_resources, '_distribute'):
160+ raise ImportError
161+ import setuptools # A flag. Sometimes pkg_resources is installed alone.
162+except ImportError:
163+ ez_code = urllib2.urlopen(
164+ options.setup_source).read().replace('\r\n', '\n')
165+ ez = {}
166+ exec ez_code in ez
167+ setup_args = dict(to_dir=eggs_dir, download_delay=0)
168+ if options.download_base:
169+ setup_args['download_base'] = options.download_base
170+ if options.use_distribute:
171+ setup_args['no_fake'] = True
172+ ez['use_setuptools'](**setup_args)
173+ if to_reload:
174+ reload(pkg_resources)
175+ else:
176+ import pkg_resources
177+ # This does not (always?) update the default working set. We will
178+ # do it.
179+ for path in sys.path:
180+ if path not in pkg_resources.working_set.entries:
181+ pkg_resources.working_set.add_entry(path)
182+
183+cmd = [quote(sys.executable),
184+ '-c',
185+ quote('from setuptools.command.easy_install import main; main()'),
186+ '-mqNxd',
187+ quote(eggs_dir)]
188+
189+if not has_broken_dash_S:
190+ cmd.insert(1, '-S')
191+
192+if options.download_base:
193+ cmd.extend(['-f', quote(options.download_base)])
194+
195+requirement = 'zc.buildout'
196+if options.version:
197+ requirement = '=='.join((requirement, options.version))
198+cmd.append(requirement)
199+
200+if options.use_distribute:
201+ setup_requirement = 'distribute'
202+else:
203+ setup_requirement = 'setuptools'
204+ws = pkg_resources.working_set
205+env = dict(
206+ os.environ,
207+ PYTHONPATH=ws.find(
208+ pkg_resources.Requirement.parse(setup_requirement)).location)
209+
210+if is_jython:
211+ import subprocess
212+ exitcode = subprocess.Popen(cmd, env=env).wait()
213+else: # Windows prefers this, apparently; otherwise we would prefer subprocess
214+ exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
215+if exitcode != 0:
216+ sys.stdout.flush()
217+ sys.stderr.flush()
218+ print ("An error occured when trying to install zc.buildout. "
219+ "Look above this message for any errors that "
220+ "were output by easy_install.")
221+ sys.exit(exitcode)
222+
223+ws.add_entry(eggs_dir)
224+ws.require(requirement)
225+import zc.buildout.buildout
226+zc.buildout.buildout.main(args)
227+if not options.eggs: # clean up temporary egg directory
228+ shutil.rmtree(eggs_dir)
229
230=== modified file 'src/zc/buildout/easy_install.py'
231--- src/zc/buildout/easy_install.py 2010-06-16 15:38:24 +0000
232+++ src/zc/buildout/easy_install.py 2010-06-16 15:38:24 +0000
233@@ -818,7 +818,7 @@
234 def _maybe_add_setuptools(self, ws, dist):
235 if dist.has_metadata('namespace_packages.txt'):
236 for r in dist.requires():
237- if r.project_name == 'setuptools':
238+ if r.project_name in ('setuptools', 'distribute'):
239 break
240 else:
241 # We have a namespace package but no requirement for setuptools
242@@ -1673,7 +1673,8 @@
243 %s
244 ]
245 for path in original_paths:
246- addsitedir(path, known_paths)'''
247+ if path not in known_paths:
248+ addsitedir(path, known_paths)'''
249
250 addsitepackages_script = '''\
251 def addsitepackages(known_paths):
252
253=== modified file 'src/zc/buildout/easy_install.txt'
254--- src/zc/buildout/easy_install.txt 1970-01-01 00:00:00 +0000
255+++ src/zc/buildout/easy_install.txt 2010-06-16 15:38:24 +0000
256@@ -1291,7 +1291,8 @@
257 ...
258 ]
259 for path in original_paths:
260- addsitedir(path, known_paths)
261+ if path not in known_paths:
262+ addsitedir(path, known_paths)
263 return known_paths
264 <BLANKLINE>
265 def original_addsitepackages(known_paths):...
266@@ -1368,7 +1369,8 @@
267 ...
268 ]
269 for path in original_paths:
270- addsitedir(path, known_paths)
271+ if path not in known_paths:
272+ addsitedir(path, known_paths)
273 return known_paths
274 <BLANKLINE>
275 def original_addsitepackages(known_paths):...
276@@ -1432,7 +1434,8 @@
277 ...
278 ]
279 for path in original_paths:
280- addsitedir(path, known_paths)
281+ if path not in known_paths:
282+ addsitedir(path, known_paths)
283 return known_paths
284 <BLANKLINE>
285 def original_addsitepackages(known_paths):...
286
287=== added file 'z3c.recipe.scripts_/MANIFEST.in'
288--- z3c.recipe.scripts_/MANIFEST.in 1970-01-01 00:00:00 +0000
289+++ z3c.recipe.scripts_/MANIFEST.in 2010-06-16 15:38:24 +0000
290@@ -0,0 +1,3 @@
291+include *.txt
292+recursive-include src *.txt
293+exclude MANIFEST.in buildout.cfg .bzrignore
294
295=== added file 'zc.recipe.egg_/MANIFEST.in'
296--- zc.recipe.egg_/MANIFEST.in 1970-01-01 00:00:00 +0000
297+++ zc.recipe.egg_/MANIFEST.in 2010-06-16 15:38:24 +0000
298@@ -0,0 +1,3 @@
299+include *.txt
300+recursive-include src *.txt
301+exclude MANIFEST.in buildout.cfg .bzrignore

Subscribers

People subscribed via source and target branches

to all changes: