Merge lp:~cjwatson/launchpad/virtualenv-pip into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18517
Proposed branch: lp:~cjwatson/launchpad/virtualenv-pip
Merge into: lp:launchpad
Diff against target: 3021 lines (+859/-1585)
29 files modified
.bzrignore (+1/-2)
Makefile (+93/-77)
_pythonpath.py (+44/-12)
bootstrap.py (+0/-258)
buildout.cfg (+0/-53)
bzr-trunk-buildout.cfg (+0/-12)
bzrplugins/lpserve/test_lpserve.py (+3/-11)
constraints.txt (+356/-0)
doc/index.txt (+1/-1)
doc/pip.txt (+176/-441)
ez_setup.py (+0/-288)
lib/lp/codehosting/__init__.py (+2/-10)
lib/lp/scripts/harness.py (+2/-4)
lib/lp/scripts/utilities/bzr.py (+0/-13)
lib/lp/scripts/utilities/importfascist.py (+4/-0)
lib/lp/services/job/runner.py (+2/-1)
lib/lp/services/mailman/monkeypatches/mm_cfg.py.in (+2/-3)
lib/lp/services/scripts/tests/test_logger.txt (+0/-6)
lib/lp_sitecustomize.py (+12/-10)
pip-requirements.txt (+1/-0)
setup.cfg (+0/-12)
setup.py (+130/-14)
utilities/link-external-sourcecode (+2/-2)
utilities/relocate-virtualenv (+25/-0)
utilities/rocketfuel-branch (+1/-6)
utilities/rocketfuel-get (+2/-4)
versions.cfg (+0/-193)
zopeapp-versions.cfg (+0/-40)
ztk-versions.cfg (+0/-112)
To merge this branch: bzr merge lp:~cjwatson/launchpad/virtualenv-pip
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+331388@code.launchpad.net

Commit message

Convert build system to virtualenv and pip.

Description of the change

Convert build system to virtualenv and pip.

This is a more or less complete rewrite of the build system to get us to the
point where we can upgrade packages with non-trivial uses of setup_requires.
It will only work on xenial (precise would be possible in principle, but
requires somewhat more complicated bootstrapping of the virtualenv that
doesn't seem worth it now).

This requires some package upgrades:

Twisted: 13.0.0-p2 -> 13.0.0post3
  Use PEP 440-compliant version.
d2to1: 0.2.10 -> 0.2.12
  Cope with modern setuptools.
distribute: 0.6.36 -> 0.7.3
  Switch to legacy wrapper for modern setuptools.
launchpad-buildd: 136 -> 157
  Normalise Python packaging to avoid buildd-slave.tac being installed at
  the root of the virtualenv.
pip: 1.4 -> 9.0.1
  Modern pip.
setuptools: 0.6c11 -> 36.4.0
  Modern setuptools.
setuptools-git: 1.0 -> 1.2
  Avoid a significant performance regression.
virtualenv-tools3: None -> 2.0.0
  Used to relocate virtualenvs.
wheel: None -> 0.29.0
  For now we're still mostly using sdists, but some eggs need to be replaced
  with corresponding wheels.
z3c.recipe.tag: 0.6 -> None
  No longer needed. The ID Makefile target was already broken so I removed
  it, and it's relatively easy to provide good-enough reimplementations of
  TAGS and tags.
zope.pagetemplate: 3.5.0-p1 -> 3.5.0.post2
  Cherry-pick dependency tweak; use PEP 440-compliant version.

Some bits of application code need minor adjustments to cope with the
changes to the Python module path.

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) wrote :

We may need a bit of extra care to make this work properly with deployments. At the moment we do "make build_eggs" (which also runs buildout in the old world, or builds the virtualenv in the new world), sync that out everywhere, and then run "make compile" on each deployment target. That isn't quite good enough here though, because "make compile" won't rebuild the virtualenv to account for changed paths, and in any case if we can avoid building a virtualenv on each deployment target then we wouldn't have to cope with deployments being significantly slower.

I think the best approach is probably to use something like virtualenv-tools to relocate the environment. I'm not thrilled about this, but it may be the least bad answer for now. If that doesn't work, we can probably arrange for "make compile" to check whether the virtualenv's paths are correct and rebuild it if they aren't.

Revision history for this message
Colin Watson (cjwatson) wrote :

This seems to do the job. There's a bit of care needed because virtualenv-tools3 misses a couple of things, but it's close enough that we can fix the rest up manually.

Revision history for this message
William Grant (wgrant) wrote :

