comparison planemo/lib/python3.7/site-packages/pip/_internal/commands/show.py @ 1:56ad4e20f292 draft

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