Skip to content

Commit 8aab76c

Browse files
authored
Merge pull request #8910 from hugovk/pip-cache-http
Include http subdirectory in 'pip cache info' and 'pip cache purge'
2 parents d0f80a4 + 0652a2f commit 8aab76c

File tree

3 files changed

+115
-20
lines changed

3 files changed

+115
-20
lines changed

news/8892.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Include http subdirectory in ``pip cache info`` and ``pip cache purge`` commands.

src/pip/_internal/commands/cache.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,19 +102,30 @@ def get_cache_info(self, options, args):
102102
if args:
103103
raise CommandError('Too many arguments')
104104

105+
num_http_files = len(self._find_http_files(options))
105106
num_packages = len(self._find_wheels(options, '*'))
106107

107-
cache_location = self._wheels_cache_dir(options)
108-
cache_size = filesystem.format_directory_size(cache_location)
108+
http_cache_location = self._cache_dir(options, 'http')
109+
wheels_cache_location = self._cache_dir(options, 'wheels')
110+
http_cache_size = filesystem.format_directory_size(http_cache_location)
111+
wheels_cache_size = filesystem.format_directory_size(
112+
wheels_cache_location
113+
)
109114

110115
message = textwrap.dedent("""
111-
Location: {location}
112-
Size: {size}
116+
Package index page cache location: {http_cache_location}
117+
Package index page cache size: {http_cache_size}
118+
Number of HTTP files: {num_http_files}
119+
Wheels location: {wheels_cache_location}
120+
Wheels size: {wheels_cache_size}
113121
Number of wheels: {package_count}
114122
""").format(
115-
location=cache_location,
123+
http_cache_location=http_cache_location,
124+
http_cache_size=http_cache_size,
125+
num_http_files=num_http_files,
126+
wheels_cache_location=wheels_cache_location,
116127
package_count=num_packages,
117-
size=cache_size,
128+
wheels_cache_size=wheels_cache_size,
118129
).strip()
119130

120131
logger.info(message)
@@ -169,6 +180,11 @@ def remove_cache_items(self, options, args):
169180
raise CommandError('Please provide a pattern')
170181

171182
files = self._find_wheels(options, args[0])
183+
184+
# Only fetch http files if no specific pattern given
185+
if args[0] == '*':
186+
files += self._find_http_files(options)
187+
172188
if not files:
173189
raise CommandError('No matching packages')
174190

@@ -184,13 +200,18 @@ def purge_cache(self, options, args):
184200

185201
return self.remove_cache_items(options, ['*'])
186202

187-
def _wheels_cache_dir(self, options):
188-
# type: (Values) -> str
189-
return os.path.join(options.cache_dir, 'wheels')
203+
def _cache_dir(self, options, subdir):
204+
# type: (Values, str) -> str
205+
return os.path.join(options.cache_dir, subdir)
206+
207+
def _find_http_files(self, options):
208+
# type: (Values) -> List[str]
209+
http_dir = self._cache_dir(options, 'http')
210+
return filesystem.find_files(http_dir, '*')
190211

191212
def _find_wheels(self, options, pattern):
192213
# type: (Values, str) -> List[str]
193-
wheel_dir = self._wheels_cache_dir(options)
214+
wheel_dir = self._cache_dir(options, 'wheels')
194215

195216
# The wheel filename format, as specified in PEP 427, is:
196217
# {distribution}-{version}(-{build})?-{python}-{abi}-{platform}.whl

tests/functional/test_cache.py

Lines changed: 83 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,30 @@ def cache_dir(script):
1515
return result.stdout.strip()
1616

1717

18+
@pytest.fixture
19+
def http_cache_dir(cache_dir):
20+
return os.path.normcase(os.path.join(cache_dir, 'http'))
21+
22+
1823
@pytest.fixture
1924
def wheel_cache_dir(cache_dir):
2025
return os.path.normcase(os.path.join(cache_dir, 'wheels'))
2126

2227

28+
@pytest.fixture
29+
def http_cache_files(http_cache_dir):
30+
destination = os.path.join(http_cache_dir, 'arbitrary', 'pathname')
31+
32+
if not os.path.exists(destination):
33+
return []
34+
35+
filenames = glob(os.path.join(destination, '*'))
36+
files = []
37+
for filename in filenames:
38+
files.append(os.path.join(destination, filename))
39+
return files
40+
41+
2342
@pytest.fixture
2443
def wheel_cache_files(wheel_cache_dir):
2544
destination = os.path.join(wheel_cache_dir, 'arbitrary', 'pathname')
@@ -34,6 +53,24 @@ def wheel_cache_files(wheel_cache_dir):
3453
return files
3554

3655

