Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/pip/_internal/commands/cache.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4f3585e2f14b |
---|---|
1 import logging | |
2 import os | |
3 import textwrap | |
4 | |
5 import pip._internal.utils.filesystem as filesystem | |
6 from pip._internal.cli.base_command import Command | |
7 from pip._internal.cli.status_codes import ERROR, SUCCESS | |
8 from pip._internal.exceptions import CommandError, PipError | |
9 from pip._internal.utils.typing import MYPY_CHECK_RUNNING | |
10 | |
11 if MYPY_CHECK_RUNNING: | |
12 from optparse import Values | |
13 from typing import Any, List | |
14 | |
15 | |
16 logger = logging.getLogger(__name__) | |
17 | |
18 | |
19 class CacheCommand(Command): | |
20 """ | |
21 Inspect and manage pip's wheel cache. | |
22 | |
23 Subcommands: | |
24 | |
25 - dir: Show the cache directory. | |
26 - info: Show information about the cache. | |
27 - list: List filenames of packages stored in the cache. | |
28 - remove: Remove one or more package from the cache. | |
29 - purge: Remove all items from the cache. | |
30 | |
31 ``<pattern>`` can be a glob expression or a package name. | |
32 """ | |
33 | |
34 ignore_require_venv = True | |
35 usage = """ | |
36 %prog dir | |
37 %prog info | |
38 %prog list [<pattern>] [--format=[human, abspath]] | |
39 %prog remove <pattern> | |
40 %prog purge | |
41 """ | |
42 | |
43 def add_options(self): | |
44 # type: () -> None | |
45 | |
46 self.cmd_opts.add_option( | |
47 '--format', | |
48 action='store', | |
49 dest='list_format', | |
50 default="human", | |
51 choices=('human', 'abspath'), | |
52 help="Select the output format among: human (default) or abspath" | |
53 ) | |
54 | |
55 self.parser.insert_option_group(0, self.cmd_opts) | |
56 | |
57 def run(self, options, args): | |
58 # type: (Values, List[Any]) -> int | |
59 handlers = { | |
60 "dir": self.get_cache_dir, | |
61 "info": self.get_cache_info, | |
62 "list": self.list_cache_items, | |
63 "remove": self.remove_cache_items, | |
64 "purge": self.purge_cache, | |
65 } | |
66 | |
67 if not options.cache_dir: | |
68 logger.error("pip cache commands can not " | |
69 "function since cache is disabled.") | |
70 return ERROR | |
71 | |
72 # Determine action | |
73 if not args or args[0] not in handlers: | |
74 logger.error( | |
75 "Need an action (%s) to perform.", | |
76 ", ".join(sorted(handlers)), | |
77 ) | |
78 return ERROR | |
79 | |
80 action = args[0] | |
81 | |
82 # Error handling happens here, not in the action-handlers. | |
83 try: | |
84 handlers[action](options, args[1:]) | |
85 except PipError as e: | |
86 logger.error(e.args[0]) | |
87 return ERROR | |
88 | |
89 return SUCCESS | |
90 | |
91 def get_cache_dir(self, options, args): | |
92 # type: (Values, List[Any]) -> None | |
93 if args: | |
94 raise CommandError('Too many arguments') | |
95 | |
96 logger.info(options.cache_dir) | |
97 | |
98 def get_cache_info(self, options, args): | |
99 # type: (Values, List[Any]) -> None | |
100 if args: | |
101 raise CommandError('Too many arguments') | |
102 | |
103 num_http_files = len(self._find_http_files(options)) | |
104 num_packages = len(self._find_wheels(options, '*')) | |
105 | |
106 http_cache_location = self._cache_dir(options, 'http') | |
107 wheels_cache_location = self._cache_dir(options, 'wheels') | |
108 http_cache_size = filesystem.format_directory_size(http_cache_location) | |
109 wheels_cache_size = filesystem.format_directory_size( | |
110 wheels_cache_location | |
111 ) | |
112 | |
113 message = textwrap.dedent(""" | |
114 Package index page cache location: {http_cache_location} | |
115 Package index page cache size: {http_cache_size} | |
116 Number of HTTP files: {num_http_files} | |
117 Wheels location: {wheels_cache_location} | |
118 Wheels size: {wheels_cache_size} | |
119 Number of wheels: {package_count} | |
120 """).format( | |
121 http_cache_location=http_cache_location, | |
122 http_cache_size=http_cache_size, | |
123 num_http_files=num_http_files, | |
124 wheels_cache_location=wheels_cache_location, | |
125 package_count=num_packages, | |
126 wheels_cache_size=wheels_cache_size, | |
127 ).strip() | |
128 | |
129 logger.info(message) | |
130 | |
131 def list_cache_items(self, options, args): | |
132 # type: (Values, List[Any]) -> None | |
133 if len(args) > 1: | |
134 raise CommandError('Too many arguments') | |
135 | |
136 if args: | |
137 pattern = args[0] | |
138 else: | |
139 pattern = '*' | |
140 | |
141 files = self._find_wheels(options, pattern) | |
142 if options.list_format == 'human': | |
143 self.format_for_human(files) | |
144 else: | |
145 self.format_for_abspath(files) | |
146 | |
147 def format_for_human(self, files): | |
148 # type: (List[str]) -> None | |
149 if not files: | |
150 logger.info('Nothing cached.') | |
151 return | |
152 | |
153 results = [] | |
154 for filename in files: | |
155 wheel = os.path.basename(filename) | |
156 size = filesystem.format_file_size(filename) | |
157 results.append(f' - {wheel} ({size})') | |
158 logger.info('Cache contents:\n') | |
159 logger.info('\n'.join(sorted(results))) | |
160 | |
161 def format_for_abspath(self, files): | |
162 # type: (List[str]) -> None | |
163 if not files: | |
164 return | |
165 | |
166 results = [] | |
167 for filename in files: | |
168 results.append(filename) | |
169 | |
170 logger.info('\n'.join(sorted(results))) | |
171 | |
172 def remove_cache_items(self, options, args): | |
173 # type: (Values, List[Any]) -> None | |
174 if len(args) > 1: | |
175 raise CommandError('Too many arguments') | |
176 | |
177 if not args: | |
178 raise CommandError('Please provide a pattern') | |
179 | |
180 files = self._find_wheels(options, args[0]) | |
181 | |
182 # Only fetch http files if no specific pattern given | |
183 if args[0] == '*': | |
184 files += self._find_http_files(options) | |
185 | |
186 if not files: | |
187 raise CommandError('No matching packages') | |
188 | |
189 for filename in files: | |
190 os.unlink(filename) | |
191 logger.debug('Removed %s', filename) | |
192 logger.info('Files removed: %s', len(files)) | |
193 | |
194 def purge_cache(self, options, args): | |
195 # type: (Values, List[Any]) -> None | |
196 if args: | |
197 raise CommandError('Too many arguments') | |
198 | |
199 return self.remove_cache_items(options, ['*']) | |
200 | |
201 def _cache_dir(self, options, subdir): | |
202 # type: (Values, str) -> str | |
203 return os.path.join(options.cache_dir, subdir) | |
204 | |
205 def _find_http_files(self, options): | |
206 # type: (Values) -> List[str] | |
207 http_dir = self._cache_dir(options, 'http') | |
208 return filesystem.find_files(http_dir, '*') | |
209 | |
210 def _find_wheels(self, options, pattern): | |
211 # type: (Values, str) -> List[str] | |
212 wheel_dir = self._cache_dir(options, 'wheels') | |
213 | |
214 # The wheel filename format, as specified in PEP 427, is: | |
215 # {distribution}-{version}(-{build})?-{python}-{abi}-{platform}.whl | |
216 # | |
217 # Additionally, non-alphanumeric values in the distribution are | |
218 # normalized to underscores (_), meaning hyphens can never occur | |
219 # before `-{version}`. | |
220 # | |
221 # Given that information: | |
222 # - If the pattern we're given contains a hyphen (-), the user is | |
223 # providing at least the version. Thus, we can just append `*.whl` | |
224 # to match the rest of it. | |
225 # - If the pattern we're given doesn't contain a hyphen (-), the | |
226 # user is only providing the name. Thus, we append `-*.whl` to | |
227 # match the hyphen before the version, followed by anything else. | |
228 # | |
229 # PEP 427: https://www.python.org/dev/peps/pep-0427/ | |
230 pattern = pattern + ("*.whl" if "-" in pattern else "-*.whl") | |
231 | |
232 return filesystem.find_files(wheel_dir, pattern) |