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.")