56+
@pytest.fixture
57+
def populate_http_cache(http_cache_dir):
58+
destination = os.path.join(http_cache_dir, 'arbitrary', 'pathname')
59+
os.makedirs(destination)
60+
61+
files = [
62+
('aaaaaaaaa', os.path.join(destination, 'aaaaaaaaa')),
63+
('bbbbbbbbb', os.path.join(destination, 'bbbbbbbbb')),
64+
('ccccccccc', os.path.join(destination, 'ccccccccc')),
65+
]
66+
67+
for _name, filename in files:
68+
with open(filename, 'w'):
69+
pass
70+
71+
return files
72+
73+
3774
@pytest.fixture
3875
def populate_wheel_cache(wheel_cache_dir):
3976
destination = os.path.join(wheel_cache_dir, 'arbitrary', 'pathname')
@@ -83,6 +120,29 @@ def list_matches_wheel_abspath(wheel_name, result):
83120
and os.path.exists(l), lines))
84121

85122

123+
@pytest.fixture
124+
def remove_matches_http(http_cache_dir):
125+
"""Returns True if any line in `result`, which should be the output of
126+
a `pip cache purge` call, matches `http_filename`.
127+
128+
E.g., If http_filename is `aaaaaaaaa`, it searches for a line equal to
129+
`Removed <http files cache dir>/arbitrary/pathname/aaaaaaaaa`.
130+
"""
131+
132+
def _remove_matches_http(http_filename, result):
133+
lines = result.stdout.splitlines()
134+
135+
# The "/arbitrary/pathname/" bit is an implementation detail of how
136+
# the `populate_http_cache` fixture is implemented.
137+
path = os.path.join(
138+
http_cache_dir, 'arbitrary', 'pathname', http_filename,
139+
)
140+
expected = 'Removed {}'.format(path)
141+
return expected in lines
142+
143+
return _remove_matches_http
144+
145+
86146
@pytest.fixture
87147
def remove_matches_wheel(wheel_cache_dir):
88148
"""Returns True if any line in `result`, which should be the output of
@@ -124,11 +184,17 @@ def test_cache_dir_too_many_args(script, cache_dir):
124184
assert 'ERROR: Too many arguments' in result.stderr.splitlines()
125185

126186

127-
@pytest.mark.usefixtures("populate_wheel_cache")
128-
def test_cache_info(script, wheel_cache_dir, wheel_cache_files):
187+
@pytest.mark.usefixtures("populate_http_cache", "populate_wheel_cache")
188+
def test_cache_info(
189+
script, http_cache_dir, wheel_cache_dir, wheel_cache_files
190+
):
129191
result = script.pip('cache', 'info')
130192

131-
assert 'Location: {}'.format(wheel_cache_dir) in result.stdout
193+
assert (
194+
'Package index page cache location: {}'.format(http_cache_dir)
195+
in result.stdout
196+
)
197+
assert 'Wheels location: {}'.format(wheel_cache_dir) in result.stdout
132198
num_wheels = len(wheel_cache_files)
133199
assert 'Number of wheels: {}'.format(num_wheels) in result.stdout
134200

@@ -265,21 +331,28 @@ def test_cache_remove_name_and_version_match(script, remove_matches_wheel):
265331
assert not remove_matches_wheel('zzz-7.8.9', result)
266332

267333

268-
@pytest.mark.usefixtures("populate_wheel_cache")
269-
def test_cache_purge(script, remove_matches_wheel):
270-
"""Running `pip cache purge` should remove all cached wheels."""
334+
@pytest.mark.usefixtures("populate_http_cache", "populate_wheel_cache")
335+
def test_cache_purge(script, remove_matches_http, remove_matches_wheel):
336+
"""Running `pip cache purge` should remove all cached http files and
337+
wheels."""
271338
result = script.pip('cache', 'purge', '--verbose')
272339

340+
assert remove_matches_http('aaaaaaaaa', result)
341+
assert remove_matches_http('bbbbbbbbb', result)
342+
assert remove_matches_http('ccccccccc', result)
343+
273344
assert remove_matches_wheel('yyy-1.2.3', result)
274345
assert remove_matches_wheel('zzz-4.5.6', result)
275346
assert remove_matches_wheel('zzz-4.5.7', result)
276347
assert remove_matches_wheel('zzz-7.8.9', result)
277348

278349

279-
@pytest.mark.usefixtures("populate_wheel_cache")
280-
def test_cache_purge_too_many_args(script, wheel_cache_files):
350+
@pytest.mark.usefixtures("populate_http_cache", "populate_wheel_cache")
351+
def test_cache_purge_too_many_args(
352+
script, http_cache_files, wheel_cache_files
353+
):
281354
"""Running `pip cache purge aaa` should raise an error and remove no
282-
cached wheels."""
355+
cached http files or wheels."""
283356
result = script.pip('cache', 'purge', 'aaa', '--verbose',
284357
expect_error=True)
285358
assert result.stdout == ''
@@ -289,7 +362,7 @@ def test_cache_purge_too_many_args(script, wheel_cache_files):
289362
assert 'ERROR: Too many arguments' in result.stderr.splitlines()
290363

291364
# Make sure nothing was deleted.
292-
for filename in wheel_cache_files:
365+
for filename in http_cache_files + wheel_cache_files:
293366
assert os.path.exists(filename)
294367

295368

0 commit comments

Comments
 (0)