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 13, 2012
1 parent c6789f6 commit 2f66454
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 32 deletions.
15 changes: 11 additions & 4 deletions pip/commands/install.py
Expand Up @@ -113,7 +113,12 @@ def __init__(self):
'-U', '--upgrade',
dest='upgrade',
action='store_true',
help='Upgrade all packages to the newest available version')
help='Upgrade packages to the latest version, but not dependencies')
self.parser.add_option(
'-R', '--upgrade-recursive',
dest='upgrade_recursive',
action='store_true',
help='Upgrade packages to the latest version, including dependencies')
self.parser.add_option(
'--force-reinstall',
dest='force_reinstall',
Expand Down Expand Up @@ -213,18 +218,20 @@ 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,
force_reinstall=options.force_reinstall,
use_user_site=options.use_user_site)
upgrade = options.upgrade or options.upgrade_recursive
for name in args:
requirement_set.add_requirement(
InstallRequirement.from_line(name, None))
InstallRequirement.from_line(name, None, upgrade=upgrade))
for name in options.editables:
requirement_set.add_requirement(
InstallRequirement.from_editable(name, default_vcs=options.default_vcs))
InstallRequirement.from_editable(name, default_vcs=options.default_vcs, upgrade=upgrade))
for filename in options.requirements:
for req in parse_requirements(filename, finder=finder, options=options):
requirement_set.add_requirement(req)
Expand Down
72 changes: 44 additions & 28 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, upgrade=False):
self.extras = ()
if isinstance(req, string_types):
req = pkg_resources.Requirement.parse(req)
Expand All @@ -58,29 +58,32 @@ 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 should be upgraded to the latest version
self.upgrade = upgrade
# Set to True after successful installation
self.install_succeeded = None
# UninstallPathSet of uninstalled distribution (for possible rollback)
self.uninstalled = None
self.use_user_site = False

@classmethod
def from_editable(cls, editable_req, comes_from=None, default_vcs=None):
def from_editable(cls, editable_req, comes_from=None, default_vcs=None, upgrade=False):
name, url, extras_override = parse_editable(editable_req, default_vcs)
if url.startswith('file:'):
source_dir = url_to_path(url)
else:
source_dir = None

res = cls(name, comes_from, source_dir=source_dir, editable=True, url=url)
res = cls(name, comes_from, source_dir=source_dir, editable=True,
url=url, upgrade=upgrade)

if extras_override is not None:
res.extras = extras_override

return res

@classmethod
def from_line(cls, name, comes_from=None):
def from_line(cls, name, comes_from=None, upgrade=False):
"""Creates an InstallRequirement from a name, which might be a
requirement, directory containing 'setup.py', filename, or URL.
"""
Expand Down Expand Up @@ -114,7 +117,7 @@ def from_line(cls, name, comes_from=None):
else:
req = name

return cls(req, comes_from, url=url)
return cls(req, comes_from, url=url, upgrade=upgrade)

def __str__(self):
if self.req:
Expand Down Expand Up @@ -706,7 +709,7 @@ def is_bundle(self):
or os.path.exists(os.path.join(base, 'pyinstall-manifest.txt')))
return self._is_bundle

def bundle_requirements(self):
def bundle_requirements(self, upgrade=False):
for dest_dir in self._bundle_editable_dirs:
package = os.path.basename(dest_dir)
## FIXME: svnism:
Expand All @@ -726,13 +729,11 @@ def bundle_requirements(self):
else:
url = None
yield InstallRequirement(
package, self, editable=True, url=url,
update=False, source_dir=dest_dir)
package, self, editable=True, url=url, update=False,
source_dir=dest_dir, upgrade=upgrade)
for dest_dir in self._bundle_build_dirs:
package = os.path.basename(dest_dir)
yield InstallRequirement(
package, self,
source_dir=dest_dir)
yield InstallRequirement(package, self, source_dir=dest_dir, upgrade=upgrade)

def move_bundle_files(self, dest_build_dir, dest_src_dir):
base = self._temp_build_dir
Expand Down Expand Up @@ -808,13 +809,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 +911,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 req_to_install.upgrade:
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 +953,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 req_to_install.upgrade:
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 +977,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 +1023,7 @@ 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=req_to_install.upgrade)
else:
## FIXME: should req_to_install.url already be a link?
url = Link(req_to_install.url)
Expand All @@ -1033,7 +1044,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
is_bundle = req_to_install.is_bundle
if is_bundle:
req_to_install.move_bundle_files(self.build_dir, self.src_dir)
for subreq in req_to_install.bundle_requirements():
for subreq in req_to_install.bundle_requirements(upgrade=self.upgrade_recursive):
reqs.append(subreq)
self.add_requirement(subreq)
elif self.is_download:
Expand All @@ -1057,7 +1068,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 req_to_install.upgrade or self.ignore_installed:
req_to_install.conflicts_with = req_to_install.satisfied_by
req_to_install.satisfied_by = None
else:
Expand All @@ -1079,7 +1090,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, upgrade=self.upgrade_recursive)
reqs.append(subreq)
self.add_requirement(subreq)
if req_to_install.name not in self.requirements:
Expand Down Expand Up @@ -1322,16 +1333,21 @@ def parse_requirements(filename, finder=None, comes_from=None, options=None):
if finder:
finder.index_urls.append(line)
else:
# Use getattr since uninstall doesn't set these options
upgrade = (getattr(options, 'upgrade', False)
or getattr(options, 'upgrade_recursive', False))
comes_from = '-r %s (line %s)' % (filename, line_number)
if line.startswith('-e') or line.startswith('--editable'):
if line.startswith('-e'):
line = line[2:].strip()
else:
line = line[len('--editable'):].strip().lstrip('=')
req = InstallRequirement.from_editable(
line, comes_from=comes_from, default_vcs=options.default_vcs)
req = InstallRequirement.from_editable(line,
comes_from=comes_from,
default_vcs=options.default_vcs,
upgrade=upgrade)
else:
req = InstallRequirement.from_line(line, comes_from)
req = InstallRequirement.from_line(line, comes_from, upgrade=upgrade)
yield req


Expand Down

0 comments on commit 2f66454

Please sign in to comment.