Commit 8afe820f authored by PJ Eby's avatar PJ Eby

Got rid of the no-longer meaningful "depends" command. Consolidated the

replacement of the "install" command so that installation is always via
easy_install, but doesn't use the previous kludgy intereception technique.
Allow ``extra_path`` to be set, but ignore it, so that when easy_install
wraps a package that uses it, there won't be any confusion as to the
desired installation location.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4041181
parent 8a29467d
......@@ -13,10 +13,9 @@ setopt = setuptools.command.setopt:setopt
build_py = setuptools.command.build_py:build_py
saveopts = setuptools.command.saveopts:saveopts
egg_info = setuptools.command.egg_info:egg_info
easy_install = setuptools.command.easy_install:easy_install
upload = setuptools.command.upload:upload
alias = setuptools.command.alias:alias
depends = setuptools.command.depends:depends
easy_install = setuptools.command.easy_install:easy_install
bdist_egg = setuptools.command.bdist_egg:bdist_egg
install = setuptools.command.install:install
test = setuptools.command.test:test
......
......@@ -1713,6 +1713,10 @@ Release Notes/Change History
using entry points, so that they are extensible by third-party packages.
See `Creating distutils Extensions`_ above for more details.
* The vestigial ``depends`` command has been removed. It was never finished
or documented, and never would have worked without EasyInstall - which it
pre-dated and was never compatible with.
* Many ``pkg_resources`` API changes and enhancements:
* Added ``EntryPoint``, ``get_entry_map``, ``load_entry_point``, and
......@@ -1918,9 +1922,7 @@ Release Notes/Change History
see the ``setuptools.dist.Distribution`` class.
* Setup scripts using setuptools now always install using ``easy_install``
internally, for ease of uninstallation and upgrading. Note: you *must*
remove any ``extra_path`` argument from your setup script, as it conflicts
with the proper functioning of the ``easy_install`` command.
internally, for ease of uninstallation and upgrading.
* ``pkg_resources.AvailableDistributions.resolve()`` and related methods now
accept an ``installer`` argument: a callable taking one argument, a
......
__all__ = [
'alias', 'bdist_egg', 'build_ext', 'build_py', 'depends', 'develop',
'alias', 'bdist_egg', 'build_ext', 'build_py', 'develop',
'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts',
'sdist', 'setopt', 'test', 'upload',
]
......
import os
import sys
from distutils.cmd import Command
class depends(Command):
"""Download and install dependencies, if needed"""
description = "download and install dependencies, if needed"
user_options = [
('temp=', 't',
"directory where dependencies will be downloaded and built"),
('ignore-extra-args', 'i',
"ignore options that won't be passed to child setup scripts"),
]
path_attrs = [
# Note: these must be in *reverse* order, as they are pushed onto the
# *front* of a copy of sys.path.
('install', 'install_libbase'), # installation base if extra_path
('install_lib', 'install_dir'), # where modules are installed
]
# Command options that can be safely passed to dependencies' setup scripts
safe_opts = {
'install': [
'prefix', 'exec-prefix', 'home', 'install-base',
'install-platbase', 'root', 'optimize', 'force', 'verbose', 'quiet'
],
'build': ['compiler', 'debug', 'force', 'verbose', 'quiet'],
}
# Options with string arguments that are *not* directories or files, and
# so should *not* have absolute-path fixups applied.
non_fs_opts = {'build': ['compiler']}
def initialize_options(self):
self.temp = None; self.ignore_extra_args = None
def finalize_options(self):
self.set_undefined_options('build',('build_temp', 'temp'))
self.set_search_path()
self.set_subcommand_args()
def set_subcommand_args(self):
safe = {'install':[]} # ensure we at least perform an install
unsafe = {}
copts = self.distribution.get_cmdline_options()
if 'depends' in copts:
del copts['depends']
for cmd,opts in copts.items():
safe_opts = self.safe_opts.get(cmd,())
non_fs_opts = self.non_fs_opts.get(cmd,())
for opt,val in opts.items():
if opt in safe_opts:
cmdline = safe.setdefault(cmd,[])
if val is not None and opt not in non_fs_opts:
val = os.path.abspath(val)
else:
cmdline = unsafe.setdefault(cmd,[])
cmdline.append('--'+opt)
if val is not None:
cmdline.append(val)
self.safe_options = safe
self.unsafe_options = unsafe
def set_search_path(self):
"""Determine paths to check for installed dependencies"""
path = sys.path[:] # copy sys path
for cmd,attr in self.path_attrs:
dir = getattr(self.get_finalized_command(cmd),attr,None)
if dir and dir not in path:
path.insert(0,dir) # prepend
self.search_path = path
def run(self):
self.announce("checking for installed dependencies")
needed = [
dep for dep in self.distribution.requires if self.is_needed(dep)
]
if not needed:
self.announce("all dependencies are present and up-to-date")
return
argv = [sys.executable,'setup.py']
for cmd,line in self.safe_options.items():
argv.append(cmd); argv.extend(line)
self.announce(
"dependencies will be installed using:\n "+' '.join(argv)+'\n'
)
# Alert for unsupported commands/options, unless '-i' was used
if self.unsafe_options:
self.warn_unsafe_options_used()
if not self.ignore_extra_args:
raise SystemExit(
"Unsupported options for building dependencies; please"
" add 'depends -i'\nto your command line if you want to"
" force the build to proceed.\nOtherwise, you will need"
" to omit the unsupported options,\nor install the"
" dependencies manually."
)
# Alert the user to missing items
fmt = "\t%s\t%s\n"
items = [fmt % (dep.full_name(), dep.homepage) for dep in needed]
items.insert(0,"Please install the following packages *first*:\n")
items.append('')
raise SystemExit('\n'.join(items)) # dump msg to stderr and exit
def warn_unsafe_options_used(self):
lines = []; write = lines.append
write("the following command options are not supported for building")
write("dependencies, and will be IGNORED:")
for cmd,line in self.unsafe_options.items():
write('\t%s %s' % (cmd, ' '.join(line)))
write('')
self.warn('\n'.join(lines))
def is_needed(self,dep):
"""Does the specified dependency need to be installed/updated?"""
self.announce("searching for "+dep.full_name())
version = dep.get_version(self.search_path)
if version is None:
self.announce(name+" not found!")
return True
if str(version)=="unknown":
status = dep.name+" is installed"
else:
status = dep.name+" version "+str(version)+" found"
if dep.version_ok(version):
self.announce(status+" (OK)")
return False
else:
self.announce(status+" (update needed)")
return True
import setuptools
from distutils.command.install import install as _install
class install(_install):
"""Build dependencies before installation"""
def has_dependencies(self):
return self.distribution.has_dependencies()
def handle_extra_path(self):
# We always ignore extra_path, because we always install eggs
# (you can always use install_* commands directly if needed)
self.path_file = None
self.extra_dirs = ''
def run(self):
from setuptools.command.easy_install import easy_install
cmd = easy_install(
self.distribution, args="x", ignore_conflicts_at_my_risk=1
)
cmd.ensure_finalized() # finalize before bdist_egg munges install cmd
self.run_command('bdist_egg')
args = [self.distribution.get_command_obj('bdist_egg').egg_output]
if setuptools.bootstrap_install_from:
# Bootstrap self-installation of setuptools
args.insert(0, setuptools.bootstrap_install_from)
cmd.args = args
cmd.run()
setuptools.bootstrap_install_from = None
sub_commands = [('depends', has_dependencies)] + _install.sub_commands
......@@ -207,9 +207,8 @@ class Distribution(_Distribution):
have_package_data = hasattr(self, "package_data")
if not have_package_data:
self.package_data = {}
self.requires = [] # XXX
self.features = {}
self.requires = []
self.dist_files = []
if attrs and 'setup_requires' in attrs:
......@@ -244,18 +243,13 @@ class Distribution(_Distribution):
def finalize_options(self):
_Distribution.finalize_options(self)
if self.features:
self._set_global_opts_from_features()
if self.extra_path:
raise DistutilsSetupError(
"The 'extra_path' parameter is not needed when using "
"setuptools. Please remove it from your setup script."
)
for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
value = getattr(self,ep.name,None)
if value is not None:
......@@ -285,6 +279,12 @@ class Distribution(_Distribution):
def _set_global_opts_from_features(self):
"""Add --with-X/--without-X options based on optional features"""
......@@ -572,47 +572,6 @@ class Distribution(_Distribution):
def has_dependencies(self):
return not not self.requires
def run_commands(self):
for cmd in self.commands:
if cmd=='install' and not cmd in self.have_run:
self.install_eggs()
else:
self.run_command(cmd)
def install_eggs(self):
from setuptools.command.easy_install import easy_install
cmd = easy_install(self, args="x", ignore_conflicts_at_my_risk=1)
cmd.ensure_finalized() # finalize before bdist_egg munges install cmd
self.run_command('bdist_egg')
args = [self.get_command_obj('bdist_egg').egg_output]
if setuptools.bootstrap_install_from:
# Bootstrap self-installation of setuptools
args.insert(0, setuptools.bootstrap_install_from)
cmd.args = args
cmd.run()
self.have_run['install'] = 1
setuptools.bootstrap_install_from = None
def get_cmdline_options(self):
"""Return a '{cmd: {opt:val}}' map of all command-line options
......
......@@ -118,47 +118,6 @@ class DependsTests(TestCase):
paths = [os.path.dirname(p) for p in __path__]
self.failUnless(req.is_present(paths))
self.failUnless(req.is_current(paths))
def testDependsCmd(self):
path = convert_path('foo/bar/baz')
dist = makeSetup(
script_args=['install','--install-lib',path]
)
cmd = dist.get_command_obj('depends')
cmd.ensure_finalized()
self.assertEqual(cmd.temp, dist.get_command_obj('build').build_temp)
self.assertEqual(cmd.search_path, [path+os.path.sep,path]+sys.path)
......
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