Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/pip/_internal/commands/configuration.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 subprocess | |
4 | |
5 from pip._internal.cli.base_command import Command | |
6 from pip._internal.cli.status_codes import ERROR, SUCCESS | |
7 from pip._internal.configuration import Configuration, get_configuration_files, kinds | |
8 from pip._internal.exceptions import PipError | |
9 from pip._internal.utils.logging import indent_log | |
10 from pip._internal.utils.misc import get_prog, write_output | |
11 from pip._internal.utils.typing import MYPY_CHECK_RUNNING | |
12 | |
13 if MYPY_CHECK_RUNNING: | |
14 from optparse import Values | |
15 from typing import Any, List, Optional | |
16 | |
17 from pip._internal.configuration import Kind | |
18 | |
19 logger = logging.getLogger(__name__) | |
20 | |
21 | |
22 class ConfigurationCommand(Command): | |
23 """ | |
24 Manage local and global configuration. | |
25 | |
26 Subcommands: | |
27 | |
28 - list: List the active configuration (or from the file specified) | |
29 - edit: Edit the configuration file in an editor | |
30 - get: Get the value associated with name | |
31 - set: Set the name=value | |
32 - unset: Unset the value associated with name | |
33 - debug: List the configuration files and values defined under them | |
34 | |
35 If none of --user, --global and --site are passed, a virtual | |
36 environment configuration file is used if one is active and the file | |
37 exists. Otherwise, all modifications happen on the to the user file by | |
38 default. | |
39 """ | |
40 | |
41 ignore_require_venv = True | |
42 usage = """ | |
43 %prog [<file-option>] list | |
44 %prog [<file-option>] [--editor <editor-path>] edit | |
45 | |
46 %prog [<file-option>] get name | |
47 %prog [<file-option>] set name value | |
48 %prog [<file-option>] unset name | |
49 %prog [<file-option>] debug | |
50 """ | |
51 | |
52 def add_options(self): | |
53 # type: () -> None | |
54 self.cmd_opts.add_option( | |
55 '--editor', | |
56 dest='editor', | |
57 action='store', | |
58 default=None, | |
59 help=( | |
60 'Editor to use to edit the file. Uses VISUAL or EDITOR ' | |
61 'environment variables if not provided.' | |
62 ) | |
63 ) | |
64 | |
65 self.cmd_opts.add_option( | |
66 '--global', | |
67 dest='global_file', | |
68 action='store_true', | |
69 default=False, | |
70 help='Use the system-wide configuration file only' | |
71 ) | |
72 | |
73 self.cmd_opts.add_option( | |
74 '--user', | |
75 dest='user_file', | |
76 action='store_true', | |
77 default=False, | |
78 help='Use the user configuration file only' | |
79 ) | |
80 | |
81 self.cmd_opts.add_option( | |
82 '--site', | |
83 dest='site_file', | |
84 action='store_true', | |
85 default=False, | |
86 help='Use the current environment configuration file only' | |
87 ) | |
88 | |
89 self.parser.insert_option_group(0, self.cmd_opts) | |
90 | |
91 def run(self, options, args): | |
92 # type: (Values, List[str]) -> int | |
93 handlers = { | |
94 "list": self.list_values, | |
95 "edit": self.open_in_editor, | |
96 "get": self.get_name, | |
97 "set": self.set_name_value, | |
98 "unset": self.unset_name, | |
99 "debug": self.list_config_values, | |
100 } | |
101 | |
102 # Determine action | |
103 if not args or args[0] not in handlers: | |
104 logger.error( | |
105 "Need an action (%s) to perform.", | |
106 ", ".join(sorted(handlers)), | |
107 ) | |
108 return ERROR | |
109 | |
110 action = args[0] | |
111 | |
112 # Determine which configuration files are to be loaded | |
113 # Depends on whether the command is modifying. | |
114 try: | |
115 load_only = self._determine_file( | |
116 options, need_value=(action in ["get", "set", "unset", "edit"]) | |
117 ) | |
118 except PipError as e: | |
119 logger.error(e.args[0]) | |
120 return ERROR | |
121 | |
122 # Load a new configuration | |
123 self.configuration = Configuration( | |
124 isolated=options.isolated_mode, load_only=load_only | |
125 ) | |
126 self.configuration.load() | |
127 | |
128 # Error handling happens here, not in the action-handlers. | |
129 try: | |
130 handlers[action](options, args[1:]) | |
131 except PipError as e: | |
132 logger.error(e.args[0]) | |
133 return ERROR | |
134 | |
135 return SUCCESS | |
136 | |
137 def _determine_file(self, options, need_value): | |
138 # type: (Values, bool) -> Optional[Kind] | |
139 file_options = [key for key, value in ( | |
140 (kinds.USER, options.user_file), | |
141 (kinds.GLOBAL, options.global_file), | |
142 (kinds.SITE, options.site_file), | |
143 ) if value] | |
144 | |
145 if not file_options: | |
146 if not need_value: | |
147 return None | |
148 # Default to user, unless there's a site file. | |
149 elif any( | |
150 os.path.exists(site_config_file) | |
151 for site_config_file in get_configuration_files()[kinds.SITE] | |
152 ): | |
153 return kinds.SITE | |
154 else: | |
155 return kinds.USER | |
156 elif len(file_options) == 1: | |
157 return file_options[0] | |
158 | |
159 raise PipError( | |
160 "Need exactly one file to operate upon " | |
161 "(--user, --site, --global) to perform." | |
162 ) | |
163 | |
164 def list_values(self, options, args): | |
165 # type: (Values, List[str]) -> None | |
166 self._get_n_args(args, "list", n=0) | |
167 | |
168 for key, value in sorted(self.configuration.items()): | |
169 write_output("%s=%r", key, value) | |
170 | |
171 def get_name(self, options, args): | |
172 # type: (Values, List[str]) -> None | |
173 key = self._get_n_args(args, "get [name]", n=1) | |
174 value = self.configuration.get_value(key) | |
175 | |
176 write_output("%s", value) | |
177 | |
178 def set_name_value(self, options, args): | |
179 # type: (Values, List[str]) -> None | |
180 key, value = self._get_n_args(args, "set [name] [value]", n=2) | |
181 self.configuration.set_value(key, value) | |
182 | |
183 self._save_configuration() | |
184 | |
185 def unset_name(self, options, args): | |
186 # type: (Values, List[str]) -> None | |
187 key = self._get_n_args(args, "unset [name]", n=1) | |
188 self.configuration.unset_value(key) | |
189 | |
190 self._save_configuration() | |
191 | |
192 def list_config_values(self, options, args): | |
193 # type: (Values, List[str]) -> None | |
194 """List config key-value pairs across different config files""" | |
195 self._get_n_args(args, "debug", n=0) | |
196 | |
197 self.print_env_var_values() | |
198 # Iterate over config files and print if they exist, and the | |
199 # key-value pairs present in them if they do | |
200 for variant, files in sorted(self.configuration.iter_config_files()): | |
201 write_output("%s:", variant) | |
202 for fname in files: | |
203 with indent_log(): | |
204 file_exists = os.path.exists(fname) | |
205 write_output("%s, exists: %r", | |
206 fname, file_exists) | |
207 if file_exists: | |
208 self.print_config_file_values(variant) | |
209 | |
210 def print_config_file_values(self, variant): | |
211 # type: (Kind) -> None | |
212 """Get key-value pairs from the file of a variant""" | |
213 for name, value in self.configuration.\ | |
214 get_values_in_config(variant).items(): | |
215 with indent_log(): | |
216 write_output("%s: %s", name, value) | |
217 | |
218 def print_env_var_values(self): | |
219 # type: () -> None | |
220 """Get key-values pairs present as environment variables""" | |
221 write_output("%s:", 'env_var') | |
222 with indent_log(): | |
223 for key, value in sorted(self.configuration.get_environ_vars()): | |
224 env_var = f'PIP_{key.upper()}' | |
225 write_output("%s=%r", env_var, value) | |
226 | |
227 def open_in_editor(self, options, args): | |
228 # type: (Values, List[str]) -> None | |
229 editor = self._determine_editor(options) | |
230 | |
231 fname = self.configuration.get_file_to_edit() | |
232 if fname is None: | |
233 raise PipError("Could not determine appropriate file.") | |
234 | |
235 try: | |
236 subprocess.check_call([editor, fname]) | |
237 except subprocess.CalledProcessError as e: | |
238 raise PipError( | |
239 "Editor Subprocess exited with exit code {}" | |
240 .format(e.returncode) | |
241 ) | |
242 | |
243 def _get_n_args(self, args, example, n): | |
244 # type: (List[str], str, int) -> Any | |
245 """Helper to make sure the command got the right number of arguments | |
246 """ | |
247 if len(args) != n: | |
248 msg = ( | |
249 'Got unexpected number of arguments, expected {}. ' | |
250 '(example: "{} config {}")' | |
251 ).format(n, get_prog(), example) | |
252 raise PipError(msg) | |
253 | |
254 if n == 1: | |
255 return args[0] | |
256 else: | |
257 return args | |
258 | |
259 def _save_configuration(self): | |
260 # type: () -> None | |
261 # We successfully ran a modifying command. Need to save the | |
262 # configuration. | |
263 try: | |
264 self.configuration.save() | |
265 except Exception: | |
266 logger.exception( | |
267 "Unable to save configuration. Please report this as a bug." | |
268 ) | |
269 raise PipError("Internal Error.") | |
270 | |
271 def _determine_editor(self, options): | |
272 # type: (Values) -> str | |
273 if options.editor is not None: | |
274 return options.editor | |
275 elif "VISUAL" in os.environ: | |
276 return os.environ["VISUAL"] | |
277 elif "EDITOR" in os.environ: | |
278 return os.environ["EDITOR"] | |
279 else: | |
280 raise PipError("Could not determine editor to use.") |