Пример #1
0
    def test_description(self, capsys):
        _, rc = Sample.run(["sample", "--help"], exit=False)
        assert rc == 0
        stdout, stderr = capsys.readouterr()
        cols, _ = get_terminal_size()

        if cols < 9:
            # Terminal is too narrow to test
            pass
        else:
            # Paragraph indentation should be preserved
            assert "    ABC" in stdout
            assert "  DEF" in stdout
            assert "   - Item" in stdout
            # List items should not be combined into paragraphs
            assert "  * Star 2"
            # Lines of the same list item should be combined. (The right-hand expression of the 'or' operator
            # below is for when the terminal is too narrow, causing "GHI" to be wrapped to the next line.)
            assert "  GHI" not in stdout or "     GHI" in stdout
            # List item with invisible bullet should be indented without the bullet
            assert " XYZ" in stdout
Пример #2
0
    def test_description(self, capsys):
        _, rc = Sample.run(["sample", "--help"], exit = False)
        assert rc == 0
        stdout, stderr = capsys.readouterr()
        cols, _ = get_terminal_size()

        if cols < 9:
            # Terminal is too narrow to test
            pass
        else:
            # Paragraph indentation should be preserved
            assert "    ABC" in stdout
            assert "  DEF" in stdout
            assert "   - Item" in stdout
            # List items should not be combined into paragraphs
            assert "  * Star 2"
            # Lines of the same list item should be combined. (The right-hand expression of the 'or' operator
            # below is for when the terminal is too narrow, causing "GHI" to be wrapped to the next line.)
            assert "  GHI" not in stdout or "     GHI" in stdout
            # List item with invisible bullet should be indented without the bullet
            assert " XYZ" in stdout
Пример #3
0
    def help(self):  # @ReservedAssignment
        """Prints this help message and quits"""
        if self._get_prog_version():
            self.version()
            print("")
        if self.DESCRIPTION:
            print(self.DESCRIPTION.strip())

        m_args, m_varargs, _, m_defaults = inspect.getargspec(self.main)
        tailargs = m_args[1:]  # skip self
        if m_defaults:
            for i, d in enumerate(reversed(m_defaults)):
                tailargs[-i - 1] = "[%s=%r]" % (tailargs[-i - 1], d)
        if m_varargs:
            tailargs.append("%s..." % (m_varargs,))
        tailargs = " ".join(tailargs)

        print("Usage:")
        if not self.USAGE:
            if self._subcommands:
                self.USAGE = "    %(progname)s [SWITCHES] [SUBCOMMAND [SWITCHES]] %(tailargs)s\n"
            else:
                self.USAGE = "    %(progname)s [SWITCHES] %(tailargs)s\n"
        print(self.USAGE % {"progname": self.PROGNAME, "tailargs": tailargs})

        by_groups = {}
        for si in self._switches_by_func.values():
            if si.group not in by_groups:
                by_groups[si.group] = []
            by_groups[si.group].append(si)

        def switchs(by_groups, show_groups):
            for grp, swinfos in sorted(by_groups.items(), key = lambda item: item[0]):
                if show_groups:
                    print("%s:" % (grp,))

                for si in sorted(swinfos, key = lambda si: si.names):
                    swnames = ", ".join(("-" if len(n) == 1 else "--") + n for n in si.names
                        if n in self._switches_by_name and self._switches_by_name[n] == si)
                    if si.argtype:
                        if isinstance(si.argtype, type):
                            typename = si.argtype.__name__
                        else:
                            typename = str(si.argtype)
                        argtype = " %s:%s" % (si.argname.upper(), typename)
                    else:
                        argtype = ""
                    prefix = swnames + argtype
                    yield si, prefix

                if show_groups:
                    print("")

        sw_width = max(len(prefix) for si, prefix in switchs(by_groups, False)) + 4
        cols, _ = get_terminal_size()
        description_indent = "    %s%s%s"
        wrapper = TextWrapper(width = max(cols - min(sw_width, 60), 50) - 6)
        indentation = "\n" + " " * (cols - wrapper.width)

        for si, prefix in switchs(by_groups, True):
            help = si.help  # @ReservedAssignment
            if si.list:
                help += "; may be given multiple times"
            if si.mandatory:
                help += "; required"
            if si.requires:
                help += "; requires %s" % (", ".join((("-" if len(s) == 1 else "--") + s) for s in si.requires))
            if si.excludes:
                help += "; excludes %s" % (", ".join((("-" if len(s) == 1 else "--") + s) for s in si.excludes))

            msg = indentation.join(wrapper.wrap(" ".join(l.strip() for l in help.splitlines())))

            if len(prefix) + wrapper.width >= cols:
                padding = indentation
            else:
                padding = " " * max(cols - wrapper.width - len(prefix) - 4, 1)
            print(description_indent % (prefix, padding, msg))

        if self._subcommands:
            print("Subcommands:")
            for name, subcls in sorted(self._subcommands.items()):
                subapp = subcls.get()
                doc = subapp.DESCRIPTION if subapp.DESCRIPTION else inspect.getdoc(subapp)
                help = doc + "; " if doc else ""  # @ReservedAssignment
                help += "see '%s %s --help' for more info" % (self.PROGNAME, name)

                msg = indentation.join(wrapper.wrap(" ".join(l.strip() for l in help.splitlines())))

                if len(name) + wrapper.width >= cols:
                    padding = indentation
                else:
                    padding = " " * max(cols - wrapper.width - len(name) - 4, 1)
                print(description_indent % (name, padding, msg))
