Example #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
Example #2
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))