code: def main(args=sys.argv):
      """Main CLI entrypoint"""
      lgr.log(5, "Starting main(%r)", args)
      # record that we came in via the cmdline
      datalad.__api = "cmdline"
      completing = "_ARGCOMPLETE" in os.environ
      if completing and "COMP_LINE" in os.environ:
          import shlex
  
          # TODO support posix=False too?
          args = shlex.split(os.environ["COMP_LINE"]) or args
  
      if _on_msys_tainted_paths():
          # Possibly present DataLadRIs were stripped of a leading /
          from .helpers import _fix_datalad_ri
  
          args = [_fix_datalad_ri(s) for s in args]
  
      from datalad.support.entrypoints import load_extensions
  
      # load extensions requested by configuration
      # analog to what coreapi is doing for a Python session
      # importantly, load them prior to parser construction, such
      # that CLI tuning is also within reach for extensions
      load_extensions()
  
      # PYTHON_ARGCOMPLETE_OK
      # TODO possibly construct a dedicated parser just for autocompletion
      # rather than lobotomizing the normal one
      parser = setup_parser(args, completing=completing)
      try:
          import argcomplete
  
          argcomplete.autocomplete(parser)
      except ImportError:
          pass
  
      # parse cmd args
      lgr.debug("Parsing known args among %r", args)
      cmdlineargs, unparsed_args = parser.parse_known_args(args[1:])
      # did the parser tell us what command to run?
      has_func = (
          hasattr(cmdlineargs, "func") and cmdlineargs.func is not None
      )
      if unparsed_args:
          if has_func:
              lgr.error(
                  "unknown argument%s: %s",
                  "s" if len(unparsed_args) > 1 else "",
                  unparsed_args
                  if len(unparsed_args) > 1
                  else unparsed_args[0],
              )
              cmdlineargs.subparser.print_usage()
              sys.exit(1)
          else:
              # store all unparsed arguments
              cmdlineargs.datalad_unparsed_args = unparsed_args
  
      # pull config overrides from cmdline args and put in effect
      if cmdlineargs.cfg_overrides is not None:
          from .helpers import _parse_overrides_from_cmdline
  
          datalad.cfg.overrides.update(
              _parse_overrides_from_cmdline(cmdlineargs)
          )
          # enable overrides
          datalad.cfg.reload(force=True)
          # try loading extensions again, in case the configuration
          # added new ones to consider
          load_extensions()
  
      if "datalad.runtime.librarymode" in datalad.cfg:
          datalad.enable_librarymode()
  
      if cmdlineargs.change_path is not None:
          from datalad.utils import chpwd
  
          for path in cmdlineargs.change_path:
              chpwd(path)
  
      # check argparse could determine what commands needs to be executed
      if not has_func:
          # just let argparser spit out its error, since there is smth wrong
          parser.parse_args(args)
          # if that one didn't puke -- we should
          parser.print_usage()
          lgr.error("Please specify the command")
          # matches exit code for InsufficientArgumentsError
          sys.exit(2)
  
      _run(cmdlineargs)
  
file_path: datalad/datalad/cli/main.py
imports: import logging
  import os
  import sys
  import datalad
  from .parser import setup_parser
label_desc: Use image node_id 2 for calling a global function with example usage: main(args) without return types