Skip to content

Commit 7dd3422

Browse files
committed
Implement cache info command
1 parent 75b383a commit 7dd3422

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

pip/commands/cache.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
import logging
44
import os
5+
import textwrap
56

67
from pip.basecommand import Command
78
from pip.status_codes import SUCCESS, ERROR
9+
from pip.utils.filesystem import tree_statistics, human_size
810

911

1012
logger = logging.getLogger(__name__)
@@ -15,8 +17,9 @@ class CacheCommand(Command):
1517
Operate on pip's caches.
1618
1719
Subcommands:
18-
location: Print the location of the cache."""
19-
actions = ["location"]
20+
location: Print the location of the cache.
21+
info: Show statistics on the cache."""
22+
actions = ["location", "info"]
2023
name = "cache"
2124
usage = """
2225
%%prog [options] %s""" % "|".join(actions)
@@ -45,10 +48,32 @@ def run(self, options, args):
4548
method = getattr(self, "action_%s" % args[0])
4649
return method(options, args[1:])
4750

48-
def action_location(self, options, args):
49-
location = options.cache_dir
51+
def get_cache_location(self, cache_root, cache_type):
52+
location = cache_root
5053
suffix = {"wheel": "wheels", "http": "http"}
51-
if options.type != "all":
52-
location = os.path.join(location, suffix[options.type])
53-
logger.info(location)
54+
if cache_type != "all":
55+
location = os.path.join(location, suffix[cache_type])
56+
return location
57+
58+
def action_location(self, options, args):
59+
logger.info(self.get_cache_location(options.cache_dir, options.type))
60+
return SUCCESS
61+
62+
def action_info(self, options, args):
63+
caches = ["http", "wheel"] if options.type == "all" else [options.type]
64+
result = []
65+
for cache_type in caches:
66+
location = self.get_cache_location(options.cache_dir, cache_type)
67+
stats = tree_statistics(location)
68+
name = {"wheel": "Wheel cache", "http": "HTTP cache"}
69+
result.append(textwrap.dedent(
70+
"""\
71+
%s info:
72+
Location: %s
73+
Number of files: %s
74+
Size: %s""" %
75+
(name[cache_type], location, stats["files"],
76+
human_size(stats["size"]))
77+
))
78+
logger.info("\n\n".join(result))
5479
return SUCCESS

pip/utils/filesystem.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,31 @@ def check_path_owner(path):
2626
return os.access(path, os.W_OK)
2727
else:
2828
previous, path = path, os.path.dirname(path)
29+
30+
31+
def tree_statistics(path):
32+
"""Computes statistics on a filesystem tree.
33+
Returns a dictionary with keys:
34+
files: number of files
35+
size: total size in bytes
36+
"""
37+
result = {"files": 0, "size": 0}
38+
for root, dirs, files in os.walk(path):
39+
result["files"] += len(files)
40+
abs_paths = (os.path.join(root, f) for f in files)
41+
result["size"] += sum(os.path.getsize(f) for f in abs_paths)
42+
return result
43+
44+
45+
def human_size(n_bytes):
46+
units = ["B", "KiB", "MiB", "GiB", "TiB"]
47+
size = n_bytes
48+
for unit in units:
49+
if size <= 1024:
50+
if unit == "B":
51+
result = "%d %s" % (size, unit)
52+
else:
53+
result = "%.1f %s" % (size, unit)
54+
return result
55+
size /= 1024.
56+
return "%.1f %s" % (size, "PiB")

0 commit comments

Comments
 (0)