2011-03-19 19:30:56 +01:00
|
|
|
import pkg_resources
|
2011-07-09 12:34:15 +02:00
|
|
|
|
2011-03-19 19:30:56 +01:00
|
|
|
from pip.basecommand import Command
|
2011-07-09 12:34:15 +02:00
|
|
|
from pip.exceptions import DistributionNotFound
|
|
|
|
from pip.index import PackageFinder
|
|
|
|
from pip.log import logger
|
|
|
|
from pip.req import InstallRequirement
|
2011-03-19 19:30:56 +01:00
|
|
|
from pip.util import get_installed_distributions
|
|
|
|
|
|
|
|
|
|
|
|
class OutdatedCommand(Command):
|
|
|
|
name = 'outdated'
|
|
|
|
usage = '%prog [OPTIONS]'
|
|
|
|
summary = 'Output all currently installed outdated packages to stdout'
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
super(OutdatedCommand, self).__init__()
|
|
|
|
self.parser.add_option(
|
|
|
|
'-l', '--local',
|
|
|
|
dest='local',
|
|
|
|
action='store_true',
|
|
|
|
default=False,
|
|
|
|
help='If in a virtualenv, do not report'
|
|
|
|
' globally-installed packages')
|
|
|
|
self.parser.add_option(
|
2011-07-09 12:34:15 +02:00
|
|
|
'-f', '--find-links',
|
|
|
|
dest='find_links',
|
|
|
|
action='append',
|
|
|
|
default=[],
|
|
|
|
metavar='URL',
|
|
|
|
help='URL to look for packages at')
|
|
|
|
self.parser.add_option(
|
|
|
|
'-i', '--index-url', '--pypi-url',
|
|
|
|
dest='index_url',
|
2011-03-19 19:30:56 +01:00
|
|
|
metavar='URL',
|
2011-07-09 12:34:15 +02:00
|
|
|
default='http://pypi.python.org/simple/',
|
2011-03-19 19:30:56 +01:00
|
|
|
help='Base URL of Python Package Index (default %default)')
|
2011-07-09 12:34:15 +02:00
|
|
|
self.parser.add_option(
|
|
|
|
'--extra-index-url',
|
|
|
|
dest='extra_index_urls',
|
|
|
|
metavar='URL',
|
|
|
|
action='append',
|
|
|
|
default=[],
|
|
|
|
help='Extra URLs of package indexes to use in addition to --index-url')
|
|
|
|
self.parser.add_option(
|
|
|
|
'--no-index',
|
|
|
|
dest='no_index',
|
|
|
|
action='store_true',
|
|
|
|
default=False,
|
|
|
|
help='Ignore package index (only looking at --find-links URLs instead)')
|
|
|
|
self.parser.add_option(
|
|
|
|
'-M', '--use-mirrors',
|
|
|
|
dest='use_mirrors',
|
|
|
|
action='store_true',
|
|
|
|
default=False,
|
|
|
|
help='Use the PyPI mirrors as a fallback in case the main index is down.')
|
|
|
|
self.parser.add_option(
|
|
|
|
'--mirrors',
|
|
|
|
dest='mirrors',
|
|
|
|
metavar='URL',
|
|
|
|
action='append',
|
|
|
|
default=[],
|
|
|
|
help='Specific mirror URLs to query when --use-mirrors is used')
|
|
|
|
|
|
|
|
def _build_package_finder(self, options, index_urls):
|
|
|
|
"""
|
|
|
|
Create a package finder appropriate to this outdated command.
|
|
|
|
"""
|
|
|
|
return PackageFinder(find_links=options.find_links,
|
|
|
|
index_urls=index_urls,
|
|
|
|
use_mirrors=options.use_mirrors,
|
|
|
|
mirrors=options.mirrors)
|
2011-03-19 19:30:56 +01:00
|
|
|
|
|
|
|
def run(self, options, args):
|
|
|
|
local_only = options.local
|
2011-07-09 12:34:15 +02:00
|
|
|
index_urls = [options.index_url] + options.extra_index_urls
|
|
|
|
if options.no_index:
|
|
|
|
logger.notify('Ignoring indexes: %s' % ','.join(index_urls))
|
|
|
|
index_urls = []
|
2011-03-19 19:30:56 +01:00
|
|
|
|
|
|
|
installations = {}
|
|
|
|
dependency_links = []
|
|
|
|
|
|
|
|
for dist in pkg_resources.working_set:
|
|
|
|
if dist.has_metadata('dependency_links.txt'):
|
|
|
|
dependency_links.extend(
|
|
|
|
dist.get_metadata_lines('dependency_links.txt'),
|
|
|
|
)
|
|
|
|
|
|
|
|
for dist in get_installed_distributions(local_only=local_only):
|
2011-07-09 12:34:15 +02:00
|
|
|
req = InstallRequirement.from_line(dist.key, None)
|
2011-07-13 15:36:49 +02:00
|
|
|
req.check_if_exists()
|
2011-03-19 19:30:56 +01:00
|
|
|
installations[req.name] = req
|
|
|
|
|
2011-07-09 12:34:15 +02:00
|
|
|
finder = self._build_package_finder(options, index_urls)
|
|
|
|
finder.add_dependency_links(dependency_links)
|
2011-03-19 19:30:56 +01:00
|
|
|
|
2011-07-09 12:34:15 +02:00
|
|
|
for req in installations.values():
|
2011-03-19 19:30:56 +01:00
|
|
|
try:
|
2011-07-09 12:34:15 +02:00
|
|
|
link = finder.find_requirement(req, True)
|
2011-07-13 15:36:49 +02:00
|
|
|
|
|
|
|
# If link is None, means installed version is most up-to-date
|
|
|
|
if link is None:
|
|
|
|
continue
|
2011-07-09 12:34:15 +02:00
|
|
|
except DistributionNotFound:
|
|
|
|
continue
|
|
|
|
|
|
|
|
# It might be a good idea that link or finder had a public method
|
|
|
|
# that returned version
|
|
|
|
remote_version = finder._link_package_versions(link, req.name)[0][2]
|
2011-03-19 19:30:56 +01:00
|
|
|
|
2011-07-13 15:36:49 +02:00
|
|
|
if remote_version > req.installed_version:
|
|
|
|
logger.notify('%s (CURRENT: %s LATEST: %s)' % (str(req), req.installed_version, remote_version))
|
2012-09-11 23:22:10 +02:00
|
|
|
|
2011-03-19 19:30:56 +01:00
|
|
|
|
|
|
|
OutdatedCommand()
|