From 6429bf7d6b1e8273579554f086b43b90710221ef Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Wed, 15 Jan 2020 20:36:46 -0800 Subject: [PATCH] Enable multiline command descriptions --- amanuensis/__main__.py | 5 ++++- amanuensis/cli/__init__.py | 9 ++++++--- amanuensis/cli/server.py | 29 +++++++++++++++++++++++++---- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/amanuensis/__main__.py b/amanuensis/__main__.py index 300fe21..278c22f 100644 --- a/amanuensis/__main__.py +++ b/amanuensis/__main__.py @@ -45,6 +45,9 @@ def repl(args): except Exception as e: traceback.print_exc() +def process_doc(docstring): + return '\n'.join([line.strip() for line in (docstring or "").strip().splitlines()]) + def get_parser(valid_commands): # Set up the top-level parser. parser = argparse.ArgumentParser( @@ -89,7 +92,7 @@ def get_parser(valid_commands): for name, func in valid_commands.items(): # Create the subparser, set the docstring as the description. cmd = subp.add_parser(name, - description=func.__doc__, + description=process_doc(func.__doc__), formatter_class=argparse.RawDescriptionHelpFormatter) # Delegate subparser setup to the command. func(cmd) diff --git a/amanuensis/cli/__init__.py b/amanuensis/cli/__init__.py index 8505028..8460fed 100644 --- a/amanuensis/cli/__init__.py +++ b/amanuensis/cli/__init__.py @@ -38,22 +38,25 @@ def user_commands(commands={}): def get_commands(): return {**server_commands(), **lexicon_commands(), **user_commands()} +def cmd_desc(func): + return ((func.__doc__ or "").strip() or '\n').splitlines()[0] + def describe_commands(): longest = max(map(len, server_commands().keys())) server_desc = "General commands:\n{}\n".format("\n".join([ - " {1:<{0}} : {2}".format(longest, name, func.__doc__ or "") + " {1:<{0}} : {2}".format(longest, name, cmd_desc(func)) for name, func in server_commands().items() ])) longest = max(map(len, lexicon_commands().keys())) lexicon_desc = "Lexicon commands:\n{}\n".format("\n".join([ - " {1:<{0}} : {2}".format(longest, name, func.__doc__ or "") + " {1:<{0}} : {2}".format(longest, name, cmd_desc(func)) for name, func in lexicon_commands().items() ])) longest = max(map(len, user_commands().keys())) user_desc = "User commands:\n{}\n".format("\n".join([ - " {1:<{0}} : {2}".format(longest, name, func.__doc__ or "") + " {1:<{0}} : {2}".format(longest, name, cmd_desc(func)) for name, func in user_commands().items() ])) diff --git a/amanuensis/cli/server.py b/amanuensis/cli/server.py index 5af0c15..ee1043a 100644 --- a/amanuensis/cli/server.py +++ b/amanuensis/cli/server.py @@ -4,7 +4,13 @@ CONFIG_GET_ROOT_VALUE = object() @add_argument("--update", action="store_true", help="Refresh an existing config directory") def command_init(args): - """Initialize a config directory at the directory given by --config-dir""" + """ + Initialize a config directory at --config-dir + + A clean config directory will contain a config.json, a + pidfile, a lexicon config directory, and a user config + directory. + """ from collections import OrderedDict import fcntl import json @@ -58,7 +64,12 @@ def command_init(args): @no_argument def command_generate_secret(args): - """Generate a secret key for Flask""" + """ + Generate a Flask secret key + + The Flask server will not run unless a secret key has + been generated. + """ import os import config @@ -71,7 +82,12 @@ def command_generate_secret(args): @add_argument("-a", "--address", default="127.0.0.1") @add_argument("-p", "--port", default="5000") def command_run(args): - """Run the default Flask server""" + """ + Run the default Flask server + + The default Flask server is not secure, and should + only be used for development. + """ import server import config @@ -85,7 +101,12 @@ def command_run(args): @add_argument("--set", metavar=("PATHSPEC", "VALUE"), dest="set", nargs=2, help="Set the value of a config key") def command_config(args): - """Interact with the global config""" + """ + Interact with the global config + + PATHSPEC is a path into the config object formatted as + a dot-separated sequence of keys. + """ import json import config