Commit 26a5ebfb authored by PJ Eby's avatar PJ Eby

Add 'ez_setup' bootstrap installer. Prep for 0.4a2 release.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4041054
parent 5bf51fa2
......@@ -22,34 +22,28 @@ Using "Easy Install"
Installing "Easy Install"
-------------------------
Unix-like Systems (including Mac OS X and Cygwin)
Download either the `Python 2.3 easy_install shell script
<http://peak.telecommunity.com/dist/ez_install-0.4a1-py2.3-unix.sh>`_ or the
`Python 2.4 easy_install shell script
<http://peak.telecommunity.com/dist/ez_install-0.4a1-py2.4-unix.sh>`_. Place
the file somewhere on your PATH, after renaming it to ``easy_install``. Note
that these scripts assume you have ``python2.3`` or ``python2.4`` accessible
via the ``PATH`` environment variable. Then, you can use ``easy_install`` to
finish its own installation, by running one of the following, depending on
your Python version::
# Python 2.3
easy_install http://peak.telecommunity.com/dist/setuptools-0.4a1-py2.3.egg
# Python 2.4
easy_install http://peak.telecommunity.com/dist/setuptools-0.4a1-py2.4.egg
All Other Systems
Download the `easy_install (aka setuptools) source distribution
<http://peak.telecommunity.com/dist/setuptools-0.4a1.zip>`_, and follow the
normal procedure for installing a source package with distutils. An
``easy_install.py`` script will be installed in the normal location for
Python scripts on your platform. In the examples below, you'll need to
replace references to ``easy_install`` with the correct invocation to run
``easy_install.py`` on your system. If you have Python 2.4 or better, you
can also use ``python -m easy_install``, which will have the same effect,
but which may be easier for you to type.
Windows users can just download and run the `setuptools binary installer for
Windows <http://peak.telecommunity.com/dist/setuptools-0.4a2.win32.exe>`_.
All others should just download `ez_setup.py
<http://peak.telecommunity.com/dist/ez_setup.py>`_, and run it; this will
download and install the correct version of ``setuptools`` for your Python
version. You may receive a message telling you about an obsolete version of
setuptools being present; if so, you must be sure to delete it entirely, along
with the old ``pkg_resources`` module if it's present on ``sys.path``.
An ``easy_install.py`` script will be installed in the normal location for
Python scripts on your platform. In the examples below, you'll need to replace
references to ``easy_install`` with the correct invocation to run
``easy_install.py`` on your system. If you have Python 2.4 or better, you can
also use ``python -m easy_install``, which will have the same effect, but which
may be easier for you to type.
(Note: the ``ez_setup.py`` script accepts the same `Command-Line Options`_ and
`Configuration Files`_ as ``easy_install`` itself, so you can use them to
control its behavior. However, you should avoid using a custom installation
directory or doing multi-version installs of the setuptools package, because
this may make it impossible for scripts installed with EasyInstall to access
it afterwards.)
Downloading and Installing a Package
......@@ -68,7 +62,7 @@ version, and automatically downloading, building, and installing it::
**Example 2**. Install or upgrade a package by name and version by finding
links on a given "download page"::
easy_install -f http://peak.telecommunity.com/dist "setuptools>=0.4a1"
easy_install -f http://peak.telecommunity.com/dist "setuptools>=0.4a2"
**Example 3**. Download a source distribution from a specified URL,
automatically building and installing it::
......@@ -391,14 +385,22 @@ Known Issues
* There's no automatic retry for borked Sourceforge mirrors, which can easily
time out or be missing a file.
* EasyInstall does not yet respect the distutils "verbose/quite" and "dry-run"
options, even though it accepts them.
0.4a2
* Added support for installing scripts
* Added support for setting options via distutils configuration files
* Added support for setting options via distutils configuration files, and
using distutils' default options as a basis for EasyInstall's defaults.
* Renamed ``--scan-url/-s`` to ``--find-links/-f`` to free up ``-s`` for the
script installation directory option.
* Added ``ez_setup.py`` installer/bootstrap script to make initial setuptools
installation easier, and to allow distributions using setuptools to avoid
having to include setuptools in their source distribution.
* Use ``urllib2`` instead of ``urllib``, to allow use of ``https:`` URLs if
Python includes SSL support.
......@@ -409,7 +411,8 @@ Known Issues
* The ``Installer`` class no longer handles downloading, manages a temporary
directory, or tracks the ``zip_ok`` option. Downloading is now handled
by ``PackageIndex``, and the latter two are now managed by ``main()``.
by ``PackageIndex``, and ``Installer`` has become an ``easy_install``
command class based on ``setuptools.Command``.
* There is a new ``setuptools.sandbox.run_setup()`` API to invoke a setup
script in a directory sandbox, and a new ``setuptools.archive_util`` module
......@@ -476,13 +479,13 @@ Known Issues
Initial release.
Future Plans
============
* Log progress to a logger, with -v and -q options to control verbosity
* Display more information about downloads and progress when being verbose
* Process the installed package's dependencies as well as the base package
* Support installation from bdist_wininst packages?
* Additional utilities to list/remove/verify packages
* Signature checking? SSL? Ability to suppress PyPI search?
* Support installation from bdist_wininst packages?
......@@ -247,6 +247,7 @@ class easy_install(Command):
def install_egg(self, egg_path, zip_ok, tmpdir):
destination = os.path.join(self.install_dir,os.path.basename(egg_path))
destination = os.path.abspath(destination)
ensure_directory(destination)
if not samefile(egg_path, destination):
......@@ -284,7 +285,6 @@ class easy_install(Command):
def installation_report(self, dist):
"""Helpful installation message for display to package users"""
......
#!python
"""Bootstrap setuptools installation
If you want to use setuptools in your package's setup.py, just include this
file in the same directory with it, and add this to the top of your setup.py::
from ez_setup import use_setuptools
use_setuptools()
If you want to require a specific version of setuptools, set a download
mirror, or use an alternate download directory, you can do so by supplying
the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools.
"""
DEFAULT_VERSION = "0.4a2"
DEFAULT_URL = "http://peak.telecommunity.com/dist/"
import sys, os
def use_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir
):
"""Automatically find/download setuptools and make it available on sys.path
`version` should be a valid setuptools version number that is available
as an egg for download under the `download_base` URL (which should end with
a '/'). `to_dir` is the directory where setuptools will be downloaded, if
it is not already available.
If an older version of setuptools is installed, this will print a message
to ``sys.stderr`` and raise SystemExit in an attempt to abort the calling
script.
"""
try:
import setuptools
if setuptools.__version__ == '0.0.1':
print >>sys.stderr, (
"You have an obsolete version of setuptools installed. Please\n"
"remove it from your system entirely before rerunning this script."
)
sys.exit(2)
except ImportError:
sys.path.insert(0, download_setuptools(version, download_base, to_dir))
import pkg_resources
try:
pkg_resources.require("setuptools>="+version)
except pkg_resources.VersionConflict:
# XXX could we install in a subprocess here?
print >>sys.stderr, (
"The required version of setuptools (>=%s) is not available, and\n"
"can't be installed while this script is running. Please install\n"
" a more recent version first."
) % version
sys.exit(2)
def download_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir
):
"""Download setuptools from a specified location and return its filename
`version` should be a valid setuptools version number that is available
as an egg for download under the `download_base` URL (which should end
with a '/'). `to_dir` is the directory where the egg will be downloaded.
"""
import urllib2, shutil
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
url = download_base + egg_name
saveto = os.path.join(to_dir, egg_name)
src = dst = None
try:
src = urllib2.urlopen(url)
dst = open(saveto,"wb")
shutil.copyfileobj(src,dst)
finally:
if src: src.close()
if dst: dst.close()
return os.path.realpath(saveto)
def main(argv, version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall"""
try:
import setuptools
except ImportError:
import tempfile, shutil
tmpdir = tempfile.mkdtemp(prefix="easy_install-")
try:
egg = download_setuptools(version, to_dir=tmpdir)
sys.path.insert(0,egg)
from easy_install import main
main(list(argv)+[egg])
finally:
shutil.rmtree(tmpdir)
else:
if setuptools.__version__ == '0.0.1':
# tell the user to uninstall obsolete version
use_setuptools(version)
req = "setuptools>="+version
import pkg_resources
try:
pkg_resources.require(req)
except pkg_resources.VersionConflict:
from easy_install import main
main(list(argv)+[req])
sys.exit(0) # try to force an exit
else:
if argv:
from easy_install import main
main(argv)
else:
print "Setuptools successfully installed or upgraded."
if __name__=='__main__':
main(sys.argv[1:])
......@@ -1307,7 +1307,7 @@ class Distribution(object):
)
version = property(version)
#@property
......@@ -1350,6 +1350,47 @@ class Distribution(object):
if path is sys.path:
fixup_namespace_packages(self.path)
map(declare_namespace, self._get_metadata('namespace_packages.txt'))
def egg_name(self):
"""Return what this distribution's standard .egg filename should be"""
filename = "%s-%s-py%s" % (
self.name.replace('-','_'), self.version.replace('-','_'),
self.py_version or PY_MAJOR
)
if self.platform:
filename += '-'+self.platform
return filename
def parse_requirements(strs):
"""Yield ``Requirement`` objects for each specification in `strs`
......
#!/usr/bin/env python
"""Distutils setup file, used to install or test 'setuptools'"""
VERSION = "0.4a1"
import sys
VERSION = "0.4a2"
from setuptools import setup, find_packages, Require
PYVER = sys.version[:3]
setup(
name="setuptools",
......@@ -26,7 +24,7 @@ setup(
"download mirrors, or from Python Eggs. Been looking for a CPAN "
"clone for Python? When combined with PyPI, this gets pretty darn "
"close. See the home page and download page for details and docs.",
keywords = "CPAN PyPI distutils eggs package management",
url = "http://peak.telecommunity.com/PythonEggs",
download_url = "http://peak.telecommunity.com/DevCenter/EasyInstall",
......@@ -39,10 +37,12 @@ setup(
Require('PyUnit', None, 'unittest', "http://pyunit.sf.net/"),
],
packages = find_packages(),
py_modules = ['pkg_resources', 'easy_install'],
scripts = ['easy_install.py'],
extra_path = ('setuptools', 'setuptools-%s-py%s.egg' % (VERSION,PYVER)),
extra_path = ('setuptools', 'setuptools-%s.egg' % VERSION),
classifiers = [f.strip() for f in """
Development Status :: 3 - Alpha
......
......@@ -8,7 +8,7 @@ from distutils.core import Command as _Command
from distutils.util import convert_path
import os.path
__version__ = '0.0.1'
__version__ = '0.4a2'
__all__ = [
'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require',
......
......@@ -10,7 +10,8 @@ from distutils.dir_util import create_tree, remove_tree, ensure_relative,mkpath
from distutils.sysconfig import get_python_version, get_python_lib
from distutils.errors import *
from distutils import log
from pkg_resources import parse_requirements, get_platform, safe_name, safe_version
from pkg_resources import parse_requirements, get_platform, safe_name, \
safe_version, Distribution
class bdist_egg(Command):
description = "create an \"egg\" distribution"
......@@ -34,7 +35,6 @@ class bdist_egg(Command):
('skip-build', None,
"skip rebuilding everything (for testing/debugging)"),
]
boolean_options = [
'keep-temp', 'skip-build', 'relative','tag-date','tag-svn-revision'
]
......@@ -133,14 +133,14 @@ class bdist_egg(Command):
)
to_compile = []
for ext_name in ext_outputs:
for (p,ext_name) in enumerate(ext_outputs):
filename,ext = os.path.splitext(ext_name)
pyfile = os.path.join(self.bdist_dir, filename + '.py')
log.info("creating stub loader for %s" % ext_name)
if not self.dry_run:
self.write_stub(os.path.basename(ext_name), pyfile)
to_compile.append(pyfile)
ext_outputs[p] = ext_name.replace(os.sep,'/')
if to_compile:
cmd.byte_compile(to_compile)
......@@ -155,18 +155,10 @@ class bdist_egg(Command):
# And make an archive relative to the root of the
# pseudo-installation tree.
archive_basename = "%s-%s-py%s" % ( self.egg_name.replace('-','_'),
self.egg_version.replace('-','_'), get_python_version())
if ext_outputs:
archive_basename += "-" + self.plat_name
ext_outputs = [out.replace(os.sep,'/') for out in ext_outputs]
# OS/2 objects to any ":" characters in a filename (such as when
# a timestamp is used in a version) so change them to underscores.
if os.name == "os2":
archive_basename = archive_basename.replace(":", "_")
archive_basename = Distribution(
None, None, self.egg_name, self.egg_version, get_python_version(),
ext_outputs and self.plat_name
).egg_name()
pseudoinstall_root = os.path.join(self.dist_dir, archive_basename)
archive_root = self.bdist_dir
......@@ -174,6 +166,7 @@ class bdist_egg(Command):
egg_info = os.path.join(archive_root,'EGG-INFO')
self.mkpath(egg_info)
self.mkpath(self.egg_info)
log.info("writing %s" % os.path.join(self.egg_info,'PKG-INFO'))
if not self.dry_run:
metadata = self.distribution.metadata
......@@ -244,6 +237,13 @@ class bdist_egg(Command):
return cmd
# Attribute names of options for commands that might need to be convinced to
# install to the egg build directory
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment