1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
# Copyright (C) 2012 Anaconda, Inc |
3
|
|
|
# SPDX-License-Identifier: BSD-3-Clause |
4
|
|
|
from __future__ import absolute_import, division, print_function, unicode_literals |
5
|
|
|
|
6
|
|
|
from argparse import (ArgumentParser as ArgumentParserBase, REMAINDER, RawDescriptionHelpFormatter, |
7
|
7 |
|
SUPPRESS, _CountAction, _HelpAction) |
8
|
|
|
from logging import getLogger |
9
|
7 |
|
import os |
10
|
7 |
|
from os.path import abspath, expanduser, join |
11
|
7 |
|
from subprocess import Popen |
12
|
7 |
|
import sys |
13
|
7 |
|
from textwrap import dedent |
14
|
|
|
|
15
|
7 |
|
from .. import __version__ |
16
|
7 |
|
from ..base.constants import COMPATIBLE_SHELLS, CONDA_HOMEPAGE_URL, DepsModifier, UpdateModifier |
17
|
7 |
|
from ..common.constants import NULL |
18
|
|
|
|
19
|
7 |
|
log = getLogger(__name__) |
20
|
|
|
|
21
|
|
|
# duplicated code in the interest of import efficiency |
22
|
7 |
|
on_win = bool(sys.platform == "win32") |
23
|
7 |
|
user_rc_path = abspath(expanduser('~/.condarc')) |
24
|
|
|
escaped_user_rc_path = user_rc_path.replace("%", "%%") |
25
|
|
|
escaped_sys_rc_path = abspath(join(sys.prefix, '.condarc')).replace("%", "%%") |
26
|
|
|
|
27
|
|
|
|
28
|
|
|
def generate_parser(): |
29
|
|
|
p = ArgumentParser( |
30
|
|
|
description='conda is a tool for managing and deploying applications,' |
31
|
|
|
' environments and packages.', |
32
|
|
|
) |
33
|
7 |
|
p.add_argument( |
34
|
7 |
|
'-V', '--version', |
35
|
|
|
action='version', |
36
|
7 |
|
version='conda %s' % __version__, |
37
|
|
|
help="Show the conda version number and exit." |
38
|
|
|
) |
39
|
7 |
|
p.add_argument( |
40
|
|
|
"--debug", |
41
|
7 |
|
action="store_true", |
42
|
|
|
help=SUPPRESS, |
43
|
|
|
) |
44
|
|
|
p.add_argument( |
45
|
|
|
"--json", |
46
|
|
|
action="store_true", |
47
|
|
|
help=SUPPRESS, |
48
|
|
|
) |
49
|
|
|
sub_parsers = p.add_subparsers( |
50
|
|
|
metavar='command', |
51
|
|
|
dest='cmd', |
52
|
|
|
) |
53
|
|
|
# http://bugs.python.org/issue9253 |
54
|
|
|
# http://stackoverflow.com/a/18283730/1599393 |
55
|
|
|
sub_parsers.required = True |
56
|
|
|
|
57
|
|
|
configure_parser_clean(sub_parsers) |
58
|
|
|
configure_parser_config(sub_parsers) |
59
|
|
|
configure_parser_create(sub_parsers) |
60
|
|
|
configure_parser_help(sub_parsers) |
61
|
|
|
configure_parser_info(sub_parsers) |
62
|
|
|
configure_parser_init(sub_parsers) |
63
|
|
|
configure_parser_install(sub_parsers) |
64
|
|
|
configure_parser_list(sub_parsers) |
65
|
|
|
configure_parser_package(sub_parsers) |
66
|
|
|
configure_parser_remove(sub_parsers) |
67
|
|
|
configure_parser_remove(sub_parsers, name='uninstall') |
68
|
|
|
configure_parser_run(sub_parsers) |
69
|
|
|
configure_parser_search(sub_parsers) |
70
|
|
|
configure_parser_update(sub_parsers) |
71
|
|
|
configure_parser_update(sub_parsers, name='upgrade') |
72
|
|
|
|
73
|
|
|
return p |
74
|
|
|
|
75
|
|
|
|
76
|
|
|
def do_call(args, parser): |
77
|
|
|
relative_mod, func_name = args.func.rsplit('.', 1) |
78
|
|
|
# func_name should always be 'execute' |
79
|
7 |
|
from importlib import import_module |
80
|
7 |
|
module = import_module(relative_mod, __name__.rsplit('.', 1)[0]) |
81
|
7 |
|
exit_code = getattr(module, func_name)(args, parser) |
82
|
7 |
|
return exit_code |
83
|
7 |
|
|
84
|
7 |
|
|
85
|
7 |
|
class ArgumentParser(ArgumentParserBase): |
86
|
|
|
def __init__(self, *args, **kwargs): |
87
|
7 |
|
if not kwargs.get('formatter_class'): |
88
|
7 |
|
kwargs['formatter_class'] = RawDescriptionHelpFormatter |
89
|
|
|
if 'add_help' not in kwargs: |
90
|
7 |
|
add_custom_help = True |
91
|
7 |
|
kwargs['add_help'] = False |
92
|
|
|
else: |
93
|
7 |
|
add_custom_help = False |
94
|
7 |
|
super(ArgumentParser, self).__init__(*args, **kwargs) |
95
|
|
|
|
96
|
7 |
|
if add_custom_help: |
97
|
|
|
add_parser_help(self) |
98
|
|
|
|
99
|
|
|
if self.description: |
100
|
|
|
self.description += "\n\nOptions:\n" |
101
|
7 |
|
|
102
|
7 |
|
def _get_action_from_name(self, name): |
103
|
|
|
"""Given a name, get the Action instance registered with this parser. |
104
|
7 |
|
If only it were made available in the ArgumentError object. It is |
105
|
7 |
|
passed as it's first arg... |
106
|
7 |
|
""" |
107
|
7 |
|
container = self._actions |
108
|
|
|
if name is None: |
109
|
7 |
|
return None |
110
|
|
|
for action in container: |
111
|
|
|
if '/'.join(action.option_strings) == name: |
112
|
7 |
|
return action |
113
|
7 |
|
elif action.metavar == name: |
114
|
7 |
|
return action |
115
|
7 |
|
elif action.dest == name: |
116
|
|
|
return action |
117
|
7 |
|
|
118
|
7 |
|
def error(self, message): |
119
|
|
|
import re |
120
|
|
|
from .find_commands import find_executable |
121
|
7 |
|
exc = sys.exc_info()[1] |
122
|
7 |
|
if exc: |
123
|
|
|
# this is incredibly lame, but argparse stupidly does not expose |
124
|
|
|
# reasonable hooks for customizing error handling |
125
|
7 |
|
if hasattr(exc, 'argument_name'): |
126
|
|
|
argument = self._get_action_from_name(exc.argument_name) |
127
|
|
|
else: |
128
|
|
|
argument = None |
129
|
|
|
if argument and argument.dest == "cmd": |
130
|
|
|
m = re.match(r"invalid choice: u?'([\w\-]*?)'", exc.message) |
131
|
|
|
if m: |
132
|
|
|
cmd = m.group(1) |
133
|
|
|
if not cmd: |
134
|
|
|
self.print_help() |
135
|
|
|
sys.exit(0) |
136
|
|
|
else: |
137
|
|
|
executable = find_executable('conda-' + cmd) |
138
|
|
|
if not executable: |
139
|
|
|
from ..exceptions import CommandNotFoundError |
140
|
|
|
raise CommandNotFoundError(cmd) |
141
|
|
|
args = [find_executable('conda-' + cmd)] |
142
|
|
|
args.extend(sys.argv[2:]) |
143
|
|
|
_exec(args, os.environ) |
144
|
|
|
|
145
|
|
|
super(ArgumentParser, self).error(message) |
146
|
|
|
|
147
|
|
|
def print_help(self): |
148
|
|
|
super(ArgumentParser, self).print_help() |
149
|
|
|
|
150
|
|
|
if sys.argv[1:] in ([], [''], ['help'], ['-h'], ['--help']): |
151
|
|
|
from .find_commands import find_commands |
152
|
|
|
other_commands = find_commands() |
153
|
|
|
if other_commands: |
154
|
|
|
builder = [''] |
155
|
|
|
builder.append("conda commands available from other packages:") |
156
|
|
|
builder.extend(' %s' % cmd for cmd in sorted(other_commands)) |
157
|
7 |
|
print('\n'.join(builder)) |
158
|
|
|
|
159
|
7 |
|
|
160
|
|
|
def _exec(executable_args, env_vars): |
161
|
|
|
return (_exec_win if on_win else _exec_unix)(executable_args, env_vars) |
162
|
|
|
|
163
|
|
|
|
164
|
|
|
def _exec_win(executable_args, env_vars): |
165
|
|
|
p = Popen(executable_args, env=env_vars) |
166
|
|
|
try: |
167
|
|
|
p.communicate() |
168
|
7 |
|
except KeyboardInterrupt: |
169
|
7 |
|
p.wait() |
170
|
|
|
finally: |
171
|
|
|
sys.exit(p.returncode) |
172
|
7 |
|
|
173
|
|
|
|
174
|
|
|
def _exec_unix(executable_args, env_vars): |
175
|
|
|
os.execvpe(executable_args[0], executable_args, env_vars) |
176
|
|
|
|
177
|
|
|
|
178
|
|
|
class NullCountAction(_CountAction): |
179
|
|
|
|
180
|
|
|
@staticmethod |
181
|
|
|
def _ensure_value(namespace, name, value): |
182
|
|
|
if getattr(namespace, name, NULL) in (NULL, None): |
183
|
|
|
setattr(namespace, name, value) |
184
|
|
|
return getattr(namespace, name) |
185
|
|
|
|
186
|
|
|
def __call__(self, parser, namespace, values, option_string=None): |
187
|
|
|
new_count = self._ensure_value(namespace, self.dest, 0) + 1 |
188
|
|
|
setattr(namespace, self.dest, new_count) |
189
|
|
|
|
190
|
|
|
|
191
|
|
|
# ############################################################################################# |
192
|
|
|
# |
193
|
|
|
# sub-parsers |
194
|
|
|
# |
195
|
|
|
# ############################################################################################# |
196
|
|
|
|
197
|
|
|
def configure_parser_clean(sub_parsers): |
198
|
|
|
descr = dedent(""" |
199
|
|
|
Remove unused packages and caches. |
200
|
|
|
""") |
201
|
|
|
example = dedent(""" |
202
|
|
|
Examples: |
203
|
|
View Code Duplication |
|
|
|
|
|
204
|
|
|
conda clean --tarballs |
205
|
|
|
""") |
206
|
|
|
p = sub_parsers.add_parser( |
207
|
|
|
'clean', |
208
|
|
|
description=descr, |
209
|
|
|
help=descr, |
210
|
|
|
epilog=example, |
211
|
|
|
) |
212
|
|
|
|
213
|
|
|
removal_target_options = p.add_argument_group("Removal Targets") |
214
|
|
|
removal_target_options.add_argument( |
215
|
|
|
"-a", "--all", |
216
|
|
|
action="store_true", |
217
|
|
|
help="Remove index cache, lock files, unused cache packages, and tarballs.", |
218
|
|
|
) |
219
|
|
|
removal_target_options.add_argument( |
220
|
|
|
"-i", "--index-cache", |
221
|
|
|
action="store_true", |
222
|
|
|
help="Remove index cache.", |
223
|
|
|
) |
224
|
|
|
removal_target_options.add_argument( |
225
|
|
|
"-l", "--lock", |
226
|
|
|
action="store_true", |
227
|
|
|
help="Remove all conda lock files.", |
228
|
|
|
) |
229
|
|
|
removal_target_options.add_argument( |
230
|
|
|
'-p', '--packages', |
231
|
|
|
action='store_true', |
232
|
|
|
help="Remove unused cached packages. Warning: This does not check for symlinked packages.", |
233
|
|
|
) |
234
|
|
|
removal_target_options.add_argument( |
235
|
|
|
'-s', '--source-cache', |
236
|
|
|
action='store_true', |
237
|
|
|
# help="Remove files from the source cache of conda build.", |
238
|
|
|
help=SUPPRESS, |
239
|
|
|
) |
240
|
|
|
removal_target_options.add_argument( |
241
|
|
|
"-t", "--tarballs", |
242
|
|
|
action="store_true", |
243
|
|
|
help="Remove cached package tarballs.", |
244
|
|
|
) |
245
|
|
|
|
246
|
|
|
add_output_and_prompt_options(p) |
247
|
|
|
|
248
|
|
|
p.set_defaults(func='.main_clean.execute') |
249
|
|
|
|
250
|
|
|
|
251
|
|
|
def configure_parser_info(sub_parsers): |
252
|
|
|
help = "Display information about current conda install." |
253
|
|
|
|
254
|
|
|
p = sub_parsers.add_parser( |
255
|
|
|
'info', |
256
|
|
|
description=help, |
257
|
|
|
help=help, |
258
|
|
|
) |
259
|
|
|
add_parser_json(p) |
260
|
|
|
p.add_argument( |
261
|
|
|
"--offline", |
262
|
|
|
action='store_true', |
263
|
|
|
default=NULL, |
264
|
|
|
help=SUPPRESS, |
265
|
|
|
) |
266
|
|
|
p.add_argument( |
267
|
|
|
'-a', "--all", |
268
|
|
|
action="store_true", |
269
|
|
|
help="Show all information.", |
270
|
|
|
) |
271
|
|
|
p.add_argument( |
272
|
|
|
'--base', |
273
|
|
|
action='store_true', |
274
|
|
|
help='Display base environment path.', |
275
|
|
|
) |
276
|
|
|
# TODO: deprecate 'conda info --envs' and create 'conda list --envs' |
277
|
|
|
p.add_argument( |
278
|
|
|
'-e', "--envs", |
279
|
|
|
action="store_true", |
280
|
|
|
help="List all known conda environments.", |
281
|
|
|
) |
282
|
|
|
p.add_argument( |
283
|
|
|
'-l', "--license", |
284
|
|
|
action="store_true", |
285
|
|
|
help=SUPPRESS, |
286
|
|
|
) |
287
|
|
|
p.add_argument( |
288
|
|
|
'-s', "--system", |
289
|
|
|
action="store_true", |
290
|
|
|
help="List environment variables.", |
291
|
|
|
) |
292
|
|
|
p.add_argument( |
293
|
|
|
'--root', |
294
|
|
|
action='store_true', |
295
|
|
|
help=SUPPRESS, |
296
|
|
|
dest='base', |
297
|
|
|
) |
298
|
|
|
p.add_argument( |
299
|
|
|
'--unsafe-channels', |
300
|
|
|
action='store_true', |
301
|
|
|
help='Display list of channels with tokens exposed.', |
302
|
|
|
) |
303
|
|
|
|
304
|
|
|
# TODO: deprecate 'conda info <PACKAGE>' |
305
|
|
|
p.add_argument( |
306
|
|
|
'packages', |
307
|
|
|
action="store", |
308
|
|
|
nargs='*', |
309
|
|
|
help="Display information about packages.", |
310
|
|
|
) |
311
|
|
|
|
312
|
|
|
p.set_defaults(func='.main_info.execute') |
313
|
|
|
|
314
|
|
|
|
315
|
|
|
def configure_parser_config(sub_parsers): |
316
|
|
|
descr = dedent(""" |
317
|
|
|
Modify configuration values in .condarc. This is modeled after the git |
318
|
|
|
config command. Writes to the user .condarc file (%s) by default. |
319
|
|
|
|
320
|
|
|
""") % escaped_user_rc_path |
321
|
|
|
|
322
|
|
|
# Note, the extra whitespace in the list keys is on purpose. It's so the |
323
|
|
|
# formatting from help2man is still valid YAML (otherwise it line wraps the |
324
|
|
|
# keys like "- conda - defaults"). Technically the parser here still won't |
325
|
|
|
# recognize it because it removes the indentation, but at least it will be |
326
|
|
|
# valid. |
327
|
|
|
additional_descr = dedent(""" |
328
|
|
|
See `conda config --describe` or %s/docs/config.html |
329
|
|
|
for details on all the options that can go in .condarc. |
330
|
|
|
|
331
|
|
|
Examples: |
332
|
|
|
|
333
|
|
|
Display all configuration values as calculated and compiled: |
334
|
|
|
|
335
|
|
|
conda config --show |
336
|
|
|
|
337
|
|
|
Display all identified configuration sources: |
338
|
|
|
|
339
|
|
|
conda config --show-sources |
340
|
|
|
|
341
|
|
|
Describe all available configuration options: |
342
|
|
|
|
343
|
|
|
conda config --describe |
344
|
|
|
|
345
|
|
|
Add the conda-canary channel: |
346
|
|
|
|
347
|
|
|
conda config --add channels conda-canary |
348
|
|
|
|
349
|
|
|
Set the output verbosity to level 3 (highest) for the current activate environment: |
350
|
|
|
|
351
|
|
|
conda config --set verbosity 3 --env |
352
|
|
|
|
353
|
|
|
Add the 'conda-forge' channel as a backup to 'defaults': |
354
|
|
|
|
355
|
|
|
conda config --append channels conda-forge |
356
|
|
|
|
357
|
|
|
""") % CONDA_HOMEPAGE_URL |
358
|
|
|
|
359
|
|
|
p = sub_parsers.add_parser( |
360
|
|
|
'config', |
361
|
|
|
description=descr, |
362
|
|
|
help=descr, |
363
|
|
|
epilog=additional_descr, |
364
|
|
|
) |
365
|
|
|
add_parser_json(p) |
366
|
|
|
|
367
|
|
|
# TODO: use argparse.FileType |
368
|
|
|
config_file_location_group = p.add_argument_group( |
369
|
|
|
'Config File Location Selection', |
370
|
|
|
"Without one of these flags, the user config file at '%s' is used." % escaped_user_rc_path |
371
|
|
|
) |
372
|
|
|
location = config_file_location_group.add_mutually_exclusive_group() |
373
|
|
|
location.add_argument( |
374
|
|
|
"--system", |
375
|
|
|
action="store_true", |
376
|
|
|
help="Write to the system .condarc file at '%s'." % escaped_sys_rc_path, |
377
|
|
|
) |
378
|
|
|
location.add_argument( |
379
|
|
|
"--env", |
380
|
|
|
action="store_true", |
381
|
|
|
help="Write to the active conda environment .condarc file (%s). " |
382
|
|
|
"If no environment is active, write to the user config file (%s)." |
383
|
|
|
"" % ( |
384
|
|
|
os.getenv('CONDA_PREFIX', "<no active environment>").replace("%", "%%"), |
385
|
|
|
escaped_user_rc_path, |
386
|
|
|
), |
387
|
|
|
) |
388
|
|
|
location.add_argument( |
389
|
|
|
"--file", |
390
|
|
|
action="store", |
391
|
|
|
help="Write to the given file." |
392
|
|
|
) |
393
|
|
|
|
394
|
|
|
# XXX: Does this really have to be mutually exclusive. I think the below |
395
|
|
|
# code will work even if it is a regular group (although combination of |
396
|
|
|
# --add and --remove with the same keys will not be well-defined). |
397
|
|
|
_config_subcommands = p.add_argument_group("Config Subcommands") |
398
|
|
|
config_subcommands = _config_subcommands.add_mutually_exclusive_group() |
399
|
|
|
config_subcommands.add_argument( |
400
|
|
|
"--show", |
401
|
|
|
nargs='*', |
402
|
|
|
default=None, |
403
|
|
|
help="Display configuration values as calculated and compiled. " |
404
|
|
|
"If no arguments given, show information for all configuration values.", |
405
|
|
|
) |
406
|
|
|
config_subcommands.add_argument( |
407
|
|
|
"--show-sources", |
408
|
|
|
action="store_true", |
409
|
|
|
help="Display all identified configuration sources.", |
410
|
|
|
) |
411
|
|
|
config_subcommands.add_argument( |
412
|
|
|
"--validate", |
413
|
|
|
action="store_true", |
414
|
|
|
help="Validate all configuration sources.", |
415
|
|
|
) |
416
|
|
|
config_subcommands.add_argument( |
417
|
|
|
"--describe", |
418
|
|
|
nargs='*', |
419
|
|
|
default=None, |
420
|
|
|
help="Describe given configuration parameters. If no arguments given, show " |
421
|
|
|
"information for all configuration parameters.", |
422
|
|
|
) |
423
|
|
|
config_subcommands.add_argument( |
424
|
|
|
"--write-default", |
425
|
|
|
action="store_true", |
426
|
|
|
help="Write the default configuration to a file. " |
427
|
|
|
"Equivalent to `conda config --describe > ~/.condarc`.", |
428
|
|
|
) |
429
|
|
|
|
430
|
|
|
_config_modifiers = p.add_argument_group("Config Modifiers") |
431
|
|
|
config_modifiers = _config_modifiers.add_mutually_exclusive_group() |
432
|
|
|
config_modifiers.add_argument( |
433
|
|
|
"--get", |
434
|
|
|
nargs='*', |
435
|
|
|
action="store", |
436
|
|
|
help="Get a configuration value.", |
437
|
|
|
default=None, |
438
|
|
|
metavar='KEY', |
439
|
|
|
) |
440
|
|
|
config_modifiers.add_argument( |
441
|
|
|
"--append", |
442
|
|
|
nargs=2, |
443
|
|
|
action="append", |
444
|
|
|
help="""Add one configuration value to the end of a list key.""", |
445
|
|
|
default=[], |
446
|
|
|
metavar=('KEY', 'VALUE'), |
447
|
|
|
) |
448
|
|
|
config_modifiers.add_argument( |
449
|
|
|
"--prepend", "--add", |
450
|
|
|
nargs=2, |
451
|
|
|
action="append", |
452
|
|
|
help="""Add one configuration value to the beginning of a list key.""", |
453
|
|
|
default=[], |
454
|
|
|
metavar=('KEY', 'VALUE'), |
455
|
|
|
) |
456
|
|
|
config_modifiers.add_argument( |
457
|
|
|
"--set", |
458
|
|
|
nargs=2, |
459
|
|
|
action="append", |
460
|
|
|
help="""Set a boolean or string key""", |
461
|
|
|
default=[], |
462
|
|
|
metavar=('KEY', 'VALUE'), |
463
|
|
|
) |
464
|
|
|
config_modifiers.add_argument( |
465
|
|
|
"--remove", |
466
|
|
|
nargs=2, |
467
|
|
|
action="append", |
468
|
|
|
help="""Remove a configuration value from a list key. This removes |
469
|
|
|
all instances of the value.""", |
470
|
|
|
default=[], |
471
|
|
|
metavar=('KEY', 'VALUE'), |
472
|
|
|
) |
473
|
|
|
config_modifiers.add_argument( |
474
|
|
|
"--remove-key", |
475
|
|
|
nargs=1, |
476
|
|
|
action="append", |
477
|
|
|
help="""Remove a configuration key (and all its values).""", |
478
|
|
|
default=[], |
479
|
|
|
metavar="KEY", |
480
|
|
|
) |
481
|
|
|
config_modifiers.add_argument( |
482
|
|
|
"--stdin", |
483
|
|
|
action="store_true", |
484
|
|
|
help="Apply configuration information given in yaml format piped through stdin.", |
485
|
|
|
) |
486
|
|
|
|
487
|
|
|
p.add_argument( |
488
|
|
|
"-f", "--force", |
489
|
|
|
action="store_true", |
490
|
|
|
default=NULL, |
491
|
|
|
help=SUPPRESS, # TODO: No longer used. Remove in a future release. |
492
|
|
|
) |
493
|
|
|
|
494
|
|
|
p.set_defaults(func='.main_config.execute') |
495
|
|
|
|
496
|
|
|
|
497
|
|
View Code Duplication |
def configure_parser_create(sub_parsers): |
|
|
|
|
498
|
|
|
help = "Create a new conda environment from a list of specified packages. " |
499
|
|
|
descr = (help + |
500
|
|
|
"To use the created environment, use 'source activate " |
501
|
|
|
"envname' look in that directory first. This command requires either " |
502
|
|
|
"the -n NAME or -p PREFIX option.") |
503
|
|
|
|
504
|
|
|
example = dedent(""" |
505
|
|
|
Examples: |
506
|
|
|
|
507
|
|
|
conda create -n myenv sqlite |
508
|
|
|
|
509
|
|
|
""") |
510
|
|
|
p = sub_parsers.add_parser( |
511
|
|
|
'create', |
512
|
|
|
description=descr, |
513
|
|
|
help=help, |
514
|
|
|
epilog=example, |
515
|
|
|
) |
516
|
|
|
p.add_argument( |
517
|
|
|
"--clone", |
518
|
|
|
action="store", |
519
|
|
|
help='Path to (or name of) existing local environment.', |
520
|
|
|
metavar='ENV', |
521
|
|
|
) |
522
|
|
|
solver_mode_options, package_install_options = add_parser_create_install_update(p) |
523
|
|
|
solver_mode_options.add_argument( |
524
|
|
|
"--no-default-packages", |
525
|
|
|
action="store_true", |
526
|
|
|
help='Ignore create_default_packages in the .condarc file.', |
527
|
|
|
) |
528
|
|
|
p.add_argument( |
529
|
|
|
'-m', "--mkdir", |
530
|
|
|
action="store_true", |
531
|
|
|
help=SUPPRESS, |
532
|
|
|
) |
533
|
|
|
p.set_defaults(func='.main_create.execute') |
534
|
|
|
|
535
|
|
|
|
536
|
|
|
def configure_parser_init(sub_parsers): |
537
|
|
|
help = "Initialize conda for shell interaction. [Experimental]" |
538
|
|
|
descr = help |
539
|
|
|
|
540
|
|
|
epilog = dedent(""" |
541
|
|
|
Key parts of conda's functionality require that it interact directly with the shell |
542
|
|
|
within which conda is being invoked. The `conda activate` and `conda deactivate` commands |
543
|
|
|
specifically are shell-level commands. That is, they affect the state (e.g. environment |
544
|
|
|
variables) of the shell context being interacted with. Other core commands, like |
545
|
|
|
`conda create` and `conda install`, also necessarily interact with the shell environment. |
546
|
|
|
They're therefore implemented in ways specific to each shell. Each shell must be configured |
547
|
|
|
to make use of them. |
548
|
|
|
|
549
|
|
|
This command makes changes to your system that are specific and customized for each shell. |
550
|
|
|
To see the specific files and locations on your system that will be affected before, use the |
551
|
|
|
'--dry-run' flag. To see the exact changes that are being or will be made to each location, |
552
|
|
|
use the '--verbose' flag. |
553
|
|
|
|
554
|
|
|
IMPORTANT: After running `conda init`, most shells will need to be closed and restarted |
555
|
|
|
for changes to take effect. |
556
|
|
|
|
557
|
|
|
""") |
558
|
|
|
|
559
|
|
|
# dev_example = dedent(""" |
560
|
|
|
# # An example for creating an environment to develop on conda's own code. Clone the |
561
|
|
|
# # conda repo and install a dedicated miniconda within it. Remove all remnants of |
562
|
|
|
# # conda source files in the `site-packages` directory associated with |
563
|
|
|
# # `~/conda/devenv/bin/python`. Write a `conda.pth` file in that `site-packages` |
564
|
|
|
# # directory pointing to source code in `~/conda`, the current working directory. |
565
|
|
|
# # Write commands to stdout, suitable for bash `eval`, that sets up the current |
566
|
|
|
# # shell as a dev environment. |
567
|
|
|
# |
568
|
|
|
# $ CONDA_PROJECT_ROOT="~/conda" |
569
|
|
|
# $ git clone [email protected]:conda/conda "$CONDA_PROJECT_ROOT" |
570
|
|
|
# $ cd "$CONDA_PROJECT_ROOT" |
571
|
|
|
# $ wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh |
572
|
|
|
# $ bash Miniconda3-latest-Linux-x86_64.sh -bfp ./devenv |
573
|
|
|
# $ eval "$(./devenv/bin/python -m conda init --dev bash)" |
574
|
|
|
# |
575
|
|
|
# |
576
|
|
|
# """) |
577
|
|
|
|
578
|
|
|
p = sub_parsers.add_parser( |
579
|
|
|
'init', |
580
|
|
|
description=descr, |
581
|
|
|
help=help, |
582
|
|
|
epilog=epilog, |
583
|
|
|
) |
584
|
|
|
|
585
|
|
|
p.add_argument( |
586
|
|
|
"--dev", |
587
|
|
|
action="store_true", |
588
|
|
|
help=SUPPRESS, |
589
|
|
|
default=NULL, |
590
|
|
|
) |
591
|
|
|
|
592
|
|
|
p.add_argument( |
593
|
|
|
"--all", |
594
|
|
|
action="store_true", |
595
|
|
|
help="Initialize all currently available shells.", |
596
|
|
|
default=NULL, |
597
|
|
|
) |
598
|
|
|
|
599
|
|
|
setup_type_group = p.add_argument_group('setup type') |
600
|
|
|
setup_type_group.add_argument( |
601
|
|
|
"--install", |
602
|
|
|
action="store_true", |
603
|
|
|
help=SUPPRESS, |
604
|
|
|
default=NULL, |
605
|
|
|
) |
606
|
|
|
setup_type_group.add_argument( |
607
|
|
|
"--user", |
608
|
|
|
action="store_true", |
609
|
|
|
# help="Initialize conda for the current user (default).", |
610
|
|
|
help=SUPPRESS, |
611
|
|
|
default=NULL, |
612
|
|
|
) |
613
|
|
|
setup_type_group.add_argument( |
614
|
|
|
"--no-user", |
615
|
|
|
action="store_false", |
616
|
|
|
# help="Don't initialize conda for the current user (default).", |
617
|
|
|
help=SUPPRESS, |
618
|
|
|
default=NULL, |
619
|
|
|
) |
620
|
|
|
setup_type_group.add_argument( |
621
|
|
|
"--system", |
622
|
|
|
action="store_true", |
623
|
|
|
# help="Initialize conda for all users on the system.", |
624
|
|
|
help=SUPPRESS, |
625
|
|
|
default=NULL, |
626
|
|
|
) |
627
|
|
|
|
628
|
|
|
p.add_argument( |
629
|
|
|
'shells', |
630
|
|
|
nargs='*', |
631
|
|
|
help="One or more shells to be initialized. If not given, the default value is " |
632
|
|
|
"'bash' on unix and 'cmd.exe' on Windows. Use the '--all' flag to initialize " |
633
|
|
|
"all shells. Currently compatible shells are {%s}" |
634
|
|
|
% ", ".join(sorted(COMPATIBLE_SHELLS)), |
635
|
|
|
) |
636
|
|
|
|
637
|
|
|
if on_win: |
638
|
|
|
p.add_argument( |
639
|
|
|
"--anaconda-prompt", |
640
|
|
|
action="store_true", |
641
|
|
|
help="Add an 'Anaconda Prompt' icon to your desktop.", |
642
|
|
|
default=NULL, |
643
|
|
|
) |
644
|
|
|
|
645
|
|
|
add_parser_json(p) |
646
|
|
|
p.add_argument( |
647
|
|
|
"--dry-run", |
648
|
|
|
action="store_true", |
649
|
|
|
help="Only display what would have been done.", |
650
|
|
|
) |
651
|
|
|
p.set_defaults(func='.main_init.execute') |
652
|
|
|
|
653
|
|
|
|
654
|
|
|
def configure_parser_help(sub_parsers): |
655
|
|
|
descr = "Displays a list of available conda commands and their help strings." |
656
|
|
|
|
657
|
|
|
p = sub_parsers.add_parser( |
658
|
|
|
'help', |
659
|
|
|
description=descr, |
660
|
|
|
help=descr, |
661
|
|
|
) |
662
|
|
|
p.add_argument( |
663
|
|
|
'command', |
664
|
|
|
metavar='COMMAND', |
665
|
|
|
action="store", |
666
|
|
|
nargs='?', |
667
|
|
|
help="Print help information for COMMAND (same as: conda COMMAND --help).", |
668
|
|
|
) |
669
|
|
|
p.set_defaults(func='.main_help.execute') |
670
|
|
|
|
671
|
|
|
|
672
|
|
|
def configure_parser_install(sub_parsers): |
673
|
|
|
help = "Installs a list of packages into a specified conda environment." |
674
|
|
|
descr = dedent(help + """ |
675
|
|
|
|
676
|
|
|
This command accepts a list of package specifications (e.g, bitarray=0.8) |
677
|
|
|
and installs a set of packages consistent with those specifications and |
678
|
|
View Code Duplication |
compatible with the underlying environment. If full compatibility cannot |
|
|
|
|
679
|
|
|
be assured, an error is reported and the environment is not changed. |
680
|
|
|
|
681
|
|
|
Conda attempts to install the newest versions of the requested packages. To |
682
|
|
|
accomplish this, it may update some packages that are already installed, or |
683
|
|
|
install additional packages. To prevent existing packages from updating, |
684
|
|
|
use the --freeze-installed option. This may force conda to install older |
685
|
|
|
versions of the requested packages, and it does not prevent additional |
686
|
|
|
dependency packages from being installed. |
687
|
|
|
|
688
|
|
|
If you wish to skip dependency checking altogether, use the '--no-deps' |
689
|
|
|
option. This may result in an environment with incompatible packages, so |
690
|
|
|
this option must be used with great caution. |
691
|
|
|
|
692
|
|
|
conda can also be called with a list of explicit conda package filenames |
693
|
|
|
(e.g. ./lxml-3.2.0-py27_0.tar.bz2). Using conda in this mode implies the |
694
|
|
|
--no-deps option, and should likewise be used with great caution. Explicit |
695
|
|
|
filenames and package specifications cannot be mixed in a single command. |
696
|
|
|
""") |
697
|
|
|
example = dedent(""" |
698
|
|
|
Examples: |
699
|
|
|
|
700
|
|
|
conda install -n myenv scipy |
701
|
|
|
|
702
|
|
|
""") |
703
|
|
|
p = sub_parsers.add_parser( |
704
|
|
|
'install', |
705
|
|
|
description=descr, |
706
|
|
|
help=help, |
707
|
|
|
epilog=example, |
708
|
|
|
) |
709
|
|
|
p.add_argument( |
710
|
|
|
"--revision", |
711
|
|
|
action="store", |
712
|
|
|
help="Revert to the specified REVISION.", |
713
|
|
|
metavar='REVISION', |
714
|
|
|
) |
715
|
|
|
|
716
|
|
|
solver_mode_options, package_install_options = add_parser_create_install_update(p) |
717
|
|
|
|
718
|
|
|
add_parser_prune(solver_mode_options) |
719
|
|
|
solver_mode_options.add_argument( |
720
|
|
|
"--force-reinstall", |
721
|
|
|
action="store_true", |
722
|
|
|
default=NULL, |
723
|
|
|
help="Ensure that any user-requested package for the current operation is uninstalled and " |
724
|
|
|
"reinstalled, even if that package already exists in the environment.", |
725
|
|
|
) |
726
|
|
|
add_parser_update_modifiers(solver_mode_options) |
727
|
|
|
package_install_options.add_argument( |
728
|
|
|
'-m', "--mkdir", |
729
|
|
|
action="store_true", |
730
|
|
|
help="Create the environment directory if necessary.", |
731
|
|
|
) |
732
|
|
|
package_install_options.add_argument( |
733
|
|
|
"--clobber", |
734
|
|
|
action="store_true", |
735
|
|
|
default=NULL, |
736
|
|
|
help="Allow clobbering of overlapping file paths within packages, " |
737
|
|
|
"and suppress related warnings.", |
738
|
|
|
) |
739
|
|
|
p.set_defaults(func='.main_install.execute') |
740
|
|
|
|
741
|
|
|
|
742
|
|
|
def configure_parser_list(sub_parsers): |
743
|
|
|
descr = "List linked packages in a conda environment." |
744
|
|
|
|
745
|
|
|
# Note, the formatting of this is designed to work well with help2man |
746
|
|
|
examples = dedent(""" |
747
|
|
|
Examples: |
748
|
|
|
|
749
|
|
|
List all packages in the current environment: |
750
|
|
|
|
751
|
|
|
conda list |
752
|
|
|
|
753
|
|
|
List all packages installed into the environment 'myenv': |
754
|
|
|
|
755
|
|
|
conda list -n myenv |
756
|
|
|
|
757
|
|
|
Save packages for future use: |
758
|
|
|
|
759
|
|
|
conda list --export > package-list.txt |
760
|
|
|
|
761
|
|
|
Reinstall packages from an export file: |
762
|
|
|
|
763
|
|
|
conda create -n myenv --file package-list.txt |
764
|
|
|
|
765
|
|
|
""") |
766
|
|
|
p = sub_parsers.add_parser( |
767
|
|
|
'list', |
768
|
|
|
description=descr, |
769
|
|
|
help=descr, |
770
|
|
|
formatter_class=RawDescriptionHelpFormatter, |
771
|
|
|
epilog=examples, |
772
|
|
|
add_help=False, |
773
|
|
|
) |
774
|
|
|
add_parser_help(p) |
775
|
|
|
add_parser_prefix(p) |
776
|
|
|
add_parser_json(p) |
777
|
|
|
add_parser_show_channel_urls(p) |
778
|
|
|
p.add_argument( |
779
|
|
|
'-c', "--canonical", |
780
|
|
|
action="store_true", |
781
|
|
|
help="Output canonical names of packages only. Implies --no-pip. ", |
782
|
|
|
) |
783
|
|
|
p.add_argument( |
784
|
|
|
'-f', "--full-name", |
785
|
|
|
action="store_true", |
786
|
|
|
help="Only search for full names, i.e., ^<regex>$.", |
787
|
|
|
) |
788
|
|
|
p.add_argument( |
789
|
|
|
"--explicit", |
790
|
|
|
action="store_true", |
791
|
|
|
help="List explicitly all installed conda packaged with URL " |
792
|
|
|
"(output may be used by conda create --file).", |
793
|
|
|
) |
794
|
|
|
p.add_argument( |
795
|
|
|
"--md5", |
796
|
|
|
action="store_true", |
797
|
|
|
help="Add MD5 hashsum when using --explicit", |
798
|
|
|
) |
799
|
|
|
p.add_argument( |
800
|
|
|
'-e', "--export", |
801
|
|
|
action="store_true", |
802
|
|
|
help="Output requirement string only (output may be used by " |
803
|
|
|
" conda create --file).", |
804
|
|
|
) |
805
|
|
|
p.add_argument( |
806
|
|
|
'-r', "--revisions", |
807
|
|
|
action="store_true", |
808
|
|
|
help="List the revision history and exit.", |
809
|
|
|
) |
810
|
|
|
p.add_argument( |
811
|
|
|
"--no-pip", |
812
|
|
|
action="store_false", |
813
|
|
|
default=True, |
814
|
|
|
dest="pip", |
815
|
|
|
help="Do not include pip-only installed packages.") |
816
|
|
|
p.add_argument( |
817
|
|
|
'regex', |
818
|
|
|
action="store", |
819
|
|
|
nargs="?", |
820
|
|
|
help="List only packages matching this regular expression.", |
821
|
|
|
) |
822
|
|
|
p.set_defaults(func='.main_list.execute') |
823
|
|
|
|
824
|
|
|
|
825
|
|
|
def configure_parser_package(sub_parsers): |
826
|
|
|
descr = "Low-level conda package utility. (EXPERIMENTAL)" |
827
|
|
|
p = sub_parsers.add_parser( |
828
|
|
|
'package', |
829
|
|
|
description=descr, |
830
|
|
|
help=descr, |
831
|
|
View Code Duplication |
) |
|
|
|
|
832
|
|
|
add_parser_prefix(p) |
833
|
|
|
p.add_argument( |
834
|
|
|
'-w', "--which", |
835
|
|
|
metavar="PATH", |
836
|
|
|
nargs='+', |
837
|
|
|
action="store", |
838
|
|
|
help="Given some PATH print which conda package the file came from.", |
839
|
|
|
) |
840
|
|
|
p.add_argument( |
841
|
|
|
'-r', "--reset", |
842
|
|
|
action="store_true", |
843
|
|
|
help="Remove all untracked files and exit.", |
844
|
|
|
) |
845
|
|
|
p.add_argument( |
846
|
|
|
'-u', "--untracked", |
847
|
|
|
action="store_true", |
848
|
|
|
help="Display all untracked files and exit.", |
849
|
|
|
) |
850
|
|
|
p.add_argument( |
851
|
|
|
"--pkg-name", |
852
|
|
|
action="store", |
853
|
|
|
default="unknown", |
854
|
|
|
help="Package name of the created package.", |
855
|
|
|
) |
856
|
|
|
p.add_argument( |
857
|
|
|
"--pkg-version", |
858
|
|
|
action="store", |
859
|
|
|
default="0.0", |
860
|
|
|
help="Package version of the created package.", |
861
|
|
|
) |
862
|
|
|
p.add_argument( |
863
|
|
|
"--pkg-build", |
864
|
|
|
action="store", |
865
|
|
|
default=0, |
866
|
|
|
help="Package build number of the created package.", |
867
|
|
|
) |
868
|
|
|
p.set_defaults(func='.main_package.execute') |
869
|
|
|
|
870
|
|
|
|
871
|
|
|
def configure_parser_remove(sub_parsers, name='remove'): |
872
|
|
|
help = "%s a list of packages from a specified conda environment." |
873
|
|
|
descr = dedent(help + """ |
874
|
|
|
|
875
|
|
|
This command will also remove any package that depends on any of the |
876
|
|
|
specified packages as well---unless a replacement can be found without |
877
|
|
|
that dependency. If you wish to skip this dependency checking and remove |
878
|
|
|
just the requested packages, add the '--force' option. Note however that |
879
|
|
|
this may result in a broken environment, so use this with caution. |
880
|
|
|
""") |
881
|
|
|
example = dedent(""" |
882
|
|
|
Examples: |
883
|
|
|
|
884
|
|
|
conda %s -n myenv scipy |
885
|
|
|
|
886
|
|
|
""") |
887
|
|
|
|
888
|
|
|
uninstall_help = "Alias for conda remove." |
889
|
|
|
if name == 'remove': |
890
|
|
|
p = sub_parsers.add_parser( |
891
|
|
|
name, |
892
|
|
|
formatter_class=RawDescriptionHelpFormatter, |
893
|
|
|
description=descr % name.capitalize(), |
894
|
|
|
help=help % name.capitalize(), |
895
|
|
|
epilog=example % name, |
896
|
|
|
add_help=False, |
897
|
|
|
) |
898
|
|
|
else: |
899
|
|
|
p = sub_parsers.add_parser( |
900
|
|
|
name, |
901
|
|
|
formatter_class=RawDescriptionHelpFormatter, |
902
|
|
|
description=uninstall_help, |
903
|
|
|
help=uninstall_help, |
904
|
|
|
epilog=example % name, |
905
|
|
|
add_help=False, |
906
|
|
|
) |
907
|
|
|
add_parser_help(p) |
908
|
|
|
add_parser_pscheck(p) |
909
|
|
|
|
910
|
|
|
add_parser_prefix(p) |
911
|
|
|
add_parser_channels(p) |
912
|
|
|
|
913
|
|
|
solver_mode_options = p.add_argument_group("Solver Mode Modifiers") |
914
|
|
|
solver_mode_options.add_argument( |
915
|
|
|
"--all", |
916
|
|
|
action="store_true", |
917
|
|
|
help="%s all packages, i.e., the entire environment." % name.capitalize(), |
918
|
|
|
) |
919
|
|
|
solver_mode_options.add_argument( |
920
|
|
|
"--features", |
921
|
|
|
action="store_true", |
922
|
|
|
help="%s features (instead of packages)." % name.capitalize(), |
923
|
|
|
) |
924
|
|
|
solver_mode_options.add_argument( |
925
|
|
|
"--force-remove", "--force", |
926
|
|
|
action="store_true", |
927
|
|
|
help="Forces removal of a package without removing packages that depend on it. " |
928
|
|
|
"Using this option will usually leave your environment in a broken and " |
929
|
|
|
"inconsistent state.", |
930
|
|
|
dest='force_remove', |
931
|
|
|
) |
932
|
|
|
solver_mode_options.add_argument( |
933
|
|
|
"--no-pin", |
934
|
|
|
action="store_true", |
935
|
|
|
dest='ignore_pinned', |
936
|
|
|
default=NULL, |
937
|
|
|
help="Ignore pinned file.", |
938
|
|
|
) |
939
|
|
|
add_parser_prune(solver_mode_options) |
940
|
|
|
|
941
|
|
|
add_parser_networking(p) |
942
|
|
|
add_output_and_prompt_options(p) |
943
|
|
|
|
944
|
|
|
p.add_argument( |
945
|
|
|
'package_names', |
946
|
|
|
metavar='package_name', |
947
|
|
|
action="store", |
948
|
|
|
nargs='*', |
949
|
|
|
help="Package names to %s from the environment." % name, |
950
|
|
|
) |
951
|
|
|
|
952
|
|
|
p.set_defaults(func='.main_remove.execute') |
953
|
|
|
|
954
|
|
|
|
955
|
|
View Code Duplication |
def configure_parser_run(sub_parsers): |
|
|
|
|
956
|
|
|
help = "Run an executable in a conda environment. [Experimental]" |
957
|
|
|
descr = help + dedent(""" |
958
|
|
|
|
959
|
|
|
Use '--' (double dash) to separate CLI flags for 'conda run' from CLI flags sent to |
960
|
|
|
the process being launched. |
961
|
|
|
|
962
|
|
|
Example usage: |
963
|
|
|
|
964
|
|
|
$ conda create -y -n my-python-2-env python=2 |
965
|
|
|
$ conda run -n my-python-2-env python -- --version |
966
|
|
|
""") |
967
|
|
|
|
968
|
|
|
epilog = dedent(""" |
969
|
|
|
""") |
970
|
|
|
|
971
|
|
|
p = sub_parsers.add_parser( |
972
|
|
|
'run', |
973
|
|
|
description=descr, |
974
|
|
|
help=help, |
975
|
|
|
epilog=epilog, |
976
|
|
|
) |
977
|
|
|
|
978
|
|
|
add_parser_prefix(p) |
979
|
|
|
p.add_argument( |
980
|
|
|
"-v", "--verbose", |
981
|
|
|
action=NullCountAction, |
982
|
|
|
help="Use once for info, twice for debug, three times for trace.", |
983
|
|
|
dest="verbosity", |
984
|
|
|
default=NULL, |
985
|
|
|
) |
986
|
|
|
|
987
|
|
|
p.add_argument( |
988
|
|
|
'executable_call', |
989
|
|
|
nargs=REMAINDER, |
990
|
|
|
help="Executable name, with additional arguments to be passed to the executable " |
991
|
|
|
"on invocation.", |
992
|
|
|
) |
993
|
|
|
p.set_defaults(func='.main_run.execute') |
994
|
|
|
|
995
|
|
|
|
996
|
|
|
def configure_parser_search(sub_parsers): |
997
|
|
|
descr = dedent("""Search for packages and display associated information. |
998
|
|
|
The input is a MatchSpec, a query language for conda packages. |
999
|
|
|
See examples below. |
1000
|
|
|
""") |
1001
|
|
|
|
1002
|
|
|
example = dedent(""" |
1003
|
|
|
Examples: |
1004
|
|
|
|
1005
|
|
|
Search for a specific package named 'scikit-learn': |
1006
|
|
|
|
1007
|
|
|
conda search scikit-learn |
1008
|
|
|
|
1009
|
|
|
Search for packages containing 'scikit' in the package name: |
1010
|
|
|
|
1011
|
|
|
conda search *scikit* |
1012
|
|
|
|
1013
|
|
|
Note that your shell may expand '*' before handing the command over to conda. |
1014
|
|
|
Therefore it is sometimes necessary to use single or double quotes around the query. |
1015
|
|
|
|
1016
|
|
|
conda search '*scikit' |
1017
|
|
|
conda search "*scikit*" |
1018
|
|
|
|
1019
|
|
|
Search for packages for 64-bit Linux (by default, packages for your current |
1020
|
|
|
platform are shown): |
1021
|
|
|
|
1022
|
|
|
conda search numpy[subdir=linux-64] |
1023
|
|
|
|
1024
|
|
|
Search for a specific version of a package: |
1025
|
|
|
|
1026
|
|
|
conda search 'numpy>=1.12' |
1027
|
|
|
|
1028
|
|
|
Search for a package on a specific channel |
1029
|
|
|
|
1030
|
|
|
conda search conda-forge::numpy |
1031
|
|
|
conda search 'numpy[channel=conda-forge, subdir=osx-64]' |
1032
|
|
|
""") |
1033
|
|
|
p = sub_parsers.add_parser( |
1034
|
|
|
'search', |
1035
|
|
|
description=descr, |
1036
|
|
|
help=descr, |
1037
|
|
|
epilog=example, |
1038
|
|
|
) |
1039
|
|
|
p.add_argument( |
1040
|
|
|
"--envs", |
1041
|
|
|
action="store_true", |
1042
|
|
|
help="Search all of the current user's environments. If run as Administrator " |
1043
|
|
|
"(on Windows) or UID 0 (on unix), search all known environments on the system.", |
1044
|
|
|
) |
1045
|
|
|
p.add_argument( |
1046
|
|
|
'-i', "--info", |
1047
|
|
|
action="store_true", |
1048
|
|
|
help="Provide detailed information about each package." |
1049
|
|
|
) |
1050
|
|
|
p.add_argument( |
1051
|
|
|
'--subdir', '--platform', |
1052
|
|
|
action='store', |
1053
|
|
|
dest='subdir', |
1054
|
|
|
help="Search the given subdir. Should be formatted like 'osx-64', 'linux-32', " |
1055
|
|
|
"'win-64', and so on. The default is to search the current platform.", |
1056
|
|
|
default=NULL, |
1057
|
|
|
) |
1058
|
|
|
p.add_argument( |
1059
|
|
|
'match_spec', |
1060
|
|
|
default='*', |
1061
|
|
|
nargs='?', |
1062
|
|
|
help=SUPPRESS, |
1063
|
|
|
) |
1064
|
|
|
|
1065
|
|
|
p.add_argument( |
1066
|
|
|
"--canonical", |
1067
|
|
|
action="store_true", |
1068
|
|
|
help=SUPPRESS, |
1069
|
|
|
) |
1070
|
|
|
p.add_argument( |
1071
|
|
|
'-f', "--full-name", |
1072
|
|
|
action="store_true", |
1073
|
|
|
help=SUPPRESS, |
1074
|
|
|
) |
1075
|
|
|
p.add_argument( |
1076
|
|
|
"--names-only", |
1077
|
|
|
action="store_true", |
1078
|
|
|
help=SUPPRESS, |
1079
|
|
|
) |
1080
|
|
|
add_parser_known(p) |
1081
|
|
|
p.add_argument( |
1082
|
|
|
'-o', "--outdated", |
1083
|
|
|
action="store_true", |
1084
|
|
|
help=SUPPRESS, |
1085
|
|
|
) |
1086
|
|
|
p.add_argument( |
1087
|
|
|
"--spec", |
1088
|
|
|
action="store_true", |
1089
|
|
|
help=SUPPRESS, |
1090
|
|
|
) |
1091
|
|
|
p.add_argument( |
1092
|
|
|
"--reverse-dependency", |
1093
|
|
|
action="store_true", |
1094
|
|
|
# help="Perform a reverse dependency search. Use 'conda search package --info' " |
1095
|
|
|
# "to see the dependencies of a package.", |
1096
|
|
|
help=SUPPRESS, # TODO: re-enable once we have --reverse-dependency working again |
1097
|
|
|
) |
1098
|
|
|
|
1099
|
|
|
add_parser_channels(p) |
1100
|
|
|
add_parser_networking(p) |
1101
|
|
|
add_parser_json(p) |
1102
|
|
|
p.set_defaults(func='.main_search.execute') |
1103
|
|
|
|
1104
|
|
|
|
1105
|
|
|
def configure_parser_update(sub_parsers, name='update'): |
1106
|
|
|
help = "Updates conda packages to the latest compatible version." |
1107
|
|
|
descr = dedent(help + """ |
1108
|
|
|
|
1109
|
|
|
This command accepts a list of package names and updates them to the latest |
1110
|
|
|
versions that are compatible with all other packages in the environment. |
1111
|
|
|
|
1112
|
|
|
Conda attempts to install the newest versions of the requested packages. To |
1113
|
|
|
accomplish this, it may update some packages that are already installed, or |
1114
|
|
|
install additional packages. To prevent existing packages from updating, |
1115
|
|
|
use the --no-update-deps option. This may force conda to install older |
1116
|
|
|
versions of the requested packages, and it does not prevent additional |
1117
|
|
|
dependency packages from being installed. |
1118
|
|
|
""") |
1119
|
|
|
example = dedent(""" |
1120
|
|
|
Examples: |
1121
|
|
|
|
1122
|
|
|
conda %s -n myenv scipy |
1123
|
|
|
|
1124
|
|
|
""") |
1125
|
|
|
|
1126
|
|
|
alias_help = "Alias for conda update." |
1127
|
|
|
if name == 'update': |
1128
|
|
|
p = sub_parsers.add_parser( |
1129
|
|
|
'update', |
1130
|
|
|
description=descr, |
1131
|
|
|
help=help, |
1132
|
|
|
epilog=example % name, |
1133
|
|
|
) |
1134
|
|
|
else: |
1135
|
|
|
p = sub_parsers.add_parser( |
1136
|
|
|
name, |
1137
|
|
|
description=alias_help, |
1138
|
|
|
help=alias_help, |
1139
|
|
|
epilog=example % name, |
1140
|
|
|
) |
1141
|
|
|
solver_mode_options, package_install_options = add_parser_create_install_update(p) |
1142
|
|
|
|
1143
|
|
|
add_parser_prune(solver_mode_options) |
1144
|
|
|
solver_mode_options.add_argument( |
1145
|
|
|
"--force-reinstall", |
1146
|
|
|
action="store_true", |
1147
|
|
|
default=NULL, |
1148
|
|
|
help="Ensure that any user-requested package for the current operation is uninstalled and " |
1149
|
|
|
"reinstalled, even if that package already exists in the environment.", |
1150
|
|
|
) |
1151
|
|
|
add_parser_update_modifiers(solver_mode_options) |
1152
|
|
|
|
1153
|
|
|
package_install_options.add_argument( |
1154
|
|
|
"--clobber", |
1155
|
|
|
action="store_true", |
1156
|
|
|
default=NULL, |
1157
|
|
|
help="Allow clobbering of overlapping file paths within packages, " |
1158
|
|
|
"and suppress related warnings.", |
1159
|
|
|
) |
1160
|
|
|
p.set_defaults(func='.main_update.execute') |
1161
|
|
|
|
1162
|
|
|
|
1163
|
|
|
# ############################################################################################# |
1164
|
|
|
# |
1165
|
|
|
# parser helpers |
1166
|
|
|
# |
1167
|
|
|
# ############################################################################################# |
1168
|
|
|
|
1169
|
|
|
def add_parser_create_install_update(p): |
1170
|
|
|
add_parser_prefix(p) |
1171
|
|
|
add_parser_channels(p) |
1172
|
|
|
solver_mode_options = add_parser_solver_mode(p) |
1173
|
|
|
package_install_options = add_parser_package_install_options(p) |
1174
|
|
|
add_parser_networking(p) |
1175
|
|
|
|
1176
|
|
|
output_and_prompt_options = add_output_and_prompt_options(p) |
1177
|
|
|
output_and_prompt_options.add_argument( |
1178
|
|
|
"--download-only", |
1179
|
|
|
action="store_true", |
1180
|
|
|
default=NULL, |
1181
|
|
|
help="Solve an environment and ensure package caches are populated, but exit " |
1182
|
|
|
"prior to unlinking and linking packages into the prefix.", |
1183
|
|
|
) |
1184
|
|
|
add_parser_show_channel_urls(output_and_prompt_options) |
1185
|
|
|
|
1186
|
|
|
add_parser_pscheck(p) |
1187
|
|
|
add_parser_known(p) |
1188
|
|
|
|
1189
|
|
|
# Add the file kwarg. We don't use {action="store", nargs='*'} as we don't |
1190
|
|
|
# want to gobble up all arguments after --file. |
1191
|
|
|
p.add_argument( |
1192
|
|
|
"--file", |
1193
|
|
|
default=[], |
1194
|
|
|
action='append', |
1195
|
|
|
help="Read package versions from the given file. Repeated file " |
1196
|
|
|
"specifications can be passed (e.g. --file=file1 --file=file2).", |
1197
|
|
|
) |
1198
|
|
|
p.add_argument( |
1199
|
|
|
'packages', |
1200
|
|
|
metavar='package_spec', |
1201
|
|
|
action="store", |
1202
|
|
|
nargs='*', |
1203
|
|
|
help="Packages to install or update in the conda environment.", |
1204
|
|
|
) |
1205
|
|
|
|
1206
|
|
|
return solver_mode_options, package_install_options |
1207
|
|
|
|
1208
|
|
|
|
1209
|
|
|
def add_parser_pscheck(p): |
1210
|
|
|
p.add_argument( |
1211
|
|
|
"--force-pscheck", |
1212
|
|
|
action="store_true", |
1213
|
|
|
help=SUPPRESS |
1214
|
|
|
) |
1215
|
|
|
|
1216
|
|
|
|
1217
|
|
|
def add_parser_show_channel_urls(p): |
1218
|
|
|
p.add_argument( |
1219
|
|
|
"--show-channel-urls", |
1220
|
|
|
action="store_true", |
1221
|
|
|
dest="show_channel_urls", |
1222
|
|
|
default=NULL, |
1223
|
|
|
help="Show channel urls. " |
1224
|
|
|
"Overrides the value given by `conda config --show show_channel_urls`.", |
1225
|
|
|
) |
1226
|
|
|
p.add_argument( |
1227
|
|
|
"--no-show-channel-urls", |
1228
|
|
|
action="store_false", |
1229
|
|
|
dest="show_channel_urls", |
1230
|
|
|
help=SUPPRESS, |
1231
|
|
|
) |
1232
|
|
|
|
1233
|
|
|
|
1234
|
|
|
def add_parser_help(p): |
1235
|
|
|
""" |
1236
|
|
|
So we can use consistent capitalization and periods in the help. You must |
1237
|
|
|
use the add_help=False argument to ArgumentParser or add_parser to use |
1238
|
|
|
this. Add this first to be consistent with the default argparse output. |
1239
|
|
|
|
1240
|
|
|
""" |
1241
|
|
|
p.add_argument( |
1242
|
|
|
'-h', '--help', |
1243
|
|
|
action=_HelpAction, |
1244
|
|
|
help="Show this help message and exit.", |
1245
|
|
|
) |
1246
|
|
|
|
1247
|
|
|
|
1248
|
|
|
def add_parser_prefix(p): |
1249
|
|
|
target_environment_group = p.add_argument_group("Target Environment Specification") |
1250
|
|
|
npgroup = target_environment_group.add_mutually_exclusive_group() |
1251
|
|
|
npgroup.add_argument( |
1252
|
|
|
'-n', "--name", |
1253
|
|
|
action="store", |
1254
|
|
|
help="Name of environment.", |
1255
|
|
|
metavar="ENVIRONMENT", |
1256
|
|
|
) |
1257
|
|
|
npgroup.add_argument( |
1258
|
|
|
'-p', "--prefix", |
1259
|
|
|
action="store", |
1260
|
|
|
help="Full path to environment location (i.e. prefix).", |
1261
|
|
|
metavar='PATH', |
1262
|
|
|
) |
1263
|
|
|
|
1264
|
|
|
|
1265
|
|
|
def add_parser_json(p): |
1266
|
|
|
output_and_prompt_options = p.add_argument_group("Output, Prompt, and Flow Control Options") |
1267
|
|
|
output_and_prompt_options.add_argument( |
1268
|
|
|
"--debug", |
1269
|
|
|
action="store_true", |
1270
|
|
|
default=NULL, |
1271
|
|
|
help=SUPPRESS, |
1272
|
|
|
) |
1273
|
|
|
output_and_prompt_options.add_argument( |
1274
|
|
|
"--json", |
1275
|
|
|
action="store_true", |
1276
|
|
|
default=NULL, |
1277
|
|
|
help="Report all output as json. Suitable for using conda programmatically." |
1278
|
|
|
) |
1279
|
|
|
output_and_prompt_options.add_argument( |
1280
|
|
|
"-v", "--verbose", |
1281
|
|
|
action=NullCountAction, |
1282
|
|
|
help="Use once for info, twice for debug, three times for trace.", |
1283
|
|
|
dest="verbosity", |
1284
|
|
|
default=NULL, |
1285
|
|
|
) |
1286
|
|
|
output_and_prompt_options.add_argument( |
1287
|
|
|
'-q', "--quiet", |
1288
|
|
|
action="store_true", |
1289
|
|
|
default=NULL, |
1290
|
|
|
help="Do not display progress bar.", |
1291
|
|
|
) |
1292
|
|
|
return output_and_prompt_options |
1293
|
|
|
|
1294
|
|
|
|
1295
|
|
|
def add_output_and_prompt_options(p): |
1296
|
|
|
output_and_prompt_options = p.add_argument_group("Output, Prompt, and Flow Control Options") |
1297
|
|
|
output_and_prompt_options.add_argument( |
1298
|
|
|
"--debug", |
1299
|
|
|
action="store_true", |
1300
|
|
|
default=NULL, |
1301
|
|
|
help=SUPPRESS, |
1302
|
|
|
) |
1303
|
|
|
output_and_prompt_options.add_argument( |
1304
|
|
|
"--dry-run", |
1305
|
|
|
action="store_true", |
1306
|
|
|
help="Only display what would have been done.", |
1307
|
|
|
) |
1308
|
|
|
output_and_prompt_options.add_argument( |
1309
|
|
|
"--json", |
1310
|
|
|
action="store_true", |
1311
|
|
|
default=NULL, |
1312
|
|
|
help="Report all output as json. Suitable for using conda programmatically." |
1313
|
|
|
) |
1314
|
|
|
output_and_prompt_options.add_argument( |
1315
|
|
|
'-q', "--quiet", |
1316
|
|
|
action="store_true", |
1317
|
|
|
default=NULL, |
1318
|
|
|
help="Do not display progress bar.", |
1319
|
|
|
) |
1320
|
|
|
output_and_prompt_options.add_argument( |
1321
|
|
|
"-v", "--verbose", |
1322
|
|
|
action=NullCountAction, |
1323
|
|
|
help="Can be used multiple times. Once for INFO, twice for DEBUG, three times for TRACE.", |
1324
|
|
|
dest="verbosity", |
1325
|
|
|
default=NULL, |
1326
|
|
|
) |
1327
|
|
|
output_and_prompt_options.add_argument( |
1328
|
|
|
"-y", "--yes", |
1329
|
|
|
action="store_true", |
1330
|
|
|
default=NULL, |
1331
|
|
|
help="Do not ask for confirmation.", |
1332
|
|
|
) |
1333
|
|
|
return output_and_prompt_options |
1334
|
|
|
|
1335
|
|
|
|
1336
|
|
|
def add_parser_channels(p): |
1337
|
|
|
channel_customization_options = p.add_argument_group("Channel Customization") |
1338
|
|
|
channel_customization_options.add_argument( |
1339
|
|
|
'-c', '--channel', |
1340
|
|
|
dest='channel', # apparently conda-build uses this; someday rename to channels are remove context.channels alias to channel # NOQA |
1341
|
|
|
# TODO: if you ever change 'channel' to 'channels', make sure you modify the context.channels property accordingly # NOQA |
1342
|
|
|
action="append", |
1343
|
|
|
help="""Additional channel to search for packages. These are URLs searched in the order |
1344
|
|
|
they are given (including file:// for local directories). Then, the defaults |
1345
|
|
|
or channels from .condarc are searched (unless --override-channels is given). You can use |
1346
|
|
|
'defaults' to get the default packages for conda. You can also use any name and the |
1347
|
|
|
.condarc channel_alias value will be prepended. The default channel_alias |
1348
|
|
|
is http://conda.anaconda.org/.""", |
1349
|
|
|
) |
1350
|
|
|
channel_customization_options.add_argument( |
1351
|
|
|
"--use-local", |
1352
|
|
|
action="store_true", |
1353
|
|
|
default=NULL, |
1354
|
|
|
help="Use locally built packages. Identical to '-c local'.", |
1355
|
|
|
) |
1356
|
|
|
channel_customization_options.add_argument( |
1357
|
|
|
"--override-channels", |
1358
|
|
|
action="store_true", |
1359
|
|
|
help="""Do not search default or .condarc channels. Requires --channel.""", |
1360
|
|
|
) |
1361
|
|
|
return channel_customization_options |
1362
|
|
|
|
1363
|
|
|
|
1364
|
|
|
def add_parser_solver_mode(p): |
1365
|
|
|
solver_mode_options = p.add_argument_group("Solver Mode Modifiers") |
1366
|
|
|
deps_modifiers = solver_mode_options.add_mutually_exclusive_group() |
1367
|
|
|
solver_mode_options.add_argument( |
1368
|
|
|
"--channel-priority", |
1369
|
|
|
action="store_true", |
1370
|
|
|
dest="channel_priority", |
1371
|
|
|
default=NULL, |
1372
|
|
|
help=SUPPRESS, |
1373
|
|
|
) |
1374
|
|
|
solver_mode_options.add_argument( |
1375
|
|
|
"--no-channel-priority", |
1376
|
|
|
action="store_false", |
1377
|
|
|
dest="channel_priority", |
1378
|
|
|
default=NULL, |
1379
|
|
|
help="Package version takes precedence over channel priority. " |
1380
|
|
|
"Overrides the value given by `conda config --show channel_priority`." |
1381
|
|
|
) |
1382
|
|
|
deps_modifiers.add_argument( |
1383
|
|
|
"--no-deps", |
1384
|
|
|
action="store_const", |
1385
|
|
|
const=DepsModifier.NO_DEPS, |
1386
|
|
|
dest="deps_modifier", |
1387
|
|
|
help="Do not install, update, remove, or change dependencies. This WILL lead " |
1388
|
|
|
"to broken environments and inconsistent behavior. Use at your own risk.", |
1389
|
|
|
default=NULL, |
1390
|
|
|
) |
1391
|
|
|
deps_modifiers.add_argument( |
1392
|
|
|
"--only-deps", |
1393
|
|
|
action="store_const", |
1394
|
|
|
const=DepsModifier.ONLY_DEPS, |
1395
|
|
|
dest="deps_modifier", |
1396
|
|
|
help="Only install dependencies.", |
1397
|
|
|
default=NULL, |
1398
|
|
|
) |
1399
|
|
|
solver_mode_options.add_argument( |
1400
|
|
|
"--no-pin", |
1401
|
|
|
action="store_true", |
1402
|
|
|
dest='ignore_pinned', |
1403
|
|
|
default=NULL, |
1404
|
|
|
help="Ignore pinned file.", |
1405
|
|
|
) |
1406
|
|
|
return solver_mode_options |
1407
|
|
|
|
1408
|
|
|
|
1409
|
|
|
def add_parser_update_modifiers(solver_mode_options): |
1410
|
|
|
update_modifiers = solver_mode_options.add_mutually_exclusive_group() |
1411
|
|
|
update_modifiers.add_argument( |
1412
|
|
|
"--freeze-installed", "--no-update-deps", |
1413
|
|
|
action="store_const", |
1414
|
|
|
const=UpdateModifier.FREEZE_INSTALLED, |
1415
|
|
|
dest="update_modifier", |
1416
|
|
|
default=NULL, |
1417
|
|
|
help="Do not update or change already-installed dependencies.", |
1418
|
|
|
) |
1419
|
|
|
update_modifiers.add_argument( |
1420
|
|
|
"--update-deps", |
1421
|
|
|
action="store_const", |
1422
|
|
|
const=UpdateModifier.UPDATE_DEPS, |
1423
|
|
|
dest="update_modifier", |
1424
|
|
|
default=NULL, |
1425
|
|
|
help="Update dependencies.", |
1426
|
|
|
) |
1427
|
|
|
update_modifiers.add_argument( |
1428
|
|
|
"-S", "--satisfied-skip-solve", |
1429
|
|
|
action="store_const", |
1430
|
|
|
const=UpdateModifier.SPECS_SATISFIED_SKIP_SOLVE, |
1431
|
|
|
dest="update_modifier", |
1432
|
|
|
default=NULL, |
1433
|
|
|
help="Exit early and do not run the solver if the requested specs are satisfied. " |
1434
|
|
|
"Also skips aggressive updates as configured by 'aggressive_update_packages'. " |
1435
|
|
|
"Similar to the default behavior of 'pip install'.", |
1436
|
|
|
) |
1437
|
|
|
update_modifiers.add_argument( |
1438
|
|
|
"--update-all", "--all", |
1439
|
|
|
action="store_const", |
1440
|
|
|
const=UpdateModifier.UPDATE_ALL, |
1441
|
|
|
dest="update_modifier", |
1442
|
|
|
help="Update all installed packages in the environment.", |
1443
|
|
|
default=NULL, |
1444
|
|
|
) |
1445
|
|
|
|
1446
|
|
|
|
1447
|
|
|
def add_parser_prune(p): |
1448
|
|
|
p.add_argument( |
1449
|
|
|
"--prune", |
1450
|
|
|
action="store_true", |
1451
|
|
|
default=NULL, |
1452
|
|
|
help="Remove packages that have previously been brought into the environment to satisfy " |
1453
|
|
|
"dependencies of user-requested packages, but are no longer needed.", |
1454
|
|
|
) |
1455
|
|
|
|
1456
|
|
|
|
1457
|
|
|
def add_parser_networking(p): |
1458
|
|
|
networking_options = p.add_argument_group("Networking Options") |
1459
|
|
|
networking_options.add_argument( |
1460
|
|
|
"-C", "--use-index-cache", |
1461
|
|
|
action="store_true", |
1462
|
|
|
default=False, |
1463
|
|
|
help="Use cache of channel index files, even if it has expired.", |
1464
|
|
|
) |
1465
|
|
|
networking_options.add_argument( |
1466
|
|
|
"-k", "--insecure", |
1467
|
|
|
action="store_false", |
1468
|
|
|
dest="ssl_verify", |
1469
|
|
|
default=NULL, |
1470
|
|
|
help="Allow conda to perform \"insecure\" SSL connections and transfers. " |
1471
|
|
|
"Equivalent to setting 'ssl_verify' to 'false'." |
1472
|
|
|
) |
1473
|
|
|
networking_options.add_argument( |
1474
|
|
|
"--offline", |
1475
|
|
|
action='store_true', |
1476
|
|
|
default=NULL, |
1477
|
|
|
help="Offline mode. Don't connect to the Internet.", |
1478
|
|
|
) |
1479
|
|
|
return networking_options |
1480
|
|
|
|
1481
|
|
|
|
1482
|
|
|
def add_parser_package_install_options(p): |
1483
|
|
|
package_install_options = p.add_argument_group("Package Linking and Install-time Options") |
1484
|
|
|
package_install_options.add_argument( |
1485
|
|
|
'-f', "--force", |
1486
|
|
|
action="store_true", |
1487
|
|
|
default=NULL, |
1488
|
|
|
help=SUPPRESS, |
1489
|
|
|
) |
1490
|
|
|
package_install_options.add_argument( |
1491
|
|
|
'--copy', |
1492
|
|
|
action="store_true", |
1493
|
|
|
default=NULL, |
1494
|
|
|
help="Install all packages using copies instead of hard- or soft-linking." |
1495
|
|
|
) |
1496
|
|
|
if on_win: |
1497
|
|
|
package_install_options.add_argument( |
1498
|
|
|
"--shortcuts", |
1499
|
|
|
action="store_true", |
1500
|
|
|
help=SUPPRESS, |
1501
|
|
|
dest="shortcuts", |
1502
|
|
|
default=NULL, |
1503
|
|
|
) |
1504
|
|
|
package_install_options.add_argument( |
1505
|
|
|
"--no-shortcuts", |
1506
|
|
|
action="store_false", |
1507
|
|
|
help="Don't install start menu shortcuts", |
1508
|
|
|
dest="shortcuts", |
1509
|
|
|
default=NULL, |
1510
|
|
|
) |
1511
|
|
|
return package_install_options |
1512
|
|
|
|
1513
|
|
|
|
1514
|
|
|
def add_parser_known(p): |
1515
|
|
|
p.add_argument( |
1516
|
|
|
"--unknown", |
1517
|
|
|
action="store_true", |
1518
|
|
|
default=False, |
1519
|
|
|
dest='unknown', |
1520
|
|
|
help=SUPPRESS, |
1521
|
|
|
) |
1522
|
|
|
|