예제 #1
0
def test_strip_ansi():
    assert strutils.strip_ansi(
        '\x1b[0m\x1b[1;36mart\x1b[46;34m\xdc') == 'art\xdc'
    assert strutils.strip_ansi(
        u'\x1b[0m\x1b[1;36mart\x1b[46;34m\xdc') == u'artÜ'
    assert strutils.strip_ansi(
        u'╒══════╕\n│ \x1b[1mCell\x1b[0m │\n╘══════╛') == (
            u'╒══════╕\n'
            u'│ Cell │\n'
            u'╘══════╛')
    assert strutils.strip_ansi(
        u'ls\r\n\x1B[00m\x1b[01;31mfile.zip\x1b[00m\r\n\x1b[01;31m') == \
        u'ls\r\nfile.zip\r\n'
    assert strutils.strip_ansi(
        u'\t\u001b[0;35mIP\u001b[0m\t\u001b[0;36m192.1.0.2\u001b[0m') == \
        u'\tIP\t192.1.0.2'
    assert strutils.strip_ansi(u'(╯°□°)╯︵ \x1b[1m┻━┻\x1b[0m') == (
        u'(╯°□°)╯︵ ┻━┻')
    assert strutils.strip_ansi('(╯°□°)╯︵ \x1b[1m┻━┻\x1b[0m') == (
        '(╯°□°)╯︵ ┻━┻')
    assert strutils.strip_ansi(
        b'(\xe2\x95\xaf\xc2\xb0\xe2\x96\xa1\xc2\xb0)\xe2\x95\xaf\xef\xb8'
        b'\xb5 \x1b[1m\xe2\x94\xbb\xe2\x94\x81\xe2\x94\xbb\x1b[0m') == (
            b'(\xe2\x95\xaf\xc2\xb0\xe2\x96\xa1\xc2\xb0)\xe2\x95\xaf\xef\xb8'
            b'\xb5 \xe2\x94\xbb\xe2\x94\x81\xe2\x94\xbb')
    assert strutils.strip_ansi(
        bytearray(u'(╯°□°)╯︵ \x1b[1m┻━┻\x1b[0m', 'utf-8')) == \
        bytearray(
            b'(\xe2\x95\xaf\xc2\xb0\xe2\x96\xa1\xc2\xb0)\xe2\x95\xaf\xef\xb8'
            b'\xb5 \xe2\x94\xbb\xe2\x94\x81\xe2\x94\xbb')
예제 #2
0
    def run(self, *args, dry_run=False):
        """ Run a shell command, return the output and keep error message.

        Removes ANSI escape codes, and returns ready-to-use strings.
        """
        # Serialize Path objects to strings.
        args = list(map(str, flatten(args)))
        args_str = click.style(' '.join(args), fg='white')
        logger.debug(f"► {args_str}")

        code = 0
        output = None
        error = None

        if not dry_run:
            code, output, error = run(*args)
        else:
            logger.warning("Dry-run: skip execution of command.")

        # Normalize messages.
        if error:
            error = strip_ansi(error)
            error = error if error else None
        if output:
            output = strip_ansi(output)
            output = output if output else None

        # Non-successful run.
        if code and error:
            # Produce an exception and eventually raise it.
            exception = CLIError(code, output, error)
            if self.raise_on_cli_error:
                raise exception
            # Accumulate errors.
            self.cli_errors.append(exception)

        # Log <stdout> and <stderr> output.
        if output:
            logger.debug(indent(output, '  '))
        if error:
            # Non-fatal error messages are logged as warnings.
            log_func = logger.error if code else logger.warning
            log_func(indent(error, '  '))

        return output
예제 #3
0
 def _deserialize(self, value, attr, data):
     out = super()._deserialize(value, attr, data)
     out = out.strip()
     if self.lower:
         out = out.lower()
     if strutils.html2text(out) != out:
         self.fail('invalid')
     elif strutils.strip_ansi(out) != out:
         self.fail('invalid')
     return out
