[svn r20974] Renaming pyinstall to pip

This commit is contained in:
Ian Bicking 2008-10-15 17:02:57 -05:00
commit c2000d7de6
14 changed files with 3384 additions and 0 deletions

133
docs/conf.py Normal file
View File

@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
#
# Paste documentation build configuration file, created by
# sphinx-quickstart on Tue Apr 22 22:08:49 2008.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# The contents of this file are pickled, so don't put values in the namespace
# that aren't pickleable (module imports are okay, they're removed automatically).
#
# All configuration values have a default value; values that are commented out
# serve to show the default value.
import sys
# If your extensions are in another directory, add it here.
#sys.path.append('some/directory')
# General configuration
# ---------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
#extensions = ['sphinx.ext.autodoc']
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.txt'
# The master toctree document.
master_doc = 'index'
# General substitutions.
project = 'pyinstall'
copyright = '2008, The Open Planning Project'
# The default replacements for |version| and |release|, also used in various
# other places throughout the built documents.
#
# The short X.Y version.
version = '0.1.3'
# The full version, including alpha/beta/rc tags.
release = '0.1.3'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
unused_docs = []
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# Options for HTML output
# -----------------------
# The style sheet to use for HTML and HTML Help pages. A file of that name
# must exist either in Sphinx' static/ path, or in one of the custom paths
# given in html_static_path.
html_style = 'default.css'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Content template for the index page.
#html_index = ''
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If true, the reST sources are included in the HTML build as _sources/<name>.
#html_copy_source = True
# Output file base name for HTML help builder.
htmlhelp_basename = 'pyinstalldocs'
# Options for LaTeX output
# ------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
#latex_documents = []
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True

192
docs/index.txt Normal file
View File

