Ejemplo n.º 1
0
def cmd(command, message=False, show_stderr=True, **kwargs):
    """ Run an arbitrary command.

    :param command: The entire command line to run.
    :param message: A custom message to display, or True (bool) to use a default.
    :param show_stderr: On error, display the contents of STDERR.
    :param kwargs: Any kwargs supported by subprocess.Popen
    :returns: CommandResultItem object.
    """
    from azdev.utilities import IS_WINDOWS, display

    # use default message if custom not provided
    if message is True:
        message = 'Running: {}\n'.format(command)

    if message:
        display(message)

    try:
        output = subprocess.check_output(
            command.split(),
            stderr=subprocess.STDOUT if show_stderr else None,
            shell=IS_WINDOWS,
            **kwargs).decode('utf-8').strip()
        return CommandResultItem(output, exit_code=0, error=None)
    except subprocess.CalledProcessError as err:
        return CommandResultItem(err.output,
                                 exit_code=err.returncode,
                                 error=err)
Ejemplo n.º 2
0
    def _run_job(self, expanded_arg, cmd_copy):
        params = self._filter_params(expanded_arg)
        try:
            result = cmd_copy(params)
            if cmd_copy.supports_no_wait and getattr(expanded_arg, 'no_wait',
                                                     False):
                result = None
            elif cmd_copy.no_wait_param and getattr(
                    expanded_arg, cmd_copy.no_wait_param, False):
                result = None

            transform_op = cmd_copy.command_kwargs.get('transform', None)
            if transform_op:
                result = transform_op(result)

            if _is_poller(result):
                result = LongRunningOperation(
                    cmd_copy.cli_ctx,
                    'Starting {}'.format(cmd_copy.name))(result)
            elif _is_paged(result):
                result = list(result)

            result = todict(result,
                            AzCliCommandInvoker.remove_additional_prop_layer)
            event_data = {'result': result}
            cmd_copy.cli_ctx.raise_event(EVENT_INVOKER_TRANSFORM_RESULT,
                                         event_data=event_data)
            return event_data['result']
        except Exception as ex:  # pylint: disable=broad-except
            if cmd_copy.exception_handler:
                cmd_copy.exception_handler(ex)
                return CommandResultItem(None, exit_code=1, error=ex)
            else:
                six.reraise(*sys.exc_info())
Ejemplo n.º 3
0
def shell_cmd(command, message=False, stderr=None, stdout=None, check=True, raise_ex=True, timeout=None,
              executable=None, capture_output=False):

    # use default message if custom not provided
    if message is True:
        message = '\nRunning: {}\n'.format(command)
    from . import display
    if message:
        display(message)

    try:
        output = subprocess.run(command,
                                stdout=subprocess.PIPE if capture_output else stdout,
                                stderr=subprocess.PIPE if capture_output else stderr,
                                check=check,
                                timeout=timeout,
                                executable=executable,
                                shell=True)
        if capture_output:
            return CommandResultItem(output.stdout.decode('utf-8').strip(), exit_code=0, error=None)
    except subprocess.CalledProcessError as err:
        if raise_ex:
            raise err
        logger.debug(err)
        raise CLIError("Command " + command + " failed. Trying running with --debug for more info")
    return None
