Skip to content

Commit d60c1f4

Browse files
committed
Merge pull request #2173 from msabramo/extract_freeze_operation
Separate pip freeze command from operation
2 parents 268a497 + 0711744 commit d60c1f4

File tree

4 files changed

+123
-111
lines changed

4 files changed

+123
-111
lines changed

pip/commands/freeze.py

+11-110
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,9 @@
11
from __future__ import absolute_import
22

3-
import logging
4-
import re
53
import sys
64

7-
8-
import pip
9-
10-
from pip.compat import stdlib_pkgs
11-
from pip.req import InstallRequirement
125
from pip.basecommand import Command
13-
from pip.utils import get_installed_distributions
14-
from pip._vendor import pkg_resources
15-
16-
# packages to exclude from freeze output
17-
freeze_excludes = stdlib_pkgs + ['setuptools', 'pip', 'distribute']
18-
19-
20-
logger = logging.getLogger(__name__)
6+
from pip.operations.freeze import freeze
217

228

239
class FreezeCommand(Command):
@@ -68,98 +54,13 @@ def __init__(self, *args, **kw):
6854
self.parser.insert_option_group(0, self.cmd_opts)
6955

7056
def run(self, options, args):
71-
requirement = options.requirement
72-
find_links = options.find_links or []
73-
local_only = options.local
74-
user_only = options.user
75-
# FIXME: Obviously this should be settable:
76-
find_tags = False
77-
skip_match = None
78-
79-
skip_regex = options.skip_requirements_regex
80-
if skip_regex:
81-
skip_match = re.compile(skip_regex)
82-
83-
dependency_links = []
84-
85-
f = sys.stdout
86-
87-
for dist in pkg_resources.working_set:
88-
if dist.has_metadata('dependency_links.txt'):
89-
dependency_links.extend(
90-
dist.get_metadata_lines('dependency_links.txt')
91-
)
92-
for link in find_links:
93-
if '#egg=' in link:
94-
dependency_links.append(link)
95-
for link in find_links:
96-
f.write('-f %s\n' % link)
97-
installations = {}
98-
for dist in get_installed_distributions(local_only=local_only,
99-
skip=freeze_excludes,
100-
user_only=user_only):
101-
req = pip.FrozenRequirement.from_dist(
102-
dist,
103-
dependency_links,
104-
find_tags=find_tags,
105-
)
106-
installations[req.name] = req
107-
108-
if requirement:
109-
with open(requirement) as req_file:
110-
for line in req_file:
111-
if (not line.strip()
112-
or line.strip().startswith('#')
113-
or (skip_match and skip_match.search(line))
114-
or line.startswith((
115-
'-r', '--requirement',
116-
'-Z', '--always-unzip',
117-
'-f', '--find-links',
118-
'-i', '--index-url',
119-
'--extra-index-url'))):
120-
f.write(line)
121-
continue
122-
123-
if line.startswith('-e') or line.startswith('--editable'):
124-
if line.startswith('-e'):
125-
line = line[2:].strip()
126-
else:
127-
line = line[len('--editable'):].strip().lstrip('=')
128-
line_req = InstallRequirement.from_editable(
129-
line,
130-
default_vcs=options.default_vcs,
131-
isolated=options.isolated_mode,
132-
)
133-
else:
134-
line_req = InstallRequirement.from_line(
135-
line,
136-
isolated=options.isolated_mode,
137-
)
138-
139-
if not line_req.name:
140-
logger.info(
141-
"Skipping line because it's not clear what it "
142-
"would install: %s",
143-
line.strip(),
144-
)
145-
logger.info(
146-
" (add #egg=PackageName to the URL to avoid"
147-
" this warning)"
148-
)
149-
elif line_req.name not in installations:
150-
logger.warning(
151-
"Requirement file contains %s, but that package is"
152-
" not installed",
153-
line.strip(),
154-
)
155-
else:
156-
f.write(str(installations[line_req.name]))
157-
del installations[line_req.name]
158-
159-
f.write(
160-
'## The following requirements were added by '
161-
'pip %(name)s:\n' % dict(name=self.name)
162-
)
163-
for installation in sorted(
164-
installations.values(), key=lambda x: x.name.lower()):
165-
f.write(str(installation))
57+
freeze_kwargs = dict(
58+
requirement=options.requirement,
59+
find_links=options.find_links,
60+
local_only=options.local,
61+
user_only=options.user,
62+
skip_regex=options.skip_requirements_regex,
63+
isolated=options.isolated_mode)
64+
65+
for line in freeze(**freeze_kwargs):
66+
sys.stdout.write(line + '\n')