@ -0,0 +1,192 @@
pyinstall
=========
.. toctree::
news
requirement-format
.. comment: split here
.. contents::
Introduction
------------
pyinstall is a replacement for `easy_install
<http://peak.telecommunity.com/DevCenter/EasyInstall>`_. It uses mostly the
same techniques for finding packages, so packages that were made
easy_installable should be pyinstallable as well.
pyinstall is meant to improve on easy_install. Some of the improvements:
* All packages are downloaded before installation. Partially-completed
installation doesn't occur as a result.
* Care is taken to present useful output on the console.
* The reasons for actions are kept track of. For instance, if a package is
being installed, pyinstall keeps track of why that package was required.
* Error messages should be useful.
* The code is relatively concise and cohesive, making it easier to use
programmatically.
* Packages don't have to be installed as egg archives, they can be installed
flat (while keeping the egg metadata).
* Maybe features like native support for other version control systems, or
uninstallation, will get added. (They might get added to easy_install, but I
think the chance for pyinstall is higher.)
Also, pyinstall will eventually be merged directly with poacheggs, making it
simple to define fixed sets of requirements and reliably reproduce a set of
packages.
pyinstall is complementary with `virtualenv
<http://pypi.python.org/pypi/virtualenv>`_, and it is encouraged that you use
virtualenv to isolate your installation.
Community
---------
The homepage for pyinstall is temporarily located `on PyPI
<http://pypi.python.org/pypi/pyinstall>`_ -- a more proper homepage
will follow. Bugs can go on the `poacheggs Trac instance
<http://trac.openplans.org/poacheggs/>`_ (probably that will change
too). Discussion should happen on the `virtualenv email group
<http://groups.google.com/group/python-virtualenv?hl=en>`_.
Differences From easy_install
-----------------------------
pyinstall cannot install some packages. Specifically:
* It cannot install from eggs. It only installs from source. (Maybe this will
be changed sometime, but it's low priority.)
* It doesn't understand Setuptools extras (like ``package[test]``). This should
be added eventually.
* It is incompatible with some packages that customize distutils or setuptools
in their ``setup.py`` files.
* Maybe it doesn't work on Windows. At least, the author doesn't test on
Windows often.
* It also has some extra features. Extra features the author thinks are great.
.. _`requirements file`:
Requirements Files
------------------
When installing software, and Python packages in particular, it's common that
you get a lot of libraries installed. You just did ``easy_install MyPackage``
and you get a dozen packages. Each of these packages has its own version.
Maybe you ran that installation and it works. Great! Will it keep working?
Did you have to provide special options to get it to find everything? Did you
have to install a bunch of other optional pieces? Most of all, will you be able
to do it again?
If you've ever tried to setup an application on a new system, or with slightly
updated pieces, and had it fail, pyinstall requirements are for you. If you
haven't had this problem then you will eventually, so pyinstall requirements are
for you too -- requirements make explicit, repeatable installation of packages.
So what are requirements files? They are very simple: lists of packages to
install. Instead of running something like ``pyinstall MyApp`` and getting
whatever libraries come along, you can create a requirements file something like::
MyApp
Framework==0.9.4
Library>=0.2
Then, regardless of what MyApp lists in ``setup.py``, you'll get a specific
version of Framework and at least the 0.2 version of Library. (You might think
you could list these specific versions in ``setup.py`` -- try it and you'll
quickly see why that doesn't work.) You can add optional libraries and support
tools that MyApp doesn't strictly require.
You can also include "editable" packages -- packages that are checked out from
subversion (in the future other VCS will be supported). These are just like
using the ``-e`` option to pyinstall. They look like::
-e svn+http://myrepo/svn/MyApp#egg=MyApp
You have to start the URL with ``svn+`` (eventually you'll be able to use
``hg+`` etc), and you have to include ``#egg=Package`` so pyinstall knows what
to expect at that URL. You can also include ``@rev`` in the URL, e.g., ``@275``
to check out revision 275.
Freezing Requirements
---------------------
So you have a working set of packages, and you want to be able to install them
elsewhere. `Requirements files`_ let you install exact versions, but it won't
tell you what all the exact versions are.
To create a new requirements file from a known working environment, use::
$ pyinstall.py --freeze=stable-req.txt
This will write a listing of *all* installed libraries to ``stable-req.txt``
with exact versions for every library. You may want to edit the file down after
generating (e.g., to eliminate unnecessary libraries), but it'll give you a
stable starting point for constructing your requirements file.
You can also give it an existing requirements file, and it will use that as a
sort of template for the new file. So if you do::
$ pyinstall.py --freeze=stable-req.txt -r devel-req.txt
it will keep the packages listed in ``devel-req.txt`` in order and preserve
comments.
Bundles
-------
Another way to distribute a set of libraries is a bundle format (specific to
pyinstall). This format is not stable at this time (there simply hasn't been
any feedback, nor a great deal of thought). A bundle file contains all the
source for your package, and you can have pyinstall install then all together.
Once you have the bundle file further network access won't be necessary. To
build a bundle file, do::
$ pyinstall.py --bundle=MyApp.pybundle MyApp
(Using a `requirements file`_ would be wise.) Then someone else can get the
file ``MyApp.pybundle`` and run::
$ pyinstall.py MyApp.pybundle
This is *not* a binary format. This only packages source. If you have binary
packages, then the person who installs the files will have to have a compiler,
any necessary headers installed, etc. Binary packages are hard, this is
relatively easy.
Using pyinstall With virtualenv
-------------------------------
pyinstall is most nutritious when used with `virtualenv
<http://pypi.python.org/pypi/virtualenv>`_. One of the reasons pyinstall
doesn't install "multi-version" eggs is that virtualenv removes much of the need
for it.
pyinstall does not have to be installed to use it, you can run ``python
pyinstall.py`` and it will work. This is intended to avoid the bootstrapping
problem of installation. You can also run pyinstall inside any virtualenv
environment, like::
$ virtualenv new-env/
... creates new-env/ ...
$ pyinstall.py -E new-env/ MyPackage
This is exactly equivalent to::
$ ./new-env/bin/python pyinstall.py MyPackage
Except, if you have ``virtualenv`` installed and the path ``new-env/``
doesn't exist, then a new virtualenv will be created.

67
docs/news.txt Normal file
View File

@ -0,0 +1,67 @@
News for pyinstall
==================
0.1.4
-----
* Added an option ``--install-option`` to pass options to pass
arguments to ``setup.py install``
* ``.svn/`` directories are no longer included in bundles, as these
directories are specific to a version of svn -- if you build a
bundle on a system with svn 1.5, you can't use the checkout on a
system with svn 1.4. Instead a file ``svn-checkout.txt`` is
included that notes the original location and revision, and the
command you can use to turn it back into an svn checkout. (Probably
unpacking the bundle should, maybe optionally, recreate this
information -- but that is not currently implemented, and it would
require network access.)
* Avoid ambiguities over project name case, where for instance
MyPackage and mypackage would be considered different packages.
This in particular caused problems on Macs, where ``MyPackage/`` and
``mypackage/`` are the same directory.
* Added support for an environmental variable
``$PYINSTALL_DOWNLOAD_CACHE`` which will cache package downloads, so
future installations won't require large downloads. Network access
is still required, but just some downloads will be avoided when
using this.
0.1.3
-----
* Always use ``svn checkout`` (not ``export``) so that
``tag_svn_revision`` settings give the revision of the package.
* Don't update checkouts that came from ``.pybundle`` files.
0.1.2
-----
* Improve error text when there are errors fetching HTML pages when
seeking packages.
* Improve bundles: include empty directories, make them work with
editable packages.
* If you use ``-E env`` and the environment ``env/`` doesn't exist, a
new virtual environment will be created.
* Fix ``dependency_links`` for finding packages.
0.1.1
-----
* Fixed a NameError exception when running pyinstall outside of a
virtualenv environment.
* Added HTTP proxy support (from Prabhu Ramachandran)
* Fixed use of ``hashlib.md5`` on python2.5+ (also from Prabhu
Ramachandran)
0.1
---
* Initial release

View File

@ -0,0 +1,51 @@
The requirements file format
============================
The requirements file is what poacheggs uses to install packages.
This document describes that format.
Each line of the requirements file indicates something to be
installed. For example::
MyPackage==3.0
tells poacheggs to install the 3.0 version of MyPackage.
You can also install a package in an "editable" form. This puts the
source code into ``src/distname`` (making the name lower case) and
runs ``python setup.py develop`` on the package. To indicate
editable, use ``-e``, like::
-e svn+http://svn.myproject.org/svn/MyProject/trunk#egg=MyProject
The ``#egg=MyProject`` part is important, because while you can
install simply given the svn location, the project name is useful in
other places.
If you need to give poacheggs (and by association easy_install) hints
about where to find a package, you can use the ``-f``
(``--find-links``) option, like::
-f http://someserver.org/MyPackage-3.0.tar.gz
If the package is named like ``PackageName-Version.tar.gz`` (or a zip)
then you don't need ``#egg=...``. Note that you cannot provide
multiple ``-f`` arguments to easy_install, but you can in a
requirements file (they all get concatenated into a single ``-f`` for
easy_install).
Version Control
---------------
Right now poacheggs only knows Subversion. I hope to add Mercurial in
the not-too-distant future, as that system in particular is used by
quite a few open source Python projects (once that's added, support
for Bazaar, git, etc. will probably be easy).
You can also give specific revisions to an SVN URL, like::
-e svn+http://svn.myproject.org/svn/MyProject/trunk@2019
which will check out revision 2019. ``@{20080101}`` would also check
out the revision from 2008-01-01. You can only check out specific
revisions using ``-e svn+...``.

2538
pyinstall.py Normal file

File diff suppressed because it is too large Load Diff

9
regen-docs Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
mkdir -p docs/_static docs/_build
sphinx-build -E -b html docs/ docs/_build || exit 1
if [ "$1" = "publish" ] ; then
cd docs/_build
echo "Uploading files..."
tar czvf - . | ssh flow.openplans.org 'ssh acura.openplans.org "cd /www/pyinstall.openplans.org/; tar xzvf -"'
fi

3
setup.cfg Normal file
View File

@ -0,0 +1,3 @@
[egg_info]
tag_build = dev
tag_svn_revision = true

41
setup.py Normal file
View File

@ -0,0 +1,41 @@
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
import os
version = '0.1.5'
doc_dir = os.path.join(os.path.dirname(__file__), 'docs')
index_filename = os.path.join(doc_dir, 'index.txt')
long_description = """\
The main website for pyinstall is `pyinstall.openplans.org
<http://pyinstall.openplans.org>`_
"""
long_description = long_description + open(index_filename).read().split('split here', 1)[1]
setup(name='pyinstall',
version=version,
description="Installer for Python packages",
long_description=long_description,
classifiers=[
'Development Status :: 4 - Beta',
#'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Topic :: Software Development :: Build Tools',
],
keywords='easy_install distutils setuptools egg virtualenv',
author='The Open Planning Project',
author_email='python-virtualenv@groups.google.com',
url='http://pyinstall.openplans.org',
license='MIT',
py_modules=['pyinstall'],
## FIXME: is this the best way? (Works with distutils, but
## don't we really require setuptools anyway?)
scripts=['pyinstall.py'],
)

View File

@ -0,0 +1,90 @@
import urllib2
import re
import sys
import os
import subprocess
import shutil
pyinstall_fn = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'pyinstall.py')
def all_projects():
data = urllib2.urlopen('http://pypi.python.org/pypi/').read()
projects = [m.group(1) for m in re.finditer(r'href="/pypi/([^/"]*)', data)]
return projects
def main(args=None):
if args is None:
args = sys.argv[1:]
if not args:
print 'Usage: test_all_pyinstall.py <output-dir>'
sys.exit(1)
output = args[0]
if not os.path.exists(output):
print 'Creating %s' % output
os.makedirs(output)
pending_fn = os.path.join(output, 'pending.txt')
if not os.path.exists(pending_fn):
print 'Downloading pending list'
projects = all_projects()
print 'Found %s projects' % len(projects)
f = open(pending_fn, 'w')
for name in projects:
f.write(name + '\n')
f.close()
print 'Starting testing...'
while os.stat(pending_fn).st_size:
test_packages(output, pending_fn)
print 'Finished all pending!'
def test_packages(output, pending_fn):
package = get_last_item(pending_fn)
print 'Testing package %s' % package
dest_dir = os.path.join(output, package)
print 'Creating virtualenv in %s' % dest_dir
code = subprocess.call(['virtualenv', dest_dir])
assert not code, "virtualenv failed"
print 'Trying installation of %s' % dest_dir
code = subprocess.call([os.path.join(dest_dir, 'bin', 'python'),
pyinstall_fn, package])
if code:
print 'Installation of %s failed' % package
print 'Now checking easy_install...'
code = subprocess.call([os.path.join(dest_dir, 'bin', 'easy_install'),
package])
if code:
print 'easy_install also failed'
add_package(os.path.join(output, 'easy-failure.txt'), package)
else:
print 'easy_install succeeded'
add_package(os.path.join(output, 'failure.txt'), package)
pop_last_item(pending_fn, package)
else:
print 'Installation of %s succeeded' % package
add_package(os.path.join(output, 'success.txt'), package)
pop_last_item(pending_fn, package)
shutil.rmtree(dest_dir)
def get_last_item(fn):
f = open(fn, 'r')
lines = f.readlines()
f.close()
return lines[-1].strip()
def pop_last_item(fn, line=None):
f = open(fn, 'r')
lines = f.readlines()
f.close()
if line:
assert lines[-1].strip() == line.strip()
lines.pop()
f = open(fn, 'w')
f.writelines(lines)
f.close()
def add_package(filename, package):
f = open(filename, 'a')
f.write(package + '\n')
f.close()
if __name__ == '__main__':
main()

41
tests/test_basic.txt Normal file
View File

@ -0,0 +1,41 @@
Basic setup::
>>> from __main__ import here, reset_env, run_pyinstall, pyversion, lib_py
>>> reset_env()
First a test of the distutils-configuration-setting command (which is distinct from other commands)::
#>>> print run_pyinstall('-vv', '--distutils-cfg=easy_install:index_url:http://download.zope.org/ppix/', expect_error=True)
#Script result: python ../../poacheggs.py -E .../poacheggs-tests/test-scratch -vv --distutils-cfg=easy_install:index_url:http://download.zope.org/ppix/
#-- stdout: --------------------
#Distutils config .../poacheggs-tests/test-scratch/lib/python.../distutils/distutils.cfg is writable
#Replaced setting index_url
#Updated .../poacheggs-tests/test-scratch/lib/python.../distutils/distutils.cfg
#<BLANKLINE>
#-- updated: -------------------
# lib/python2.4/distutils/distutils.cfg (346 bytes)
Next, a simple test::
>>> result = run_pyinstall('-vvv', 'INITools==0.2', expect_error=True)
>>> assert (lib_py + 'site-packages/INITools-0.2-py%s.egg-info' % pyversion) in result.files_created
>>> assert (lib_py + 'site-packages/initools') in result.files_created
Let's try that again, editable::
>>> reset_env()
>>> result = run_pyinstall('-e', 'INITools==0.2', expect_error=True)
>>> assert "--editable=INITools==0.2 is not the right format" in result.stdout
>>> assert len(result.files_created) == 1 and not result.files_updated
Now, checking out from svn::
>>> reset_env()
>>> result = run_pyinstall('-e', 'svn+http://svn.colorstudy.com/INITools/trunk#egg=initools-dev', expect_error=True)
>>> egg_link = result.files_created[lib_py + 'site-packages/INITools.egg-link']
>>> # FIXME: I don't understand why there's a trailing . here:
>>> egg_link.bytes
'.../test-scratch/src/initools\n.'
>>> assert (lib_py + 'site-packages/easy-install.pth') in result.files_updated
>>> assert 'src/initools' in result.files_created
>>> assert 'src/initools/.svn' in result.files_created

62
tests/test_freeze.txt Normal file
View File

@ -0,0 +1,62 @@
Basic setup::
>>> import os
>>> from __main__ import base_path, reset_env, run_pyinstall, pyversion, lib_py, write_file, get_env
Some tests of freeze, first we have to install some stuff::
>>> reset_env()
>>> write_file('initools-req.txt', '''\
... INITools==0.2
... # and something else to test out:
... simplejson<=1.7.4
... ''')
>>> result = run_pyinstall('-r', 'initools-req.txt')
>>> result = run_pyinstall('--freeze=-', expect_stderr=True)
>>> print result
Script result: python ../../pyinstall.py -E .../test-scratch --freeze=-
-- stdout: --------------------
INITools==0.2
simplejson==1.7.4
<BLANKLINE>
Now lets try it with an svn checkout::
>>> env = get_env()
>>> result = env.run('svn', 'co', '-r3472', 'http://svn.colorstudy.com/INITools/trunk', 'initools-trunk')
>>> result = env.run(os.path.join(env.base_path, 'bin/python'), 'setup.py', 'develop',
... cwd=os.path.join(env.base_path, 'initools-trunk'))
>>> result = run_pyinstall('--freeze=-', expect_stderr=True)
>>> print result
Script result: python ../../pyinstall.py -E .../test-scratch --freeze=-
-- stdout: --------------------
-e svn+http://svn.colorstudy.com/INITools/trunk@3472#egg=INITools-0.2.1dev_r3472-py2.4-dev
simplejson==1.7.4
<BLANKLINE>
Now, straight from trunk (but not editable/setup.py develop)::
>>> result = env.run(os.path.join(env.base_path, 'bin/easy_install'), 'http://svn.colorstudy.com/INITools/trunk')
>>> result = run_pyinstall('--freeze=-', expect_stderr=True)
>>> print result
Script result: python ../../pyinstall.py -E .../test-scratch --freeze=-
-- stderr: --------------------
Warning: cannot find svn location for INITools==...dev-r...
<BLANKLINE>
-- stdout: --------------------
## FIXME: could not find svn URL in dependency_links for this package:
INITools==...dev-r...
simplejson==1.7.4
<BLANKLINE>
Bah, that's no good! Let's give it a hint::
>>> result = run_pyinstall('--freeze=-', '-f', 'http://svn.colorstudy.com/INITools/trunk#egg=INITools-dev', expect_stderr=True)
>>> print result
Script result: python ../../pyinstall.py -E .../test-scratch --freeze=- -f http://svn.colorstudy.com/INITools/trunk#egg=INITools-dev
-- stdout: --------------------
-f http://svn.colorstudy.com/INITools/trunk#egg=INITools-dev
# Installing as editable to satisfy requirement INITools==...dev-r...:
-e svn+http://svn.colorstudy.com/INITools/trunk@...#egg=INITools-...dev_r...
simplejson==1.7.4
<BLANKLINE>

43
tests/test_proxy.txt Normal file
View File

@ -0,0 +1,43 @@
Tests for the proxy support in pyinstall::
>>> import os
>>> import pyinstall
Remove proxy from environ:
>>> if 'HTTP_PROXY' in os.environ:
... del os.environ['HTTP_PROXY']
>>> print pyinstall.get_proxy()
None
>>> os.environ['HTTP_PROXY'] = 'user:pwd@server.com:port'
>>> pyinstall.get_proxy()
'user:pwd@server.com:port'
>>> del os.environ['HTTP_PROXY']
>>> pyinstall.get_proxy('server.com')
'server.com'
>>> pyinstall.get_proxy('server.com:80')
'server.com:80'
>>> pyinstall.get_proxy('user:passwd@server.com:3128')
'user:passwd@server.com:3128'
Now, a quick monkeypatch for getpass.getpass, to avoid asking for a password::
>>> import getpass
>>> old_getpass = getpass.getpass
>>> def new_getpass(prompt, answer='passwd'):
... print '%s%s' % (prompt, answer)
... return answer
>>> getpass.getpass = new_getpass
Test it:
>>> pyinstall.get_proxy('user:@server.com:3128')
'user:@server.com:3128'
>>> pyinstall.get_proxy('user@server.com:3128')
Password for user@server.com:3128: passwd
'user:passwd@server.com:3128'
Undo monkeypatch:
>>> getpass.getpass = old_getpass

76
tests/test_pyinstall.py Executable file
View File

@ -0,0 +1,76 @@
#!/usr/bin/env python
import os, sys
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
import doctest
pyversion = sys.version[:3]
lib_py = 'lib/python%s/' % pyversion
here = os.path.dirname(os.path.abspath(__file__))
base_path = os.path.join(here, 'test-scratch')
from scripttest import TestFileEnvironment
if 'PYTHONPATH' in os.environ:
del os.environ['PYTHONPATH']
def reset_env():
global env
env = TestFileEnvironment(base_path, ignore_hidden=False)
env.run('virtualenv', '--no-site-packages', env.base_path)
# To avoid the 0.9c8 svn 1.5 incompatibility:
env.run('%s/bin/easy_install' % env.base_path, 'http://peak.telecommunity.com/snapshots/setuptools-0.7a1dev-r66388.tar.gz')
env.run('mkdir', 'src')
def run_pyinstall(*args, **kw):
import sys
args = ('python', '../../pyinstall.py', '-E', env.base_path) + args
#print >> sys.__stdout__, 'running', ' '.join(args)
if options.show_error:
kw['expect_error'] = True
result = env.run(*args, **kw)
if options.show_error and result.returncode:
print result
return result
def write_file(filename, text):
f = open(os.path.join(base_path, filename), 'w')
f.write(text)
f.close()
def get_env():
return env
import optparse
parser = optparse.OptionParser(usage='%prog [OPTIONS] [TEST_FILE...]')
parser.add_option('--first', action='store_true',
help='Show only first failure')
parser.add_option('--diff', action='store_true',
help='Show diffs in doctest failures')
parser.add_option('--show-error', action='store_true',
help='Show the errors (use expect_error=True in run_pyinstall)')
parser.add_option('-v', action='store_true',
help='Be verbose')
def main():
global options
options, args = parser.parse_args()
reset_env()
if not args:
args = ['test_basic.txt', 'test_requirements.txt', 'test_freeze.txt', 'test_proxy.txt']
optionflags = doctest.ELLIPSIS
if options.first:
optionflags |= doctest.REPORT_ONLY_FIRST_FAILURE
if options.diff:
optionflags |= doctest.REPORT_UDIFF
for filename in args:
if not filename.endswith('.txt'):
filename += '.txt'
if not filename.startswith('test_'):
filename = 'test_' + filename
## FIXME: test for filename existance
failures, successes = doctest.testfile(filename, optionflags=optionflags)
if options.first and failures:
break
if __name__ == '__main__':
main()

View File

@ -0,0 +1,38 @@
Basic setup::
>>> import os
>>> from __main__ import base_path, reset_env, run_pyinstall, pyversion, lib_py, write_file
Some tests of requirement files::
>>> reset_env()
>>> write_file('initools-req.txt', '''\
... INITools==0.2
... # and something else to test out:
... simplejson<=1.7.4
... ''')
>>> result = run_pyinstall('-r', 'initools-req.txt')
>>> len(result.wildcard_matches('lib/python*/site-packages/INITools-0.2-py*.egg-info'))
1
>>> len(result.wildcard_matches('lib/python*/site-packages/initools'))
1
>>> dirs = result.wildcard_matches('lib/python*/site-packages/simplejson*')
>>> len(dirs)
2
>>> dirs[0].dir, dirs[1].dir
(True, True)
Now with more than one file::
>>> reset_env()
>>> write_file('initools-req.txt', '''\
... -e svn+http://svn.colorstudy.com/INITools/trunk@3139#egg=INITools-dev
... -r simplejson-req.txt''')
>>> write_file('simplejson-req.txt', '''\
... simplejson<=1.7.4
... ''')
>>> result = run_pyinstall('-r', 'initools-req.txt')
>>> len(result.wildcard_matches('lib/python*/site-packages/simplejson*'))
2
>>> assert 'src/initools' in result.files_created