Ejemplo n.º 4
0
    def test_out_table_no_query_yes_transformer_order(self):
        output_producer = OutputProducer(cli_ctx=self.mock_ctx)
        obj = {
            'name': 'qwerty',
            'val': '0b1f6472qwerty',
            'active': True,
            'sub': '0b1f6472'
        }

        def transformer(r):
            return OrderedDict([('Name', r['name']), ('Val', r['val']),
                                ('Active', r['active']), ('Sub', r['sub'])])

        result_item = CommandResultItem(obj,
                                        table_transformer=transformer,
                                        is_query_active=False)
        output_producer.out(result_item,
                            formatter=format_table,
                            out_file=self.io)
        # Should be table transformer order
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""Name    Val             Active    Sub
------  --------------  --------  --------
qwerty  0b1f6472qwerty  True      0b1f6472
"""))
Ejemplo n.º 5
0
def _combine_command_result(cli_result, ext_result):

    final_result = CommandResultItem(None)

    def apply_result(item):
        if item:
            final_result.exit_code += item.exit_code
            if item.error:
                if final_result.error:
                    try:
                        final_result.error.message += item.error.message
                    except AttributeError:
                        final_result.error.message += str(item.error)
                else:
                    final_result.error = item.error
                    setattr(final_result.error, 'message', '')
            if item.result:
                if final_result.result:
                    final_result.result += item.result
                else:
                    final_result.result = item.result

    apply_result(cli_result)
    apply_result(ext_result)
    return final_result
Ejemplo n.º 6
0
 def execute(self, args):
     try:
         return super(EgorInvoker, self).execute(args)
     except TypeError as e:
         from knack.log import get_logger
         logger = get_logger(__name__)
         logger.error('Could not execute egor command ', e)
         return CommandResultItem(None, exit_code=0)
Ejemplo n.º 7
0
    def test_output_format_ordereddict_list_not_sorted(self):
        obj1 = OrderedDict()
        obj1['B'] = 1
        obj1['A'] = 2

        obj2 = OrderedDict()
        obj2['A'] = 3
        obj2['B'] = 4
        result = format_tsv(CommandResultItem([obj1, obj2]))
        self.assertEqual(result, '1\t2\n3\t4\n')
Ejemplo n.º 8
0
    def test_out_table_list_of_lists(self):
        output_producer = OutputProducer(formatter=format_table, file=self.io)
        obj = [['a', 'b'], ['c', 'd']]
        output_producer.out(CommandResultItem(obj))
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""Column1    Column2
---------  ---------
a          b
c          d
"""))
Ejemplo n.º 9
0
    def test_out_table(self):
        output_producer = OutputProducer(formatter=format_table, file=self.io)
        obj = OrderedDict()
        obj['active'] = True
        obj['val'] = '0b1f6472'
        output_producer.out(CommandResultItem(obj))
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""Active    Val
--------  --------
True      0b1f6472
"""))
Ejemplo n.º 10
0
    def test_out_table_with_number(self):
        output_producer = OutputProducer(cli_ctx=self.mock_ctx)
        obj = OrderedDict()
        obj['Sku'] = '6.10'
        output_producer.out(CommandResultItem(obj),
                            formatter=format_table,
                            out_file=self.io)
        self.assertEqual(normalize_newlines(self.io.getvalue()),
                         normalize_newlines("""Sku
-----
6.10
"""))
Ejemplo n.º 11
0
    def test_out_yaml_non_ASCII(self):
        output_producer = OutputProducer(cli_ctx=self.mock_ctx)
        output_producer.out(CommandResultItem({
            'active': True,
            'contents': 'こんにちは'
        }),
                            formatter=format_yaml,
                            out_file=self.io)
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""active: true
contents: こんにちは
"""))
Ejemplo n.º 12
0
    def test_out_yaml_byte(self):
        output_producer = OutputProducer(cli_ctx=self.mock_ctx)
        output_producer.out(CommandResultItem({
            'active': True,
            'contents': b'0b1f6472'
        }),
                            formatter=format_yaml,
                            out_file=self.io)
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""active: true
contents: !!binary |
  MGIxZjY0NzI=
