Execute main CLI logic, based on ``argv``. :param argv: The arguments to execute against. May be ``None``, a list of strings, or a string. See `.normalize_argv` for details. :param bool exit: When ``False`` (default: ``True``), will igno
(self, argv: Optional[List[str]] = None, exit: bool = True)
| 353 | self.config.merge() |
| 354 | |
| 355 | def run(self, argv: Optional[List[str]] = None, exit: bool = True) -> None: |
| 356 | """ |
| 357 | Execute main CLI logic, based on ``argv``. |
| 358 | |
| 359 | :param argv: |
| 360 | The arguments to execute against. May be ``None``, a list of |
| 361 | strings, or a string. See `.normalize_argv` for details. |
| 362 | |
| 363 | :param bool exit: |
| 364 | When ``False`` (default: ``True``), will ignore `.ParseError`, |
| 365 | `.Exit` and `.Failure` exceptions, which otherwise trigger calls to |
| 366 | `sys.exit`. |
| 367 | |
| 368 | .. note:: |
| 369 | This is mostly a concession to testing. If you're setting this |
| 370 | to ``False`` in a production setting, you should probably be |
| 371 | using `.Executor` and friends directly instead! |
| 372 | |
| 373 | .. versionadded:: 1.0 |
| 374 | """ |
| 375 | try: |
| 376 | # Create an initial config, which will hold defaults & values from |
| 377 | # most config file locations (all but runtime.) Used to inform |
| 378 | # loading & parsing behavior. |
| 379 | self.create_config() |
| 380 | # Parse the given ARGV with our CLI parsing machinery, resulting in |
| 381 | # things like self.args (core args/flags), self.collection (the |
| 382 | # loaded namespace, which may be affected by the core flags) and |
| 383 | # self.tasks (the tasks requested for exec and their own |
| 384 | # args/flags) |
| 385 | self.parse_core(argv) |
| 386 | # Handle collection concerns including project config |
| 387 | self.parse_collection() |
| 388 | # Parse remainder of argv as task-related input |
| 389 | self.parse_tasks() |
| 390 | # End of parsing (typically bailout stuff like --list, --help) |
| 391 | self.parse_cleanup() |
| 392 | # Update the earlier Config with new values from the parse step - |
| 393 | # runtime config file contents and flag-derived overrides (e.g. for |
| 394 | # run()'s echo, warn, etc options.) |
| 395 | self.update_config() |
| 396 | # Create an Executor, passing in the data resulting from the prior |
| 397 | # steps, then tell it to execute the tasks. |
| 398 | self.execute() |
| 399 | except (UnexpectedExit, Exit, ParseError) as e: |
| 400 | debug("Received a possibly-skippable exception: {!r}".format(e)) |
| 401 | # Print error messages from parser, runner, etc if necessary; |
| 402 | # prevents messy traceback but still clues interactive user into |
| 403 | # problems. |
| 404 | if isinstance(e, ParseError): |
| 405 | print(e, file=sys.stderr) |
| 406 | if isinstance(e, Exit) and e.message: |
| 407 | print(e.message, file=sys.stderr) |
| 408 | if isinstance(e, UnexpectedExit) and e.result.hide: |
| 409 | print(e, file=sys.stderr, end="") |
| 410 | # Terminate execution unless we were told not to. |
| 411 | if exit: |
| 412 | if isinstance(e, UnexpectedExit): |
no test coverage detected