Mercurial > repos > guerler > hhblits
comparison lib/python3.8/site-packages/pip/_internal/commands/show.py @ 0:9e54283cc701 draft
"planemo upload commit d12c32a45bcd441307e632fca6d9af7d60289d44"
author | guerler |
---|---|
date | Mon, 27 Jul 2020 03:47:31 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:9e54283cc701 |
---|---|
1 # The following comment should be removed at some point in the future. | |
2 # mypy: disallow-untyped-defs=False | |
3 | |
4 from __future__ import absolute_import | |
5 | |
6 import logging | |
7 import os | |
8 from email.parser import FeedParser | |
9 | |
10 from pip._vendor import pkg_resources | |
11 from pip._vendor.packaging.utils import canonicalize_name | |
12 | |
13 from pip._internal.cli.base_command import Command | |
14 from pip._internal.cli.status_codes import ERROR, SUCCESS | |
15 from pip._internal.utils.misc import write_output | |
16 | |
17 logger = logging.getLogger(__name__) | |
18 | |
19 | |
20 class ShowCommand(Command): | |
21 """ | |
22 Show information about one or more installed packages. | |
23 | |
24 The output is in RFC-compliant mail header format. | |
25 """ | |
26 | |
27 usage = """ | |
28 %prog [options] <package> ...""" | |
29 ignore_require_venv = True | |
30 | |
31 def __init__(self, *args, **kw): | |
32 super(ShowCommand, self).__init__(*args, **kw) | |
33 self.cmd_opts.add_option( | |
34 '-f', '--files', | |
35 dest='files', | |
36 action='store_true', | |
37 default=False, | |
38 help='Show the full list of installed files for each package.') | |
39 | |
40 self.parser.insert_option_group(0, self.cmd_opts) | |
41 | |
42 def run(self, options, args): | |
43 if not args: | |
44 logger.warning('ERROR: Please provide a package name or names.') | |
45 return ERROR | |
46 query = args | |
47 | |
48 results = search_packages_info(query) | |
49 if not print_results( | |
50 results, list_files=options.files, verbose=options.verbose): | |
51 return ERROR | |
52 return SUCCESS | |
53 | |
54 | |
55 def search_packages_info(query): | |
56 """ | |
57 Gather details from installed distributions. Print distribution name, | |
58 version, location, and installed files. Installed files requires a | |
59 pip generated 'installed-files.txt' in the distributions '.egg-info' | |
60 directory. | |
61 """ | |
62 installed = {} | |
63 for p in pkg_resources.working_set: | |
64 installed[canonicalize_name(p.project_name)] = p | |
65 | |
66 query_names = [canonicalize_name(name) for name in query] | |
67 missing = sorted( | |
68 [name for name, pkg in zip(query, query_names) if pkg not in installed] | |
69 ) | |
70 if missing: | |
71 logger.warning('Package(s) not found: %s', ', '.join(missing)) | |
72 | |
73 def get_requiring_packages(package_name): | |
74 canonical_name = canonicalize_name(package_name) | |
75 return [ | |
76 pkg.project_name for pkg in pkg_resources.working_set | |
77 if canonical_name in | |
78 [canonicalize_name(required.name) for required in | |
79 pkg.requires()] | |
80 ] | |
81 | |
82 for dist in [installed[pkg] for pkg in query_names if pkg in installed]: | |
83 package = { | |
84 'name': dist.project_name, | |
85 'version': dist.version, | |
86 'location': dist.location, | |
87 'requires': [dep.project_name for dep in dist.requires()], | |
88 'required_by': get_requiring_packages(dist.project_name) | |
89 } | |
90 file_list = None | |
91 metadata = None | |
92 if isinstance(dist, pkg_resources.DistInfoDistribution): | |
93 # RECORDs should be part of .dist-info metadatas | |
94 if dist.has_metadata('RECORD'): | |
95 lines = dist.get_metadata_lines('RECORD') | |
96 paths = [l.split(',')[0] for l in lines] | |
97 paths = [os.path.join(dist.location, p) for p in paths] | |
98 file_list = [os.path.relpath(p, dist.location) for p in paths] | |
99 | |
100 if dist.has_metadata('METADATA'): | |
101 metadata = dist.get_metadata('METADATA') | |
102 else: | |
103 # Otherwise use pip's log for .egg-info's | |
104 if dist.has_metadata('installed-files.txt'): | |
105 paths = dist.get_metadata_lines('installed-files.txt') | |
106 paths = [os.path.join(dist.egg_info, p) for p in paths] | |
107 file_list = [os.path.relpath(p, dist.location) for p in paths] | |
108 | |
109 if dist.has_metadata('PKG-INFO'): | |
110 metadata = dist.get_metadata('PKG-INFO') | |
111 | |
112 if dist.has_metadata('entry_points.txt'): | |
113 entry_points = dist.get_metadata_lines('entry_points.txt') | |
114 package['entry_points'] = entry_points | |
115 | |
116 if dist.has_metadata('INSTALLER'): | |
117 for line in dist.get_metadata_lines('INSTALLER'): | |
118 if line.strip(): | |
119 package['installer'] = line.strip() | |
120 break | |
121 | |
122 # @todo: Should pkg_resources.Distribution have a | |
123 # `get_pkg_info` method? | |
124 feed_parser = FeedParser() | |
125 feed_parser.feed(metadata) | |
126 pkg_info_dict = feed_parser.close() | |
127 for key in ('metadata-version', 'summary', | |
128 'home-page', 'author', 'author-email', 'license'): | |
129 package[key] = pkg_info_dict.get(key) | |
130 | |
131 # It looks like FeedParser cannot deal with repeated headers | |
132 classifiers = [] | |
133 for line in metadata.splitlines(): | |
134 if line.startswith('Classifier: '): | |
135 classifiers.append(line[len('Classifier: '):]) | |
136 package['classifiers'] = classifiers | |
137 | |
138 if file_list: | |
139 package['files'] = sorted(file_list) | |
140 yield package | |
141 | |
142 | |
143 def print_results(distributions, list_files=False, verbose=False): | |
144 """ | |
145 Print the informations from installed distributions found. | |
146 """ | |
147 results_printed = False | |
148 for i, dist in enumerate(distributions): | |
149 results_printed = True | |
150 if i > 0: | |
151 write_output("---") | |
152 | |
153 write_output("Name: %s", dist.get('name', '')) | |
154 write_output("Version: %s", dist.get('version', '')) | |
155 write_output("Summary: %s", dist.get('summary', '')) | |
156 write_output("Home-page: %s", dist.get('home-page', '')) | |
157 write_output("Author: %s", dist.get('author', '')) | |
158 write_output("Author-email: %s", dist.get('author-email', '')) | |
159 write_output("License: %s", dist.get('license', '')) | |
160 write_output("Location: %s", dist.get('location', '')) | |
161 write_output("Requires: %s", ', '.join(dist.get('requires', []))) | |
162 write_output("Required-by: %s", ', '.join(dist.get('required_by', []))) | |
163 | |
164 if verbose: | |
165 write_output("Metadata-Version: %s", | |
166 dist.get('metadata-version', '')) | |
167 write_output("Installer: %s", dist.get('installer', '')) | |
168 write_output("Classifiers:") | |
169 for classifier in dist.get('classifiers', []): | |
170 write_output(" %s", classifier) | |
171 write_output("Entry-points:") | |
172 for entry in dist.get('entry_points', []): | |
173 write_output(" %s", entry.strip()) | |
174 if list_files: | |
175 write_output("Files:") | |
176 for line in dist.get('files', []): | |
177 write_output(" %s", line.strip()) | |
178 if "files" not in dist: | |
179 write_output("Cannot locate installed-files.txt") | |
180 return results_printed |