Fix --upgrade to leave already up-to-date packages alone. Add --force-reinstall to force reinstallation even of up-to-date packages, as was the prior behavior.

This commit is contained in:
Erik Bray 2011-08-24 14:07:16 -04:00
parent 2a5e21b41f
commit 1ecda0db16
4 changed files with 43 additions and 11 deletions

View File

@ -106,6 +106,12 @@ class InstallCommand(Command):
dest='upgrade',
action='store_true',
help='Upgrade all packages to the newest available version')
self.parser.add_option(
'--force-reinstall',
dest='force_reinstall',
action='store_true',
help='When upgrading, reinstall all packages even if they are '
'already up-to-date.')
self.parser.add_option(
'-I', '--ignore-installed',
dest='ignore_installed',
@ -190,7 +196,8 @@ class InstallCommand(Command):
download_cache=options.download_cache,
upgrade=options.upgrade,
ignore_installed=options.ignore_installed,
ignore_dependencies=options.ignore_dependencies)
ignore_dependencies=options.ignore_dependencies,
force_reinstall=options.force_reinstall)
for name in args:
requirement_set.add_requirement(
InstallRequirement.from_line(name, None))

View File

@ -13,6 +13,11 @@ class DistributionNotFound(InstallationError):
"""Raised when a distribution cannot be found to satisfy a requirement"""
class BestVersionAlreadyInstalled(Exception):
"""Raised when the most up-to-date version of a package is already
installed.
"""
class BadCommand(Exception):
"""Raised when virtualenv or a command is not found"""

View File

@ -15,7 +15,7 @@ import zlib
from pip.log import logger
from pip.util import Inf
from pip.util import normalize_name, splitext
from pip.exceptions import DistributionNotFound
from pip.exceptions import DistributionNotFound, BestVersionAlreadyInstalled
from pip.backwardcompat import (WindowsError, BytesIO,
Queue, httplib, urlparse,
URLError, HTTPError, u,
@ -172,6 +172,7 @@ class PackageFinder(object):
if applicable_versions[0][1] is Inf:
logger.info('Existing installed version (%s) is most up-to-date and satisfies requirement'
% req.satisfied_by.version)
raise BestVersionAlreadyInstalled
else:
logger.info('Existing installed version (%s) satisfies requirement (most up-to-date version is %s)'
% (req.satisfied_by.version, applicable_versions[0][1]))
@ -184,7 +185,7 @@ class PackageFinder(object):
# We have an existing version, and its the best version
logger.info('Installed version (%s) is most up-to-date (past versions: %s)'
% (req.satisfied_by.version, ', '.join([version for link, version in applicable_versions[1:]]) or 'none'))
return None
raise BestVersionAlreadyInstalled
if len(applicable_versions) > 1:
logger.info('Using version %s (newest of versions: %s)' %
(applicable_versions[0][1], ', '.join([version for link, version in applicable_versions])))

View File

@ -6,7 +6,8 @@ import zipfile
import pkg_resources
import tempfile
from pip.locations import bin_py, running_under_virtualenv
from pip.exceptions import InstallationError, UninstallationError
from pip.exceptions import (InstallationError, UninstallationError,
BestVersionAlreadyInstalled)
from pip.vcs import vcs
from pip.log import logger
from pip.util import display_path, rmtree
@ -776,13 +777,14 @@ class RequirementSet(object):
def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
upgrade=False, ignore_installed=False,
ignore_dependencies=False):
ignore_dependencies=False, force_reinstall=False):
self.build_dir = build_dir
self.src_dir = src_dir
self.download_dir = download_dir
self.download_cache = download_cache
self.upgrade = upgrade
self.ignore_installed = ignore_installed
self.force_reinstall = force_reinstall
self.requirements = Requirements()
# Mapping of alias: real_name
self.requirement_aliases = {}
@ -903,18 +905,35 @@ class RequirementSet(object):
else:
req_to_install = reqs.pop(0)
install = True
best_installed = False
if not self.ignore_installed and not req_to_install.editable:
req_to_install.check_if_exists()
if req_to_install.satisfied_by:
if self.upgrade:
req_to_install.conflicts_with = req_to_install.satisfied_by
req_to_install.satisfied_by = None
if not self.force_reinstall:
try:
finder.find_requirement(req_to_install,
self.uninstall)
except BestVersionAlreadyInstalled:
best_installed = True
install = False
except:
# Ignore DistributionNotFound for now
pass
if self.force_reinstall or not best_installed:
req_to_install.conflicts_with = req_to_install.satisfied_by
req_to_install.satisfied_by = None
else:
install = False
if req_to_install.satisfied_by:
logger.notify('Requirement already satisfied '
'(use --upgrade to upgrade): %s'
% req_to_install)
if best_installed:
logger.notify('Requirement already up-to-date: %s'
% req_to_install)
else:
logger.notify('Requirement already satisfied '
'(use --upgrade to upgrade): %s'
% req_to_install)
if req_to_install.editable:
logger.notify('Obtaining %s' % req_to_install)
elif install:
@ -1081,7 +1100,7 @@ class RequirementSet(object):
def install(self, install_options, global_options=()):
"""Install everything in this set (after having downloaded and unpacked the packages)"""
to_install = [r for r in self.requirements.values()
if self.upgrade or not r.satisfied_by]
if (self.upgrade and not r.satisfied_by) or not r.satisfied_by]
if to_install:
logger.notify('Installing collected packages: %s' % ', '.join([req.name for req in to_install]))