Пример #4
0
    def help(self):  # @ReservedAssignment
        """Prints this help message and quits"""
        if self._get_prog_version():
            self.version()
            print("")
        if self.DESCRIPTION:
            print(self.COLOR_DISCRIPTION[self.DESCRIPTION.strip() + '\n'])

        m_args, m_varargs, _, m_defaults = inspect.getargspec(self.main)
        tailargs = m_args[1:]  # skip self
        if m_defaults:
            for i, d in enumerate(reversed(m_defaults)):
                tailargs[-i - 1] = "[%s=%r]" % (tailargs[-i - 1], d)
        if m_varargs:
            tailargs.append("%s..." % (m_varargs, ))
        tailargs = " ".join(tailargs)

        with self.COLOR_USAGE:
            print(self.COLOR_HEADING["Usage:"])
            if not self.USAGE:
                if self._subcommands:
                    self.USAGE = "    %(progname)s [SWITCHES] [SUBCOMMAND [SWITCHES]] %(tailargs)s\n"
                else:
                    self.USAGE = "    %(progname)s [SWITCHES] %(tailargs)s\n"
            print(self.USAGE % {
                "progname": self.PROGNAME,
                "tailargs": tailargs
            })

        by_groups = {}
        for si in self._switches_by_func.values():
            if si.group not in by_groups:
                by_groups[si.group] = []
            by_groups[si.group].append(si)

        def switchs(by_groups, show_groups):
            for grp, swinfos in sorted(by_groups.items(),
                                       key=lambda item: item[0]):
                if show_groups:
                    with (self.COLOR_HEADING + self.COLOR_GROUPS[grp]):
                        print("%s:" % grp)

                # Print in body color unless empty, otherwise group color, otherwise nothing
                with self.COLOR_GROUPS_BODY.get(grp, self.COLOR_GROUPS[grp]):
                    for si in sorted(swinfos, key=lambda si: si.names):
                        swnames = ", ".join(
                            ("-" if len(n) == 1 else "--") + n
                            for n in si.names if n in self._switches_by_name
                            and self._switches_by_name[n] == si)
                        if si.argtype:
                            if isinstance(si.argtype, type):
                                typename = si.argtype.__name__
                            else:
                                typename = str(si.argtype)
                            argtype = " %s:%s" % (si.argname.upper(), typename)
                        else:
                            argtype = ""
                        prefix = swnames + argtype
                        yield si, prefix

                if show_groups:
                    print("")

        sw_width = max(
            len(prefix) for si, prefix in switchs(by_groups, False)) + 4
        cols, _ = get_terminal_size()
        description_indent = "    %s%s%s"
        wrapper = TextWrapper(width=max(cols - min(sw_width, 60), 50) - 6)
        indentation = "\n" + " " * (cols - wrapper.width)

        for si, prefix in switchs(by_groups, True):
            help = si.help  # @ReservedAssignment
            if si.list:
                help += "; may be given multiple times"
            if si.mandatory:
                help += "; required"
            if si.requires:
                help += "; requires %s" % (", ".join(
                    (("-" if len(s) == 1 else "--") + s) for s in si.requires))
            if si.excludes:
                help += "; excludes %s" % (", ".join(
                    (("-" if len(s) == 1 else "--") + s) for s in si.excludes))

            msg = indentation.join(
                wrapper.wrap(" ".join(l.strip() for l in help.splitlines())))

            if len(prefix) + wrapper.width >= cols:
                padding = indentation
            else:
                padding = " " * max(cols - wrapper.width - len(prefix) - 4, 1)
            print(description_indent % (prefix, padding, msg))

        if self._subcommands:
            with (self.COLOR_HEADING + self.COLOR_SUBCOMMANDS):
                print("Subcommands:")
            for name, subcls in sorted(self._subcommands.items()):
                with self.COLOR_SUBCOMMANDS:
                    subapp = subcls.get()
                    doc = subapp.DESCRIPTION if subapp.DESCRIPTION else inspect.getdoc(
                        subapp)
                    help = doc + "; " if doc else ""  # @ReservedAssignment
                    help += "see '%s %s --help' for more info" % (
                        self.PROGNAME, name)

                    msg = indentation.join(
                        wrapper.wrap(" ".join(l.strip()
                                              for l in help.splitlines())))

                    if len(name) + wrapper.width >= cols:
                        padding = indentation
                    else:
                        padding = " " * max(
                            cols - wrapper.width - len(name) - 4, 1)
                    print(description_indent % (name, padding, msg))
