Commit 18b9ae1e authored by PJ Eby's avatar PJ Eby

Restructure easy_install as a distutils "Command" object, so that it can

access the distutils configuration and logging infrastructure, and can
"inherit" options from a distutils setup script that wants to use it to
install its own dependencies.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4041052
parent 8f64fbe5
...@@ -179,11 +179,39 @@ files or directories. ...@@ -179,11 +179,39 @@ files or directories.
Reference Manual Reference Manual
================ ================
Configuration Files
-------------------
(New in 0.4a2)
You may specify default options for EasyInstall using the standard
distutils configuration files, under the command heading ``easy_install``.
EasyInstall will look first for a ``setup.cfg`` file in the current directory,
then a ``~/.pydistutils.cfg`` or ``$HOME\\pydistutils.cfg`` (on Unix-like OSes
and Windows, respectively), and finally a ``distutils.cfg`` file in the
``distutils`` package directory. Here's a simple example::
[easy_install]
# set the default location to install packages
install_dir = /home/me/lib/python
# Notice that indentation can be used to continue an option
# value; this is especially useful for the "--find-links"
# option, which tells easy_install to use download links on
# these pages before consulting PyPI:
#
find_links = http://sqlobject.org/
http://peak.telecommunity.com/dist/
See also the current Python documentation on the `use and location of distutils
configuration files <http://docs.python.org/inst/config-syntax.html>`_.
Command-Line Options Command-Line Options
-------------------- --------------------
``--zip, -z`` ``--zip-ok, -z``
Enable installing the package as a zip file. This can significantly Enable installing the package as a zip file. This can significantly
increase Python's overall import performance if you're installing to increase Python's overall import performance if you're installing to
``site-packages`` and not using the ``--multi`` option, because Python ``site-packages`` and not using the ``--multi`` option, because Python
...@@ -221,11 +249,13 @@ Command-Line Options ...@@ -221,11 +249,13 @@ Command-Line Options
which will put the latest installed version of the specified packages on which will put the latest installed version of the specified packages on
``sys.path`` for you. (For more advanced uses, like selecting specific ``sys.path`` for you. (For more advanced uses, like selecting specific
versions and enabling optional dependencies, see the ``pkg_resources`` API versions and enabling optional dependencies, see the ``pkg_resources`` API
doc.) Note that if you install to a directory other than ``site-packages``, doc.)
Note that if you install to a directory other than ``site-packages``,
this option is automatically in effect, because ``.pth`` files can only be this option is automatically in effect, because ``.pth`` files can only be
used in ``site-packages`` (at least in Python 2.3 and 2.4). So, if you use used in ``site-packages`` (at least in Python 2.3 and 2.4). So, if you use
the ``--install-dir`` or ``-i`` options, you must also use ``require()`` to the ``--install-dir`` or ``-d`` option (or they are set via configuration
enable packages at runtime file(s)) you must also use ``require()`` to enable packages at runtime.
``--install-dir=DIR, -d DIR`` ``--install-dir=DIR, -d DIR``
Set the installation directory. It is up to you to ensure that this Set the installation directory. It is up to you to ensure that this
...@@ -233,39 +263,53 @@ Command-Line Options ...@@ -233,39 +263,53 @@ Command-Line Options
``pkg_resources.require()`` to enable the installed package(s) that you ``pkg_resources.require()`` to enable the installed package(s) that you
need. need.
``--build-directory=DIR, -b DIR`` (New in 0.3a3) (New in 0.4a2) If this option is not directly specified on the command line
Set the directory used to download, extract, and install the package. The or in a distutils configuration file, the distutils default installation
directory is not cleared before or after installation, so the downloaded location is used. Normally, this would be the ``site-packages`` directory,
packages and extracted contents will remain there afterwards, allowing you but if you are using distutils configuration files, setting things like
to read any documentation, examples, scripts, etc. that may have been ``--prefix`` or ``--install-lib``, then those settings are taken into
included with the source distribution (if any). account when computing the default directory.
This option can only be used when you are specifying a single installation
URL or filename, so that the installer will not be confused by the presence
of multiple ``setup.py`` files in the build directory.
``--scan-url=URL, -s URL`` (New in 0.4a1) ``--find-links=URL, -f URL`` (Option renamed in 0.4a2)
Scan the specified "download page" for direct links to downloadable eggs or Scan the specified "download pages" for direct links to downloadable eggs
source distributions. Any usable packages will be downloaded if they are or source distributions. Any usable packages will be downloaded if they
required by a command line argument. For example, this:: are required by a command line argument. For example, this::
easy_install -s http://peak.telecommunity.com/dist PyProtocols easy_install -f http://peak.telecommunity.com/dist PyProtocols
will download and install the latest version of PyProtocols linked from will download and install the latest version of PyProtocols linked from
the PEAK downloads page, but ignore the other download links on that page. the PEAK downloads page, but ignore the other download links on that page.
If all requested packages can be found using links on the specified
You may use this option more than once, to list multiple download pages. download pages, the Python Package Index will *not* be consulted. You can
If all requested packages can be found using the specified download pages, use ``file:`` URLs to reference a local filename.
the Python Package Index will *not* be consulted.
You may specify multiple URLs with this option, separated by whitespace.
Note that on the command line, you will probably have to surround the URLs
with quotes, so that they are recognized as a single option value. You can
also specify URLs in a configuration file; see `Configuration Files`_,
above; but note that this means the specified pages will be downloaded
every time you use EasyInstall (unless overridden on the command line) and
thus may make startup slower.
``--index-url=URL, -u URL`` (New in 0.4a1) ``--index-url=URL, -u URL`` (New in 0.4a1)
Specifies the base URL of the Python Package Index. The default is Specifies the base URL of the Python Package Index. The default is
http://www.python.org/pypi if not specified. When a package is requested http://www.python.org/pypi if not specified. When a package is requested
that is not locally available or linked from a ``--scan-url`` download that is not locally available or linked from a ``--find-links`` download
page, the package index will be searched for download pages for the needed page, the package index will be searched for download pages for the needed
package, and those download pages will be searched for links to download package, and those download pages will be searched for links to download
an egg or source distribution. an egg or source distribution.
``--build-directory=DIR, -b DIR`` (New in 0.3a3)
Set the directory used to download, extract, and install the package. The
directory is not cleared before or after installation, so the downloaded
packages and extracted contents will remain there afterwards, allowing you
to read any documentation, examples, scripts, etc. that may have been
included with the source distribution (if any).
This option can only be used when you are specifying a single installation
URL or filename, so that the installer will not be confused by the presence
of multiple ``setup.py`` files in the build directory.
Release Notes/Change History Release Notes/Change History
============================ ============================
...@@ -275,6 +319,11 @@ Known Issues ...@@ -275,6 +319,11 @@ Known Issues
time out or be missing a file. time out or be missing a file.
0.4a2 0.4a2
* Added support for setting options via distutils configuration files
* Renamed ``--scan-url/-s`` to ``--find-links/-f`` to free up ``-s`` for the
script installation directory option.
* Use ``urllib2`` instead of ``urllib``, to allow use of ``https:`` URLs if * Use ``urllib2`` instead of ``urllib``, to allow use of ``https:`` URLs if
Python includes SSL support. Python includes SSL support.
...@@ -292,6 +341,11 @@ Known Issues ...@@ -292,6 +341,11 @@ Known Issues
with an ``unpack_archive()`` API. These were split out of EasyInstall to with an ``unpack_archive()`` API. These were split out of EasyInstall to
allow reuse by other tools and applications. allow reuse by other tools and applications.
* ``setuptools.Command`` now supports reinitializing commands using keyword
arguments to set/reset options. Also, ``Command`` subclasses can now set
their ``command_consumes_arguments`` attribute to ``True`` in order to
receive an ``args`` option containing the rest of the command line.
0.4a1 0.4a1
* Added ``--scan-url`` and ``--index-url`` options, to scan download pages * Added ``--scan-url`` and ``--index-url`` options, to scan download pages
and search PyPI for needed packages. and search PyPI for needed packages.
......
This diff is collapsed.
...@@ -4,7 +4,7 @@ import distutils.core, setuptools.command ...@@ -4,7 +4,7 @@ import distutils.core, setuptools.command
from setuptools.dist import Distribution, Feature from setuptools.dist import Distribution, Feature
from setuptools.extension import Extension from setuptools.extension import Extension
from setuptools.depends import Require from setuptools.depends import Require
from distutils.core import Command from distutils.core import Command as _Command
from distutils.util import convert_path from distutils.util import convert_path
import os.path import os.path
...@@ -37,6 +37,8 @@ def find_packages(where='.'): ...@@ -37,6 +37,8 @@ def find_packages(where='.'):
return out return out
def setup(**attrs): def setup(**attrs):
"""Do package setup """Do package setup
...@@ -47,3 +49,34 @@ def setup(**attrs): ...@@ -47,3 +49,34 @@ def setup(**attrs):
""" """
attrs.setdefault("distclass",Distribution) attrs.setdefault("distclass",Distribution)
return distutils.core.setup(**attrs) return distutils.core.setup(**attrs)
class Command(_Command):
__doc__ = _Command.__doc__
command_consumes_arguments = False
def reinitialize_command(self, command, reinit_subcommands=0, **kw):
cmd = _Command.reinitialize_command(self, command, reinit_subcommands)
for k,v in kw.items():
setattr(cmd,k,v) # update command with keywords
return cmd
...@@ -4,7 +4,7 @@ Build .egg distributions""" ...@@ -4,7 +4,7 @@ Build .egg distributions"""
# This module should be kept compatible with Python 2.3 # This module should be kept compatible with Python 2.3
import os import os
from distutils.core import Command from setuptools import Command
from distutils.util import get_platform from distutils.util import get_platform
from distutils.dir_util import create_tree, remove_tree, ensure_relative,mkpath from distutils.dir_util import create_tree, remove_tree, ensure_relative,mkpath
from distutils.sysconfig import get_python_version, get_python_lib from distutils.sysconfig import get_python_version, get_python_lib
...@@ -234,16 +234,16 @@ class bdist_egg(Command): ...@@ -234,16 +234,16 @@ class bdist_egg(Command):
return match.group(1) return match.group(1)
def call_command(self,cmdname,**kw): def call_command(self,cmdname,**kw):
cmd = self.reinitialize_command(cmdname) """Invoke reinitialized command `cmdname` with keyword args"""
for dirname in INSTALL_DIRECTORY_ATTRS: for dirname in INSTALL_DIRECTORY_ATTRS:
if dirname in cmd.__dict__: # don't overwrite methods! kw.setdefault(dirname,self.bdist_dir)
setattr(cmd,dirname,self.bdist_dir) kw.setdefault('skip_build',self.skip_build)
cmd.skip_build = self.skip_build
for k,v in kw.items(): cmd = self.reinitialize_command(cmdname, **kw)
setattr(cmd,k,v)
self.run_command(cmdname) self.run_command(cmdname)
return cmd return cmd
# Attribute names of options for commands that might need to be convinced to # Attribute names of options for commands that might need to be convinced to
# install to the egg build directory # install to the egg build directory
......
__all__ = ['Distribution', 'Feature'] __all__ = ['Distribution', 'Feature']
from distutils.core import Distribution as _Distribution from distutils.core import Distribution as _Distribution
from distutils.core import Extension from distutils.core import Extension
from setuptools.depends import Require from setuptools.depends import Require
...@@ -7,8 +8,37 @@ from setuptools.command.install import install ...@@ -7,8 +8,37 @@ from setuptools.command.install import install
from setuptools.command.install_lib import install_lib from setuptools.command.install_lib import install_lib
from distutils.errors import DistutilsOptionError, DistutilsPlatformError from distutils.errors import DistutilsOptionError, DistutilsPlatformError
from distutils.errors import DistutilsSetupError from distutils.errors import DistutilsSetupError
sequence = tuple, list sequence = tuple, list
class Distribution(_Distribution): class Distribution(_Distribution):
"""Distribution with support for features, tests, and package data """Distribution with support for features, tests, and package data
...@@ -54,7 +84,6 @@ class Distribution(_Distribution): ...@@ -54,7 +84,6 @@ class Distribution(_Distribution):
the distribution. They are used by the feature subsystem to configure the the distribution. They are used by the feature subsystem to configure the
distribution for the included and excluded features. distribution for the included and excluded features.
""" """
def __init__ (self, attrs=None): def __init__ (self, attrs=None):
have_package_data = hasattr(self, "package_data") have_package_data = hasattr(self, "package_data")
if not have_package_data: if not have_package_data:
...@@ -83,6 +112,15 @@ class Distribution(_Distribution): ...@@ -83,6 +112,15 @@ class Distribution(_Distribution):
"""Convert feature name to corresponding option attribute name""" """Convert feature name to corresponding option attribute name"""
return 'with_'+name.replace('-','_') return 'with_'+name.replace('-','_')
def _set_global_opts_from_features(self): def _set_global_opts_from_features(self):
"""Add --with-X/--without-X options based on optional features""" """Add --with-X/--without-X options based on optional features"""
...@@ -277,14 +315,55 @@ class Distribution(_Distribution): ...@@ -277,14 +315,55 @@ class Distribution(_Distribution):
) )
map(self.exclude_package, packages) map(self.exclude_package, packages)
def _parse_command_opts(self, parser, args): def _parse_command_opts(self, parser, args):
# Remove --with-X/--without-X options when processing command args # Remove --with-X/--without-X options when processing command args
self.global_options = self.__class__.global_options self.global_options = self.__class__.global_options
self.negative_opt = self.__class__.negative_opt self.negative_opt = self.__class__.negative_opt
return _Distribution._parse_command_opts(self, parser, args)
# Handle commands that want to consume all remaining arguments
command = args[0]
nargs = _Distribution._parse_command_opts(self, parser, args)
cmd_class = self.get_command_class(command)
if getattr(cmd_class,'command_consumes_arguments',None):
self.get_option_dict(command)['args'] = ("command line", nargs)
if nargs is not None:
return []
return nargs
def has_dependencies(self): def has_dependencies(self):
return not not self.requires return not not self.requires
......
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