Skip to content

Commit 2f66454

Browse files
committed
Adds --upgrade-recursive option, makes -U non-recursive by default.
refs pypa#304
1 parent c6789f6 commit 2f66454

File tree

2 files changed

+55
-32
lines changed

2 files changed

+55
-32
lines changed

pip/commands/install.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,12 @@ def __init__(self):
113113
'-U', '--upgrade',
114114
dest='upgrade',
115115
action='store_true',
116-
help='Upgrade all packages to the newest available version')
116+
help='Upgrade packages to the latest version, but not dependencies')
117+
self.parser.add_option(
118+
'-R', '--upgrade-recursive',
119+
dest='upgrade_recursive',
120+
action='store_true',
121+
help='Upgrade packages to the latest version, including dependencies')
117122
self.parser.add_option(
118123
'--force-reinstall',
119124
dest='force_reinstall',
@@ -213,18 +218,20 @@ def run(self, options, args):
213218
src_dir=options.src_dir,
214219
download_dir=options.download_dir,
215220
download_cache=options.download_cache,
216-
upgrade=options.upgrade,
221+
upgrade=options.upgrade or options.upgrade_recursive,
222+
upgrade_recursive=options.upgrade_recursive,
217223
as_egg=options.as_egg,
218224
ignore_installed=options.ignore_installed,
219225
ignore_dependencies=options.ignore_dependencies,
220226
force_reinstall=options.force_reinstall,
221227
use_user_site=options.use_user_site)
228+
upgrade = options.upgrade or options.upgrade_recursive
222229
for name in args:
223230
requirement_set.add_requirement(
224-
InstallRequirement.from_line(name, None))
231+
InstallRequirement.from_line(name, None, upgrade=upgrade))
225232
for name in options.editables:
226233
requirement_set.add_requirement(
227-
InstallRequirement.from_editable(name, default_vcs=options.default_vcs))
234+
InstallRequirement.from_editable(name, default_vcs=options.default_vcs, upgrade=upgrade))
228235
for filename in options.requirements:
229236
for req in parse_requirements(filename, finder=finder, options=options):
230237
requirement_set.add_requirement(req)

pip/req.py

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
class InstallRequirement(object):
3737

3838
def __init__(self, req, comes_from, source_dir=None, editable=False,
39-
url=None, as_egg=False, update=True):
39+
url=None, as_egg=False, update=True, upgrade=False):
4040
self.extras = ()
4141
if isinstance(req, string_types):
4242
req = pkg_resources.Requirement.parse(req)
@@ -58,29 +58,32 @@ def __init__(self, req, comes_from, source_dir=None, editable=False,
5858
self._is_bundle = None
5959
# True if the editable should be updated:
6060
self.update = update
61+
# True if the requirement should be upgraded to the latest version
62+
self.upgrade = upgrade
6163
# Set to True after successful installation
6264
self.install_succeeded = None
6365
# UninstallPathSet of uninstalled distribution (for possible rollback)
6466
self.uninstalled = None
6567
self.use_user_site = False
6668

6769
@classmethod
68-
def from_editable(cls, editable_req, comes_from=None, default_vcs=None):
70+
def from_editable(cls, editable_req, comes_from=None, default_vcs=None, upgrade=False):
6971
name, url, extras_override = parse_editable(editable_req, default_vcs)
7072
if url.startswith('file:'):
7173
source_dir = url_to_path(url)
7274
else:
7375
source_dir = None
7476

75-
res = cls(name, comes_from, source_dir=source_dir, editable=True, url=url)
77+
res = cls(name, comes_from, source_dir=source_dir, editable=True,
78+
url=url, upgrade=upgrade)
7679

7780
if extras_override is not None:
7881
res.extras = extras_override
7982

8083
return res
8184

8285
@classmethod
83-
def from_line(cls, name, comes_from=None):
86+
def from_line(cls, name, comes_from=None, upgrade=False):
8487
"""Creates an InstallRequirement from a name, which might be a
8588
requirement, directory containing 'setup.py', filename, or URL.
8689
"""
@@ -114,7 +117,7 @@ def from_line(cls, name, comes_from=None):
114117
else:
115118
req = name
116119

117-
return cls(req, comes_from, url=url)
120+
return cls(req, comes_from, url=url, upgrade=upgrade)
118121

119122
def __str__(self):
120123
if self.req:
@@ -706,7 +709,7 @@ def is_bundle(self):
706709
or os.path.exists(os.path.join(base, 'pyinstall-manifest.txt')))
707710
return self._is_bundle
708711

