1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00

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', dest='upgrade',
action='store_true', action='store_true',
help='Upgrade all packages to the newest available version') 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( self.parser.add_option(
'-I', '--ignore-installed', '-I', '--ignore-installed',
dest='ignore_installed', dest='ignore_installed',
@ -190,7 +196,8 @@ class InstallCommand(Command):
download_cache=options.download_cache, download_cache=options.download_cache,
upgrade=options.upgrade, upgrade=options.upgrade,
ignore_installed=options.ignore_installed, ignore_installed=options.ignore_installed,
ignore_dependencies=options.ignore_dependencies) ignore_dependencies=options.ignore_dependencies,
force_reinstall=options.force_reinstall)
for name in args: for name in args:
requirement_set.add_requirement( requirement_set.add_requirement(
InstallRequirement.from_line(name, None)) 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""" """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): class BadCommand(Exception):
"""Raised when virtualenv or a command is not found""" """Raised when virtualenv or a command is not found"""

View file

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

View file

@ -6,7 +6,8 @@ import zipfile
import pkg_resources import pkg_resources
import tempfile import tempfile
from pip.locations import bin_py, running_under_virtualenv 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.vcs import vcs
from pip.log import logger from pip.log import logger
from pip.util import display_path, rmtree 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, def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
upgrade=False, ignore_installed=False, upgrade=False, ignore_installed=False,
ignore_dependencies=False): ignore_dependencies=False, force_reinstall=False):
self.build_dir = build_dir self.build_dir = build_dir
self.src_dir = src_dir self.src_dir = src_dir
self.download_dir = download_dir self.download_dir = download_dir
self.download_cache = download_cache self.download_cache = download_cache
self.upgrade = upgrade self.upgrade = upgrade
self.ignore_installed = ignore_installed self.ignore_installed = ignore_installed
self.force_reinstall = force_reinstall
self.requirements = Requirements() self.requirements = Requirements()
# Mapping of alias: real_name # Mapping of alias: real_name
self.requirement_aliases = {} self.requirement_aliases = {}
@ -903,15 +905,32 @@ class RequirementSet(object):
else: else:
req_to_install = reqs.pop(0) req_to_install = reqs.pop(0)
install = True install = True
best_installed = False
if not self.ignore_installed and not req_to_install.editable: if not self.ignore_installed and not req_to_install.editable:
req_to_install.check_if_exists() req_to_install.check_if_exists()
if req_to_install.satisfied_by: if req_to_install.satisfied_by:
if self.upgrade: if self.upgrade:
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.conflicts_with = req_to_install.satisfied_by
req_to_install.satisfied_by = None req_to_install.satisfied_by = None
else: else:
install = False install = False
if req_to_install.satisfied_by: if req_to_install.satisfied_by:
if best_installed:
logger.notify('Requirement already up-to-date: %s'
% req_to_install)
else:
logger.notify('Requirement already satisfied ' logger.notify('Requirement already satisfied '
'(use --upgrade to upgrade): %s' '(use --upgrade to upgrade): %s'
% req_to_install) % req_to_install)
@ -1081,7 +1100,7 @@ class RequirementSet(object):
def install(self, install_options, global_options=()): def install(self, install_options, global_options=()):
"""Install everything in this set (after having downloaded and unpacked the packages)""" """Install everything in this set (after having downloaded and unpacked the packages)"""
to_install = [r for r in self.requirements.values() 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: if to_install:
logger.notify('Installing collected packages: %s' % ', '.join([req.name for req in to_install])) logger.notify('Installing collected packages: %s' % ', '.join([req.name for req in to_install]))