'Invokes a command in an isolated environment.  The arguments are
forwarded directly to the command line script, the `extra` keyword
arguments are passed to the :meth:`~clickpkg.Command.main` function of
the command.
This returns a :class:`Result` object.
.. versionadded:: 3.0
The ``catch_exceptions`` parameter was added.
.. versionchanged:: 3.0
The result object now has an `exc_info` attribute with the
traceback if available.
.. versionadded:: 4.0
The ``color`` parameter was added.
:param cli: the command to invoke
:param args: the arguments to invoke. It may be given as an iterable
or a string. When given as string it will be interpreted
as a Unix shell command. More details at
:func:`shlex.split`.
:param input: the input data for `sys.stdin`.
:param env: the environment overrides.
:param catch_exceptions: Whether to catch any other exceptions than
``SystemExit``.
:param extra: the keyword arguments to pass to :meth:`main`.
:param color: whether the output should contain color codes. The
application can still override this explicitly.'

def invoke(self, cli, args=None, input=None, env=None, catch_exceptions=True, color=False, **extra):

    exc_info = None
    with self.isolation(input=input, env=env, color=color) as out:
        exception = None
        exit_code = 0
        if isinstance(args, string_types):
            args = shlex.split(args)
        try:
            cli.main(args=(args or ()), prog_name=self.get_default_prog_name(cli), **extra)
        except SystemExit as e:
            exc_info = sys.exc_info()
            exit_code = e.code
            if (exit_code is None):
                exit_code = 0
            if (exit_code != 0):
                exception = e
            if (not isinstance(exit_code, int)):
                sys.stdout.write(str(exit_code))
                sys.stdout.write('\n')
                exit_code = 1
        except Exception as e:
            if (not catch_exceptions):
                raise
            exception = e
            exit_code = 1
            exc_info = sys.exc_info()
        finally:
            sys.stdout.flush()
            output = out.getvalue()
    return Result(runner=self, output_bytes=output, exit_code=exit_code, exception=exception, exc_info=exc_info)
