Skip to content

Commit

Permalink
Adds --upgrade-recursive option, makes -U non-recursive by default.
Browse files Browse the repository at this point in the history
  • Loading branch information
fdintino committed Jul 3, 2012
1 parent 5562a6b commit bbf37ad
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
9 changes: 8 additions & 1 deletion pip/commands/install.py
Expand Up @@ -114,6 +114,12 @@ def __init__(self):
dest='upgrade',
action='store_true',
help='Upgrade all packages to the newest available version')
self.parser.add_option(
'-R', '--upgrade-recursive',
dest='upgrade_recursive',
action='store_true',
help='Upgrade package to the newest available version, recursing '
'into its dependencies')
self.parser.add_option(
'--force-reinstall',
dest='force_reinstall',
Expand Down Expand Up @@ -213,7 +219,8 @@ def run(self, options, args):
src_dir=options.src_dir,
download_dir=options.download_dir,
download_cache=options.download_cache,
upgrade=options.upgrade,
upgrade=options.upgrade or options.upgrade_recursive,
upgrade_recursive=options.upgrade_recursive,
as_egg=options.as_egg,
ignore_installed=options.ignore_installed,
ignore_dependencies=options.ignore_dependencies,
Expand Down
55 changes: 39 additions & 16 deletions pip/req.py
Expand Up @@ -36,7 +36,7 @@
class InstallRequirement(object):

def __init__(self, req, comes_from, source_dir=None, editable=False,
url=None, as_egg=False, update=True):
url=None, as_egg=False, update=True, is_extra=False):
self.extras = ()
if isinstance(req, string_types):
req = pkg_resources.Requirement.parse(req)
Expand All @@ -58,6 +58,8 @@ def __init__(self, req, comes_from, source_dir=None, editable=False,
self._is_bundle = None
# True if the editable should be updated:
self.update = update
# True if the requirement comes from another requirement's extras
self.is_extra = is_extra
# Set to True after successful installation
self.install_succeeded = None
# UninstallPathSet of uninstalled distribution (for possible rollback)
Expand Down Expand Up @@ -208,6 +210,10 @@ def url_name(self):
def setup_py(self):
return os.path.join(self.source_dir, 'setup.py')

@property
def is_subrequirement(self):
return self.req and self.comes_from.__class__ is self.__class__

def run_egg_info(self, force_root_egg_info=False):
assert self.source_dir
if self.name:
Expand Down Expand Up @@ -353,7 +359,7 @@ def requirements(self, extras=()):
logger.debug('skipping extra %s' % in_extra)
# Skip requirement for an extra we aren't requiring
continue
yield line
yield line, bool(in_extra in extras)

@property
def absolute_versions(self):
Expand Down Expand Up @@ -808,13 +814,15 @@ def __repr__(self):
class RequirementSet(object):

def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
upgrade=False, ignore_installed=False, as_egg=False,
ignore_dependencies=False, force_reinstall=False, use_user_site=False):
ignore_installed=False, as_egg=False, force_reinstall=False,
ignore_dependencies=False, use_user_site=False, upgrade=False,
upgrade_recursive=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.upgrade = upgrade or upgrade_recursive
self.upgrade_recursive = upgrade_recursive
self.ignore_installed = ignore_installed
self.force_reinstall = force_reinstall
self.requirements = Requirements()
Expand Down Expand Up @@ -908,15 +916,19 @@ def locate_files(self):
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:
if self.is_upgradeable(req_to_install):
req_to_install.conflicts_with = req_to_install.satisfied_by
req_to_install.satisfied_by = None
else:
install_needed = False
if req_to_install.satisfied_by:
if self.upgrade and not self.upgrade_recursive:
upgrade_cmd = '--upgrade-recursive'
else:
upgrade_cmd = '--upgrade'
logger.notify('Requirement already satisfied '
'(use --upgrade to upgrade): %s'
% req_to_install)
'(use %s to upgrade): %s'
% (upgrade_cmd, req_to_install))

if req_to_install.editable:
if req_to_install.source_dir is None:
Expand Down Expand Up @@ -946,11 +958,11 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=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:
if self.is_upgradeable(req_to_install):
if not self.force_reinstall and not req_to_install.url:
try:
url = finder.find_requirement(
req_to_install, self.upgrade)
req_to_install, upgrade=True)
except BestVersionAlreadyInstalled:
best_installed = True
install = False
Expand All @@ -970,9 +982,13 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
logger.notify('Requirement already up-to-date: %s'
% req_to_install)
else:
if self.upgrade and not self.upgrade_recursive:
upgrade_cmd = '--upgrade-recursive'
else:
upgrade_cmd = '--upgrade'
logger.notify('Requirement already satisfied '
'(use --upgrade to upgrade): %s'
% req_to_install)
'(use %s to upgrade): %s'
% (upgrade_cmd, req_to_install))
if req_to_install.editable:
logger.notify('Obtaining %s' % req_to_install)
elif install:
Expand Down Expand Up @@ -1012,7 +1028,8 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
if req_to_install.url is None:
if not_found:
raise not_found
url = finder.find_requirement(req_to_install, upgrade=self.upgrade)
url = finder.find_requirement(req_to_install,
upgrade=self.is_upgradeable(req_to_install))
else:
## FIXME: should req_to_install.url already be a link?
url = Link(req_to_install.url)
Expand Down Expand Up @@ -1057,7 +1074,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
# repeat check_if_exists to uninstall-on-upgrade (#14)
req_to_install.check_if_exists()
if req_to_install.satisfied_by:
if self.upgrade or self.ignore_installed:
if self.ignore_installed or self.is_upgradeable(req_to_install):
req_to_install.conflicts_with = req_to_install.satisfied_by
req_to_install.satisfied_by = None
else:
Expand All @@ -1068,7 +1085,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
if (req_to_install.extras):
logger.notify("Installing extra requirements: %r" % ','.join(req_to_install.extras))
if not self.ignore_dependencies:
for req in req_to_install.requirements(req_to_install.extras):
for req, is_extra in req_to_install.requirements(req_to_install.extras):
try:
name = pkg_resources.Requirement.parse(req).project_name
except ValueError:
Expand All @@ -1079,7 +1096,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
if self.has_requirement(name):
## FIXME: check for conflict
continue
subreq = InstallRequirement(req, req_to_install)
subreq = InstallRequirement(req, req_to_install, is_extra=is_extra)
reqs.append(subreq)
self.add_requirement(subreq)
if req_to_install.name not in self.requirements:
Expand All @@ -1096,6 +1113,12 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
finally:
logger.indent -= 2

def is_upgradeable(self, requirement):
if requirement.is_subrequirement and not requirement.is_extra:
return self.upgrade_recursive
else:
return self.upgrade

def cleanup_files(self, bundle=False):
"""Clean up files, remove builds."""
logger.notify('Cleaning up...')
Expand Down

0 comments on commit bbf37ad

Please sign in to comment.