summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Pokorný <jpokorny@redhat.com>2014-11-11 23:32:00 +0100
committerJan Pokorný <jpokorny@redhat.com>2014-11-14 22:11:07 +0100
commit14318c2897c74626e4729d394b7956fafca79ddb (patch)
treeefd9ab3a21b0b10d120e373b4af633a420c6016f
parent7cb961c7c94b64664d6e453ebc71a32b92399bfd (diff)
downloadclufter-14318c2897c74626e4729d394b7956fafca79ddb.tar.gz
clufter-14318c2897c74626e4729d394b7956fafca79ddb.tar.xz
clufter-14318c2897c74626e4729d394b7956fafca79ddb.zip
main + more: introduce concept of "expert" cmd switches
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
-rw-r--r--command.py7
-rw-r--r--completion.py1
-rw-r--r--main.py66
-rw-r--r--utils_prog.py12
4 files changed, 71 insertions, 15 deletions
diff --git a/command.py b/command.py
index 0bd9de4..6c6a4c9 100644
--- a/command.py
+++ b/command.py
@@ -8,7 +8,6 @@ __author__ = "Jan Pokorný <jpokorny @at@ Red Hat .dot. com>"
import logging
from collections import MutableMapping
from itertools import izip_longest
-from optparse import SUPPRESS_HELP
from sys import stderr
from time import time
@@ -223,6 +222,7 @@ class Command(object):
action='append',
choices=choices + ['ANY'] if universal else choices,
default=[],
+ expert=True,
help=help_text,
)
options.append([["--" + optname_used], opt])
@@ -234,7 +234,10 @@ class Command(object):
short_aliases = shortopts.setdefault(optname_used[0], [])
assert optname_used not in \
(options[i][0][0] for i in short_aliases)
- options.append([["--" + optname_used], dict(help=SUPPRESS_HELP)])
+ options.append([["--" + optname_used], dict(\
+ expert=True,
+ help="(undocumented expert option)",
+ )])
def _figure_parser_desc_opts(self, fnc_defaults, fnc_varnames):
readopts, shortopts, options = False, {}, []
diff --git a/completion.py b/completion.py
index a3d96b9..25947b3 100644
--- a/completion.py
+++ b/completion.py
@@ -62,6 +62,7 @@ class Completion(object):
@Completion.deco("bash")
class BashCompletion(Completion):
+ # XXX include expert options?
def __init__(self, prog, *args):
prog = basename(prog)
super(BashCompletion, self).__init__(prog, *args)
diff --git a/main.py b/main.py
index 5e89391..174b159 100644
--- a/main.py
+++ b/main.py
@@ -17,7 +17,7 @@ from . import version_text, description_text
from .command_manager import CommandManager
from .completion import Completion
from .error import EC
-from .utils_prog import make_options, set_logging
+from .utils_prog import ExpertOption, make_options, set_logging
_system = system()
@@ -25,13 +25,18 @@ _system_extra = linux_distribution(full_distribution_name=0) \
if _system == 'Linux' else ()
-def parser_callback_help(option, opt_str, value, parser):
+def parser_callback_help(option, opt_str, value, parser, arg=False, full=False):
"""Makes 'help' option accept 'optional option arguments'"""
- rargs, val = parser.rargs, ''
- if rargs and not rargs[0].startswith('-'):
- val = rargs[0]
- del rargs[:1]
+ if arg:
+ rargs, val = parser.rargs, ''
+ if rargs and not rargs[0].startswith('-'):
+ val = rargs[0]
+ del rargs[:1]
+ else:
+ val = True
setattr(parser.values, 'help', val)
+ setattr(parser.values, 'help_full', full)
+
opts_common = (
(('-q', '--quiet', ), dict(
@@ -64,11 +69,13 @@ opts_common = (
(('--sys', ), dict(
action='store',
default=_system,
+ expert=True,
help="override autodetected system [%default]"
)),
(('--dist', ), dict(
action='store',
default=','.join(_system_extra),
+ expert=True,
help="override autodetected distro if `sys' is `Linux' [%default]"
)),
)
@@ -79,8 +86,16 @@ opts_main = (
type='string',
nargs=0, # <- we take one if suitable
action='callback',
- callback=parser_callback_help,
- help="show this help message (global or command-specific) and exit"
+ callback=lambda *args: parser_callback_help(*args, arg=True),
+ help="show the help message (global or command-specific) and exit"
+ )),
+ (('-H', '--help-full'), dict(
+ metavar="[CMD]",
+ type='string',
+ nargs=0, # <- we take one if suitable
+ action='callback',
+ callback=lambda *args: parser_callback_help(*args, arg=True, full=True),
+ help="show the full help message (global or command-specific) and exit"
)),
(('-v', '--version'), dict(
action='store_true',
@@ -99,8 +114,14 @@ opts_main = (
opts_nonmain = (
(('-h', '--help'), dict(
- action='store_true',
- help="show this help message and exit"
+ action='callback',
+ callback=parser_callback_help,
+ help="show the help message and exit"
+ )),
+ (('-H', '--help-full'), dict(
+ action='callback',
+ callback=lambda *args: parser_callback_help(*args, full=True),
+ help="show the full help message and exit"
)),
)
@@ -114,14 +135,28 @@ class SharedHelpFormatter(IndentedHelpFormatter):
return ret.replace(self.choices_tag, ', '.join(option.choices or []))
+class SharedHelpFormatterNonExpert(SharedHelpFormatter):
+ """SharedHelpFormatter to filter out expert options"""
+ def format_option(self, option):
+ if not isinstance(option, ExpertOption):
+ ret = SharedHelpFormatter.format_option(self, option)
+ else:
+ ret = ''
+ return ret
+
+
class SharedOptionParser(OptionParser):
"""OptionParser with a dynamic on-demand help screen customization."""
+ formatter_nonexpert = SharedHelpFormatterNonExpert()
+ formatter_expert = SharedHelpFormatter()
+
# overridden methods
def __init__(self, **kwargs):
+ # a bit awkward, but in place as a sort of memoizing
if 'formatter' not in kwargs:
- kwargs['formatter'] = SharedHelpFormatter()
+ kwargs['formatter'] = self.formatter_nonexpert
OptionParser.__init__(self, **kwargs)
self.description_raw = ''
@@ -138,6 +173,9 @@ class SharedOptionParser(OptionParser):
v = kwargs.pop(k, None)
if v:
setattr(self, k, v)
+ help_full = getattr(self.values, 'help_full', None)
+ if help_full in (True, False):
+ self.help_full(help_full)
return self.format_help(**kwargs)
def add_option_group_by_args(self, *args, **kwargs):
@@ -147,6 +185,12 @@ class SharedOptionParser(OptionParser):
group.add_options(option_list)
self.add_option_group(group)
+ def help_full(self, expert):
+ assert self.formatter in (self.formatter_nonexpert,
+ self.formatter_expert), "explicit formatter"
+ self.formatter = (self.formatter_expert if expert else
+ self.formatter_nonexpert)
+
def run(argv=None, *args):
"""Entry point"""
diff --git a/utils_prog.py b/utils_prog.py
index ca0ac79..cfbecbf 100644
--- a/utils_prog.py
+++ b/utils_prog.py
@@ -7,7 +7,7 @@ __author__ = "Jan Pokorný <jpokorny @at@ Red Hat .dot. com>"
import logging
from collections import Mapping, MutableMapping, MutableSequence, MutableSet
-from optparse import make_option
+from optparse import Option
from os import environ, pathsep
from os.path import abspath, dirname, samefile, \
isabs as path_isabs, \
@@ -19,6 +19,7 @@ from sys import stderr, stdin
from . import package_name
from .error import ClufterError
from .utils import areinstances, \
+ filterdict_invkeep, \
filterdict_pop, \
func_defaults_varnames, \
isinstanceexcept, \
@@ -153,7 +154,14 @@ longopt_letters_reprio = \
key=lambda x: int(x.lower() in 'aeiouy')))
)(filter(lambda c: c.isalpha(), longopt))
-# extrapolate optparse.make_option to specifically-encoded "plural"
+class ExpertOption(Option):
+ pass
+
+make_option = \
+ lambda *a, **kw: \
+ (ExpertOption if kw.pop('expert', False) else Option)(*a, **kw)
+
+# extrapolate make_option to specifically-encoded "plural"
make_options = lambda opt_decl: [make_option(*a, **kw) for a, kw in opt_decl]