예제 #4
0
    def check_manager_selection(result, selected=MANAGER_IDS):
        """ Check inclusion and exclusion of a set of managers.

        Check all manager are there by default.

        .. todo:

            Parametrize/fixturize signals to pin point output depending on
            subcommand.
        """
        assert isinstance(selected, (frozenset, set))

        found_managers = set()
        skipped_managers = set()

        for mid in MANAGER_IDS:

            # List of signals indicating a package manager has been retained by
            # the CLI. Roughly sorted from most specific to more forgiving.
            signals = [
                # Common "not found" warning message.
                "warning: Skip unavailable {} manager.".format(
                    mid) in result.stderr,
                # Common "not implemented" optional command warning message.
                bool(re.search(
                    r"warning: (Sync|Cleanup) not implemented for {}.".format(
                        mid), result.stderr)),
                # Stats line at the end of output.
                "{}: ".format(mid) in result.stdout.splitlines(
                    )[-1] if result.stdout else '',
                # Match output of managers command.
                bool(re.search(r"\s+│\s+{}\s+│\s+(✓|✘).+│\s+(✓|✘)".format(mid),
                               strip_ansi(result.stdout))),
                # Sync command.
                "Sync {} package info...".format(mid) in result.stderr,
                # Upgrade command.
                "Updating all outdated packages from {}...".format(
                    mid) in result.stderr,
                # Cleanup command.
                "Cleanup {}...".format(mid) in result.stderr,
                # Log message for backup command.
                "Dumping packages from {}...".format(mid) in result.stderr,
                # Restoring message.
                "Restore {} packages...".format(mid) in result.stderr,
                # Warning message for restore command.
                "warning: No [{}] section found.".format(mid) in result.stderr]

            if True in signals:
                found_managers.add(mid)
            else:
                skipped_managers.add(mid)

        # Compare managers reported by the CLI and those expected.
        assert found_managers == selected
        assert skipped_managers == MANAGER_IDS - selected
예제 #5
0
    def run(self, args, dry_run=False):
        """ Run a shell command, return the output and keep error message.

        Removes ANSI escape codes, and returns ready-to-use strings.
        """
        assert isinstance(args, list)
        logger.debug("Running `{}`...".format(' '.join(args)))

        code = 0
        output = None
        error = None

        if not dry_run:
            code, output, error = run(*args)
        else:
            logger.warning("Dry-run mode active: skip execution of command.")

        # Normalize messages.
        if error:
            error = strip_ansi(error)
            error = error if error else None
        if output:
            output = strip_ansi(output)
            output = output if output else None

        if code and error:
            exception = CLIError(code, output, error)
            if self.raise_on_cli_error:
                raise exception
            else:
                logger.error(error)
                self.cli_errors.append(exception)

        logger.debug(output)

        return output
예제 #6
0
    def sort_method(line):
        """ Serialize line's content for natural sorting.

        1. Extract each cell value in the order provided by `sort_order`;
        2. Strip terminal color formating;
        3. Then tokenize each cell's content for user-friendly natural sorting.
        """
        sorting_key = []
        for cell in itemgetter(*sort_order)(line):
            if isinstance(cell, TokenizedString):
                key = cell
            else:
                key = TokenizedString(strip_ansi(cell))
            sorting_key.append(key)
        return tuple(sorting_key)
예제 #7
0
def echo(msg, **kw):
    """A better-behaved :func:`print()` function for command-line applications.

    Writes text or bytes to a file or stream and flushes. Seamlessly
    handles stripping ANSI color codes when the output file is not a
    TTY.

      >>> echo('test')
      test

    Args:

      msg (str): A text or byte string to echo.
      err (bool): Set the default output file to ``sys.stderr``
      file (file): Stream or other file-like object to output
        to. Defaults to ``sys.stdout``, or ``sys.stderr`` if *err* is
        True.
      nl (bool): If ``True``, sets *end* to ``'\\n'``, the newline character.
      end (str): Explicitly set the line-ending character. Setting this overrides *nl*.
      color (bool): Set to ``True``/``False`` to always/never echo ANSI color
        codes. Defaults to inspecting whether *file* is a TTY.

    """
    msg = msg or ''
    if not isinstance(msg, (unicode, bytes)):
        msg = unicode(msg)
    is_err = kw.pop('err', False)
    _file = kw.pop('file', sys.stdout if not is_err else sys.stderr)
    end = kw.pop('end', None)
    enable_color = kw.pop('color', None)

    if enable_color is None:
        enable_color = not should_strip_ansi(_file)

    if end is None:
        if kw.pop('nl', True):
            end = u'\n' if isinstance(msg, unicode) else b'\n'
    if end:
        msg += end

    if msg:
        if not enable_color:
            msg = strip_ansi(msg)
        _file.write(msg)

    _file.flush()

    return
def echo(msg, **kw):
    msg = msg or ''
    is_err = kw.pop('err', False)
    _file = kw.pop('file', sys.stdout if not is_err else sys.stderr)
    end = kw.pop('end', None)
    enable_color = kw.pop('color', None)

    if enable_color is None:
        enable_color = not should_strip_ansi(_file)

    if end is None:
        if kw.pop('nl', True):
            end = u'\n' if isinstance(msg, unicode) else b'\n'
    if end:
        msg += end

    if msg:
        if not enable_color:
            msg = strip_ansi(msg)
        _file.write(msg)

    _file.flush()

    return