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