diff --git a/pip/commands/freeze.py b/pip/commands/freeze.py index 00279162edc..82409620d05 100644 --- a/pip/commands/freeze.py +++ b/pip/commands/freeze.py @@ -1,23 +1,9 @@ from __future__ import absolute_import -import logging -import re import sys - -import pip - -from pip.compat import stdlib_pkgs -from pip.req import InstallRequirement from pip.basecommand import Command -from pip.utils import get_installed_distributions -from pip._vendor import pkg_resources - -# packages to exclude from freeze output -freeze_excludes = stdlib_pkgs + ['setuptools', 'pip', 'distribute'] - - -logger = logging.getLogger(__name__) +from pip.operations.freeze import freeze class FreezeCommand(Command): @@ -68,98 +54,13 @@ def __init__(self, *args, **kw): self.parser.insert_option_group(0, self.cmd_opts) def run(self, options, args): - requirement = options.requirement - find_links = options.find_links or [] - local_only = options.local - user_only = options.user - # 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) - - dependency_links = [] - - f = sys.stdout - - 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 link in find_links: - if '#egg=' in link: - dependency_links.append(link) - for link in find_links: - f.write('-f %s\n' % link) - installations = {} - for dist in get_installed_distributions(local_only=local_only, - skip=freeze_excludes, - user_only=user_only): - req = pip.FrozenRequirement.from_dist( - dist, - dependency_links, - find_tags=find_tags, - ) - installations[req.name] = req - - if requirement: - with open(requirement) as req_file: - for line in req_file: - if (not line.strip() - or line.strip().startswith('#') - or (skip_match and skip_match.search(line)) - or line.startswith(( - '-r', '--requirement', - '-Z', '--always-unzip', - '-f', '--find-links', - '-i', '--index-url', - '--extra-index-url'))): - f.write(line) - continue - - if 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, - isolated=options.isolated_mode, - ) - else: - line_req = InstallRequirement.from_line( - line, - isolated=options.isolated_mode, - ) - - if not line_req.name: - logger.info( - "Skipping line because it's not clear what it " - "would install: %s", - line.strip(), - ) - logger.info( - " (add #egg=PackageName to the URL to avoid" - " this warning)" - ) - elif line_req.name not in installations: - logger.warning( - "Requirement file contains %s, but that package is" - " not installed", - line.strip(), - ) - else: - f.write(str(installations[line_req.name])) - del installations[line_req.name] - - f.write( - '## The following requirements were added by ' - 'pip %(name)s:\n' % dict(name=self.name) - ) - for installation in sorted( - installations.values(), key=lambda x: x.name.lower()): - f.write(str(installation)) + freeze_kwargs = dict( + requirement=options.requirement, + find_links=options.find_links, + local_only=options.local, + user_only=options.user, + skip_regex=options.skip_requirements_regex, + isolated=options.isolated_mode) + + for line in freeze(**freeze_kwargs): + sys.stdout.write(line + '\n') diff --git a/pip/operations/__init__.py b/pip/operations/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/pip/operations/freeze.py b/pip/operations/freeze.py new file mode 100644 index 00000000000..7bea426f2c8 --- /dev/null +++ b/pip/operations/freeze.py @@ -0,0 +1,111 @@ +from __future__ import absolute_import + +import logging +import re + +import pip +from pip.compat import stdlib_pkgs +from pip.req import InstallRequirement +from pip.utils import get_installed_distributions +from pip._vendor import pkg_resources + + +logger = logging.getLogger(__name__) + +# packages to exclude from freeze output +freeze_excludes = stdlib_pkgs + ['setuptools', 'pip', 'distribute'] + + +def freeze( + requirement=None, + find_links=None, local_only=None, user_only=None, skip_regex=None, + find_tags=False, + default_vcs=None, + isolated=False): + find_links = find_links or [] + skip_match = None + + if skip_regex: + skip_match = re.compile(skip_regex) + + 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 link in find_links: + if '#egg=' in link: + dependency_links.append(link) + for link in find_links: + yield '-f %s' % link + installations = {} + for dist in get_installed_distributions(local_only=local_only, + skip=freeze_excludes, + user_only=user_only): + req = pip.FrozenRequirement.from_dist( + dist, + dependency_links, + find_tags=find_tags, + ) + installations[req.name] = req + + if requirement: + with open(requirement) as req_file: + for line in req_file: + if (not line.strip() + or line.strip().startswith('#') + or (skip_match and skip_match.search(line)) + or line.startswith(( + '-r', '--requirement', + '-Z', '--always-unzip', + '-f', '--find-links', + '-i', '--index-url', + '--extra-index-url'))): + yield line.rstrip() + continue + + if 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=default_vcs, + isolated=isolated, + ) + else: + line_req = InstallRequirement.from_line( + line, + isolated=isolated, + ) + + if not line_req.name: + logger.info( + "Skipping line because it's not clear what it " + "would install: %s", + line.strip(), + ) + logger.info( + " (add #egg=PackageName to the URL to avoid" + " this warning)" + ) + elif line_req.name not in installations: + logger.warning( + "Requirement file contains %s, but that package is" + " not installed", + line.strip(), + ) + else: + yield str(installations[line_req.name]).rstrip() + del installations[line_req.name] + + yield( + '## The following requirements were added by ' + 'pip freeze:' + ) + for installation in sorted( + installations.values(), key=lambda x: x.name.lower()): + yield str(installation).rstrip() diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 50cedfd2d47..af5200635d3 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -14,7 +14,7 @@ from pip.exceptions import BadCommand from pip.utils import (egg_link_path, Inf, get_installed_distributions, find_command, untar_file, unzip_file) -from pip.commands.freeze import freeze_excludes +from pip.operations.freeze import freeze_excludes class Tests_EgglinkPath: