# Copyright (C) 2012 Anaconda, Inc # SPDX-License-Identifier: BSD-3-Clause """Entry point for all conda subcommands.""" import sys from ..deprecations import deprecated @deprecated.argument( "24.3", "24.9", "context", addendum="The context is a global state, no need to pass it around.", ) def init_loggers(): import logging from ..base.context import context from ..gateways.logging import initialize_logging, set_log_level initialize_logging() # silence logging info to avoid interfering with JSON output if context.json: for logger in ("conda.stdout.verbose", "conda.stdoutlog", "conda.stderrlog"): logging.getLogger(logger).setLevel(logging.CRITICAL + 10) # set log_level set_log_level(context.log_level) @deprecated( "24.3", "24.9", addendum="Use `conda.cli.conda_argparse.generate_parser` instead.", ) def generate_parser(*args, **kwargs): """ Some code paths import this function directly from this module instead of from conda_argparse. We add the forwarder for backwards compatibility. """ from .conda_argparse import generate_parser return generate_parser(*args, **kwargs) def main_subshell(*args, post_parse_hook=None, **kwargs): """Entrypoint for the "subshell" invocation of CLI interface. E.g. `conda create`.""" # defer import here so it doesn't hit the 'conda shell.*' subcommands paths from ..base.context import context from .conda_argparse import do_call, generate_parser, generate_pre_parser args = args or ["--help"] pre_parser = generate_pre_parser(add_help=False) pre_args, _ = pre_parser.parse_known_args(args) # the arguments that we want to pass to the main parser later on override_args = { "json": pre_args.json, "debug": pre_args.debug, "trace": pre_args.trace, "verbosity": pre_args.verbosity, } context.__init__(argparse_args=pre_args) if context.no_plugins: context.plugin_manager.disable_external_plugins() # reinitialize in case any of the entrypoints modified the context context.__init__(argparse_args=pre_args) parser = generate_parser(add_help=True) args = parser.parse_args(args, override_args=override_args, namespace=pre_args) context.__init__(argparse_args=args) init_loggers() # used with main_pip.py if post_parse_hook: post_parse_hook(args, parser) exit_code = do_call(args, parser) if isinstance(exit_code, int): return exit_code elif hasattr(exit_code, "rc"): return exit_code.rc def main_sourced(shell, *args, **kwargs): """Entrypoint for the "sourced" invocation of CLI interface. E.g. `conda activate`.""" shell = shell.replace("shell.", "", 1) # This is called any way later in conda.activate, so no point in removing it from ..base.context import context context.__init__() from ..activate import _build_activator_cls try: activator_cls = _build_activator_cls(shell) except KeyError: from ..exceptions import CondaError raise CondaError("%s is not a supported shell." % shell) activator = activator_cls(args) print(activator.execute(), end="") return 0 def main(*args, **kwargs): # conda.common.compat contains only stdlib imports from ..common.compat import ensure_text_type from ..exception_handler import conda_exception_handler # cleanup argv args = args or sys.argv[1:] # drop executable/script args = tuple(ensure_text_type(s) for s in args) if args and args[0].strip().startswith("shell."): main = main_sourced else: main = main_subshell return conda_exception_handler(main, *args, **kwargs)