Bring fixes suggested by the review on UnixCommand
This commit is contained in:
parent
916d7933aa
commit
848b4c588c
2 changed files with 119 additions and 69 deletions
|
|
@ -947,14 +947,14 @@ class CmdDummy(UnixCommand):
|
||||||
|
|
||||||
"""A dummy UnixCommand."""
|
"""A dummy UnixCommand."""
|
||||||
|
|
||||||
def init(self):
|
key = "dummy"
|
||||||
|
|
||||||
|
def init_parser(self):
|
||||||
"""Fill out options."""
|
"""Fill out options."""
|
||||||
self.parser.add_argument("nb1", type=int, help="the first number")
|
self.parser.add_argument("nb1", type=int, help="the first number")
|
||||||
self.parser.add_argument("nb2", type=int, help="the second number")
|
self.parser.add_argument("nb2", type=int, help="the second number")
|
||||||
self.parser.add_argument("-v", "--verbose", action="store_true")
|
self.parser.add_argument("-v", "--verbose", action="store_true")
|
||||||
|
|
||||||
key = "dummy"
|
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
nb1 = self.opts.nb1
|
nb1 = self.opts.nb1
|
||||||
nb2 = self.opts.nb2
|
nb2 = self.opts.nb2
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ options.
|
||||||
|
|
||||||
The UnixCommand can be ovverridden to have your commands parsed.
|
The UnixCommand can be ovverridden to have your commands parsed.
|
||||||
You will need to override two methods:
|
You will need to override two methods:
|
||||||
- The `init` method, which adds options to the parser.
|
- The `init_parser` method, which adds options to the parser.
|
||||||
- The `func` method, called to execute the command once parsed.
|
- The `func` method, called to execute the command once parsed.
|
||||||
|
|
||||||
Here's a short example:
|
Here's a short example:
|
||||||
|
|
@ -30,7 +30,7 @@ class CmdPlant(UnixCommand):
|
||||||
|
|
||||||
key = "plant"
|
key = "plant"
|
||||||
|
|
||||||
def init(self):
|
def init_parser(self):
|
||||||
"Add the arguments to the parser."
|
"Add the arguments to the parser."
|
||||||
# 'self.parser' inherits `argparse.ArgumentParser`
|
# 'self.parser' inherits `argparse.ArgumentParser`
|
||||||
self.parser.add_argument("key",
|
self.parser.add_argument("key",
|
||||||
|
|
@ -62,6 +62,112 @@ from textwrap import dedent
|
||||||
from evennia import Command, InterruptCommand
|
from evennia import Command, InterruptCommand
|
||||||
from evennia.utils.ansi import raw
|
from evennia.utils.ansi import raw
|
||||||
|
|
||||||
|
class ParseError(Exception):
|
||||||
|
|
||||||
|
"""An error occurred during parsing."""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class UnixCommandParser(argparse.ArgumentParser):
|
||||||
|
|
||||||
|
"""A modifier command parser for unix commands.
|
||||||
|
|
||||||
|
This parser is used to replace `argparse.ArgumentParser`. It
|
||||||
|
is aware of the command calling it, and can more easily report to
|
||||||
|
the caller. Some features (like the "brutal exit" of the original
|
||||||
|
parser) are disabled or replaced. This parser is used by UnixCommand
|
||||||
|
and creating one directly isn't recommended nor necessary. Even
|
||||||
|
adding a sub-command will use this replaced parser automatically.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, prog, description="", epilogue="", command=None, **kwargs):
|
||||||
|
prog = prog or command.key
|
||||||
|
super(UnixCommandParser, self).__init__(
|
||||||
|
prog=prog, description=description,
|
||||||
|
conflict_handler='resolve', add_help=False, **kwargs)
|
||||||
|
self.command = command
|
||||||
|
self.post_help = epilogue
|
||||||
|
def n_exit(code=None, msg=None):
|
||||||
|
raise ParseError(msg)
|
||||||
|
|
||||||
|
self.exit = n_exit
|
||||||
|
|
||||||
|
# Replace the -h/--help
|
||||||
|
self.add_argument("-h", "--hel", nargs=0, action=HelpAction,
|
||||||
|
help="display the command help")
|
||||||
|
|
||||||
|
def format_usage(self):
|
||||||
|
"""Return the usage line.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This method is present to return the raw-escaped usage line,
|
||||||
|
in order to avoid unintentional color codes.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return raw(super(UnixCommandParser, self).format_usage())
|
||||||
|
|
||||||
|
def format_help(self):
|
||||||
|
"""Return the parser help, including its epilogue.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This method is present to return the raw-escaped help,
|
||||||
|
in order to avoid unintentional color codes. Color codes
|
||||||
|
in the epilogue (the command docstring) are supported.
|
||||||
|
|
||||||
|
"""
|
||||||
|
autohelp = raw(super(UnixCommandParser, self).format_help())
|
||||||
|
return "\n" + autohelp + "\n" + self.post_help
|
||||||
|
|
||||||
|
def print_usage(self, file=None):
|
||||||
|
"""Print the usage to the caller.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file (file-object): not used here, the caller is used.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This method will override `argparse.ArgumentParser`'s in order
|
||||||
|
to not display the help on stdout or stderr, but to the
|
||||||
|
command's caller.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if self.command:
|
||||||
|
self.command.msg(self.format_usage().strip())
|
||||||
|
|
||||||
|
def print_help(self, file=None):
|
||||||
|
"""Print the help to the caller.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file (file-object): not used here, the caller is used.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This method will override `argparse.ArgumentParser`'s in order
|
||||||
|
to not display the help on stdout or stderr, but to the
|
||||||
|
command's caller.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if self.command:
|
||||||
|
self.command.msg(self.format_help().strip())
|
||||||
|
|
||||||
|
|
||||||
|
class HelpAction(argparse.Action):
|
||||||
|
|
||||||
|
"""Override the -h/--help action in the default parser.
|
||||||
|
|
||||||
|
Using the default -h/--help will call the exit function in different
|
||||||
|
ways, preventing the entire help message to be provided. Hence
|
||||||
|
this override.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __call__(self, parser, namespace, values, option_string=None):
|
||||||
|
"""If asked for help, display to the caller."""
|
||||||
|
if parser.command:
|
||||||
|
parser.command.msg(parser.format_help().strip())
|
||||||
|
parser.exit(0, "")
|
||||||
|
|
||||||
|
|
||||||
class UnixCommand(Command):
|
class UnixCommand(Command):
|
||||||
"""
|
"""
|
||||||
Unix-type commands, supporting short and long options.
|
Unix-type commands, supporting short and long options.
|
||||||
|
|
@ -71,7 +177,7 @@ class UnixCommand(Command):
|
||||||
used to parse the command.
|
used to parse the command.
|
||||||
|
|
||||||
In order to use it, you should override two methods:
|
In order to use it, you should override two methods:
|
||||||
- `init`: the init method is called when the command is created.
|
- `init_parser`: this method is called when the command is created.
|
||||||
It can be used to set options in the parser. `self.parser`
|
It can be used to set options in the parser. `self.parser`
|
||||||
contains the `argparse.ArgumentParser`, so you can add arguments
|
contains the `argparse.ArgumentParser`, so you can add arguments
|
||||||
here.
|
here.
|
||||||
|
|
@ -84,7 +190,7 @@ class UnixCommand(Command):
|
||||||
slightly different way than usual: the first line of the docstring
|
slightly different way than usual: the first line of the docstring
|
||||||
is used to represent the program description (the very short
|
is used to represent the program description (the very short
|
||||||
line at the top of the help message). The other lines below are
|
line at the top of the help message). The other lines below are
|
||||||
used as the program's "epilog", displayed below the options. It
|
used as the program's "epilogue", displayed below the options. It
|
||||||
means in your docstring, you don't have to write the options.
|
means in your docstring, you don't have to write the options.
|
||||||
They will be automatically provided by the parser and displayed
|
They will be automatically provided by the parser and displayed
|
||||||
accordingly. The `argparse` module provides a default '-h' or
|
accordingly. The `argparse` module provides a default '-h' or
|
||||||
|
|
@ -97,16 +203,16 @@ class UnixCommand(Command):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(UnixCommand, self).__init__()
|
super(UnixCommand, self).__init__()
|
||||||
|
|
||||||
# Create the empty EvenniaParser, inheriting argparse.ArgumentParser
|
# Create the empty UnixCommandParser, inheriting argparse.ArgumentParser
|
||||||
lines = dedent(self.__doc__.strip("\n")).splitlines()
|
lines = dedent(self.__doc__.strip("\n")).splitlines()
|
||||||
description = lines[0].strip()
|
description = lines[0].strip()
|
||||||
epilog = "\n".join(lines[1:]).strip()
|
epilogue = "\n".join(lines[1:]).strip()
|
||||||
self.parser = EvenniaParser(None, description, epilog, command=self)
|
self.parser = UnixCommandParser(None, description, epilogue, command=self)
|
||||||
|
|
||||||
# Fill the argument parser
|
# Fill the argument parser
|
||||||
self.init()
|
self.init_parser()
|
||||||
|
|
||||||
def init(self):
|
def init_parser(self):
|
||||||
"""
|
"""
|
||||||
Configure the argument parser, adding in options.
|
Configure the argument parser, adding in options.
|
||||||
|
|
||||||
|
|
@ -143,7 +249,7 @@ class UnixCommand(Command):
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
You should not override this method. Consider overriding
|
You should not override this method. Consider overriding
|
||||||
`init` instead.
|
`init_parser` instead.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -153,59 +259,3 @@ class UnixCommand(Command):
|
||||||
if msg:
|
if msg:
|
||||||
self.msg(msg)
|
self.msg(msg)
|
||||||
raise InterruptCommand
|
raise InterruptCommand
|
||||||
|
|
||||||
|
|
||||||
class ParseError(Exception):
|
|
||||||
|
|
||||||
"""An error occurred during parsing."""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class EvenniaParser(argparse.ArgumentParser):
|
|
||||||
|
|
||||||
"""A parser just for Evennia."""
|
|
||||||
|
|
||||||
def __init__(self, prog, description="", epilog="", command=None, **kwargs):
|
|
||||||
prog = prog or command.key
|
|
||||||
super(EvenniaParser, self).__init__(
|
|
||||||
prog=prog, description=description,
|
|
||||||
conflict_handler='resolve', add_help=False, **kwargs)
|
|
||||||
self.command = command
|
|
||||||
self.post_help = epilog
|
|
||||||
def n_exit(code=None, msg=None):
|
|
||||||
raise ParseError(msg)
|
|
||||||
|
|
||||||
self.exit = n_exit
|
|
||||||
|
|
||||||
# Replace the -h/--help
|
|
||||||
self.add_argument("-h", "--hel", nargs=0, action=HelpAction, help="display heeeelp")
|
|
||||||
|
|
||||||
def format_usage(self):
|
|
||||||
"""Return the usage line."""
|
|
||||||
return raw(super(EvenniaParser, self).format_usage())
|
|
||||||
|
|
||||||
def format_help(self):
|
|
||||||
"""Return the parser help, including its epilog."""
|
|
||||||
autohelp = raw(super(EvenniaParser, self).format_help())
|
|
||||||
return "\n" + autohelp + "\n" + self.post_help
|
|
||||||
|
|
||||||
def print_usage(self, file=None):
|
|
||||||
"""Print the usage to the caller."""
|
|
||||||
if self.command:
|
|
||||||
self.command.msg(self.format_usage().strip())
|
|
||||||
|
|
||||||
def print_help(self, file=None):
|
|
||||||
"""Print the help to the caller."""
|
|
||||||
if self.command:
|
|
||||||
self.command.msg(self.format_help().strip())
|
|
||||||
|
|
||||||
|
|
||||||
class HelpAction(argparse.Action):
|
|
||||||
|
|
||||||
"""Override the -h/--he.p."""
|
|
||||||
|
|
||||||
def __call__(self, parser, namespace, values, option_string=None):
|
|
||||||
if parser.command:
|
|
||||||
parser.command.msg(parser.format_help().strip())
|
|
||||||
parser.exit(0, "")
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue