Skip to content

Separate pip freeze command from operation #2173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 11 additions & 110 deletions pip/commands/freeze.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down Expand Up @@ -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')
Empty file added pip/operations/__init__.py
Empty file.
111 changes: 111 additions & 0 deletions pip/operations/freeze.py
Original file line number Diff line number Diff line change
@@ -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()
2 changes: 1 addition & 1 deletion tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down