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