I've played with it locally and can't obviously break it. I'm sure it'll break the build process and production in unknown ways, but we can hardly avoid that.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2017-07-24 12:47:04 +0000
3+++ .bzrignore 2017-12-19 09:48:36 +0000
4@@ -33,15 +33,14 @@
5 lib/canonical/launchpad/icing/build/*
6 lib/canonical/launchpad/icing/combo.css
7 bin
8-develop-eggs
9 .installed.cfg
10 parts
11 *.egg-info
12 build
13-*.egg
14 dist
15 ./eggs
16 ./download-cache
17+./env
18 ./production-configs
19 bzr.dev
20 _trial_temp
21
22=== modified file 'Makefile'
23--- Makefile 2017-10-20 13:03:40 +0000
24+++ Makefile 2017-12-19 09:48:36 +0000
25@@ -6,9 +6,24 @@
26 WD:=$(shell pwd)
27 PY=$(WD)/bin/py
28 PYTHONPATH:=$(WD)/lib:${PYTHONPATH}
29-BUILDOUT_CFG=buildout.cfg
30 VERBOSITY=-vv
31
32+# virtualenv and pip fail if setlocale fails, so force a valid locale.
33+VIRTUALENV := LC_ALL=C.UTF-8 virtualenv
34+PIP := PYTHONPATH= LC_ALL=C.UTF-8 env/bin/pip
35+# Run with "make PIP_NO_INDEX=" if you want pip to find software
36+# dependencies *other* than those in our download-cache. Once you have the
37+# desired software, commit it to lp:lp-source-dependencies if it is going to
38+# be reviewed/merged/deployed.
39+# Although --ignore-installed is slower, we need it to avoid confusion with
40+# system-installed Python packages. If we ever manage to remove the need
41+# for virtualenv --system-site-packages, then we can remove this too.
42+PIP_NO_INDEX := --no-index
43+PIP_INSTALL_ARGS := \
44+ $(PIP_NO_INDEX) \
45+ --ignore-installed \
46+ --find-links=file://$(WD)/download-cache/dist/ \
47+
48 TESTFLAGS=-p $(VERBOSITY)
49 TESTOPTS=
50
51@@ -40,22 +55,32 @@
52 APIDOC_TMPDIR = $(APIDOC_DIR).tmp/
53 API_INDEX = $(APIDOC_DIR)/index.html
54
55-# Do not add bin/buildout to this list.
56-# It is impossible to get buildout to tell us all the files it would
57-# build, since each egg's setup.py doesn't tell us that information.
58+# It is impossible to get pip to tell us all the files it would build, since
59+# each package's setup.py doesn't tell us that information.
60 #
61-# NB: It's important BUILDOUT_BIN only mentions things genuinely produced by
62-# buildout.
63-BUILDOUT_BIN = \
64- $(PY) bin/build-twisted-plugin-cache bin/bzr \
65- bin/combine-css bin/fl-build-report \
66- bin/fl-credential-ctl bin/fl-install-demo bin/fl-monitor-ctl \
67- bin/fl-record bin/fl-run-bench bin/fl-run-test bin/googletestservice \
68- bin/harness bin/iharness bin/ipy bin/jsbuild bin/lpjsmin\
69- bin/killservice bin/kill-test-services bin/retest \
70- bin/run bin/run-testapp bin/sprite-util bin/start_librarian \
71- bin/tags bin/test bin/tracereport bin/twistd \
72- bin/watch_jsbuild bin/with-xvfb
73+# NB: It's important PIP_BIN only mentions things genuinely produced by pip.
74+PIP_BIN = \
75+ $(PY) \
76+ bin/build-twisted-plugin-cache \
77+ bin/combine-css \
78+ bin/googletestservice \
79+ bin/harness \
80+ bin/iharness \
81+ bin/ipy \
82+ bin/jsbuild \
83+ bin/lpjsmin \
84+ bin/killservice \
85+ bin/kill-test-services \
86+ bin/retest \
87+ bin/run \
88+ bin/run-testapp \
89+ bin/sprite-util \
90+ bin/start_librarian \
91+ bin/test \
92+ bin/tracereport \
93+ bin/twistd \
94+ bin/watch_jsbuild \
95+ bin/with-xvfb
96
97 # DO NOT ALTER : this should just build by default
98 default: inplace
99@@ -131,7 +156,7 @@
100 build: compile apidoc jsbuild css_combine
101
102 # LP_SOURCEDEPS_PATH should point to the sourcecode directory, but we
103-# want the parent directory where the download-cache and eggs directory
104+# want the parent directory where the download-cache and env directories
105 # are. We re-use the variable that is using for the rocketfuel-get script.
106 download-cache:
107 ifdef LP_SOURCEDEPS_PATH
108@@ -189,55 +214,48 @@
109 build/js/lp/meta.js >/dev/null
110 utilities/check-js-deps
111
112-eggs:
113- # Usually this is linked via link-external-sourcecode, but in
114- # deployment we create this ourselves.
115- mkdir eggs
116-
117-buildonce_eggs: $(PY)
118- find eggs -name '*.pyc' -exec rm {} \;
119-
120-# The download-cache dependency comes *before* eggs so that developers get the
121-# warning before the eggs directory is made. The target for the eggs
122-# directory is only there for deployment convenience.
123-# Note that the buildout version must be maintained here and in versions.cfg
124-# to make sure that the build does not go over the network.
125-#
126-# buildout won't touch files that would have the same contents, but for Make's
127-# sake we need them to get fresh timestamps, so we touch them after building.
128-bin/buildout: download-cache eggs
129- $(SHHH) PYTHONPATH= $(PYTHON) bootstrap.py\
130- --setup-source=ez_setup.py \
131- --download-base=download-cache/dist --eggs=eggs \
132- --version=1.7.1
133- touch --no-create $@
134-
135 # This target is used by LOSAs to prepare a build to be pushed out to
136-# destination machines. We only want eggs: they are the expensive bits,
137+# destination machines. We only want wheels: they are the expensive bits,
138 # and the other bits might run into problems like bug 575037. This
139-# target runs buildout, and then removes everything created except for
140-# the eggs.
141-build_eggs: $(BUILDOUT_BIN) clean_buildout
142-
143-# This builds bin/py and all the other bin files except bin/buildout.
144-# Remove the target before calling buildout to ensure that buildout
145-# updates the timestamp.
146-buildout_bin: $(BUILDOUT_BIN)
147-
148-# buildout won't touch files that would have the same contents, but for Make's
149-# sake we need them to get fresh timestamps, so we touch them after building.
150+# target runs pip, and then removes everything created except for the
151+# wheels.
152+build_wheels: $(PIP_BIN) clean_pip
153+
154+# Compatibility.
155+build_eggs: build_wheels
156+
157+# setuptools won't touch files that would have the same contents, but for
158+# Make's sake we need them to get fresh timestamps, so we touch them after
159+# building.
160 #
161 # If we listed every target on the left-hand side, a parallel make would try
162 # multiple copies of this rule to build them all. Instead, we nominally build
163 # just $(PY), and everything else is implicitly updated by that.
164-$(PY): bin/buildout versions.cfg $(BUILDOUT_CFG) setup.py
165- $(SHHH) PYTHONPATH= ./bin/buildout \
166- configuration:instance_name=${LPCONFIG} -c $(BUILDOUT_CFG)
167+$(PY): download-cache constraints.txt setup.py
168+ rm -rf env
169+ mkdir -p env
170+ (echo '[easy_install]'; \
171+ echo "allow_hosts = ''"; \
172+ echo 'find_links = file://$(WD)/download-cache/dist/') \
173+ >env/.pydistutils.cfg
174+ $(VIRTUALENV) \
175+ --python=$(PYTHON) --system-site-packages --never-download \
176+ --extra-search-dir=$(WD)/download-cache/dist/ \
177+ env
178+ ln -sfn env/bin bin
179+ $(SHHH) $(PIP) install $(PIP_INSTALL_ARGS) \
180+ -r pip-requirements.txt
181+ $(SHHH) LPCONFIG=$(LPCONFIG) $(PIP) \
182+ --cache-dir=$(WD)/download-cache/ \
183+ install $(PIP_INSTALL_ARGS) \
184+ -c pip-requirements.txt -c constraints.txt -e . \
185+ || { code=$$?; rm -f $@; exit $$code; }
186 touch $@
187
188-$(subst $(PY),,$(BUILDOUT_BIN)): $(PY)
189+$(subst $(PY),,$(PIP_BIN)): $(PY)
190
191 compile: $(PY) $(VERSION_INFO)
192+ ${SHHH} utilities/relocate-virtualenv env
193 ${SHHH} $(MAKE) -C sourcecode build PYTHON=${PYTHON} \
194 LPCONFIG=${LPCONFIG}
195 ${SHHH} bin/build-twisted-plugin-cache
196@@ -345,14 +363,16 @@
197 $(RM) -r $(JS_BUILD_DIR)
198 $(RM) -r yarn/node_modules
199
200-clean_buildout:
201+clean_pip:
202 $(RM) -r build
203 if [ -d $(CONVOY_ROOT) ]; then $(RM) -r $(CONVOY_ROOT) ; fi
204 $(RM) -r bin
205 $(RM) -r parts
206- $(RM) -r develop-eggs
207 $(RM) .installed.cfg
208
209+# Compatibility.
210+clean_buildout: clean_pip
211+
212 clean_logs:
213 $(RM) logs/thread*.request
214
215@@ -365,7 +385,7 @@
216 $(RM) -r lib/mailman
217 endif
218
219-lxc-clean: clean_js clean_mailman clean_buildout clean_logs
220+lxc-clean: clean_js clean_mailman clean_pip clean_logs
221 # XXX: BradCrittenden 2012-05-25 bug=1004514:
222 # It is important for parallel tests inside LXC that the
223 # $(CODEHOSTING_ROOT) directory not be completely removed.
224@@ -381,10 +401,7 @@
225 if test -f sourcecode/mailman/Makefile; then \
226 $(MAKE) -C sourcecode/mailman clean; \
227 fi
228- find . -path ./eggs -prune -false -o \
229- -type f \( -name '*.o' -o -name '*.so' -o -name '*.la' -o \
230- -name '*.lo' -o -name '*.py[co]' -o -name '*.dll' \) \
231- -print0 | xargs -r0 $(RM)
232+ $(RM) -r env
233 $(RM) -r lib/subvertpy/*.so
234 $(RM) -r $(LP_BUILT_JS_ROOT)/*
235 $(RM) -r $(CODEHOSTING_ROOT)/*
236@@ -466,15 +483,15 @@
237
238 TAGS: compile
239 # emacs tags
240- bin/tags -e
241+ ctags -R -e --languages=-JavaScript --python-kinds=-i -f $@.new \
242+ $(CURDIR)/lib $(CURDIR)/env/lib/$(PYTHON)/site-packages
243+ mv $@.new $@
244
245 tags: compile
246 # vi tags
247- bin/tags -v
248-
249-ID: compile
250- # idutils ID file
251- bin/tags -i
252+ ctags -R --languages=-JavaScript --python-kinds=-i -f $@.new \
253+ $(CURDIR)/lib $(CURDIR)/env/lib/$(PYTHON)/site-packages
254+ mv $@.new $@
255
256 PYDOCTOR = pydoctor
257 PYDOCTOR_OPTIONS =
258@@ -485,11 +502,10 @@
259 --docformat restructuredtext --verbose-about epytext-summary \
260 $(PYDOCTOR_OPTIONS)
261
262-.PHONY: apidoc build_eggs buildonce_eggs buildout_bin check \
263- check_config check_mailman clean clean_buildout clean_js \
264- clean_logs compile css_combine debug default doc ftest_build \
265- ftest_inplace hosted_branches jsbuild jsbuild_widget_css \
266- launchpad.pot pagetests pull_branches pydoctor realclean \
267- reload-apache run run-testapp runner scan_branches schema \
268- sprite_css sprite_image start stop sync_branches TAGS tags \
269- test_build test_inplace $(LP_JS_BUILD)
270+.PHONY: apidoc build_eggs build_wheels check check_config check_mailman \
271+ clean clean_buildout clean_js clean_logs clean_pip compile \
272+ css_combine debug default doc ftest_build ftest_inplace \
273+ hosted_branches jsbuild jsbuild_widget_css launchpad.pot \
274+ pydoctor realclean reload-apache run run-testapp runner schema \
275+ sprite_css sprite_image start stop TAGS tags test_build \
276+ test_inplace $(LP_JS_BUILD)
277
278=== modified file '_pythonpath.py'
279--- _pythonpath.py 2017-05-08 12:39:30 +0000
280+++ _pythonpath.py 2017-12-19 09:48:36 +0000
281@@ -19,11 +19,12 @@
282 # project root.
283 top = os.path.dirname(os.path.abspath(os.path.realpath(filename)))
284
285-site_dir = os.path.join(top, 'parts', 'scripts')
286+env = os.path.join(top, 'env')
287+stdlib_dir = os.path.join(env, 'lib', 'python%s' % sys.version[:3])
288
289 if ('site' in sys.modules and
290 not sys.modules['site'].__file__.startswith(
291- os.path.join(site_dir, 'site.py'))):
292+ os.path.join(stdlib_dir, 'site.py'))):
293 # We have the wrong site.py, so our paths are not set up correctly.
294 # We blow up, with a hopefully helpful error message.
295 raise RuntimeError(
296@@ -31,13 +32,44 @@
297 'Scripts should usually be '
298 "started with Launchpad's bin/py, or with a Python invoked with "
299 'the -S flag.' % (
300- sys.modules['site'].__file__, os.path.join(site_dir, 'site.py')))
301-
302-if site_dir not in sys.path:
303- sys.path.insert(0, site_dir)
304-elif 'site' not in sys.modules:
305- # XXX 2010-05-04 gary bug 575206
306- # This one line is to support Mailman 2, which does something unexpected
307- # to set up its paths.
308- sys.path[:] = [p for p in sys.path if 'site-packages' not in p]
309-import site # sets up paths
310+ sys.modules['site'].__file__, os.path.join(stdlib_dir, 'site.py')))
311+
312+# Ensure that the virtualenv's standard library directory is in sys.path;
313+# activate_this will not put it there.
314+if stdlib_dir not in sys.path and (stdlib_dir + os.sep) not in sys.path:
315+ sys.path.insert(0, stdlib_dir)
316+
317+if not sys.executable.startswith(top + os.sep) or 'site' not in sys.modules:
318+ # Activate the virtualenv. Avoid importing lp_sitecustomize here, as
319+ # activate_this imports site before it's finished setting up sys.path.
320+ orig_disable_sitecustomize = os.environ.get('LP_DISABLE_SITECUSTOMIZE')
321+ os.environ['LP_DISABLE_SITECUSTOMIZE'] = '1'
322+ # This is a bit like env/bin/activate_this.py, but to help namespace
323+ # packages work properly we change sys.prefix before importing site
324+ # rather than after.
325+ sys.real_prefix = sys.prefix
326+ sys.prefix = env
327+ os.environ['PATH'] = (
328+ os.path.join(env, 'bin') + os.pathsep + os.environ.get('PATH', ''))
329+ site_packages = os.path.join(
330+ env, 'lib', 'python%s' % sys.version[:3], 'site-packages')
331+ import site
332+ site.addsitedir(site_packages)
333+ if orig_disable_sitecustomize is not None:
334+ os.environ['LP_DISABLE_SITECUSTOMIZE'] = orig_disable_sitecustomize
335+ else:
336+ del os.environ['LP_DISABLE_SITECUSTOMIZE']
337+
338+# Move all our own directories to the front of the path.
339+new_sys_path = []
340+for item in list(sys.path):
341+ if item == top or item.startswith(top + os.sep):
342+ new_sys_path.append(item)
343+ sys.path.remove(item)
344+sys.path[:0] = new_sys_path
345+
346+# Initialise the Launchpad environment.
347+if 'LP_DISABLE_SITECUSTOMIZE' not in os.environ:
348+ if 'lp_sitecustomize' not in sys.modules:
349+ import lp_sitecustomize
350+ lp_sitecustomize.main()
351
352=== removed file 'bootstrap.py'
353--- bootstrap.py 2010-08-23 14:40:19 +0000
354+++ bootstrap.py 1970-01-01 00:00:00 +0000
355@@ -1,258 +0,0 @@
356-##############################################################################
357-#
358-# Copyright (c) 2006 Zope Foundation and Contributors.
359-# All Rights Reserved.
360-#
361-# This software is subject to the provisions of the Zope Public License,
362-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
363-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
364-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
365-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
366-# FOR A PARTICULAR PURPOSE.
367-#
368-##############################################################################
369-"""Bootstrap a buildout-based project
370-
371-Simply run this script in a directory containing a buildout.cfg.
372-The script accepts buildout command-line options, so you can
373-use the -c option to specify an alternate configuration file.
374-"""
375-
376-import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
377-from optparse import OptionParser
378-
379-if sys.platform == 'win32':
380- def quote(c):
381- if ' ' in c:
382- return '"%s"' % c # work around spawn lamosity on windows
383- else:
384- return c
385-else:
386- quote = str
387-
388-# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
389-stdout, stderr = subprocess.Popen(
390- [sys.executable, '-Sc',
391- 'try:\n'
392- ' import ConfigParser\n'
393- 'except ImportError:\n'
394- ' print 1\n'
395- 'else:\n'
396- ' print 0\n'],
397- stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
398-has_broken_dash_S = bool(int(stdout.strip()))
399-
400-# In order to be more robust in the face of system Pythons, we want to
401-# run without site-packages loaded. This is somewhat tricky, in
402-# particular because Python 2.6's distutils imports site, so starting
403-# with the -S flag is not sufficient. However, we'll start with that:
404-if not has_broken_dash_S and 'site' in sys.modules:
405- # We will restart with python -S.
406- args = sys.argv[:]
407- args[0:0] = [sys.executable, '-S']
408- args = map(quote, args)
409- os.execv(sys.executable, args)
410-# Now we are running with -S. We'll get the clean sys.path, import site
411-# because distutils will do it later, and then reset the path and clean
412-# out any namespace packages from site-packages that might have been
413-# loaded by .pth files.
414-clean_path = sys.path[:]
415-import site
416-sys.path[:] = clean_path
417-for k, v in sys.modules.items():
418- if (hasattr(v, '__path__') and
419- len(v.__path__)==1 and
420- not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
421- # This is a namespace package. Remove it.
422- sys.modules.pop(k)
423-
424-is_jython = sys.platform.startswith('java')
425-
426-setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
427-distribute_source = 'http://python-distribute.org/distribute_setup.py'
428-
429-# parsing arguments
430-def normalize_to_url(option, opt_str, value, parser):
431- if value:
432- if '://' not in value: # It doesn't smell like a URL.
433- value = 'file://%s' % (
434- urllib.pathname2url(
435- os.path.abspath(os.path.expanduser(value))),)
436- if opt_str == '--download-base' and not value.endswith('/'):
437- # Download base needs a trailing slash to make the world happy.
438- value += '/'
439- else:
440- value = None
441- name = opt_str[2:].replace('-', '_')
442- setattr(parser.values, name, value)
443-
444-usage = '''\
445-[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
446-
447-Bootstraps a buildout-based project.
448-
449-Simply run this script in a directory containing a buildout.cfg, using the
450-Python that you want bin/buildout to use.
451-
452-Note that by using --setup-source and --download-base to point to
453-local resources, you can keep this script from going over the network.
454-'''
455-
456-parser = OptionParser(usage=usage)
457-parser.add_option("-v", "--version", dest="version",
458- help="use a specific zc.buildout version")
459-parser.add_option("-d", "--distribute",
460- action="store_true", dest="use_distribute", default=False,
461- help="Use Distribute rather than Setuptools.")
462-parser.add_option("--setup-source", action="callback", dest="setup_source",
463- callback=normalize_to_url, nargs=1, type="string",
464- help=("Specify a URL or file location for the setup file. "
465- "If you use Setuptools, this will default to " +
466- setuptools_source + "; if you use Distribute, this "
467- "will default to " + distribute_source +"."))
468-parser.add_option("--download-base", action="callback", dest="download_base",
469- callback=normalize_to_url, nargs=1, type="string",
470- help=("Specify a URL or directory for downloading "
471- "zc.buildout and either Setuptools or Distribute. "
472- "Defaults to PyPI."))
473-parser.add_option("--eggs",
474- help=("Specify a directory for storing eggs. Defaults to "
475- "a temporary directory that is deleted when the "
476- "bootstrap script completes."))
477-parser.add_option("-t", "--accept-buildout-test-releases",
478- dest='accept_buildout_test_releases',
479- action="store_true", default=False,
480- help=("Normally, if you do not specify a --version, the "
481- "bootstrap script and buildout gets the newest "
482- "*final* versions of zc.buildout and its recipes and "
483- "extensions for you. If you use this flag, "
484- "bootstrap and buildout will get the newest releases "
485- "even if they are alphas or betas."))
486-parser.add_option("-c", None, action="store", dest="config_file",
487- help=("Specify the path to the buildout configuration "
488- "file to be used."))
489-
490-options, args = parser.parse_args()
491-
492-# if -c was provided, we push it back into args for buildout's main function
493-if options.config_file is not None:
494- args += ['-c', options.config_file]
495-
496-if options.eggs:
497- eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
498-else:
499- eggs_dir = tempfile.mkdtemp()
500-
501-if options.setup_source is None:
502- if options.use_distribute:
503- options.setup_source = distribute_source
504- else:
505- options.setup_source = setuptools_source
506-
507-if options.accept_buildout_test_releases:
508- args.append('buildout:accept-buildout-test-releases=true')
509-args.append('bootstrap')
510-
511-try:
512- import pkg_resources
513- import setuptools # A flag. Sometimes pkg_resources is installed alone.
514- if not hasattr(pkg_resources, '_distribute'):
515- raise ImportError
516-except ImportError:
517- ez_code = urllib2.urlopen(
518- options.setup_source).read().replace('\r\n', '\n')
519- ez = {}
520- exec ez_code in ez
521- setup_args = dict(to_dir=eggs_dir, download_delay=0)
522- if options.download_base:
523- setup_args['download_base'] = options.download_base
524- if options.use_distribute:
525- setup_args['no_fake'] = True
526- ez['use_setuptools'](**setup_args)
527- reload(sys.modules['pkg_resources'])
528- import pkg_resources
529- # This does not (always?) update the default working set. We will
530- # do it.
531- for path in sys.path:
532- if path not in pkg_resources.working_set.entries:
533- pkg_resources.working_set.add_entry(path)
534-
535-cmd = [quote(sys.executable),
536- '-c',
537- quote('from setuptools.command.easy_install import main; main()'),
538- '-mqNxd',
539- quote(eggs_dir)]
540-
541-if not has_broken_dash_S:
542- cmd.insert(1, '-S')
543-
544-find_links = options.download_base
545-if not find_links:
546- find_links = os.environ.get('bootstrap-testing-find-links')
547-if find_links:
548- cmd.extend(['-f', quote(find_links)])
549-
550-if options.use_distribute:
551- setup_requirement = 'distribute'
552-else:
553- setup_requirement = 'setuptools'
554-ws = pkg_resources.working_set
555-setup_requirement_path = ws.find(
556- pkg_resources.Requirement.parse(setup_requirement)).location
557-env = dict(
558- os.environ,
559- PYTHONPATH=setup_requirement_path)
560-
561-requirement = 'zc.buildout'
562-version = options.version
563-if version is None and not options.accept_buildout_test_releases:
564- # Figure out the most recent final version of zc.buildout.
565- import setuptools.package_index
566- _final_parts = '*final-', '*final'
567- def _final_version(parsed_version):
568- for part in parsed_version:
569- if (part[:1] == '*') and (part not in _final_parts):
570- return False
571- return True
572- index = setuptools.package_index.PackageIndex(
573- search_path=[setup_requirement_path])
574- if find_links:
575- index.add_find_links((find_links,))
576- req = pkg_resources.Requirement.parse(requirement)
577- if index.obtain(req) is not None:
578- best = []
579- bestv = None
580- for dist in index[req.project_name]:
581- distv = dist.parsed_version
582- if _final_version(distv):
583- if bestv is None or distv > bestv:
584- best = [dist]
585- bestv = distv
586- elif distv == bestv:
587- best.append(dist)
588- if best:
589- best.sort()
590- version = best[-1].version
591-if version:
592- requirement = '=='.join((requirement, version))
593-cmd.append(requirement)
594-
595-if is_jython:
596- import subprocess
597- exitcode = subprocess.Popen(cmd, env=env).wait()
598-else: # Windows prefers this, apparently; otherwise we would prefer subprocess
599- exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
600-if exitcode != 0:
601- sys.stdout.flush()
602- sys.stderr.flush()
603- print ("An error occurred when trying to install zc.buildout. "
604- "Look above this message for any errors that "
605- "were output by easy_install.")
606- sys.exit(exitcode)
607-
608-ws.add_entry(eggs_dir)
609-ws.require(requirement)
610-import zc.buildout.buildout
611-zc.buildout.buildout.main(args)
612-if not options.eggs: # clean up temporary egg directory
613- shutil.rmtree(eggs_dir)
614
615=== removed file 'buildout.cfg'
616--- buildout.cfg 2017-09-23 03:13:41 +0000
617+++ buildout.cfg 1970-01-01 00:00:00 +0000
618@@ -1,53 +0,0 @@
619-# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
620-# GNU Affero General Public License version 3 (see the file LICENSE).
621-
622-[buildout]
623-parts =
624- scripts
625- tags
626-unzip = true
627-eggs-directory = eggs
628-download-cache = download-cache
629-relative-paths = true
630-
631-# Disable this option temporarily if you want buildout to find software
632-# dependencies *other* than those in our download-cache. Once you have the
633-# desired software, reenable this option (and check in the new software to
634-# lp:lp-source-dependencies if this is going to be reviewed/merged/deployed.)
635-install-from-cache = true
636-
637-# This also will need to be temporarily disabled or changed for package
638-# upgrades. Newly-added packages should also add their desired version number
639-# to versions.cfg.
640-extends = versions.cfg
641-
642-allow-picked-versions = false
643-
644-prefer-final = true
645-
646-develop = .
647-
648-[configuration]
649-instance_name = development
650-
651-[scripts]
652-recipe = z3c.recipe.scripts
653-eggs = lp
654- celery
655- jsautobuild
656- lazr.jobrunner
657- lpjsmin
658- pyinotify
659- zc.zservertracelog
660-include-site-packages = true
661-allowed-eggs-from-site-packages =
662-interpreter = py
663-# Note that any indentation is lost in initialization blocks.
664-initialization =
665- # See buildout.cfg, [scripts] section, "initialization" key.
666- from lp_sitecustomize import main
667- main('${configuration:instance_name}') # Initializes LP environment.
668-
669-[tags]
670-recipe = z3c.recipe.tag:tags
671-eggs = lp
672
673=== removed file 'bzr-trunk-buildout.cfg'
674--- bzr-trunk-buildout.cfg 2009-07-24 03:39:09 +0000
675+++ bzr-trunk-buildout.cfg 1970-01-01 00:00:00 +0000
676@@ -1,12 +0,0 @@
677-# A custom buildout.cfg file for testing against a newer bzr.
678-# Checkout or symlink the new bzr as 'bzr.dev' in the root of the
679-# launchpad tree then run 'make BUILDOUT_CFG=bzr-trunk-buildout.cfg'.
680-
681-[buildout]
682-extends = buildout.cfg
683-
684-develop = .
685- bzr.dev
686-
687-[versions]
688-bzr =
689
690=== modified file 'bzrplugins/lpserve/test_lpserve.py'
691--- bzrplugins/lpserve/test_lpserve.py 2014-01-30 09:58:18 +0000
692+++ bzrplugins/lpserve/test_lpserve.py 2017-12-19 09:48:36 +0000
693@@ -1,4 +1,4 @@
694-# Copyright 2010-2011 Canonical Ltd. This software is licensed under the
695+# Copyright 2010-2017 Canonical Ltd. This software is licensed under the
696 # GNU Affero General Public License version 3 (see the file LICENSE).
697
698 import errno
699@@ -24,7 +24,6 @@
700 get_bzr_path,
701 get_BZR_PLUGIN_PATH_for_subprocess,
702 )
703-from lp.services.config import config
704 from lp.testing.fakemethod import FakeMethod
705
706
707@@ -319,10 +318,6 @@
708 same as the bzrlib.tests.TestCase version.
709 """
710
711- def get_python_path(self):
712- """Return the path to the Python interpreter."""
713- return '%s/bin/py' % config.root
714-
715 def start_bzr_subprocess(self, process_args, env_changes=None,
716 working_dir=None):
717 """Start bzr in a subprocess for testing.
718@@ -353,15 +348,12 @@
719 cwd = osutils.getcwd()
720 os.chdir(working_dir)
721
722- # LAUNCHPAD: Because of buildout, we need to get a custom Python
723- # binary, not sys.executable.
724- python_path = self.get_python_path()
725 # LAUNCHPAD: We can't use self.get_bzr_path(), since it'll find
726- # lib/bzrlib, rather than the path to sourcecode/bzr/bzr.
727+ # lib/bzrlib, rather than the path to bin/bzr.
728 bzr_path = get_bzr_path()
729 try:
730 cleanup_environment()
731- command = [python_path, bzr_path]
732+ command = [bzr_path]
733 command.extend(process_args)
734 process = self._popen(
735 command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
736
737=== added file 'constraints.txt'
738--- constraints.txt 1970-01-01 00:00:00 +0000
739+++ constraints.txt 2017-12-19 09:48:36 +0000
740@@ -0,0 +1,356 @@
741+# ztk-versions.cfg from ZTK 1.1.6, with some upgrades
742+# ---------------------------------------------------
743+
744+zope.annotation==3.6.0
745+zope.applicationcontrol==3.5.5
746+zope.authentication==3.7.1
747+zope.broken==3.6.0
748+zope.browser==1.3
749+zope.browsermenu==3.9.1
750+zope.browserpage==3.12.2
751+zope.browserresource==3.12.0
752+zope.cachedescriptors==3.5.1
753+zope.catalog==3.8.2
754+#zope.component==3.10.0
755+# Tell pip about extras to work around https://github.com/pypa/pip/issues/3046
756+# XXX cjwatson 2017-09-03: This should be fixed in pip 9.0.0, but apparently
757+# isn't.
758+# Upgrade from ZTK 1.1.6 for ZCML registration performance.
759+zope.component[hook,zcml]==3.11.0
760+zope.componentvocabulary==1.0.1
761+zope.configuration==3.7.4
762+zope.container==3.12.0
763+zope.contentprovider==3.7.2
764+zope.contenttype==3.5.5
765+zope.copy==3.5.0
766+zope.copypastemove==3.8.0
767+zope.datetime==3.4.1
768+zope.deferredimport==3.5.3
769+zope.deprecation==3.4.1
770+zope.dottedname==3.4.6
771+zope.dublincore==3.8.2
772+zope.error==3.7.4
773+zope.event==3.5.2
774+zope.exceptions==3.6.2
775+zope.filerepresentation==3.6.1
776+zope.formlib==4.0.6
777+zope.hookable==3.4.1
778+zope.i18n==3.7.4
779+zope.i18nmessageid==3.5.3
780+zope.index==3.6.4
781+#zope.interface==3.7.0
782+# Upgrade from ZTK 1.1.6 for ZCML registration performance.
783+zope.interface==4.4.3
784+zope.intid==3.7.2
785+zope.keyreference==3.6.4
786+zope.lifecycleevent==3.6.2
787+zope.location==3.9.1
788+zope.login==1.0.0
789+zope.mimetype==1.3.1
790+zope.minmax==1.1.2
791+#zope.pagetemplate==3.5.2
792+# Build of lp:~wallyworld/zope.pagetemplate/fix-isinstance
793+# p1 This version adds a small change to the traversal logic so that the
794+# optimisation which applies if the object is a dict also works for
795+# subclasses of dict. This patch has been merged in 4.2.0, so we can
796+# drop it when we upgrade.
797+# post2 Cherry-pick zope.security [untrustedpython] dependency from 3.5.1.
798+# Use PEP 440-compliant version.
799+zope.pagetemplate==3.5.0.post2
800+zope.password==3.6.1
801+zope.pluggableauth==1.2
802+zope.principalannotation==3.6.1
803+zope.principalregistry==3.7.1
804+zope.processlifetime==1.0
805+zope.proxy==3.6.1
806+zope.ptresource==3.9.0
807+zope.publisher==3.12.6
808+zope.ramcache==1.0
809+zope.schema==3.7.1
810+#zope.security==3.8.3
811+# Tell pip about extras to work around https://github.com/pypa/pip/issues/3046
812+# XXX cjwatson 2017-09-03: This should be fixed in pip 9.0.0, but apparently
813+# isn't.
814+zope.security[untrustedpython]==3.8.3
815+zope.securitypolicy==3.7.0
816+zope.sendmail==3.7.5
817+zope.sequencesort==3.4.0
818+zope.server==3.8.6
819+#zope.session==3.9.5
820+# XXX: downgraded to avoid 3.9.2 cookie calculation changes
821+zope.session==3.9.1
822+zope.site==3.9.2
823+zope.size==3.4.1
824+zope.structuredtext==3.5.1
825+zope.tal==3.5.2
826+zope.tales==3.5.3
827+#zope.testing==3.10.3
828+# p1 Build of lp:~mars/zope.testing/3.9.4-p1. Fixes bugs 570380 and 587886.
829+# p2 With patch for thread leaks to make them skips, fixes windmill errors
830+# with 'new threads' in hudson/ec2 builds.
831+# p3 And always tear down layers, because thats the Right Thing To Do.
832+# p4 fixes --subunit --list to really just list the tests.
833+# p5 Build of lp:~launchpad/zope.testing/3.9.4-p5. Fixes bug #609986.
834+# p6 reinstates fix from p4. Build of lp:~launchpad/zope.testing/3.9.4-fork
835+# revision 26.
836+# p7 was unused
837+# p8 redirects stdout and stderr to a black hole device when --subunit is used
838+# p9 adds the redirection of __stderr__ to a black hole device
839+# p10 changed the test reporting to use test.id() rather than
840+# str(test) since only the id is unique.
841+# p11 reverts p9.
842+# p12 reverts p11, restoring p9.
843+# p13 Add a new --require-unique flag to the testrunner. When set,
844+# this will cause the testrunner to check all tests IDs to ensure they
845+# haven't been loaded before. If it encounters a duplicate, it will
846+# raise an error and quit.
847+# p14 Adds test data written to stderr and stdout into the subunit output.
848+# p15 Fixed internal tests.
849+# p16 Adds support for skips in Python 2.7.
850+# p17 Fixes skip support for Python 2.6.
851+# To build (use Python 2.6) run "python bootstrap.py; ./bin/buildout". Then to
852+# build the distribution run "bin/buildout setup . sdist"
853+# Make sure you have subunit installed.
854+zope.testing==3.9.4-p17
855+zope.testrunner==4.0.4
856+zope.traversing==3.14.0
857+zope.viewlet==3.7.2
858+
859+# Deprecating
860+
861+# Dependencies
862+#distribute==0.6.36
863+distribute==0.7.3
864+docutils==0.7
865+Jinja2==2.5.5
866+mechanize==0.2.5
867+Paste==1.7.5.1
868+PasteDeploy==1.3.4
869+PasteScript==1.7.5
870+py==1.4.8
871+#Pygments==1.4
872+Pygments==1.6
873+python-gettext==1.0
874+#python-subunit==0.0.7
875+python-subunit==0.0.8beta
876+#pytz==2014.10
877+pytz==2017.2
878+RestrictedPython==3.6.0
879+#setuptools==0.6c11
880+setuptools==36.4.0
881+Sphinx==1.0.8
882+#testtools==0.9.12
883+testtools==0.9.30
884+transaction==1.1.1
885+z3c.recipe.sphinxdoc==0.0.8
886+zc.buildout==1.7.1
887+zc.lockfile==1.0.2
888+#ZConfig==2.8.0
889+ZConfig==2.9.1dev-20110728
890+zc.recipe.egg==1.3.2
891+zc.recipe.testrunner==1.4.0
892+zc.resourcelibrary==1.3.4
893+zdaemon==2.0.7
894+ZODB3==3.10.5
895+zope.mkzeoinstance==3.9.5
896+
897+# toolchain
898+#argparse==1.1
899+argparse==1.2.1
900+coverage==3.5.2
901+lxml==2.2.8
902+mr.developer==1.25
903+nose==1.1.2
904+tl.eggdeps==0.4
905+z3c.checkversions==0.4.1
906+z3c.recipe.compattest==0.13.1
907+z3c.recipe.depgraph==0.5
908+z3c.recipe.scripts==1.0.1
909+zope.kgs==1.2.0
910+
911+# zopeapp-versions.cfg from ZTK 1.1.6, with some upgrades
912+# -------------------------------------------------------
913+
914+# ZopeApp
915+zc.sourcefactory==0.7.0
916+zope.app.applicationcontrol==3.5.10
917+zope.app.appsetup==3.15.0
918+zope.app.debug==3.4.1
919+zope.app.http==3.9.0
920+zope.app.publication==3.12.0
921+zope.app.wsgi==3.10.0
922+zope.testbrowser==3.10.4
923+
924+# Deprecated
925+roman==1.4.0
926+#wsgi-intercept==0.4
927+# Upgrade from ZTK 1.1.5 to intercept lazr.restfulclient.
928+wsgi-intercept==0.5.1
929+zope.app.authentication==3.9.0
930+zope.app.basicskin==3.5.1
931+zope.app.broken==3.6.0
932+zope.app.component==3.9.3
933+zope.app.container==3.9.2
934+zope.app.content==3.5.1
935+zope.app.dependable==3.5.1
936+zope.app.error==3.5.3
937+zope.app.exception==3.6.3
938+zope.app.folder==3.5.2
939+zope.app.form==4.0.2
940+zope.app.generations==3.7.1
941+zope.app.i18n==3.6.4
942+zope.app.locales==3.6.2
943+zope.app.localpermission==3.7.2
944+zope.app.pagetemplate==3.11.2
945+zope.app.principalannotation==3.7.0
946+zope.app.publisher==3.10.2
947+zope.app.renderer==3.5.1
948+zope.app.rotterdam==3.5.3
949+zope.app.schema==3.5.0
950+zope.app.security==3.7.5
951+zope.app.testing==3.8.1
952+zope.app.zcmlfiles==3.7.1
953+zope.app.zopeappgenerations==3.6.1
954+zope.generations==3.7.1
955+
956+# Launchpad
957+# ---------
958+
959+# Alphabetical, case-insensitive, please! :-)
960+
961+# lp:~launchpad/ampoule/lp
962+# post1 Don't add a process back to the ready set if it received an error
963+# such as a timeout.
964+ampoule==0.2.0.post1
965+amqp==1.4.9
966+amqplib==1.0.2
967+anyjson==0.3.3
968+auditor==0.0.3
969+auditorclient==0.0.4
970+auditorfixture==0.0.7
971+backports.lzma==0.0.3
972+BeautifulSoup==3.2.1
973+billiard==3.3.0.20
974+bson==0.3.3
975+bzr==2.6.0.lp.2
976+celery==3.1.18
977+Chameleon==2.11
978+cssselect==0.9.1
979+cssutils==0.9.10
980+d2to1==0.2.12
981+Django==1.4
982+dkimpy==0.5.4
983+# Required by dkimpy
984+dnspython==1.10.0
985+elementtree==1.2.6-20050316
986+epydoc==3.0.1
987+extras==0.0.3
988+feedparser==4.1
989+feedvalidator==0.0.0DEV-r1049
990+fixtures==0.3.9
991+FormEncode==1.2.4
992+grokcore.component==1.6
993+html5browser==0.0.9
994+httmock==1.2.3
995+httplib2==0.8
996+importlib==1.0.2
997+ipython==0.13.2
998+iso8601==0.1.4
999+jsautobuild==0.2
1000+keyring==0.6.2
1001+kombu==3.0.30
1002+launchpad-buildd==157
1003+launchpadlib==1.10.5
1004+lazr.authentication==0.1.1
1005+lazr.batchnavigator==1.2.11
1006+lazr.config==2.2.1
1007+lazr.delegates==2.0.4
1008+lazr.enum==1.1.3
1009+lazr.jobrunner==0.13
1010+lazr.lifecycle==1.1
1011+lazr.restful==0.20.0
1012+lazr.restfulclient==0.13.2
1013+lazr.smtptest==1.3
1014+lazr.sshserver==0.1.3
1015+lazr.testing==0.1.1
1016+lazr.uri==1.0.3
1017+libnacl==1.3.6
1018+lpjsmin==0.5
1019+manuel==1.7.2
1020+Markdown==2.3.1
1021+martian==0.11
1022+meliae==0.2.0.final.0
1023+mock==1.0.1
1024+mocker==1.1.1
1025+oauth==1.0
1026+oops==0.0.13
1027+oops-amqp==0.0.8b1
1028+oops-datedir-repo==0.0.23
1029+oops-timeline==0.0.1
1030+oops-twisted==0.0.7
1031+oops-wsgi==0.0.8
1032+ordereddict==1.1
1033+oslo.config==1.1.1
1034+paramiko==1.7.7.2
1035+pbr==0.5.20
1036+pgbouncer==0.0.8
1037+prettytable==0.7.2
1038+psycopg2==2.6.1
1039+pyasn1==0.1.6
1040+pycrypto==2.6
1041+pygpgme==0.2
1042+pyinotify==0.9.4
1043+pymacaroons==0.9.2
1044+pyOpenSSL==0.13
1045+pystache==0.5.3
1046+python-dateutil==1.5
1047+python-debian==0.1.23
1048+python-keystoneclient==0.3.1
1049+python-memcached==1.58
1050+python-mimeparse==0.1.4
1051+# XXX: deryck 2012-08-10
1052+# See lp:~deryck/python-openid/python-openid-fix1034376 which
1053+# reapplied a patch from wgrant to get codehosting going again.
1054+python-openid==2.2.5-fix1034376
1055+python-swiftclient==1.5.0
1056+PyYAML==3.10
1057+rabbitfixture==0.3.6
1058+requests==2.7.0
1059+requests-toolbelt==0.6.2
1060+setproctitle==1.1.7
1061+setuptools-git==1.2
1062+simplejson==3.8.2
1063+SimpleTAL==4.3
1064+six==1.9.0
1065+soupmatchers==0.2
1066+# lp:~launchpad-committers/storm/with-without-datetime
1067+storm==0.19.0.99-lpwithnodatetime-r408
1068+subprocess32==3.2.6
1069+subvertpy==0.9.1
1070+testresources==0.2.7
1071+testscenarios==0.4
1072+timeline==0.0.3
1073+# Build of lp:~canonical-launchpad-branches/twisted:lp-backport.
1074+# p1 Support diffie-hellman-group14-sha1 key exchange in conch.ssh.
1075+# p2 Add diffie-hellman-group-exchange-sha256 to twisted.conch.ssh.
1076+# Add support in twisted.conch.ssh for hmac-sha2-256 and hmac-sha2-512.
1077+# post3 Use PEP 440-compliant version.
1078+Twisted==13.0.0post3
1079+txAMQP==0.6.2
1080+txfixtures==0.1.4
1081+txlongpoll==0.2.12
1082+txlongpollfixture==0.1.3
1083+txpkgupload==0.2
1084+unittest2==0.5.1
1085+van.testing==3.0.0
1086+virtualenv-tools3==2.0.0
1087+wadllib==1.3.2
1088+wheel==0.29.0
1089+wsgiref==0.1.2
1090+z3c.pt==2.2.3
1091+z3c.ptcompat==0.5.7
1092+zc.zservertracelog==1.3.2
1093+# Not in ZTK 1.1.5
1094+zope.app.server==3.6.0
1095+# Not in ZTK 1.1.5 (extracted from zope.app.schema)
1096+zope.vocabularyregistry==1.0.0
1097
1098=== modified file 'doc/index.txt'
1099--- doc/index.txt 2011-03-31 16:41:05 +0000
1100+++ doc/index.txt 2017-12-19 09:48:36 +0000
1101@@ -27,7 +27,7 @@
1102 .. toctree::
1103 :maxdepth: 1
1104
1105- buildout
1106+ pip
1107
1108 Possibly out-of-date
1109 --------------------
1110
1111=== renamed file 'doc/buildout.txt' => 'doc/pip.txt'
1112--- doc/buildout.txt 2017-11-18 09:49:07 +0000
1113+++ doc/pip.txt 2017-12-19 09:48:36 +0000
1114@@ -1,9 +1,8 @@
1115-Launchpad Buildout
1116-******************
1117+Launchpad pip integration
1118+*************************
1119
1120-Launchpad uses the buildout_ (or "zc.buildout") build system.
1121-Buildout's biggest strength is managing Python packages. That is also
1122-our focus for it.
1123+Launchpad uses the pip_ build system for managing Python packages (replacing
1124+`zc.buildout`, which we used for many years).
1125
1126 We have at least two other ways of managing dependencies. Apt
1127 manages our Python language installation, as well as many of our
1128@@ -12,151 +11,15 @@
1129 supposed to only contain dependencies that are not standard Python
1130 packages. bzr plugins and Javascript libraries are existing examples.
1131
1132-If you are not interested in our `Motivations`_ or in an `Introduction to
1133-zc.buildout`_, all developers will at least want to read the very brief
1134-sections about the `Set Up`_ and the `Everyday Usage`_.
1135+All developers will at least want to read the very brief sections about the
1136+`Set Up`_ and the `Everyday Usage`_.
1137
1138 Developers who manage source dependencies probably should read the general
1139 information about `Managing Dependencies and Scripts`_, but will also find
1140 detailed instructions to `Add a Package`_, to `Upgrade a Package`_, to `Add a
1141 Script`_, and to `Work with Unreleased or Forked Packages`_.
1142
1143-.. _buildout: http://www.buildout.org/
1144-
1145-===========
1146-Motivations
1147-===========
1148-
1149-These motivations are labeled as "[INTERNAL]" or "[EXTERNAL]" to indicate
1150-whether it is pertinent for internal dependencies, which we on the Launchpad
1151-team create and release ourselves; or external dependencies, which other
1152-parties, in and out of Canonical, create and release.
1153-
1154-* We want more careful specification of our dependencies across branches.
1155- [INTERNAL] [EXTERNAL]
1156-
1157- This is a real concern pertinent both for our "trunks" (devel,
1158- stable, db-devel, db-stable) and for our development boxes. For
1159- instance, before incorporating buildout, in our trunks, when we want
1160- to update a dependency, we needed to make sure that *all* the
1161- current Launchpad trunks work with the dependency initially; then
1162- submit a new Launchpad branch that uses the change dependency. A
1163- mistake can even potentially break one or both of the db-* trunks,
1164- since PQM only tests against one branch (usually devel), and
1165- sourcecode changes affect all branches at once. For simplicity,
1166- speed, and safety, we want to be able to submit a single branch that
1167- incorporates the source dependencies and the associated changes at
1168- once.
1169-
1170- This is also true, if less critical and easier to work around, on developer
1171- boxes. Without care, changes to sourcecode when working on dependencies will
1172- affect all a developer's branches, polluting test results with false
1173- negatives or false positives.
1174-
1175-* We want to default to using released versions of our software dependencies.
1176- [EXTERNAL]
1177-
1178- A significant number of projects do not always have a pristine trunk, and
1179- many also spend extra effort on polish, bug fixes, and compatibility before a
1180- release. If we do not desperately need a new feature on trunk, using a
1181- release is generally regarded as a safer, better practice. Our earlier usage
1182- of bzr branches of the development trunks does not encourage this practice.
1183-
1184-* We want to be encouraged to make the effort to interact with upstream
1185- projects to have our patches integrated. [EXTERNAL]
1186-
1187- Interacting and negotiating with upstream is undeniably more
1188- time-consuming than our previous practice of maintaining local bzr
1189- branches with our patches, especially short-term. But our previous
1190- use of bzr branches is not good open-source community behaviour--an
1191- ironic characteristic for a project like Launchpad. It also can
1192- cause problems down the road, for instance, if the patch becomes
1193- stale and we want to migrate to new releases.
1194-
1195-* We want to be protected from changes and differences in our operating system.
1196- [INTERNAL] [EXTERNAL]
1197-
1198- This is a concern both over time and across different Launchpad environments.
1199-
1200- First, our operating system, Ubuntu, is driven by many needs and
1201- goals. Launchpad is among them, but generally Launchpad serves
1202- Ubuntu, not the reverse. For instance, Jaunty dropped Launchpad's
1203- Python version. The Ubuntu developers had good reason--Python 2.4
1204- has not been supported by the Python developers for some time--but
1205- it caused a significant inconvenience to the Launchpad
1206- team. Managing our dependencies, particularly the Python library
1207- dependencies, can help alleviate these problems.
1208-
1209- Second, Launchpad developers run a significantly different version of the
1210- operating system than that run in production. Maintaining our Python library
1211- dependencies ourselves can also help alleviate these concerns.
1212-
1213-* We want to be able to easily use standard packages of our primary
1214- programming language, Python. [EXTERNAL]
1215-
1216- Our Python library dependencies are distributed for many operating systems--
1217- Windows, Mac, and other flavors of Linux--in a unified location and format:
1218- PyPI, using distutils. Using Python library dependencies in their standard
1219- distributions makes it easier for us to reuse code.
1220-
1221-* We want to be encouraged to release Python packages of our open-source
1222- code. [INTERNAL]
1223-
1224- We are beginning to realize our aspirations of abstracting and releasing some
1225- of our code. Much of that code is in Python. Consuming standard Python
1226- packages encourages us to follow good practice in releasing our own Python
1227- packages. Dogfooding can help keep us honest, and good official releases can
1228- help us support and encourage a community of users.
1229-
1230-Meanwhile, we want to be able to keep certain aspects of the legacy story.
1231-
1232-* We need deployment to not need network access.
1233-
1234-* We need to be able to use custom releases of our Python dependencies, if
1235- absolutely necessary.
1236-
1237-* We would like to be able to follow security releases in our operating system.
1238-
1239-We will be able to support the first two of these aspects entirely.
1240-
1241-As to the third, we will continue to follow operating system security releases
1242-for most or all of the dependencies that are not Python packages--a very
1243-similar situation to the one before Buildout integration.
1244-
1245-===========================
1246-Introduction to zc.buildout
1247-===========================
1248-
1249-Buildout is a relatively simple system that increases in complexity as it is
1250-extended via "recipes". It works on top of distutils_ and setuptools_. It
1251-uses declarative ini-style files to direct its work. The `Buildout site`_
1252-points to a variety of documents describing and documenting its use.
1253-
1254-For Launchpad, Buildout is hidden behind a Makefile as of this writing. If
1255-the Makefile is removed, developers will typically run ``bootstrap.py`` in the
1256-branch, and then run ``bin/buildout``. After that, the ``bin`` directory will
1257-have the commands to start, stop, test, and debug the software. If you are
1258-interested in example direct usage of Buildout, you may want to read `the
1259-"Hacking" document in the Launchpad wiki`_ that describes the usage patterns in
1260-``lazr.*`` packages.
1261-
1262-.. _`the "Hacking" document in the Launchpad wiki`: https://dev.launchpad.net/Hacking
1263-
1264-Launchpad's Buildout usage is roughly of medium complexity. It is more
1265-complex than that needed by a package with few dependencies and simple usage
1266-(see lazr.uri, for instance), but less complex than that of other large
1267-applications that use the buildout system. More complexity can come by
1268-building more non-Python tools and by having multiple configuration variations,
1269-for instance.
1270-
1271-The documentation below will focus on using Launchpad's buildout. See the
1272-links given above for a more thorough general review.
1273-
1274-.. _distutils: http://docs.python.org/distutils/index.html
1275-
1276-.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
1277-
1278-.. _`Buildout site`: http://www.buildout.org/
1279+.. _pip: https://pip.pypa.io/
1280
1281 ======
1282 Set Up
1283@@ -192,21 +55,20 @@
1284 ======================
1285
1286 If you typically use ``rocketfuel-get``, and you don't change source
1287-dependencies, you should not have any further changes, except that ``bin/test``
1288-has replaced ``test.py``. ``rocketfuel-branch`` and
1289-``link-external-dependencies`` will Do the Right Thing.
1290+dependencies, then you don't need to know any more. ``rocketfuel-branch``
1291+and ``link-external-dependencies`` will Do the Right Thing.
1292
1293 Manual
1294 ======
1295
1296 If you don't use the rocketfuel scripts, you will still use
1297-``link-external-dependencies`` as before. When a buildout complains that it
1298+``link-external-dependencies`` as before. When ``pip`` complains that it
1299 cannot find a version of a dependency, do the following, from within the
1300 branch::
1301
1302 git -C download-cache pull
1303
1304-After this, retry your make (or run ``bin/buildout`` from the branch).
1305+After this, retry your ``make``.
1306
1307 That's it for everyday usage.
1308
1309@@ -220,120 +82,42 @@
1310
1311 First let's talk a little about the anatomy of what we have set up. To be
1312 clear, much of this is based on our own decisions of what to do. If you see
1313-something problematic, bring it up with the Foundations team. Maybe together
1314-we can come up with another approach that meets our needs better.
1315-
1316-If you saw the top-level Launchpad directory before we started using Buildout,
1317-you might notice seven new items in the checkout.
1318-
1319-``bootstrap.py``
1320- This is the standard bootstrapping file provided by the Buildout
1321- distribution. As of this writing, the Makefile uses this file, and you do
1322- not have to modify it or call it directly.
1323-
1324- Without a Makefile, the first step of developing a source tree that uses
1325- Buildout is to run this file in the top level directory with the Python
1326- executable that you wish to use for the source tree. It creates a ``bin``
1327- directory, if it does not already exist, and puts a ``buildout`` executable
1328- there. The next step is to run ``bin/buildout``, which, unless you supply
1329- a ``-c`` option to specify a configuration file, will look for a
1330- buildout.cfg file by default to discover what to do.
1331-
1332- Again, as of this writing, the Makefile uses this file, and it does not
1333- need to be modified, so you need not concern yourself with it further at
1334- this time.
1335-
1336-``ez_setup.py``
1337- This is another standard file from another project. In this case, it is
1338- the file provided by the setuptools project to install setuptools. It is
1339- used by the ``setup.py`` file, described below. It does not need to be
1340- modified or called directly.
1341+something problematic, bring it up with other Launchpad developers. Maybe
1342+together we can come up with another approach that meets our needs better.
1343+
1344+These are the items in the top-level Launchpad directory associated with
1345+pip:
1346
1347 ``setup.py``
1348 This is the file that uses ``distutils``, extended by ``setuptools``, to
1349 specify direct dependencies, scripts, and other elements of the local
1350 source tree.
1351
1352- Buildout uses it, but the reverse is not true: ``setup.py`` does not know
1353- about Buildout. This means that packages that use Buildout for development
1354- do not have to require it when they are being installed in other software
1355- as a dependency.
1356+ pip uses it, but the reverse is not true: ``setup.py`` does not know
1357+ about pip.
1358
1359 Describing this file in full is well beyond the scope of this document. We
1360 will give recipes for modifying it for certain tasks below. For more
1361 information beyond these recipes, see the setuptools and distutils
1362 documentation.
1363
1364-``buildout.cfg``
1365- This is the default configuration file that ``bin/buildout`` will look to
1366- for instructions.
1367-
1368- Describing it in full is well beyond the scope of this document. However,
1369- we will give an overview here.
1370-
1371- Configuration files for Buildout are comprised of sections with key-value
1372- pairs.
1373-
1374- The key-value pairs are separated with new lines, when the subsequent line
1375- is not indented. The key and value are each separated with an equals sign.
1376-
1377- ::
1378-
1379- foo = bar
1380- baz = bing
1381- bah
1382- boo
1383- sha = zam
1384-
1385- That example shows three keys, 'foo', 'baz', and 'sha'. The 'baz' key has
1386- a string with two new lines (which might be interpreted one several ways,
1387- as defined for that key).
1388-
1389- The ``[buildout]`` section is the starting point for Buildout to determine
1390- what to do. It looks for an ``extends`` key to find any additional files
1391- to merge in; we use this for ``versions.cfg``, discussed below.
1392-
1393- In addition to general configuration and initialization such as this, it
1394- looks in the ``develop`` key to find source trees to develop as part of the
1395- buildout. In the standard Launchpad configuration, we develop only
1396- Launchpad itself (the current directory, or '.'). This means that the
1397- local ``setup.py`` will be run. If you want to develop Launchpad while you
1398- develop another dependency, you can link another source tree in, and
1399- specify an additional ``develop`` directory in another line::
1400-
1401- [buildout]
1402- develop = .
1403- lazr_uri_branch
1404-
1405- See `Developing a Dependent Library In Parallel`_ for more on this.
1406-
1407- The other basic key in the ``[buildout]`` section that we'll highlight here
1408- is ``parts``. This key identifies the other sections in buildout.cfg that
1409- will be processed. A section that is not identified in the ``[buildout]``
1410- sections ``parts`` key will usually be ignored (unless chosen for another
1411- role by another key elsewhere).
1412-
1413- Sections other than ``[buildout]`` that are specified as parts always must
1414- specify a ``recipe``: an identifier that determines what code should
1415- process that section. You'll see a variety of recipes in Launchpad's
1416- buildout.cfg, including ``zc.recipe.egg`` and others.
1417-
1418-``versions.cfg``
1419- As mentioned above, ``buildout.cfg`` extends ``versions.cfg`` by
1420- specifying it in the ``extends`` key of the ``[buildout]`` section.
1421- Versions.cfg specifies the precise versions of the dependencies we use.
1422- This means that we can have several versions of a dependency available
1423- locally, but we only build the precise one we specify. We give an
1424- example of its use below. To read about the mechanism used, see the
1425- zc.buildout documentation of the ``versions`` option in the ``[buildout]``
1426- section.
1427-
1428-``eggs``
1429- The ``eggs`` directory holds the eggs built from the downloaded
1430- distributions. Unless you set it up differently yourself, this directory is
1431- shared by all your branches. This directory is local to your system--we do
1432- not manage it in a branch. One reason for this is that eggs are often
1433- platform-specific.
1434+``pip-requirements.txt``
1435+ This is a `requirements file`_ used to upgrade pip itself to a
1436+ reasonably recent version. We use this so that we aren't confined to
1437+ features of pip supported by the version supplied by the operating
1438+ system.
1439+
1440+``constraints.txt``
1441+ This is a `constraints file`_ that specifies the precise versions of the
1442+ dependencies we use. This means that we can have several versions of a
1443+ dependency available locally, but we only build the precise one we
1444+ specify. We give an example of its use below.
1445+
1446+``env``
1447+ The ``env`` directory holds a virtualenv built from the downloaded
1448+ distributions. You have one of these per branch (virtualenvs do not
1449+ relocate especially well). This directory is local to your system--we
1450+ do not manage it in a branch.
1451
1452 ``download-cache``
1453 The ``download-cache`` directory is a set of downloaded distributions--that
1454@@ -342,20 +126,19 @@
1455 download cache as a shared resource across all of our developers with a git
1456 branch in a Launchpad project called ``lp-source-dependencies``.
1457
1458- When we run buildout, Buildout reads a special key and value in the
1459- ``[buildout]`` section: ``install-from-cache = true``. This means that, by
1460- default, Buildout will *not* use network access to find packages, but
1461- *only* look in the download cache. This has many advantages.
1462+ We run pip with the ``--no-index`` and ``--find-links`` options, which
1463+ cause it to *not* use network access to find packages, but *only* look
1464+ in the download cache. This has many advantages.
1465
1466 - First, it helps us keep our deployment boxes from needing network access
1467 out to PyPI and other download sites.
1468
1469- - Second, it makes the buildout much faster, because it does not have to
1470+ - Second, it makes the build much faster, because it does not have to
1471 look out on the net for every dependency.
1472
1473- - Third, it makes the buildout more repeatable, because we are more
1474- insulated from outages at download sites such as PyPI, and poor release
1475- management.
1476+ - Third, it makes the build more repeatable, because we are more
1477+ insulated from outages at download sites such as PyPI, and poor
1478+ release management.
1479
1480 - Fourth, it makes our deployments more auditable, because we can tell
1481 exactly what we are deploying.
1482@@ -366,24 +149,25 @@
1483 The downside is that adding and upgrading packages takes a small additional
1484 step, as we'll see below.
1485
1486-In addition to these seven listings, after you have run the Makefile (or
1487-``bin/buildout``), you will see an additional listing:
1488+In addition to these directory entries, after you have run the Makefile, you
1489+will see an additional entry:
1490
1491 ``bin``
1492- The ``bin`` directory has already been discussed many times. After running
1493- the bootstrap.py, it holds the ``buildout`` script which can be used to
1494- process Buildout configuration files. In Launchpad's case, after running
1495- the buildout, it also holds many executables, including scripts to test
1496- Launchpad; to run it; to run Python or IPython with Launchpad's sourcetree
1497- and dependencies available; to run harness or iharness (with IPython) with
1498- the sourcetree, dependencies, and database connections; or to perform
1499- several other tasks. For now, the Makefile provides aliases for many of
1500- these.
1501-
1502-Now that you have an introduction to the pertinent files and directories, we'll
1503-move on to trying to perform tasks in the buildout. We'll discuss adding a
1504-dependency, upgrading a dependency, adding a script, adding an arbitrary file,
1505-and working with unreleased packages.
1506+ The ``bin`` directory has already been discussed many times. After
1507+ running the build, it also holds many executables, including scripts to
1508+ test Launchpad; to run it; to run Python or IPython with Launchpad's
1509+ sourcetree and dependencies available; to run harness or iharness (with
1510+ IPython) with the sourcetree, dependencies, and database connections; or
1511+ to perform several other tasks. For now, the Makefile provides aliases
1512+ for many of these.
1513+
1514+Now that you have an introduction to the pertinent files and directories,
1515+we'll move on to trying to perform maintenance tasks. We'll discuss adding
1516+a dependency, upgrading a dependency, adding a script, adding an arbitrary
1517+file, and working with unreleased packages.
1518+
1519+.. _`requirements file`: https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format
1520+.. _`constraints file`: https://pip.pypa.io/en/stable/user_guide/#constraints-files
1521
1522 Add a Package
1523 =============
1524@@ -393,63 +177,81 @@
1525 1. Add the new package to the ``setup.py`` file in the ``install_requires``
1526 list.
1527
1528- Generally, our policy is to only set minimum version numbers in this file,
1529- or none at all. It doesn't really matter for an application like
1530- Launchpad, but it a good rule for library packages, so we follow it for
1531- consistency. Therefore, we might simply add ``'lazr.foo'`` to
1532- install_requires, or ``'lazr.foo >= 1.1'`` if we know that we are depending
1533- on features introduced in version 1.1 of lazr.foo.
1534-
1535-2. [OPTIONAL] If you know it, add the desired version number to versions.cfg
1536- now.
1537-
1538- For instance, if you know you want lazr.foo 1.1.2, add this line to the
1539- ``[versions]`` section of ``versions.cfg``::
1540-
1541- lazr.foo = 1.1.2
1542-
1543-3. [OPTIONAL] Add the desired distribution of lazr.foo 1.1.2 to the
1544- ``download-cache/dist`` directory.
1545-
1546-4. Run the following command (or your variation)::
1547-
1548- ./bin/buildout -v buildout:install-from-cache=false | tee out.txt | grep 'Picked'
1549-
1550- The first part (``./bin/buildout -v
1551- buildout:install-from-cache=false``) will run buildout, allowing
1552- it to download source packages from the Internet to
1553- ``download-cache/dist``. The second part (``tee out.txt``) will
1554- dump the full output to the ``out.txt`` file in case you need to
1555- debug a problem. The last part (``grep 'Picked'``) will filter the
1556- output so that only additional packages--dependencies of your
1557- dependency--will be listed. You need to see if it means that you
1558- have dependencies, some of which may be indirect
1559- dependencies. We'll see how to do this with an example. Here's an
1560- imaginary output::
1561-
1562- Picked: ipython = 0.9.1
1563- Picked: lazr.foom = 1.4
1564- Picked: zope.bar = 3.6.1
1565- Picked: z3c.shazam = 2.0.1
1566-
1567- In our example, this means that these packages have been added to
1568- your ``download-cache/dist`` directory. You now need to add those
1569- versions to the ``versions.cfg`` file::
1570-
1571- ipython = 0.9.1
1572- lazr.foom = 1.4
1573- zope.bar = 3.6.1
1574- z3c.shazam = 2.0.1
1575-
1576- Note that the output might include at least one, and possibly
1577- more, spurious "Picked:" listings. ipython, in particular, has
1578- shown up in the past incorrectly--that is, when you try to add the
1579- file to the download-cache/dist directory, you'll discover that it
1580- is already there; and you'll see that versions.cfg already
1581- specifies the version. As long as the test passes (see step 5,
1582- below), you can ignore this.
1583-
1584-5. Test.
1585+ Generally, our policy is to only set minimum version numbers in this
1586+ file, or none at all. It doesn't really matter for an application like
1587+ Launchpad, but it's a good rule for library packages, so we follow it
1588+ for consistency. Therefore, we might simply add ``'lazr.foo'`` to
1589+ install_requires, or ``'lazr.foo>=1.1'`` if we know that we are
1590+ depending on features introduced in version 1.1 of lazr.foo.
1591+
1592+2. [OPTIONAL] Add the desired package to the ``download-cache/dist``
1593+ directory.
1594+
1595+ You should only need to do this if the package is one that doesn't exist
1596+ on PyPI at all (which should be unusual). Otherwise, it's less
1597+ error-prone to fetch the desired package from PyPI along with any new
1598+ dependencies it may have.
1599+
1600+3. Run the following command (or your variation)::
1601+
1602+ bin/pip install --no-binary :all: lazr.foo
1603+
1604+ This will either produce some errors which you'll need to fix, or it
1605+ will succeed and finish with a line such as this::
1606+
1607+ Successfully installed lazr-foo-1.1.2 z3c.shazam-2.0.1 zope.bar-3.6.1
1608+
1609+ You can use `requirements specifiers`_ on this command line, so, for
1610+ instance, if you already know you want lazr.foo 1.1.2, you might run
1611+ this command instead::
1612+
1613+ bin/pip install --no-binary :all: lazr.foo==1.1.2
1614+
1615+ You may need to use the ``--ignore-installed`` option if some of the
1616+ packages involved happen to be installed system-wide on your build
1617+ system, but we want to consume them as Python packages. You can spot
1618+ this situation by looking for output like this from ``pip install``:
1619+
1620+ Requirement already satisfied: netaddr>=0.7.6 in /usr/lib/python2.7/dist-packages (from python-keystoneclient==0.7.1)
1621+
1622+ If you do this, check the output very carefully, as it can easily be
1623+ wrong. (This will stop being a problem once we stop using system
1624+ site-packages.)
1625+
1626+4. Add the successfully-installed packages to the shared download cache for
1627+ future use.
1628+
1629+ bin/pip download -d download-cache/dist/ --no-deps \
1630+ --no-binary :all: ...
1631+
1632+ You'll need to copy the list of packages from the "Successfully
1633+ installed" line above, replacing the ``-`` immediately before each
1634+ version number with ``==`` to turn each package/version pair into a
1635+ requirements specifier. So, in the case above, you would run:
1636+
1637+ bin/pip download -d download-cache/dist/ --no-deps \
1638+ --no-binary :all: \
1639+ lazr-foo==1.1.2 z3c.shazam==2.0.1 zope.bar==3.6.1
1640+
1641+ This will normally be able to fetch package files that were saved to
1642+ your ``pip`` cache directory (``~/.cache/pip/`` by default) by ``pip
1643+ install``, so it shouldn't need to download them from PyPI again.
1644+
1645+ We use ``--no-deps`` here because ``pip install`` has already done the
1646+ hard work of resolving dependencies and told us the result, and because
1647+ ``pip download`` doesn't consider what's currently installed and so is
1648+ liable to download too much otherwise.
1649+
1650+5. Add the new versions to the ``constraints.txt`` file, still using the
1651+ requirements specifier syntax::
1652+
1653+ lazr.foo==1.1.2
1654+ z3c.shazam==2.0.1
1655+ zope.bar==3.6.1
1656+
1657+6. Run ``make``. If it breaks, go back to step 3.
1658+
1659+7. Test.
1660
1661 Note that you can tell ``ec2 test`` to include all uncommitted
1662 distributions from the local download-cache in its tests with the
1663@@ -459,7 +261,7 @@
1664 *not* explicitly tell ec2 test to include or ignore the
1665 uncommitted distributions, it will refuse to start an instance.
1666
1667-6. Check old versions in the download-cache. If you are sure that
1668+8. Check old versions in the download-cache. If you are sure that
1669 they are not in use any more, *anywhere*, then remove them to save
1670 checkout space. More explicitly, check with the LOSAs to see if
1671 they are in use in production and send an email to
1672@@ -470,7 +272,7 @@
1673 information by using ``git log`` on the newer (replacement)
1674 download-cache/dist file for the particular package.
1675
1676-7. Now you need to share your package changes with the rest of the
1677+9. Now you need to share your package changes with the rest of the
1678 team. You must do this before submitting your Launchpad branch to
1679 PQM or else your branch will not build properly anywhere else,
1680 including buildbot. Commit the changes (``cd download-cache``,
1681@@ -482,32 +284,32 @@
1682 change in version number, or else very bad inconsistencies and
1683 confusion across build environments will happen.
1684
1685+.. _`requirements specifiers`: https://pip.pypa.io/en/stable/reference/pip_install/#requirement-specifiers
1686+
1687
1688 Upgrade a Package
1689 =================
1690
1691 Sometimes you need to upgrade a dependency. This may require additional
1692-dependency additions or upgrades.
1693-
1694-If you already know what version you want, the simplest thing to try is to
1695-modify versions.cfg to specify the new version and run steps 4, 5, and 6 of the
1696-`Add a Package`_ instructions.
1697-
1698-If you don't know what version you want, but just want to see what happens when
1699-you upgrade to the most recent revision, you can clear out the versions of the
1700-packages for upgrade and give it a try (that is, run steps 4, 5, and 6 of the
1701-`Add a Package`_ instructions). Note that, when not given an explicit version
1702-number, our buildout is set to prefer final releases over alpha and beta
1703-releases. If you want to temporarily override this behaviour, include
1704-``buildout:prefer-final=false`` as another argument to ``bin/buildout``.
1705+dependency additions or upgrades. In general, this works just like adding a
1706+new package, so follow the `Add a Package`_ instructions above.
1707+
1708+If you know what version you want, specify it explicitly on the ``pip
1709+install`` line.
1710+
1711+If you don't know what version you want, but just want to see what happens
1712+when you upgrade to the most recent version, then omit the version and
1713+specify the ``--upgrade`` option to ``pip install``. Note that, when not
1714+given an explicit version number, pip prefers final releases over alpha and
1715+beta releases. If you want to temporarily override this behaviour, use the
1716+``--pre`` option to ``pip``.
1717
1718 Add a Script
1719 ============
1720
1721 We often need scripts that are run in a certain environment defined by Python
1722 dependencies, and sometimes even different Python executables. Several of the
1723-scripts we have are specified using the setuptools-based spelling that the
1724-``zc.recipe.egg`` recipe supports.
1725+scripts we have are specified using setuptools.
1726
1727 For the common case, in ``setup.py``, add a string in the ``console_scripts``
1728 list of the ``entry_points`` argument. Here's an example string::
1729@@ -518,11 +320,6 @@
1730 ``start_launchpad`` function in the
1731 ``lp.scripts.runlaunchpad`` module.
1732
1733-See the `zc.recipe.egg documentation`_ for more information on how to add
1734-scripts using this method.
1735-
1736-.. _`zc.recipe.egg documentation`: http://pypi.python.org/pypi/zc.recipe.egg
1737-
1738 Work with Unreleased or Forked Packages
1739 =======================================
1740
1741@@ -531,110 +328,48 @@
1742 access. Similarly, we may require a patched or unreleased version of a package
1743 for some purpose. Hopefully, these situations will be rare, but they do occur.
1744
1745-While `other answers`_ are available for Buildout, our solution is to use the
1746-download-cache. Basically, make a custom source distribution with a unique
1747-suffix in the name, and use it (and its version name) for the normal process of
1748-adding or updating a package, as described above. Because the custom package
1749-is in the download-cache, it will be found and used.
1750-
1751-Here's an example of making a custom distribution of FeedValidator.
1752-
1753-FeedValidator is a Subversion project. We check it out::
1754-
1755- svn co http://feedvalidator.googlecode.com/svn/trunk/feedvalidator/src feedvalidator
1756-
1757-Next, we ``cd feedvalidator``, and, using a Python that has setuptools
1758-installed, we run the following command::
1759-
1760- python setup.py egg_info -r -bDEV sdist
1761-
1762-For this example, imagine that the current revision of the repository is 1049.
1763-Because setuptools has built-in Subversion support, the command above will
1764-create a tar.gz in the ``dist`` directory named
1765-``feedvalidator-0.0.0DEV-r1049.tar.gz``. The -r option specifies that the
1766-subversion revision should be part of the package name. The -bDEV option
1767-specifies that the 'DEV' suffix should be added to the version number.
1768-
1769-We could then put the tar.gz file in Launchpad's ``download-cache/dist``
1770-directory, specify ``feedvalidator = 0.0.0DEV-r1049`` in the ``versions.cfg``
1771-file, and proceed with the usual steps to update or add a new package.
1772-
1773-If you use a bzr branch, you might use the ``-d`` option instead of the ``-r``
1774-option when you create the distribution. This will add the date instead of the
1775-revision::
1776-
1777- python setup.py egg_info -d -bDEV sdist
1778-
1779-For instance, this might produce a distribution for the ``lazr.restful``
1780-project with a name like this: ``lazr.restful-0.9.1DEV-20090512.tar.gz``.
1781-
1782-See the setuptools documentation for more information about `the egg_info
1783-command`_.
1784-
1785-It is also possible that setup.py does not support the egg_info command and
1786-it is sufficient to just run the sdist command. It adds the current revision
1787-of the bzr branch to the version number::
1788-
1789- python setup.py sdist
1790-
1791-For instance, this might produce a distribution for the ``testtools``
1792-project with a name like this: ``testtools-0.9.12-r228.tar.gz``.
1793+At the moment, our solution is to use the download-cache. Basically, make a
1794+custom source distribution with a unique suffix in the name, and use it (and
1795+its version name) for the normal process of adding or updating a package, as
1796+described above. Because the custom package is in the download-cache, it
1797+will be found and used.
1798+
1799+In general, the suffix should comply with `PEP 440`_; in the case of a
1800+forked package, you should use ``lp`` as a local version identifier. For
1801+example, you might start by appending ``+lp1``, followed by ``+lp2`` and so
1802+on for further revisions.
1803
1804 .. _FeedValidator: http://feedvalidator.org/
1805
1806-.. _`other answers`: http://pypi.python.org/pypi/zc.buildoutsftp
1807-
1808-.. _`the egg_info command`: http://peak.telecommunity.com/DevCenter/setuptools#tagging-and-daily-build-or-snapshot-releases
1809+.. _`PEP 440`: https://www.python.org/dev/peps/pep-0440/
1810
1811 Developing a Dependent Library In Parallel
1812 ==========================================
1813
1814-Sometimes you need to iterate on change to a library used by Launchpad
1815-that is managed by buildout as an egg. You could just edit what it is in
1816-the ``eggs`` directory, but it is harder to produce a patch while doing
1817-this. You could instead grab a branch of the libarary and produce an egg
1818-everytime you make a change and make buildout use the new egg, but this is
1819-slow.
1820-
1821-buildout defaults to only using the current directory as code that will
1822-be used without creating a distribution. We can arrange for it to use other
1823-paths as well, so we can use a checkout of any code we like, with changes
1824-being picked up instantly without us having to create a distribution.
1825-
1826-To do this add the extra paths to the ``develop`` key in the ``[buildout]``
1827-section of ``buildout.cfg``::
1828-
1829- [buildout]
1830- develop = .
1831- path/to/branch
1832-
1833-and re-run ``make``.
1834+Sometimes you need to iterate on change to a library used by Launchpad that
1835+is managed by pip. You could just edit what is in the ``env`` directory,
1836+but it is harder to produce a patch while doing this. You could instead
1837+grab a branch of the library and produce an sdist every time you make a
1838+change and make pip use the new sdist, but this is slow.
1839+
1840+Instead, we can use "editable mode" so that changes are picked up instantly
1841+without us having to create a distribution. For example:
1842+
1843+ bin/pip install -e /path/to/branch
1844
1845 Now any changes you make in that path will be picked up, and you are free
1846 to make the changes you need and test them in the Launchpad environment.
1847
1848 Once you are finished you can produce a distribution as above for inclusion
1849-in to Launchpad, as well as sending your patch upstream. At that point you
1850-are free to revert the configuration to only develop Launchpad. You should
1851-not submit your branch with this change in the configuration as it will
1852-not work for others.
1853-
1854-Be aware that you may have to change the version for the package in
1855-``versions.cfg`` if there is a difference between the version in the
1856-``eggs`` directory and the one in the ``setup.py`` that you pointed to
1857-in the ``develop`` key.
1858-
1859-One thing to be wary of is that setuptools treats "develop eggs" created
1860-by this process with the same precedence as system packages. That means
1861-that if the version in the ``setup.py`` at the path that you put in the
1862-``develop`` key is the same as the version installed system wide, setuptools
1863-may pick the wrong one. If that happens then increase the version in
1864-setup.py and setuptools will take it.
1865+in to Launchpad, as well as sending your patch upstream. At that point you
1866+are free to revert the configuration to only develop Launchpad. Make sure
1867+to test with the final distribution before submitting your branch.
1868
1869 =====================
1870 Possible Future Goals
1871 =====================
1872
1873+- Use wheels.
1874 - No longer use system site-packages.
1875 - No longer use make.
1876 - Get rid of the sourcecode directory.
1877
1878=== removed file 'ez_setup.py'
1879--- ez_setup.py 2012-06-29 08:40:05 +0000
1880+++ ez_setup.py 1970-01-01 00:00:00 +0000
1881@@ -1,288 +0,0 @@
1882-#!python
1883-
1884-# NOTE TO LAUNCHPAD DEVELOPERS: This is a bootstrapping file from the
1885-# setuptools project. It is imported by our setup.py.
1886-
1887-"""Bootstrap setuptools installation
1888-
1889-If you want to use setuptools in your package's setup.py, just include this
1890-file in the same directory with it, and add this to the top of your setup.py::
1891-
1892- from ez_setup import use_setuptools
1893- use_setuptools()
1894-
1895-If you want to require a specific version of setuptools, set a download
1896-mirror, or use an alternate download directory, you can do so by supplying
1897-the appropriate options to ``use_setuptools()``.
1898-
1899-This file can also be run as a script to install or upgrade setuptools.
1900-"""
1901-import sys
1902-DEFAULT_VERSION = "0.6c11"
1903-DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
1904-
1905-md5_data = {
1906- 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
1907- 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
1908- 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
1909- 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
1910- 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
1911- 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
1912- 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
1913- 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
1914- 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
1915- 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
1916- 'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
1917- 'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
1918- 'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
1919- 'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
1920- 'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
1921- 'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
1922- 'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
1923- 'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
1924- 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
1925- 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
1926- 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
1927- 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
1928- 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
1929- 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
1930- 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
1931- 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
1932- 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
1933- 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
1934- 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
1935- 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
1936- 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
1937- 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
1938- 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
1939- 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
1940- 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
1941- 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
1942- 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
1943- 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
1944- 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
1945- 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
1946- 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
1947- 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
1948-}
1949-
1950-import sys, os
1951-try: from hashlib import md5
1952-except ImportError: from md5 import md5
1953-
1954-def _validate_md5(egg_name, data):
1955- if egg_name in md5_data:
1956- digest = md5(data).hexdigest()
1957- if digest != md5_data[egg_name]:
1958- print >>sys.stderr, (
1959- "md5 validation of %s failed! (Possible download problem?)"
1960- % egg_name
1961- )
1962- sys.exit(2)
1963- return data
1964-
1965-def use_setuptools(
1966- version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
1967- download_delay=15
1968-):
1969- """Automatically find/download setuptools and make it available on sys.path
1970-
1971- `version` should be a valid setuptools version number that is available
1972- as an egg for download under the `download_base` URL (which should end with
1973- a '/'). `to_dir` is the directory where setuptools will be downloaded, if
1974- it is not already available. If `download_delay` is specified, it should
1975- be the number of seconds that will be paused before initiating a download,
1976- should one be required. If an older version of setuptools is installed,
1977- this routine will print a message to ``sys.stderr`` and raise SystemExit in
1978- an attempt to abort the calling script.
1979- """
1980- was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
1981- def do_download():
1982- egg = download_setuptools(version, download_base, to_dir, download_delay)
1983- sys.path.insert(0, egg)
1984- import setuptools; setuptools.bootstrap_install_from = egg
1985- try:
1986- import pkg_resources
1987- except ImportError:
1988- return do_download()
1989- try:
1990- pkg_resources.require("setuptools>="+version); return
1991- except pkg_resources.VersionConflict as e:
1992- if was_imported:
1993- print >>sys.stderr, (
1994- "The required version of setuptools (>=%s) is not available, and\n"
1995- "can't be installed while this script is running. Please install\n"
1996- " a more recent version first, using 'easy_install -U setuptools'."
1997- "\n\n(Currently using %r)"
1998- ) % (version, e.args[0])
1999- sys.exit(2)
2000- else:
2001- del pkg_resources, sys.modules['pkg_resources'] # reload ok
2002- return do_download()
2003- except pkg_resources.DistributionNotFound:
2004- return do_download()
2005-
2006-def download_setuptools(
2007- version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
2008- delay = 15
2009-):
2010- """Download setuptools from a specified location and return its filename
2011-
2012- `version` should be a valid setuptools version number that is available
2013- as an egg for download under the `download_base` URL (which should end
2014- with a '/'). `to_dir` is the directory where the egg will be downloaded.
2015- `delay` is the number of seconds to pause before an actual download attempt.
2016- """
2017- import urllib2, shutil
2018- egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
2019- url = download_base + egg_name
2020- saveto = os.path.join(to_dir, egg_name)
2021- src = dst = None
2022- if not os.path.exists(saveto): # Avoid repeated downloads
2023- try:
2024- from distutils import log
2025- if delay:
2026- log.warn("""
2027----------------------------------------------------------------------------
2028-This script requires setuptools version %s to run (even to display
2029-help). I will attempt to download it for you (from
2030-%s), but
2031-you may need to enable firewall access for this script first.
2032-I will start the download in %d seconds.
2033-
2034-(Note: if this machine does not have network access, please obtain the file
2035-
2036- %s
2037-
2038-and place it in this directory before rerunning this script.)
2039----------------------------------------------------------------------------""",
2040- version, download_base, delay, url
2041- ); from time import sleep; sleep(delay)
2042- log.warn("Downloading %s", url)
2043- src = urllib2.urlopen(url)
2044- # Read/write all in one block, so we don't create a corrupt file
2045- # if the download is interrupted.
2046- data = _validate_md5(egg_name, src.read())
2047- dst = open(saveto,"wb"); dst.write(data)
2048- finally:
2049- if src: src.close()
2050- if dst: dst.close()
2051- return os.path.realpath(saveto)
2052-
2053-
2054-
2055-
2056-
2057-
2058-
2059-
2060-
2061-
2062-
2063-
2064-
2065-
2066-
2067-
2068-
2069-
2070-
2071-
2072-
2073-
2074-
2075-
2076-
2077-
2078-
2079-
2080-
2081-
2082-
2083-
2084-
2085-
2086-
2087-
2088-def main(argv, version=DEFAULT_VERSION):
2089- """Install or upgrade setuptools and EasyInstall"""
2090- try:
2091- import setuptools
2092- except ImportError:
2093- egg = None
2094- try:
2095- egg = download_setuptools(version, delay=0)
2096- sys.path.insert(0,egg)
2097- from setuptools.command.easy_install import main
2098- return main(list(argv)+[egg]) # we're done here
2099- finally:
2100- if egg and os.path.exists(egg):
2101- os.unlink(egg)
2102- else:
2103- if setuptools.__version__ == '0.0.1':
2104- print >>sys.stderr, (
2105- "You have an obsolete version of setuptools installed. Please\n"
2106- "remove it from your system entirely before rerunning this script."
2107- )
2108- sys.exit(2)
2109-
2110- req = "setuptools>="+version
2111- import pkg_resources
2112- try:
2113- pkg_resources.require(req)
2114- except pkg_resources.VersionConflict:
2115- try:
2116- from setuptools.command.easy_install import main
2117- except ImportError:
2118- from easy_install import main
2119- main(list(argv)+[download_setuptools(delay=0)])
2120- sys.exit(0) # try to force an exit
2121- else:
2122- if argv:
2123- from setuptools.command.easy_install import main
2124- main(argv)
2125- else:
2126- print "Setuptools version",version,"or greater has been installed."
2127- print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
2128-
2129-def update_md5(filenames):
2130- """Update our built-in md5 registry"""
2131-
2132- import re
2133-
2134- for name in filenames:
2135- base = os.path.basename(name)
2136- f = open(name,'rb')
2137- md5_data[base] = md5(f.read()).hexdigest()
2138- f.close()
2139-
2140- data = [" %r: %r,\n" % it for it in md5_data.items()]
2141- data.sort()
2142- repl = "".join(data)
2143-
2144- import inspect
2145- srcfile = inspect.getsourcefile(sys.modules[__name__])
2146- f = open(srcfile, 'rb'); src = f.read(); f.close()
2147-
2148- match = re.search("\nmd5_data = {\n([^}]+)}", src)
2149- if not match:
2150- print >>sys.stderr, "Internal error!"
2151- sys.exit(2)
2152-
2153- src = src[:match.start(1)] + repl + src[match.end(1):]
2154- f = open(srcfile,'w')
2155- f.write(src)
2156- f.close()
2157-
2158-
2159-if __name__=='__main__':
2160- if len(sys.argv)>2 and sys.argv[1]=='--md5update':
2161- update_md5(sys.argv[2:])
2162- else:
2163- main(sys.argv[1:])
2164-
2165-
2166-
2167-
2168-
2169-
2170
2171=== modified file 'lib/lp/codehosting/__init__.py'
2172--- lib/lp/codehosting/__init__.py 2012-09-06 00:01:38 +0000
2173+++ lib/lp/codehosting/__init__.py 2017-12-19 09:48:36 +0000
2174@@ -1,4 +1,4 @@
2175-# Copyright 2009 Canonical Ltd. This software is licensed under the
2176+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
2177 # GNU Affero General Public License version 3 (see the file LICENSE).
2178
2179 """Launchpad code-hosting system.
2180@@ -26,15 +26,7 @@
2181
2182 def get_bzr_path():
2183 """Find the path to the copy of Bazaar for this rocketfuel instance"""
2184- bzr_in_egg_path = os.path.join(
2185- os.path.dirname(os.path.dirname(bzrlib.__file__)),
2186- 'EGG-INFO/scripts/bzr')
2187- if os.path.exists(bzr_in_egg_path):
2188- return bzr_in_egg_path
2189- else:
2190- return os.path.join(
2191- os.path.dirname(os.path.dirname(bzrlib.__file__)),
2192- 'bzr')
2193+ return os.path.join(config.root, 'bin', 'bzr')
2194
2195
2196 def _get_bzr_plugins_path():
2197
2198=== modified file 'lib/lp/scripts/harness.py'
2199--- lib/lp/scripts/harness.py 2013-06-20 05:50:00 +0000
2200+++ lib/lp/scripts/harness.py 2017-12-19 09:48:36 +0000
2201@@ -1,4 +1,4 @@
2202-# Copyright 2004-2012 Canonical Ltd. This software is licensed under the
2203+# Copyright 2004-2017 Canonical Ltd. This software is licensed under the
2204 # GNU Affero General Public License version 3 (see the file LICENSE).
2205
2206 """Scripts for starting a Python prompt with Launchpad initialized.
2207@@ -12,10 +12,8 @@
2208 __metaclass__ = type
2209 __all__ = ['python', 'ipython']
2210
2211-# This has setup.py scripts. It is usually installed via buildout.
2212-#
2213+# This has entry points with corresponding scripts installed by setup.py.
2214
2215-#
2216 import os
2217 import readline
2218 import rlcompleter
2219
2220=== removed file 'lib/lp/scripts/utilities/bzr.py'
2221--- lib/lp/scripts/utilities/bzr.py 2017-01-18 00:55:27 +0000
2222+++ lib/lp/scripts/utilities/bzr.py 1970-01-01 00:00:00 +0000
2223@@ -1,13 +0,0 @@
2224-# Copyright 2010-2017 Canonical Ltd. This software is licensed under the
2225-# GNU Affero General Public License version 3 (see the file LICENSE).
2226-
2227-import pkg_resources
2228-
2229-
2230-def main():
2231- # Run the script.
2232- bzr_distribution = pkg_resources.get_distribution(
2233- pkg_resources.Requirement.parse('bzr'))
2234- namespace = globals().copy()
2235- namespace['__name__'] = '__main__'
2236- bzr_distribution.run_script('bzr', namespace)
2237
2238=== modified file 'lib/lp/scripts/utilities/importfascist.py'
2239--- lib/lp/scripts/utilities/importfascist.py 2016-07-16 07:53:54 +0000
2240+++ lib/lp/scripts/utilities/importfascist.py 2017-12-19 09:48:36 +0000
2241@@ -31,6 +31,10 @@
2242 'json.decoder': set(['JSONDecodeError']),
2243 'openid.fetchers': set(['Urllib2Fetcher']),
2244 'openid.message': set(['NamespaceAliasRegistrationError']),
2245+ # Exported as shlex.quote in Python 3.
2246+ 'pipes': set(['quote']),
2247+ # Exported in Python 3, but missing and so not exported in Python 2.
2248+ 'shlex': set(['quote']),
2249 'storm.database': set(['STATE_DISCONNECTED']),
2250 'textwrap': set(['dedent']),
2251 'testtools.testresult.real': set(['_details_to_str']),
2252
2253=== modified file 'lib/lp/services/job/runner.py'
2254--- lib/lp/services/job/runner.py 2017-06-14 11:40:16 +0000
2255+++ lib/lp/services/job/runner.py 2017-12-19 09:48:36 +0000
2256@@ -462,7 +462,8 @@
2257 if 'LPCONFIG' in os.environ:
2258 env['LPCONFIG'] = os.environ['LPCONFIG']
2259 env['PYTHONPATH'] = os.pathsep.join(sys.path)
2260- starter = main.ProcessStarter(env=env)
2261+ starter = main.ProcessStarter(
2262+ bootstrap="import _pythonpath\n" + main.BOOTSTRAP, env=env)
2263 super(TwistedJobRunner, self).__init__(logger, error_utility)
2264 self.job_source = job_source
2265 self.import_name = '%s.%s' % (
2266
2267=== modified file 'lib/lp/services/mailman/monkeypatches/mm_cfg.py.in'
2268--- lib/lp/services/mailman/monkeypatches/mm_cfg.py.in 2011-11-11 21:59:00 +0000
2269+++ lib/lp/services/mailman/monkeypatches/mm_cfg.py.in 2017-12-19 09:48:36 +0000
2270@@ -1,9 +1,8 @@
2271 # Automatically generated by runlaunchpad.py
2272
2273 # Initialize sys.path so that the Mailman processes, which use the standard
2274-# system Python instead of buildout's bin/py, can find all the necessary
2275-# packages and modules. Some of these are in sourcecode and some are in
2276-# buildout eggs.
2277+# system Python instead of bin/py, can find all the necessary packages and
2278+# modules. Some of these are in sourcecode and some are in the virtualenv.
2279 #
2280 # This is a two-step process. First, we hack sys.path in order to find a
2281 # directory containing _pythonpath. Then the _pythonpath module does all the
2282
2283=== modified file 'lib/lp/services/scripts/tests/test_logger.txt'
2284--- lib/lp/services/scripts/tests/test_logger.txt 2011-12-29 05:29:36 +0000
2285+++ lib/lp/services/scripts/tests/test_logger.txt 2017-12-19 09:48:36 +0000
2286@@ -7,12 +7,6 @@
2287 ... import sys
2288 ... import subprocess
2289 ... from lp.services.config import config
2290- ... if 'env' in kw:
2291- ... # We want to make sure that the subprocess will have the
2292- ... # benefit of all of the dependency paths inserted by the
2293- ... # buildout. This is already set up in our environment's
2294- ... # PYTHONPATH, so use it.
2295- ... kw['env']['PYTHONPATH'] = os.environ['PYTHONPATH']
2296 ... test_script_path = os.path.join(
2297 ... config.root, 'lib', 'lp', 'services',
2298 ... 'scripts', 'tests', 'loglevels.py')
2299
2300=== modified file 'lib/lp_sitecustomize.py'
2301--- lib/lp_sitecustomize.py 2017-10-05 12:45:46 +0000
2302+++ lib/lp_sitecustomize.py 2017-12-19 09:48:36 +0000
2303@@ -1,14 +1,15 @@
2304 # Copyright 2009-2017 Canonical Ltd. This software is licensed under the
2305 # GNU Affero General Public License version 3 (see the file LICENSE).
2306
2307-# This file is imported by parts/scripts/sitecustomize.py, as set up in our
2308-# buildout.cfg (see the "initialization" key in the "[scripts]" section).
2309+# This file is imported by _pythonpath.py and by the standard Launchpad
2310+# script preamble (see LPScriptWriter in setup.py).
2311
2312 from collections import defaultdict
2313 import itertools
2314 import logging
2315 import os
2316 import warnings
2317+import sys
2318
2319 from twisted.internet.defer import (
2320 Deferred,
2321@@ -172,14 +173,15 @@
2322 silence_swiftclient_logger()
2323
2324
2325-def main(instance_name):
2326- # This is called by our custom buildout-generated sitecustomize.py
2327- # in parts/scripts/sitecustomize.py. The instance name is sent to
2328- # buildout from the Makefile, and then inserted into
2329- # sitecustomize.py. See buildout.cfg in the "initialization" value
2330- # of the [scripts] section for the code that goes into this custom
2331- # sitecustomize.py. We do all actual initialization here, in a more
2332- # visible place.
2333+def main(instance_name=None):
2334+ # This is called by _pythonpath.py and by the standard Launchpad script
2335+ # preamble (see LPScriptWriter in setup.py). The instance name is sent
2336+ # to setup.py from the Makefile, and then written to env/instance_name.
2337+ # We do all actual initialization here, in a more visible place.
2338+ if instance_name is None:
2339+ instance_name_path = os.path.join(sys.prefix, 'instance_name')
2340+ with open(instance_name_path) as instance_name_file:
2341+ instance_name = instance_name_file.read().rstrip('\n')
2342 if instance_name and instance_name != 'development':
2343 # See bug 656213 for why we do this carefully.
2344 os.environ.setdefault('LPCONFIG', instance_name)
2345
2346=== added file 'pip-requirements.txt'
2347--- pip-requirements.txt 1970-01-01 00:00:00 +0000
2348+++ pip-requirements.txt 2017-12-19 09:48:36 +0000
2349@@ -0,0 +1,1 @@
2350+pip==9.0.1
2351
2352=== removed file 'setup.cfg'
2353--- setup.cfg 2014-01-30 15:04:06 +0000
2354+++ setup.cfg 1970-01-01 00:00:00 +0000
2355@@ -1,12 +0,0 @@
2356-[easy_install]
2357-# These settings control the behaviour of the bootstrap.py script. They keep
2358-# the version of setuptools and zc.buildout found in the download-cache as the
2359-# ones used to make the bin/buildout script. Therefore, if your system Python
2360-# already has setuptools installed, this file will keep the system from going
2361-# out on the network for any distributions during the zc.buildout
2362-# bootstrapping. Also, therefore, if you want to use a newer version of
2363-# setuptools or zc.buildout, you need to put it in ./download-cache/dist and
2364-# commit there, and change the specification in versions.cfg, as described
2365-# generally for dependencies in ./doc/buildout.txt.
2366-allow_hosts =
2367-
2368
2369=== modified file 'setup.py'
2370--- setup.py 2017-12-07 12:05:13 +0000
2371+++ setup.py 2017-12-19 09:48:36 +0000
2372@@ -3,12 +3,129 @@
2373 # Copyright 2009, 2010 Canonical Ltd. This software is licensed under the
2374 # GNU Affero General Public License version 3 (see the file LICENSE).
2375
2376-import ez_setup
2377-
2378-
2379-ez_setup.use_setuptools()
2380-
2381-from setuptools import setup, find_packages
2382+from __future__ import print_function
2383+
2384+from distutils.sysconfig import get_python_lib
2385+import imp
2386+import os.path
2387+from string import Template
2388+import sys
2389+from textwrap import dedent
2390+
2391+from setuptools import (
2392+ find_packages,
2393+ setup,
2394+ )
2395+from setuptools.command.develop import develop
2396+from setuptools.command.easy_install import ScriptWriter
2397+
2398+
2399+class LPScriptWriter(ScriptWriter):
2400+ """A modified ScriptWriter that uses Launchpad's boilerplate.
2401+
2402+ Any script written using this class will set up its environment using
2403+ `lp_sitecustomize` before calling its entry point.
2404+
2405+ The standard setuptools handling of entry_points uses
2406+ `pkg_resources.load_entry_point` to resolve requirements at run-time.
2407+ This involves walking Launchpad's entire dependency graph, which is
2408+ rather slow, and we always build all of our "optional" features anyway,
2409+ so we might as well just take the simplified approach of importing the
2410+ modules we need directly. If we ever want to start using the "extras"
2411+ feature of setuptools then we may want to revisit this.
2412+ """
2413+
2414+ template = Template(dedent("""
2415+ import sys
2416+
2417+ import ${module_name}
2418+
2419+ if __name__ == '__main__':
2420+ sys.exit(${module_name}.${attrs}())
2421+ """))
2422+
2423+ @classmethod
2424+ def get_args(cls, dist, header=None):
2425+ """See `ScriptWriter`."""
2426+ if header is None:
2427+ header = cls.get_header()
2428+ for name, ep in dist.get_entry_map("console_scripts").items():
2429+ cls._ensure_safe_name(name)
2430+ script_text = cls.template.substitute({
2431+ "attrs": ".".join(ep.attrs),
2432+ "module_name": ep.module_name,
2433+ })
2434+ args = cls._get_script_args("console", name, header, script_text)
2435+ for res in args:
2436+ yield res
2437+
2438+
2439+class lp_develop(develop):
2440+ """A modified develop command to handle LP script generation."""
2441+
2442+ def _get_orig_sitecustomize(self):
2443+ env_top = os.path.join(os.path.dirname(__file__), "env")
2444+ system_paths = [
2445+ path for path in sys.path if not path.startswith(env_top)]
2446+ try:
2447+ fp, orig_sitecustomize_path, _ = (
2448+ imp.find_module("sitecustomize", system_paths))
2449+ if fp:
2450+ fp.close()
2451+ except ImportError:
2452+ return ""
2453+ if orig_sitecustomize_path.endswith(".py"):
2454+ with open(orig_sitecustomize_path) as orig_sitecustomize_file:
2455+ orig_sitecustomize = orig_sitecustomize_file.read()
2456+ return dedent("""
2457+ # The following is from
2458+ # %s
2459+ """ % orig_sitecustomize_path) + orig_sitecustomize
2460+ else:
2461+ return ""
2462+
2463+ def install_wrapper_scripts(self, dist):
2464+ if not self.exclude_scripts:
2465+ for args in LPScriptWriter.get_args(dist):
2466+ self.write_script(*args)
2467+
2468+ # Write bin/py for compatibility. This is much like
2469+ # env/bin/python, but if we just symlink to it and try to
2470+ # execute it as bin/py then the virtualenv doesn't get
2471+ # activated. We use -S to avoid importing sitecustomize both
2472+ # before and after the execve.
2473+ py_header = LPScriptWriter.get_header("#!python -S")
2474+ py_script_text = dedent("""\
2475+ import os
2476+ import sys
2477+
2478+ os.execv(sys.executable, [sys.executable] + sys.argv[1:])
2479+ """)
2480+ self.write_script("py", py_header + py_script_text)
2481+
2482+ env_top = os.path.join(os.path.dirname(__file__), "env")
2483+ stdlib_dir = get_python_lib(standard_lib=True, prefix=env_top)
2484+ orig_sitecustomize = self._get_orig_sitecustomize()
2485+ sitecustomize_path = os.path.join(stdlib_dir, "sitecustomize.py")
2486+ with open(sitecustomize_path, "w") as sitecustomize_file:
2487+ sitecustomize_file.write(dedent("""\
2488+ import os
2489+ import sys
2490+
2491+ if "LP_DISABLE_SITECUSTOMIZE" not in os.environ:
2492+ if "lp_sitecustomize" not in sys.modules:
2493+ import lp_sitecustomize
2494+ lp_sitecustomize.main()
2495+ """))
2496+ if orig_sitecustomize:
2497+ sitecustomize_file.write(orig_sitecustomize)
2498+
2499+ # Write out the build-time value of LPCONFIG so that it can be
2500+ # used by scripts as the default instance name.
2501+ instance_name_path = os.path.join(env_top, "instance_name")
2502+ with open(instance_name_path, "w") as instance_name_file:
2503+ print(os.environ["LPCONFIG"], file=instance_name_file)
2504+
2505
2506 __version__ = '2.2.3'
2507
2508@@ -62,7 +179,8 @@
2509 'Markdown',
2510 'mechanize',
2511 'meliae',
2512- 'mock',
2513+ # Pin version for now to avoid confusion with system site-packages.
2514+ 'mock==1.0.1',
2515 'oauth',
2516 'oops',
2517 'oops_amqp',
2518@@ -105,6 +223,7 @@
2519 'txlongpoll',
2520 'txlongpollfixture',
2521 'txpkgupload',
2522+ 'virtualenv-tools3',
2523 'wadllib',
2524 'z3c.pt',
2525 'z3c.ptcompat',
2526@@ -125,6 +244,7 @@
2527 'zope.exceptions',
2528 'zope.formlib',
2529 'zope.i18n',
2530+ 'zope.i18nmessageid',
2531 'zope.interface',
2532 'zope.lifecycleevent',
2533 'zope.location',
2534@@ -158,17 +278,13 @@
2535 "Intended Audience :: Developers",
2536 "Programming Language :: Python",
2537 ],
2538- extras_require=dict(
2539- docs=[
2540- 'Sphinx',
2541- 'z3c.recipe.sphinxdoc',
2542- ]
2543- ),
2544+ cmdclass={
2545+ 'develop': lp_develop,
2546+ },
2547 entry_points=dict(
2548 console_scripts=[ # `console_scripts` is a magic name to setuptools
2549 'build-twisted-plugin-cache = '
2550 'lp.services.twistedsupport.plugincache:main',
2551- 'bzr = lp.scripts.utilities.bzr:main',
2552 'combine-css = lp.scripts.utilities.js.combinecss:main',
2553 'googletestservice = '
2554 'lp.services.googlesearch.googletestservice:main',
2555
2556=== modified file 'utilities/link-external-sourcecode'
2557--- utilities/link-external-sourcecode 2013-04-15 02:36:07 +0000
2558+++ utilities/link-external-sourcecode 2017-12-19 09:48:36 +0000
2559@@ -1,6 +1,6 @@
2560 #!/usr/bin/python
2561 #
2562-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the GNU
2563+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the GNU
2564 # Affero General Public License version 3 (see the file LICENSE).
2565
2566 import optparse
2567@@ -138,7 +138,7 @@
2568 for source, destination in missing_files:
2569 link(source, destination)
2570
2571- for folder_name in ('download-cache', 'eggs'):
2572+ for folder_name in ('download-cache',):
2573 source = abspath(join(options.parent, folder_name))
2574 destination = abspath(join(options.target, folder_name))
2575 if not exists(destination):
2576
2577=== added file 'utilities/relocate-virtualenv'
2578--- utilities/relocate-virtualenv 1970-01-01 00:00:00 +0000
2579+++ utilities/relocate-virtualenv 2017-12-19 09:48:36 +0000
2580@@ -0,0 +1,25 @@
2581+#! /bin/sh
2582+set -e
2583+
2584+# Ensure that a virtualenv is relocated to its current path. This does not
2585+# cope with moving a virtualenv to a different version of the base operating
2586+# system or a different architecture; it only copes with moving it to a
2587+# different filesystem path (perhaps on a different machine as long as it is
2588+# similar enough).
2589+
2590+if [ -z "$1" ]; then
2591+ echo "Usage: $0 ENV_PATH" 2>&1
2592+ exit 1
2593+fi
2594+
2595+# virtualenv-tools does most of the hard work. We must explicitly invoke it
2596+# with the virtualenv's Python, as its #! line is probably wrong.
2597+"$1/bin/python" "$1/bin/virtualenv-tools" --update-path=auto "$1"
2598+
2599+# Fix up a few things that virtualenv-tools doesn't handle.
2600+top="$(readlink -f "$(dirname "$0")/..")"
2601+for path in "$1"/lib/*/site-packages/lp.egg-link; do
2602+ printf '%s/lib\n../' "$top" >"$path"
2603+done
2604+sed -i "s#^find_links = .*#find_links = file://$top/download-cache/dist/#" \
2605+ "$1"/.pydistutils.cfg
2606
2607=== modified file 'utilities/rocketfuel-branch'
2608--- utilities/rocketfuel-branch 2009-06-24 20:15:50 +0000
2609+++ utilities/rocketfuel-branch 2017-12-19 09:48:36 +0000
2610@@ -1,6 +1,6 @@
2611 #! /bin/bash
2612 #
2613-# Copyright 2009 Canonical Ltd. This software is licensed under the
2614+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
2615 # GNU Affero General Public License version 3 (see the file LICENSE).
2616 #
2617 # Create a new branch of LP called "foo" in $LP_PROJECT_PATH/foo, with all the
2618@@ -12,11 +12,6 @@
2619 exit 1
2620 fi
2621
2622-LP_DOWNLOAD_CACHE_PATH=$LP_PROJECT_ROOT/$LP_SOURCEDEPS_DIR/download-cache
2623-LP_EGGS_PATH=$LP_PROJECT_ROOT/$LP_SOURCEDEPS_DIR/eggs
2624-LP_DOWNLOAD_CACHE_PATH=$(eval echo ${LP_DOWNLOAD_CACHE_PATH})
2625-LP_EGGS_PATH=$(eval echo ${LP_EGGS_PATH})
2626-
2627 if [ "x$1" == "x" ]; then
2628 echo "Usage: $0 new-branch-name"
2629 echo "Example: '$0 fixes-bug-54356'"
2630
2631=== modified file 'utilities/rocketfuel-get'
2632--- utilities/rocketfuel-get 2017-11-18 09:49:07 +0000
2633+++ utilities/rocketfuel-get 2017-12-19 09:48:36 +0000
2634@@ -1,6 +1,6 @@
2635 #! /bin/bash
2636 #
2637-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
2638+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
2639 # GNU Affero General Public License version 3 (see the file LICENSE).
2640 #
2641 # Update your copy of trunk and the necessary source dependencies, and make
2642@@ -29,10 +29,8 @@
2643 fi
2644
2645 LP_DOWNLOAD_CACHE_PATH="$LP_PROJECT_ROOT/$LP_SOURCEDEPS_DIR/download-cache"
2646-LP_EGGS_PATH="$LP_PROJECT_ROOT/$LP_SOURCEDEPS_DIR/eggs"
2647 YUI_PATH="$LP_PROJECT_ROOT/$LP_SOURCEDEPS_DIR/yui"
2648 LP_DOWNLOAD_CACHE_PATH="$(eval echo ${LP_DOWNLOAD_CACHE_PATH})"
2649-LP_EGGS_PATH="$(eval echo ${LP_EGGS_PATH})"
2650
2651 # Pull launchpad devel from launchpad.
2652 INITIAL_REV=$(bzr revno "$LP_TRUNK_PATH")
2653@@ -40,7 +38,7 @@
2654 FINAL_REV=$(bzr revno "$LP_TRUNK_PATH")
2655
2656 # Make sure our directories are around.
2657-mkdir -p "$LP_SOURCEDEPS_PATH" "$LP_EGGS_PATH" "$YUI_PATH"
2658+mkdir -p "$LP_SOURCEDEPS_PATH" "$YUI_PATH"
2659
2660 # Get/update the download cache.
2661 if [ -d "$LP_DOWNLOAD_CACHE_PATH" ]
2662
2663=== removed file 'versions.cfg'
2664--- versions.cfg 2017-12-07 12:05:13 +0000
2665+++ versions.cfg 1970-01-01 00:00:00 +0000
2666@@ -1,193 +0,0 @@
2667-[buildout]
2668-extends =
2669- ztk-versions.cfg
2670- zopeapp-versions.cfg
2671-versions = versions
2672-
2673-[versions]
2674-# Alphabetical, case-insensitive, please! :-)
2675-
2676-# lp:~launchpad/ampoule/lp
2677-# post1 Don't add a process back to the ready set if it received an error
2678-# such as a timeout.
2679-ampoule = 0.2.0.post1
2680-amqp = 1.4.9
2681-amqplib = 1.0.2
2682-anyjson = 0.3.3
2683-argparse = 1.2.1
2684-auditor = 0.0.3
2685-auditorclient = 0.0.4
2686-auditorfixture = 0.0.7
2687-backports.lzma = 0.0.3
2688-BeautifulSoup = 3.2.1
2689-billiard = 3.3.0.20
2690-bson = 0.3.3
2691-bzr = 2.6.0.lp.2
2692-celery = 3.1.18
2693-Chameleon = 2.11
2694-cssselect = 0.9.1
2695-cssutils = 0.9.10
2696-d2to1 = 0.2.10
2697-Django = 1.4
2698-dkimpy = 0.5.4
2699-# Required by dkimpy
2700-dnspython = 1.10.0
2701-elementtree = 1.2.6-20050316
2702-epydoc = 3.0.1
2703-extras = 0.0.3
2704-FeedParser = 4.1
2705-feedvalidator = 0.0.0DEV-r1049
2706-fixtures = 0.3.9
2707-FormEncode = 1.2.4
2708-grokcore.component = 1.6
2709-html5browser = 0.0.9
2710-httmock = 1.2.3
2711-httplib2 = 0.8
2712-importlib = 1.0.2
2713-ipython = 0.13.2
2714-iso8601 = 0.1.4
2715-jsautobuild = 0.2
2716-keyring = 0.6.2
2717-kombu = 3.0.30
2718-launchpad-buildd = 136
2719-launchpadlib = 1.10.5
2720-lazr.authentication = 0.1.1
2721-lazr.batchnavigator = 1.2.11
2722-lazr.config = 2.2.1
2723-lazr.delegates = 2.0.4
2724-lazr.enum = 1.1.3
2725-lazr.jobrunner = 0.13
2726-lazr.lifecycle = 1.1
2727-lazr.restful = 0.20.0
2728-lazr.restfulclient = 0.13.2
2729-lazr.smtptest = 1.3
2730-lazr.sshserver = 0.1.3
2731-lazr.testing = 0.1.1
2732-lazr.uri = 1.0.3
2733-libnacl = 1.3.6
2734-lpjsmin = 0.5
2735-manuel = 1.7.2
2736-Markdown = 2.3.1
2737-martian = 0.11
2738-meliae = 0.2.0.final.0
2739-mock = 1.0.1
2740-mocker = 1.1.1
2741-oauth = 1.0
2742-oops = 0.0.13
2743-oops-amqp = 0.0.8b1
2744-oops-datedir-repo = 0.0.23
2745-oops-timeline = 0.0.1
2746-oops-twisted = 0.0.7
2747-oops-wsgi = 0.0.8
2748-ordereddict = 1.1
2749-oslo.config = 1.1.1
2750-paramiko = 1.7.7.2
2751-pbr = 0.5.20
2752-pgbouncer = 0.0.8
2753-pip = 1.4
2754-prettytable = 0.7.2
2755-psycopg2 = 2.6.1
2756-pyasn1 = 0.1.6
2757-pycrypto = 2.6
2758-Pygments = 1.6
2759-pygpgme = 0.2
2760-pyinotify = 0.9.4
2761-pymacaroons = 0.9.2
2762-pyOpenSSL = 0.13
2763-pystache = 0.5.3
2764-python-dateutil = 1.5
2765-python-debian = 0.1.23
2766-python-keystoneclient = 0.3.1
2767-python-memcached = 1.58
2768-python-mimeparse = 0.1.4
2769-# XXX: deryck 2012-08-10
2770-# See lp:~deryck/python-openid/python-openid-fix1034376 which
2771-# reapplied a patch from wgrant to get codehosting going again.
2772-python-openid = 2.2.5-fix1034376
2773-python-subunit = 0.0.8beta
2774-python-swiftclient = 1.5.0
2775-PyYAML = 3.10
2776-pytz = 2017.2
2777-rabbitfixture = 0.3.6
2778-requests = 2.7.0
2779-requests-toolbelt = 0.6.2
2780-setproctitle = 1.1.7
2781-setuptools-git = 1.0
2782-simplejson = 3.8.2
2783-SimpleTAL = 4.3
2784-six = 1.9.0
2785-soupmatchers = 0.2
2786-# lp:~launchpad-committers/storm/with-without-datetime
2787-storm = 0.19.0.99-lpwithnodatetime-r408
2788-subprocess32 = 3.2.6
2789-subvertpy = 0.9.1
2790-testresources = 0.2.7
2791-testscenarios = 0.4
2792-testtools = 0.9.30
2793-timeline = 0.0.3
2794-# Build of lp:~canonical-launchpad-branches/twisted:lp-backport.
2795-# p1 Support diffie-hellman-group14-sha1 key exchange in conch.ssh.
2796-# p2 Add diffie-hellman-group-exchange-sha256 to twisted.conch.ssh.
2797-# Add support in twisted.conch.ssh for hmac-sha2-256 and hmac-sha2-512.
2798-Twisted = 13.0.0-p2
2799-txAMQP = 0.6.2
2800-txfixtures = 0.1.4
2801-txlongpoll = 0.2.12
2802-txlongpollfixture = 0.1.3
2803-txpkgupload = 0.2
2804-unittest2 = 0.5.1
2805-van.testing = 3.0.0
2806-wadllib = 1.3.2
2807-# Upgrade from ZTK 1.1.5 to intercept lazr.restfulclient.
2808-wsgi-intercept = 0.5.1
2809-wsgiref = 0.1.2
2810-z3c.pt = 2.2.3
2811-z3c.ptcompat = 0.5.7
2812-z3c.recipe.tag = 0.6
2813-# Also upgrade the zc.buildout version in the Makefile's bin/buildout section.
2814-zc.buildout = 1.7.1
2815-zc.zservertracelog = 1.3.2
2816-ZConfig = 2.9.1dev-20110728
2817-# Not in ZTK 1.1.5
2818-zope.app.server = 3.6.0
2819-# Upgrade from ZTK 1.1.6 for ZCML registration performance.
2820-zope.component = 3.11.0
2821-# Upgrade from ZTK 1.1.6 for ZCML registration performance.
2822-zope.interface = 4.4.3
2823-# Build of lp:~wallyworld/zope.pagetemplate/fix-isinstance
2824-# This version adds a small change to the traversal logic so that the
2825-# optimisation which applies if the object is a dict also works for subclasses
2826-# of dict. The change has been approved for merge into the official zope code
2827-# base. This patch is a temporary fix until the next official release.
2828-zope.pagetemplate = 3.5.0-p1
2829-# XXX: downgraded to avoid 3.9.2 cookie calculation changes
2830-zope.session = 3.9.1
2831-# p1 Build of lp:~mars/zope.testing/3.9.4-p1. Fixes bugs 570380 and 587886.
2832-# p2 With patch for thread leaks to make them skips, fixes windmill errors
2833-# with 'new threads' in hudson/ec2 builds.
2834-# p3 And always tear down layers, because thats the Right Thing To Do.
2835-# p4 fixes --subunit --list to really just list the tests.
2836-# p5 Build of lp:~launchpad/zope.testing/3.9.4-p5. Fixes bug #609986.
2837-# p6 reinstates fix from p4. Build of lp:~launchpad/zope.testing/3.9.4-fork
2838-# revision 26.
2839-# p7 was unused
2840-# p8 redirects stdout and stderr to a black hole device when --subunit is used
2841-# p9 adds the redirection of __stderr__ to a black hole device
2842-# p10 changed the test reporting to use test.id() rather than
2843-# str(test) since only the id is unique.
2844-# p11 reverts p9.
2845-# p12 reverts p11, restoring p9.
2846-# p13 Add a new --require-unique flag to the testrunner. When set,
2847-# this will cause the testrunner to check all tests IDs to ensure they
2848-# haven't been loaded before. If it encounters a duplicate, it will
2849-# raise an error and quit.
2850-# p14 Adds test data written to stderr and stdout into the subunit output.
2851-# p15 Fixed internal tests.
2852-# p16 Adds support for skips in Python 2.7.
2853-# p17 Fixes skip support for Python 2.6.
2854-# To build (use Python 2.6) run "python bootstrap.py; ./bin/buildout". Then to
2855-# build the distribution run "bin/buildout setup . sdist"
2856-# Make sure you have subunit installed.
2857-zope.testing = 3.9.4-p17
2858-# Not in ZTK 1.1.5 (extracted from zope.app.schema)
2859-zope.vocabularyregistry = 1.0.0
2860
2861=== removed file 'zopeapp-versions.cfg'
2862--- zopeapp-versions.cfg 2013-05-09 23:35:44 +0000
2863+++ zopeapp-versions.cfg 1970-01-01 00:00:00 +0000
2864@@ -1,40 +0,0 @@
2865-[versions]
2866-# ZopeApp
2867-zc.sourcefactory = 0.7.0
2868-zope.app.applicationcontrol = 3.5.10
2869-zope.app.appsetup = 3.15.0
2870-zope.app.debug = 3.4.1
2871-zope.app.http = 3.9.0
2872-zope.app.publication = 3.12.0
2873-zope.app.wsgi = 3.10.0
2874-zope.testbrowser = 3.10.4
2875-
2876-# Deprecated
2877-roman = 1.4.0
2878-wsgi-intercept = 0.4
2879-zope.app.authentication = 3.9.0
2880-zope.app.basicskin = 3.5.1
2881-zope.app.broken = 3.6.0
2882-zope.app.component = 3.9.3
2883-zope.app.container = 3.9.2
2884-zope.app.content = 3.5.1
2885-zope.app.dependable = 3.5.1
2886-zope.app.error = 3.5.3
2887-zope.app.exception = 3.6.3
2888-zope.app.folder = 3.5.2
2889-zope.app.form = 4.0.2
2890-zope.app.generations = 3.7.1
2891-zope.app.i18n = 3.6.4
2892-zope.app.locales = 3.6.2
2893-zope.app.localpermission = 3.7.2
2894-zope.app.pagetemplate = 3.11.2
2895-zope.app.principalannotation = 3.7.0
2896-zope.app.publisher = 3.10.2
2897-zope.app.renderer = 3.5.1
2898-zope.app.rotterdam = 3.5.3
2899-zope.app.schema = 3.5.0
2900-zope.app.security = 3.7.5
2901-zope.app.testing = 3.8.1
2902-zope.app.zcmlfiles = 3.7.1
2903-zope.app.zopeappgenerations = 3.6.1
2904-zope.generations = 3.7.1
2905
2906=== removed file 'ztk-versions.cfg'
2907--- ztk-versions.cfg 2016-06-06 07:58:13 +0000
2908+++ ztk-versions.cfg 1970-01-01 00:00:00 +0000
2909@@ -1,112 +0,0 @@
2910-[versions]
2911-# ZTK
2912-zope.annotation = 3.6.0
2913-zope.applicationcontrol = 3.5.5
2914-zope.authentication = 3.7.1
2915-zope.broken = 3.6.0
2916-zope.browser = 1.3
2917-zope.browsermenu = 3.9.1
2918-zope.browserpage = 3.12.2
2919-zope.browserresource = 3.12.0
2920-zope.cachedescriptors = 3.5.1
2921-zope.catalog = 3.8.2
2922-zope.component = 3.10.0
2923-zope.componentvocabulary = 1.0.1
2924-zope.configuration = 3.7.4
2925-zope.container = 3.12.0
2926-zope.contentprovider = 3.7.2
2927-zope.contenttype = 3.5.5
2928-zope.copy = 3.5.0
2929-zope.copypastemove = 3.8.0
2930-zope.datetime = 3.4.1
2931-zope.deferredimport = 3.5.3
2932-zope.deprecation = 3.4.1
2933-zope.dottedname = 3.4.6
2934-zope.dublincore = 3.8.2
2935-zope.error = 3.7.4
2936-zope.event = 3.5.2
2937-zope.exceptions = 3.6.2
2938-zope.filerepresentation = 3.6.1
2939-zope.formlib = 4.0.6
2940-zope.hookable = 3.4.1
2941-zope.i18n = 3.7.4
2942-zope.i18nmessageid = 3.5.3
2943-zope.index = 3.6.4
2944-zope.interface = 3.7.0
2945-zope.intid = 3.7.2
2946-zope.keyreference = 3.6.4
2947-zope.lifecycleevent = 3.6.2
2948-zope.location = 3.9.1
2949-zope.login = 1.0.0
2950-zope.mimetype = 1.3.1
2951-zope.minmax = 1.1.2
2952-zope.pagetemplate = 3.5.2
2953-zope.password = 3.6.1
2954-zope.pluggableauth = 1.2
2955-zope.principalannotation = 3.6.1
2956-zope.principalregistry = 3.7.1
2957-zope.processlifetime = 1.0
2958-zope.proxy = 3.6.1
2959-zope.ptresource = 3.9.0
2960-zope.publisher = 3.12.6
2961-zope.ramcache = 1.0
2962-zope.schema = 3.7.1
2963-zope.security = 3.8.3
2964-zope.securitypolicy = 3.7.0
2965-zope.sendmail = 3.7.5
2966-zope.sequencesort = 3.4.0
2967-zope.server = 3.8.6
2968-zope.session = 3.9.5
2969-zope.site = 3.9.2
2970-zope.size = 3.4.1
2971-zope.structuredtext = 3.5.1
2972-zope.tal = 3.5.2
2973-zope.tales = 3.5.3
2974-zope.testing = 3.10.3
2975-zope.testrunner = 4.0.4
2976-zope.traversing = 3.14.0
2977-zope.viewlet = 3.7.2
2978-
2979-# Deprecating
2980-
2981-# Dependencies
2982-distribute = 0.6.36
2983-docutils = 0.7
2984-Jinja2 = 2.5.5
2985-mechanize = 0.2.5
2986-Paste = 1.7.5.1
2987-PasteDeploy = 1.3.4
2988-PasteScript = 1.7.5
2989-py = 1.4.8
2990-Pygments = 1.4
2991-python-gettext = 1.0
2992-python-subunit = 0.0.7
2993-pytz = 2013b
2994-RestrictedPython = 3.6.0
2995-setuptools = 0.6c11
2996-Sphinx = 1.0.8
2997-testtools = 0.9.12
2998-transaction = 1.1.1
2999-z3c.recipe.sphinxdoc = 0.0.8
3000-zc.buildout = 1.7.1
3001-zc.lockfile = 1.0.2
3002-ZConfig = 2.8.0
3003-zc.recipe.egg = 1.3.2
3004-zc.recipe.testrunner = 1.4.0
3005-zc.resourcelibrary = 1.3.4
3006-zdaemon = 2.0.7
3007-ZODB3 = 3.10.5
3008-zope.mkzeoinstance = 3.9.5
3009-
3010-# toolchain
3011-argparse = 1.1
3012-coverage = 3.5.2
3013-lxml = 2.2.8
3014-mr.developer = 1.25
3015-nose = 1.1.2
3016-tl.eggdeps = 0.4
3017-z3c.checkversions = 0.4.1
3018-z3c.recipe.compattest = 0.13.1
3019-z3c.recipe.depgraph = 0.5
3020-z3c.recipe.scripts = 1.0.1
3021-zope.kgs = 1.2.0