"""))
Ejemplo n.º 13
0
    def execute(self, args):
        try:
            return super(SFInvoker, self).execute(args)

        # For exceptions happening while handling http requests, FabricErrorException is thrown with
        # 'Internal Server Error' message, but here we handle the case where gateway is unable
        # to find the service.
        except TypeError:
            if args[0] == 'events':
                from knack.log import get_logger
                logger = get_logger(__name__)
                logger.error('Service is not installed.')
                return CommandResultItem(None, exit_code=0)
            raise
Ejemplo n.º 14
0
    def test_out_json_byte_empty(self):
        output_producer = OutputProducer(formatter=format_json, file=self.io)
        output_producer.out(
            CommandResultItem({
                'active': True,
                'contents': b''
            }))
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""{
  "active": true,
  "contents": ""
}
"""))
Ejemplo n.º 15
0
    def test_out_table_complex_obj(self):
        output_producer = OutputProducer(formatter=format_table, file=self.io)
        obj = OrderedDict()
        obj['name'] = 'qwerty'
        obj['val'] = '0b1f6472qwerty'
        obj['sub'] = {'1'}
        result_item = CommandResultItem(obj)
        output_producer.out(result_item)
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""Name    Val
------  --------------
qwerty  0b1f6472qwerty
"""))
Ejemplo n.º 16
0
    def test_out_json_from_ordered_dict(self):
        # The JSON output when the input is OrderedDict should be serialized to JSON
        output_producer = OutputProducer(formatter=format_json, file=self.io)
        output_producer.out(
            CommandResultItem(OrderedDict({
                'active': True,
                'id': '0b1f6472'
            })))
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""{
  "active": true,
  "id": "0b1f6472"
}
"""))
Ejemplo n.º 17
0
    def test_out_yaml_valid(self):
        """
        Test Dict serialized to YAML
        """
        output_producer = OutputProducer(cli_ctx=self.mock_ctx)
        output_producer.out(CommandResultItem({
            'active': True,
            'id': '0b1f6472'
        }),
                            formatter=format_yaml,
                            out_file=self.io)
        self.assertEqual(normalize_newlines(self.io.getvalue()),
                         normalize_newlines("""active: true
id: 0b1f6472
"""))
Ejemplo n.º 18
0
    def test_out_table(self):
        output_producer = OutputProducer(cli_ctx=self.mock_ctx)
        obj = OrderedDict()
        obj['active'] = True
        obj['val'] = '0b1f6472'
        obj['lun'] = 0
        output_producer.out(CommandResultItem(obj),
                            formatter=format_table,
                            out_file=self.io)
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""Active    Lun    Val
--------  -----  --------
True      0      0b1f6472
"""))
Ejemplo n.º 19
0
    def test_out_json_byte(self):
        output_producer = OutputProducer(cli_ctx=self.mock_ctx)
        output_producer.out(CommandResultItem({
            'active': True,
            'contents': b'0b1f6472'
        }),
                            formatter=format_json,
                            out_file=self.io)
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""{
  "active": true,
  "contents": "0b1f6472"
}
"""))
Ejemplo n.º 20
0
    def test_out_json_valid(self):
        """
        The JSON output when the input is a dict should be the dict serialized to JSON
        """
        output_producer = OutputProducer(cli_ctx=self.mock_ctx)
        output_producer.out(CommandResultItem({
            'active': True,
            'id': '0b1f6472'
        }),
                            formatter=format_json,
                            out_file=self.io)
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""{
  "active": true,
  "id": "0b1f6472"
}
"""))
Ejemplo n.º 21
0
    def test_out_table_no_query_no_transformer_order(self):
        output_producer = OutputProducer(formatter=format_table, file=self.io)
        obj = {
            'name': 'qwerty',
            'val': '0b1f6472qwerty',
            'active': True,
            'sub': '0b1f6472'
        }
        result_item = CommandResultItem(obj,
                                        table_transformer=None,
                                        is_query_active=False)
        output_producer.out(result_item)
        # Should be alphabetical order as no table transformer and query is not active.
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""Active    Name    Sub       Val
--------  ------  --------  --------------
True      qwerty  0b1f6472  0b1f6472qwerty
"""))
Ejemplo n.º 22
0
def _combine_command_result(cli_result, ext_result):

    final_result = CommandResultItem(None)

    def apply_result(item):
        if item:
            final_result.exit_code += item.exit_code
            if item.error:
                if final_result.error:
                    final_result.error.message += item.error.message
                else:
                    final_result.error = item.error
            if item.result:
                if final_result.result:
                    final_result.result += item.result
                else:
                    final_result.result = item.result
    apply_result(cli_result)
    apply_result(ext_result)
    return final_result
