mirror of https://github.com/pypa/pip
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:
parent
2a5e21b41f
commit
1ecda0db16
|
@ -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))
|
||||
|
|
|
@ -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"""
|
||||
|
||||
|
|
|
@ -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])))
|
||||
|
|
35
pip/req.py
35
pip/req.py
|
@ -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]))
|
||||
|
|
Loading…
Reference in New Issue