Mercurial > repos > bcclaywell > argo_navis
comparison venv/lib/python2.7/site-packages/pip/basecommand.py @ 0:d67268158946 draft
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
author | bcclaywell |
---|---|
date | Mon, 12 Oct 2015 17:43:33 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d67268158946 |
---|---|
1 """Base Command class, and related routines""" | |
2 from __future__ import absolute_import | |
3 | |
4 import logging | |
5 import os | |
6 import sys | |
7 import traceback | |
8 import optparse | |
9 import warnings | |
10 | |
11 from pip._vendor.six import StringIO | |
12 | |
13 from pip import cmdoptions | |
14 from pip.locations import running_under_virtualenv | |
15 from pip.download import PipSession | |
16 from pip.exceptions import (BadCommand, InstallationError, UninstallationError, | |
17 CommandError, PreviousBuildDirError) | |
18 from pip.compat import logging_dictConfig | |
19 from pip.baseparser import ConfigOptionParser, UpdatingDefaultsHelpFormatter | |
20 from pip.status_codes import ( | |
21 SUCCESS, ERROR, UNKNOWN_ERROR, VIRTUALENV_NOT_FOUND, | |
22 PREVIOUS_BUILD_DIR_ERROR, | |
23 ) | |
24 from pip.utils import appdirs, get_prog, normalize_path | |
25 from pip.utils.deprecation import RemovedInPip8Warning | |
26 from pip.utils.filesystem import check_path_owner | |
27 from pip.utils.logging import IndentingFormatter | |
28 from pip.utils.outdated import pip_version_check | |
29 | |
30 | |
31 __all__ = ['Command'] | |
32 | |
33 | |
34 logger = logging.getLogger(__name__) | |
35 | |
36 | |
37 class Command(object): | |
38 name = None | |
39 usage = None | |
40 hidden = False | |
41 log_streams = ("ext://sys.stdout", "ext://sys.stderr") | |
42 | |
43 def __init__(self, isolated=False): | |
44 parser_kw = { | |
45 'usage': self.usage, | |
46 'prog': '%s %s' % (get_prog(), self.name), | |
47 'formatter': UpdatingDefaultsHelpFormatter(), | |
48 'add_help_option': False, | |
49 'name': self.name, | |
50 'description': self.__doc__, | |
51 'isolated': isolated, | |
52 } | |
53 | |
54 self.parser = ConfigOptionParser(**parser_kw) | |
55 | |
56 # Commands should add options to this option group | |
57 optgroup_name = '%s Options' % self.name.capitalize() | |
58 self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) | |
59 | |
60 # Add the general options | |
61 gen_opts = cmdoptions.make_option_group( | |
62 cmdoptions.general_group, | |
63 self.parser, | |
64 ) | |
65 self.parser.add_option_group(gen_opts) | |
66 | |
67 def _build_session(self, options, retries=None, timeout=None): | |
68 session = PipSession( | |
69 cache=( | |
70 normalize_path(os.path.join(options.cache_dir, "http")) | |
71 if options.cache_dir else None | |
72 ), | |
73 retries=retries if retries is not None else options.retries, | |
74 insecure_hosts=options.trusted_hosts, | |
75 ) | |
76 | |
77 # Handle custom ca-bundles from the user | |
78 if options.cert: | |
79 session.verify = options.cert | |
80 | |
81 # Handle SSL client certificate | |
82 if options.client_cert: | |
83 session.cert = options.client_cert | |
84 | |
85 # Handle timeouts | |
86 if options.timeout or timeout: | |
87 session.timeout = ( | |
88 timeout if timeout is not None else options.timeout | |
89 ) | |
90 | |
91 # Handle configured proxies | |
92 if options.proxy: | |
93 session.proxies = { | |
94 "http": options.proxy, | |
95 "https": options.proxy, | |
96 } | |
97 | |
98 # Determine if we can prompt the user for authentication or not | |
99 session.auth.prompting = not options.no_input | |
100 | |
101 return session | |
102 | |
103 def parse_args(self, args): | |
104 # factored out for testability | |
105 return self.parser.parse_args(args) | |
106 | |
107 def main(self, args): | |
108 options, args = self.parse_args(args) | |
109 | |
110 if options.quiet: | |
111 level = "WARNING" | |
112 elif options.verbose: | |
113 level = "DEBUG" | |
114 else: | |
115 level = "INFO" | |
116 | |
117 # Compute the path for our debug log. | |
118 debug_log_path = os.path.join(appdirs.user_log_dir("pip"), "debug.log") | |
119 | |
120 # Ensure that the path for our debug log is owned by the current user | |
121 # and if it is not, disable the debug log. | |
122 write_debug_log = check_path_owner(debug_log_path) | |
123 | |
124 logging_dictConfig({ | |
125 "version": 1, | |
126 "disable_existing_loggers": False, | |
127 "filters": { | |
128 "exclude_warnings": { | |
129 "()": "pip.utils.logging.MaxLevelFilter", | |
130 "level": logging.WARNING, | |
131 }, | |
132 }, | |
133 "formatters": { | |
134 "indent": { | |
135 "()": IndentingFormatter, | |
136 "format": ( | |
137 "%(message)s" | |
138 if not options.log_explicit_levels | |
139 else "[%(levelname)s] %(message)s" | |
140 ), | |
141 }, | |
142 }, | |
143 "handlers": { | |
144 "console": { | |
145 "level": level, | |
146 "class": "pip.utils.logging.ColorizedStreamHandler", | |
147 "stream": self.log_streams[0], | |
148 "filters": ["exclude_warnings"], | |
149 "formatter": "indent", | |
150 }, | |
151 "console_errors": { | |
152 "level": "WARNING", | |
153 "class": "pip.utils.logging.ColorizedStreamHandler", | |
154 "stream": self.log_streams[1], | |
155 "formatter": "indent", | |
156 }, | |
157 "debug_log": { | |
158 "level": "DEBUG", | |
159 "class": "pip.utils.logging.BetterRotatingFileHandler", | |
160 "filename": debug_log_path, | |
161 "maxBytes": 10 * 1000 * 1000, # 10 MB | |
162 "backupCount": 1, | |
163 "delay": True, | |
164 "formatter": "indent", | |
165 }, | |
166 "user_log": { | |
167 "level": "DEBUG", | |
168 "class": "pip.utils.logging.BetterRotatingFileHandler", | |
169 "filename": options.log or "/dev/null", | |
170 "delay": True, | |
171 "formatter": "indent", | |
172 }, | |
173 }, | |
174 "root": { | |
175 "level": level, | |
176 "handlers": list(filter(None, [ | |
177 "console", | |
178 "console_errors", | |
179 "debug_log" if write_debug_log else None, | |
180 "user_log" if options.log else None, | |
181 ])), | |
182 }, | |
183 # Disable any logging besides WARNING unless we have DEBUG level | |
184 # logging enabled. These use both pip._vendor and the bare names | |
185 # for the case where someone unbundles our libraries. | |
186 "loggers": dict( | |
187 ( | |
188 name, | |
189 { | |
190 "level": ( | |
191 "WARNING" | |
192 if level in ["INFO", "ERROR"] | |
193 else "DEBUG" | |
194 ), | |
195 }, | |
196 ) | |
197 for name in ["pip._vendor", "distlib", "requests", "urllib3"] | |
198 ), | |
199 }) | |
200 | |
201 # We add this warning here instead of up above, because the logger | |
202 # hasn't been configured until just now. | |
203 if not write_debug_log: | |
204 logger.warning( | |
205 "The directory '%s' or its parent directory is not owned by " | |
206 "the current user and the debug log has been disabled. Please " | |
207 "check the permissions and owner of that directory. If " | |
208 "executing pip with sudo, you may want sudo's -H flag.", | |
209 os.path.dirname(debug_log_path), | |
210 ) | |
211 | |
212 if options.log_explicit_levels: | |
213 warnings.warn( | |
214 "--log-explicit-levels has been deprecated and will be removed" | |
215 " in a future version.", | |
216 RemovedInPip8Warning, | |
217 ) | |
218 | |
219 # TODO: try to get these passing down from the command? | |
220 # without resorting to os.environ to hold these. | |
221 | |
222 if options.no_input: | |
223 os.environ['PIP_NO_INPUT'] = '1' | |
224 | |
225 if options.exists_action: | |
226 os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) | |
227 | |
228 if options.require_venv: | |
229 # If a venv is required check if it can really be found | |
230 if not running_under_virtualenv(): | |
231 logger.critical( | |
232 'Could not find an activated virtualenv (required).' | |
233 ) | |
234 sys.exit(VIRTUALENV_NOT_FOUND) | |
235 | |
236 # Check if we're using the latest version of pip available | |
237 if (not options.disable_pip_version_check and not | |
238 getattr(options, "no_index", False)): | |
239 with self._build_session( | |
240 options, | |
241 retries=0, | |
242 timeout=min(5, options.timeout)) as session: | |
243 pip_version_check(session) | |
244 | |
245 try: | |
246 status = self.run(options, args) | |
247 # FIXME: all commands should return an exit status | |
248 # and when it is done, isinstance is not needed anymore | |
249 if isinstance(status, int): | |
250 return status | |
251 except PreviousBuildDirError as exc: | |
252 logger.critical(str(exc)) | |
253 logger.debug('Exception information:\n%s', format_exc()) | |
254 | |
255 return PREVIOUS_BUILD_DIR_ERROR | |
256 except (InstallationError, UninstallationError, BadCommand) as exc: | |
257 logger.critical(str(exc)) | |
258 logger.debug('Exception information:\n%s', format_exc()) | |
259 | |
260 return ERROR | |
261 except CommandError as exc: | |
262 logger.critical('ERROR: %s', exc) | |
263 logger.debug('Exception information:\n%s', format_exc()) | |
264 | |
265 return ERROR | |
266 except KeyboardInterrupt: | |
267 logger.critical('Operation cancelled by user') | |
268 logger.debug('Exception information:\n%s', format_exc()) | |
269 | |
270 return ERROR | |
271 except: | |
272 logger.critical('Exception:\n%s', format_exc()) | |
273 | |
274 return UNKNOWN_ERROR | |
275 | |
276 return SUCCESS | |
277 | |
278 | |
279 def format_exc(exc_info=None): | |
280 if exc_info is None: | |
281 exc_info = sys.exc_info() | |
282 out = StringIO() | |
283 traceback.print_exception(*exc_info, **dict(file=out)) | |
284 return out.getvalue() |