709-
def bundle_requirements(self):
712+
def bundle_requirements(self, upgrade=False):
710713
for dest_dir in self._bundle_editable_dirs:
711714
package = os.path.basename(dest_dir)
712715
## FIXME: svnism:
@@ -726,13 +729,11 @@ def bundle_requirements(self):
726729
else:
727730
url = None
728731
yield InstallRequirement(
729-
package, self, editable=True, url=url,
730-
update=False, source_dir=dest_dir)
732+
package, self, editable=True, url=url, update=False,
733+
source_dir=dest_dir, upgrade=upgrade)
731734
for dest_dir in self._bundle_build_dirs:
732735
package = os.path.basename(dest_dir)
733-
yield InstallRequirement(
734-
package, self,
735-
source_dir=dest_dir)
736+
yield InstallRequirement(package, self, source_dir=dest_dir, upgrade=upgrade)
736737

737738
def move_bundle_files(self, dest_build_dir, dest_src_dir):
738739
base = self._temp_build_dir
@@ -808,13 +809,15 @@ def __repr__(self):
808809
class RequirementSet(object):
809810

810811
def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
811-
upgrade=False, ignore_installed=False, as_egg=False,
812-
ignore_dependencies=False, force_reinstall=False, use_user_site=False):
812+
ignore_installed=False, as_egg=False, force_reinstall=False,
813+
ignore_dependencies=False, use_user_site=False, upgrade=False,
814+
upgrade_recursive=False):
813815
self.build_dir = build_dir
814816
self.src_dir = src_dir
815817
self.download_dir = download_dir
816818
self.download_cache = download_cache
817-
self.upgrade = upgrade
819+
self.upgrade = upgrade or upgrade_recursive
820+
self.upgrade_recursive = upgrade_recursive
818821
self.ignore_installed = ignore_installed
819822
self.force_reinstall = force_reinstall
820823
self.requirements = Requirements()
@@ -908,15 +911,19 @@ def locate_files(self):
908911
if not self.ignore_installed and not req_to_install.editable:
909912
req_to_install.check_if_exists()
910913
if req_to_install.satisfied_by:
911-
if self.upgrade:
914+
if req_to_install.upgrade:
912915
req_to_install.conflicts_with = req_to_install.satisfied_by
913916
req_to_install.satisfied_by = None
914917
else:
915918
install_needed = False
916919
if req_to_install.satisfied_by:
920+
if self.upgrade and not self.upgrade_recursive:
921+
upgrade_cmd = '--upgrade-recursive'
922+
else:
923+
upgrade_cmd = '--upgrade'
917924
logger.notify('Requirement already satisfied '
918-
'(use --upgrade to upgrade): %s'
919-
% req_to_install)
925+
'(use %s to upgrade): %s'
926+
% (upgrade_cmd, req_to_install))
920927