pip/operations/__init__.py

Whitespace-only changes.

pip/operations/freeze.py

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
from __future__ import absolute_import
2+
3+
import logging
4+
import re
5+
6+
import pip
7+
from pip.compat import stdlib_pkgs
8+
from pip.req import InstallRequirement
9+
from pip.utils import get_installed_distributions
10+
from pip._vendor import pkg_resources
11+
12+
13+
logger = logging.getLogger(__name__)
14+
15+
# packages to exclude from freeze output
16+
freeze_excludes = stdlib_pkgs + ['setuptools', 'pip', 'distribute']
17+
18+
19+
def freeze(
20+
requirement=None,
21+
find_links=None, local_only=None, user_only=None, skip_regex=None,
22+
find_tags=False,
23+
default_vcs=None,
24+
isolated=False):
25+
find_links = find_links or []
26+
skip_match = None
27+
28+
if skip_regex:
29+
skip_match = re.compile(skip_regex)
30+
31+
dependency_links = []
32+
33+
for dist in pkg_resources.working_set:
34+
if dist.has_metadata('dependency_links.txt'):
35+
dependency_links.extend(
36+
dist.get_metadata_lines('dependency_links.txt')
37+
)
38+
for link in find_links:
39+
if '#egg=' in link:
40+
dependency_links.append(link)
41+
for link in find_links:
42+
yield '-f %s' % link
43+
installations = {}
44+
for dist in get_installed_distributions(local_only=local_only,
45+
skip=freeze_excludes,
46+
user_only=user_only):
47+
req = pip.FrozenRequirement.from_dist(
48+
dist,
49+
dependency_links,
50+
find_tags=find_tags,
51+
)
52+
installations[req.name] = req
53+
54+
if requirement:
55+
with open(requirement) as req_file:
56+
for line in req_file:
57+
if (not line.strip()
58+
or line.strip().startswith('#')
59+
or (skip_match and skip_match.search(line))
60+
or line.startswith((
61+
'-r', '--requirement',
62+
'-Z', '--always-unzip',
63+
'-f', '--find-links',
64+
'-i', '--index-url',
65+
'--extra-index-url'))):
66+
yield line.rstrip()
67+
continue
68+
69+
if line.startswith('-e') or line.startswith('--editable'):
70+
if line.startswith('-e'):
71+
line = line[2:].strip()
72+
else:
73+
line = line[len('--editable'):].strip().lstrip('=')
74+
line_req = InstallRequirement.from_editable(
75+
line,
76+
default_vcs=default_vcs,
77+
isolated=isolated,
78+
)
79+
else:
80+
line_req = InstallRequirement.from_line(
81+
line,
82+
isolated=isolated,
83+
)
84+
85+
if not line_req.name:
86+
logger.info(
87+
"Skipping line because it's not clear what it "
88+
"would install: %s",
89+
line.strip(),
90+
)
91+
logger.info(
92+
" (add #egg=PackageName to the URL to avoid"
93+
" this warning)"
94+
)
95+
elif line_req.name not in installations:
96+
logger.warning(
97+
"Requirement file contains %s, but that package is"
98+
" not installed",
99+
line.strip(),
100+
)
101+
else:
102+
yield str(installations[line_req.name]).rstrip()
103+
del installations[line_req.name]
104+
105+
yield(
106+
'## The following requirements were added by '
107+
'pip freeze:'
108+
)
109+
for installation in sorted(
110+
installations.values(), key=lambda x: x.name.lower()):
111+
yield str(installation).rstrip()

tests/unit/test_utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from pip.exceptions import BadCommand
1515
from pip.utils import (egg_link_path, Inf, get_installed_distributions,
1616
find_command, untar_file, unzip_file)
17-
from pip.commands.freeze import freeze_excludes
17+
from pip.operations.freeze import freeze_excludes
1818

1919

2020
class Tests_EgglinkPath:

0 commit comments

Comments
 (0)