Ejemplo n.º 23
0
    def test_out_table_no_query_yes_jmespath_table_transformer(self):
        output_producer = OutputProducer(formatter=format_table, file=self.io)
        obj = {
            'name': 'qwerty',
            'val': '0b1f6472qwerty',
            'active': True,
            'sub': '0b1f6472'
        }

        result_item = CommandResultItem(
            obj,
            table_transformer='{Name:name, Val:val, Active:active}',
            is_query_active=False)
        output_producer.out(result_item)
        # Should be table transformer order
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""Name    Val             Active
------  --------------  --------
qwerty  0b1f6472qwerty  True
"""))
Ejemplo n.º 24
0
    def _run_job(self, expanded_arg, cmd_copy):
        params = self._filter_params(expanded_arg)
        try:
            result = cmd_copy(params)
            if cmd_copy.supports_no_wait and getattr(expanded_arg, 'no_wait',
                                                     False):
                result = None
            elif cmd_copy.no_wait_param and getattr(
                    expanded_arg, cmd_copy.no_wait_param, False):
                result = None

            transform_op = cmd_copy.command_kwargs.get('transform', None)
            if transform_op:
                result = transform_op(result)

            if _is_paged(result):
                result = list(result)

            result = todict(
                result, GraphCliCommandInvoker.remove_additional_prop_layer)

            # Formatting result so that non utf8 encoded characters are ignored.
            formatted_json = format_json({'result': result})
            result = json.loads(formatted_json)

            event_data = {'result': result}
            cmd_copy.cli_ctx.raise_event(EVENT_INVOKER_TRANSFORM_RESULT,
                                         event_data=event_data)
            return event_data['result']
        except Exception as ex:  # pylint: disable=broad-except
            if isinstance(ex, HttpResponseError):
                if ex.status_code == 403:  # pylint: disable=no-member
                    self.handle_403()
                raise CLIError(ex.message) from ex  # pylint: disable=no-member
            if isinstance(ex, AuthenticationException):
                self.handle_auth_error(ex)
            if cmd_copy.exception_handler:
                cmd_copy.exception_handler(ex)
                return CommandResultItem(None, exit_code=1, error=ex)
            six.reraise(*sys.exc_info())
Ejemplo n.º 25
0
    def test_out_table(self):
        output_producer = OutputProducer(cli_ctx=self.mock_ctx)

        obj1 = OrderedDict()
        obj1['active'] = True
        obj1['val'] = '0b1f6472'
        obj1['lun'] = 0

        obj2 = OrderedDict()
        obj2['active'] = False
        obj2['val'] = '0b1f6485'
        obj2['lun'] = 0

        output_producer.out(CommandResultItem([obj1, obj2]),
                            formatter=format_table,
                            out_file=self.io)
        self.assertEqual(
            normalize_newlines(self.io.getvalue()),
            normalize_newlines("""Active    Val    Lun
