pip/pip/commands/freeze.py

130 lines
4.8 KiB
Python
Raw Normal View History

import re
import sys
import pip
2014-03-01 05:09:26 +01:00
from pip.backwardcompat import stdlib_pkgs
from pip.req import InstallRequirement
from pip.log import logger
from pip.basecommand import Command
from pip.util import get_installed_distributions
2014-03-01 05:09:26 +01:00
# packages to exclude from freeze output
freeze_excludes = stdlib_pkgs + ['setuptools', 'pip', 'distribute']
class FreezeCommand(Command):
"""Output installed packages in requirements format."""
name = 'freeze'
2013-01-18 22:25:15 +01:00
usage = """
%prog [options]"""
summary = 'Output installed packages in requirements format.'
def __init__(self, *args, **kw):
super(FreezeCommand, self).__init__(*args, **kw)
self.cmd_opts.add_option(
'-r', '--requirement',
dest='requirement',
action='store',
default=None,
2013-01-18 22:25:15 +01:00
metavar='file',
help="Use the order in the given requirements file and it's "
"comments when generating output.")
self.cmd_opts.add_option(
'-f', '--find-links',
dest='find_links',
action='append',
default=[],
metavar='URL',
help='URL for finding packages, which will be added to the '
'output.')
self.cmd_opts.add_option(
2010-02-22 06:37:28 +01:00
'-l', '--local',
dest='local',
action='store_true',
default=False,
help='If in a virtualenv that has global access, do not output '
'globally-installed packages.')
self.parser.insert_option_group(0, self.cmd_opts)
def setup_logging(self):
logger.move_stdout_to_stderr()
def run(self, options, args):
requirement = options.requirement
find_links = options.find_links or []
2010-02-22 06:37:28 +01:00
local_only = options.local
## FIXME: Obviously this should be settable:
find_tags = False
skip_match = None
skip_regex = options.skip_requirements_regex
if skip_regex:
skip_match = re.compile(skip_regex)
f = sys.stdout
for link in find_links:
f.write('-f %s\n' % link)
installations = {}
2014-03-01 05:09:26 +01:00
for dist in get_installed_distributions(local_only=local_only,
skip=freeze_excludes):
req = pip.FrozenRequirement.from_dist(dist, find_tags=find_tags)
installations[req.name] = req
if requirement:
req_f = open(requirement)
for line in req_f:
if not line.strip() or line.strip().startswith('#'):
f.write(line)
continue
if skip_match and skip_match.search(line):
f.write(line)
continue
elif line.startswith('-e') or line.startswith('--editable'):
if line.startswith('-e'):
line = line[2:].strip()
else:
line = line[len('--editable'):].strip().lstrip('=')
line_req = InstallRequirement.from_editable(
line,
default_vcs=options.default_vcs
)
elif (line.startswith('-r')
or line.startswith('--requirement')
or line.startswith('-Z')
or line.startswith('--always-unzip')
or line.startswith('-f')
or line.startswith('-i')
or line.startswith('--extra-index-url')
or line.startswith('--find-links')
or line.startswith('--index-url')):
f.write(line)
continue
else:
line_req = InstallRequirement.from_line(line)
if not line_req.name:
logger.notify(
"Skipping line because it's not clear what it would "
"install: %s" % line.strip()
)
logger.notify(
" (add #egg=PackageName to the URL to avoid"
" this warning)"
)
continue
if line_req.name not in installations:
logger.warn(
"Requirement file contains %s, but that package is not"
" installed" % line.strip()
)
continue
f.write(str(installations[line_req.name]))
del installations[line_req.name]
f.write(
'## The following requirements were added by pip --freeze:\n'
)
for installation in sorted(
installations.values(), key=lambda x: x.name):
f.write(str(installation))