Пример #5
0
    def help(self):  # @ReservedAssignment
        """Prints this help message and quits"""
        if self._get_prog_version():
            self.version()
            print("")
        if self.DESCRIPTION:
            print(self.DESCRIPTION.strip() + '\n')

        m = six.getfullargspec(self.main)
        tailargs = m.args[1:]  # skip self
        if m.defaults:
            for i, d in enumerate(reversed(m.defaults)):
                tailargs[-i - 1] = "[%s=%r]" % (tailargs[-i - 1], d)
        if m.varargs:
            tailargs.append("%s..." % (m.varargs,))
        tailargs = " ".join(tailargs)

        with self.COLOR_USAGE:
            print("Usage:")
            if not self.USAGE:
                if self._subcommands:
                    self.USAGE = "    %(progname)s [SWITCHES] [SUBCOMMAND [SWITCHES]] %(tailargs)s\n"
                else:
                    self.USAGE = "    %(progname)s [SWITCHES] %(tailargs)s\n"
            print(self.USAGE % {"progname": colors.filter(self.PROGNAME), "tailargs": tailargs})

        by_groups = {}
        for si in self._switches_by_func.values():
            if si.group not in by_groups:
                by_groups[si.group] = []
            by_groups[si.group].append(si)

        def switchs(by_groups, show_groups):
            for grp, swinfos in sorted(by_groups.items(), key = lambda item: item[0]):
                if show_groups:
                    print(self.COLOR_GROUPS[grp] | grp)

                for si in sorted(swinfos, key = lambda si: si.names):
                    swnames = ", ".join(("-" if len(n) == 1 else "--") + n for n in si.names
                        if n in self._switches_by_name and self._switches_by_name[n] == si)
                    if si.argtype:
                        if hasattr(si.argtype, '__name__'):
                            typename = si.argtype.__name__
                        else:
                            typename = str(si.argtype)
                        argtype = " %s:%s" % (si.argname.upper(), typename)
                    else:
                        argtype = ""
                    prefix = swnames + argtype
                    yield si, prefix, self.COLOR_GROUPS[grp]

                if show_groups:
                    print("")

        sw_width = max(len(prefix) for si, prefix, color in switchs(by_groups, False)) + 4
        cols, _ = get_terminal_size()
        description_indent = "    %s%s%s"
        wrapper = TextWrapper(width = max(cols - min(sw_width, 60), 50) - 6)
        indentation = "\n" + " " * (cols - wrapper.width)

        for si, prefix, color in switchs(by_groups, True):
            help = si.help  # @ReservedAssignment
            if si.list:
                help += "; may be given multiple times"
            if si.mandatory:
                help += "; required"
            if si.requires:
                help += "; requires %s" % (", ".join((("-" if len(s) == 1 else "--") + s) for s in si.requires))
            if si.excludes:
                help += "; excludes %s" % (", ".join((("-" if len(s) == 1 else "--") + s) for s in si.excludes))

            msg = indentation.join(wrapper.wrap(" ".join(l.strip() for l in help.splitlines())))

            if len(prefix) + wrapper.width >= cols:
                padding = indentation
            else:
                padding = " " * max(cols - wrapper.width - len(prefix) - 4, 1)
            print(description_indent % (color | prefix, padding, color | msg))

        if self._subcommands:
            gc = self.COLOR_GROUPS["Subcommands"]
            print(gc | "Subcommands:")
            for name, subcls in sorted(self._subcommands.items()):
                with gc:
                    subapp = subcls.get()
                    doc = subapp.DESCRIPTION if subapp.DESCRIPTION else getdoc(subapp)
                    if self.SUBCOMMAND_HELPMSG:
                        help = doc + "; " if doc else ""  # @ReservedAssignment
                        help += self.SUBCOMMAND_HELPMSG.format(parent=self.PROGNAME, sub=name)
                    else:
                        help = doc if doc else "" # @ReservedAssignment

                    msg = indentation.join(wrapper.wrap(" ".join(l.strip() for l in help.splitlines())))

                    if len(name) + wrapper.width >= cols:
                        padding = indentation
                    else:
                        padding = " " * max(cols - wrapper.width - len(name) - 4, 1)
                    if colors.contains_colors(subcls.name):
                        bodycolor = colors.extract(subcls.name)
                    else:
                        bodycolor = gc

                    print(description_indent
                            % (subcls.name, padding,
                               bodycolor | colors.filter(msg)))
Пример #6
0
def hline():
    width, height = get_terminal_size(default=(80, 25))
    print(width * u'\u2500')