--------  --------  -----
True      0b1f6472  0
False     0b1f6485  0
"""))
Ejemplo n.º 26
0
    def test_yaml_output_with_ordered_dict(self):
        from azure.cli.core._output import AzOutputProducer
        from azure.cli.core.mock import DummyCli
        from knack.util import CommandResultItem
        from collections import OrderedDict
        import yaml

        account_dict = {
            "environmentName": "AzureCloud",
            "id": "000000-000000",
            "isDefault": True,
            "name": "test_sub",
            "state": "Enabled",
            "tenantId": "000000-000000-000000",
            "user": {
                "name": "*****@*****.**",
                "type": "user"
            }
        }

        output_producer = AzOutputProducer(DummyCli())
        yaml_output = output_producer.format_yaml(CommandResultItem(result=OrderedDict(account_dict)))
        self.assertEqual(account_dict, yaml.safe_load(yaml_output))
Ejemplo n.º 27
0
 def test_output_format_ordereddict_not_sorted(self):
     obj = OrderedDict()
     obj['B'] = 1
     obj['A'] = 2
     result = format_tsv(CommandResultItem(obj))
     self.assertEqual(result, '1\t2\n')
Ejemplo n.º 28
0
 def test_output_format_dict_sort(self):
     obj = {}
     obj['B'] = 1
     obj['A'] = 2
     result = format_tsv(CommandResultItem(obj))
     self.assertEqual(result, '2\t1\n')
Ejemplo n.º 29
0
    def execute(self, args):
        from knack.events import (
            EVENT_INVOKER_PRE_CMD_TBL_CREATE,
            EVENT_INVOKER_POST_CMD_TBL_CREATE, EVENT_INVOKER_CMD_TBL_LOADED,
            EVENT_INVOKER_PRE_PARSE_ARGS, EVENT_INVOKER_POST_PARSE_ARGS,
            EVENT_INVOKER_TRANSFORM_RESULT, EVENT_INVOKER_FILTER_RESULT)
        from knack.util import CommandResultItem, todict
        from azure.cli.core.commands.events import EVENT_INVOKER_PRE_CMD_TBL_TRUNCATE

        # TODO: Can't simply be invoked as an event because args are transformed
        args = _pre_command_table_create(self.cli_ctx, args)

        self.cli_ctx.raise_event(EVENT_INVOKER_PRE_CMD_TBL_CREATE, args=args)
        self.commands_loader.load_command_table(args)
        self.cli_ctx.raise_event(
            EVENT_INVOKER_PRE_CMD_TBL_TRUNCATE,
            load_cmd_tbl_func=self.commands_loader.load_command_table,
            args=args)
        command = self._rudimentary_get_command(args)
        telemetry.set_raw_command_name(command)

        try:
            self.commands_loader.command_table = {
                command: self.commands_loader.command_table[command]
            }
        except KeyError:
            # Trim down the command table to reduce the number of subparsers required to optimize the performance.
            #
            # When given a command table like this:
            #
            # network application-gateway create
            # network application-gateway delete
            # network list-usages
            # storage account create
            # storage account list
            #
            # input:  az
            # output: network application-gateway create
            #         storage account create
            #
            # input:  az network
            # output: network application-gateway create
            #         network list-usages

            cmd_table = {}
            group_names = set()
            for cmd_name, cmd in self.commands_loader.command_table.items():
                if command and not cmd_name.startswith(command):
                    continue

                cmd_stub = cmd_name[len(command):].strip()
                group_name = cmd_stub.split(' ', 1)[0]
                if group_name not in group_names:
                    cmd_table[cmd_name] = cmd
                    group_names.add(group_name)
                self.commands_loader.command_table = cmd_table

        self.commands_loader.command_table = self.commands_loader.command_table  # update with the truncated table
        self.commands_loader.command_name = command
        self.commands_loader.load_arguments(command)
        self.cli_ctx.raise_event(EVENT_INVOKER_POST_CMD_TBL_CREATE,
                                 cmd_tbl=self.commands_loader.command_table)
        self.parser.cli_ctx = self.cli_ctx
        self.parser.load_command_table(self.commands_loader.command_table)

        self.cli_ctx.raise_event(EVENT_INVOKER_CMD_TBL_LOADED,
                                 cmd_tbl=self.commands_loader.command_table,
                                 parser=self.parser)

        if not args:
            self.cli_ctx.completion.enable_autocomplete(self.parser)
            subparser = self.parser.subparsers[tuple()]
            self.help.show_welcome(subparser)

            # TODO: No event in base with which to target
            telemetry.set_command_details('az')
            telemetry.set_success(summary='welcome')
            return None

        if args[0].lower() == 'help':
            args[0] = '--help'

        self.cli_ctx.completion.enable_autocomplete(self.parser)

        self.cli_ctx.raise_event(EVENT_INVOKER_PRE_PARSE_ARGS, args=args)
        parsed_args = self.parser.parse_args(args)
        self.cli_ctx.raise_event(EVENT_INVOKER_POST_PARSE_ARGS,
                                 command=parsed_args.command,
                                 args=parsed_args)

        # TODO: This fundamentally alters the way Knack.invocation works here. Cannot be customized
        # with an event. Would need to be customized via inheritance.
        results = []
        for expanded_arg in _explode_list_args(parsed_args):
            cmd = expanded_arg.func
            if hasattr(expanded_arg, 'cmd'):
                expanded_arg.cmd = cmd

            self.cli_ctx.data['command'] = expanded_arg.command

            self._validation(expanded_arg)

            params = self._filter_params(expanded_arg)

            command_source = self.commands_loader.command_table[
                command].command_source

            extension_version = None
            try:
                if command_source:
                    extension_version = get_extension(
                        command_source.extension_name).version
            except Exception:  # pylint: disable=broad-except
                pass

            telemetry.set_command_details(
                self.cli_ctx.data['command'],
                self.data['output'],
                [(p.split('=', 1)[0] if p.startswith('--') else p[:2])
                 for p in args if (p.startswith('-') and len(p) > 1)],
                extension_name=command_source.extension_name
                if command_source else None,
                extension_version=extension_version)
            if command_source:
                self.data[
                    'command_extension_name'] = command_source.extension_name

            try:
                result = cmd(params)
                if cmd.supports_no_wait and getattr(expanded_arg, 'no_wait',
                                                    False):
                    result = None
                elif cmd.no_wait_param and getattr(expanded_arg,
                                                   cmd.no_wait_param, False):
                    result = None

                # TODO: Not sure how to make this actually work with the TRANSFORM event...
                transform_op = cmd.command_kwargs.get('transform', None)
                if transform_op:
                    result = transform_op(result)

                if _is_poller(result):
                    result = LongRunningOperation(
                        self.cli_ctx, 'Starting {}'.format(cmd.name))(result)
                elif _is_paged(result):
                    result = list(result)

                result = todict(result)
                event_data = {'result': result}
                self.cli_ctx.raise_event(EVENT_INVOKER_TRANSFORM_RESULT,
                                         event_data=event_data)
                self.cli_ctx.raise_event(EVENT_INVOKER_FILTER_RESULT,
                                         event_data=event_data)
                result = event_data['result']
                results.append(result)

            except Exception as ex:  # pylint: disable=broad-except
                if cmd.exception_handler:
                    cmd.exception_handler(ex)
                    return None
                else:
                    six.reraise(*sys.exc_info())

        if results and len(results) == 1:
            results = results[0]

        return CommandResultItem(
            results,
            table_transformer=self.commands_loader.command_table[
                parsed_args.command].table_transformer,
            is_query_active=self.data['query_active'])
Ejemplo n.º 30
0
    def parse(self, args, initial_invocation_data=None, out_file=None):
        """ Invoke a command.

        :param args: The arguments that represent the command
        :type args: list, tuple
        :param initial_invocation_data: Prime the in memory collection of key-value data for this invocation.
        :type initial_invocation_data: dict
        :param out_file: The file to send output to. If not used, we use out_file for knack.cli.CLI instance
        :type out_file: file-like object
        :return: The exit code of the invocation
        :rtype: int
        """
        from knack.util import CommandResultItem

        if not isinstance(args, (list, tuple)):
            raise TypeError('args should be a list or tuple.')
        exit_code = 0
        try:
            if self.enable_color:
                import colorama
                colorama.init()
                if self.out_file == sys.__stdout__:
                    # point out_file to the new sys.stdout which is overwritten by colorama
                    self.out_file = sys.stdout

            args = self.completion.get_completion_args() or args
            out_file = out_file or self.out_file

            self.logging.configure(args)
            logger.debug('Command arguments: %s', args)

            self.raise_event(EVENT_CLI_PRE_EXECUTE)
            if CLI._should_show_version(args):
                self.show_version()
                self.result = CommandResultItem(None)
            else:
                self.invocation = self.invocation_cls(
                    cli_ctx=self,
                    parser_cls=self.parser_cls,
                    commands_loader_cls=self.commands_loader_cls,
                    help_cls=self.help_cls,
                    initial_data=initial_invocation_data)
                cmd_result = self.invocation.execute(args)
                self.result = cmd_result
                exit_code = self.result.exit_code
                output_type = self.invocation.data['output']
                if cmd_result and cmd_result.result is not None:
                    formatter = self.output.get_formatter(output_type)
                    self.output.out(cmd_result,
                                    formatter=formatter,
                                    out_file=out_file)

                # print(self.invocation.expanded_arg, self.invocation.cmd_copy)
        except KeyboardInterrupt as ex:
            exit_code = 1
            self.result = CommandResultItem(None,
                                            error=ex,
                                            exit_code=exit_code)
        except Exception as ex:  # pylint: disable=broad-except
            exit_code = self.exception_handler(ex)
            self.result = CommandResultItem(None,
                                            error=ex,
                                            exit_code=exit_code)
        except SystemExit as ex:
            exit_code = ex.code
            self.result = CommandResultItem(None,
                                            error=ex,
                                            exit_code=exit_code)
            raise ex
        finally:
            self.raise_event(EVENT_CLI_POST_EXECUTE)

            if self.enable_color:
                colorama.deinit()

        return exit_code