921928
if req_to_install.editable:
922929
if req_to_install.source_dir is None:
@@ -946,11 +953,11 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
946953
if not self.ignore_installed and not req_to_install.editable:
947954
req_to_install.check_if_exists()
948955
if req_to_install.satisfied_by:
949-
if self.upgrade:
956+
if req_to_install.upgrade:
950957
if not self.force_reinstall and not req_to_install.url:
951958
try:
952959
url = finder.find_requirement(
953-
req_to_install, self.upgrade)
960+
req_to_install, upgrade=True)
954961
except BestVersionAlreadyInstalled:
955962
best_installed = True
956963
install = False
@@ -970,9 +977,13 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
970977
logger.notify('Requirement already up-to-date: %s'
971978
% req_to_install)
972979
else:
980+
if self.upgrade and not self.upgrade_recursive:
981+
upgrade_cmd = '--upgrade-recursive'
982+
else:
983+
upgrade_cmd = '--upgrade'
973984
logger.notify('Requirement already satisfied '
974-
'(use --upgrade to upgrade): %s'
975-
% req_to_install)
985+
'(use %s to upgrade): %s'
986+
% (upgrade_cmd, req_to_install))
976987
if req_to_install.editable:
977988
logger.notify('Obtaining %s' % req_to_install)
978989
elif install:
@@ -1012,7 +1023,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
10121023
if req_to_install.url is None:
10131024
if not_found:
10141025
raise not_found
1015-
url = finder.find_requirement(req_to_install, upgrade=self.upgrade)
1026+
url = finder.find_requirement(req_to_install, upgrade=req_to_install.upgrade)
10161027
else:
10171028
## FIXME: should req_to_install.url already be a link?
10181029
url = Link(req_to_install.url)
@@ -1033,7 +1044,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
10331044
is_bundle = req_to_install.is_bundle
10341045
if is_bundle:
10351046
req_to_install.move_bundle_files(self.build_dir, self.src_dir)
1036-
for subreq in req_to_install.bundle_requirements():
1047+
for subreq in req_to_install.bundle_requirements(upgrade=self.upgrade_recursive):
10371048
reqs.append(subreq)
10381049
self.add_requirement(subreq)
10391050
elif self.is_download:
@@ -1057,7 +1068,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
10571068
# repeat check_if_exists to uninstall-on-upgrade (#14)
10581069
req_to_install.check_if_exists()
10591070
if req_to_install.satisfied_by:
1060-
if self.upgrade or self.ignore_installed:
1071+
if req_to_install.upgrade or self.ignore_installed:
10611072
req_to_install.conflicts_with = req_to_install.satisfied_by
10621073
req_to_install.satisfied_by = None
10631074
else:
@@ -1079,7 +1090,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
10791090
if self.has_requirement(name):
10801091
## FIXME: check for conflict
10811092
continue
1082-
subreq = InstallRequirement(req, req_to_install)
1093+
subreq = InstallRequirement(req, req_to_install, upgrade=self.upgrade_recursive)
10831094
reqs.append(subreq)
10841095
self.add_requirement(subreq)
10851096
if req_to_install.name not in self.requirements:
@@ -1322,16 +1333,21 @@ def parse_requirements(filename, finder=None, comes_from=None, options=None):
13221333
if finder:
13231334
finder.index_urls.append(line)
13241335
else:
1336+
# Use getattr since uninstall doesn't set these options
1337+
upgrade = (getattr(options, 'upgrade', False)
1338+
or getattr(options, 'upgrade_recursive', False))
13251339
comes_from = '-r %s (line %s)' % (filename, line_number)
13261340
if line.startswith('-e') or line.startswith('--editable'):
13271341
if line.startswith('-e'):
13281342
line = line[2:].strip()
13291343
else:
13301344
line = line[len('--editable'):].strip().lstrip('=')
1331-
req = InstallRequirement.from_editable(
1332-
line, comes_from=comes_from, default_vcs=options.default_vcs)
1345+
req = InstallRequirement.from_editable(line,
1346+
comes_from=comes_from,
1347+
default_vcs=options.default_vcs,
1348+
upgrade=upgrade)
13331349
else:
1334-
req = InstallRequirement.from_line(line, comes_from)
1350+
req = InstallRequirement.from_line(line, comes_from, upgrade=upgrade)
13351351
yield req
13361352

13371353

0 commit comments

Comments
 (0)