Files
deb-python-cliff/cliff/help.py
Doug Hellmann decac4318e pass the command name from HelpCommand
When the help command instantiates another command class to get its help
text, it needs to pass the command's name if the class supports it.

Change-Id: I3507f723dc8b4e68db80d6da053be61026823457
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
2017-06-29 22:29:01 -07:00

104 lines
3.9 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import argparse
import inspect
import sys
import traceback
from . import command
class HelpAction(argparse.Action):
"""Provide a custom action so the -h and --help options
to the main app will print a list of the commands.
The commands are determined by checking the CommandManager
instance, passed in as the "default" value for the action.
"""
def __call__(self, parser, namespace, values, option_string=None):
app = self.default
parser.print_help(app.stdout)
app.stdout.write('\nCommands:\n')
command_manager = app.command_manager
for name, ep in sorted(command_manager):
try:
factory = ep.load()
except Exception:
app.stdout.write('Could not load %r\n' % ep)
if namespace.debug:
traceback.print_exc(file=app.stdout)
continue
try:
kwargs = {}
if 'cmd_name' in inspect.getargspec(factory.__init__).args:
kwargs['cmd_name'] = name
cmd = factory(app, None, **kwargs)
if cmd.deprecated:
continue
except Exception as err:
app.stdout.write('Could not instantiate %r: %s\n' % (ep, err))
if namespace.debug:
traceback.print_exc(file=app.stdout)
continue
one_liner = cmd.get_description().split('\n')[0]
app.stdout.write(' %-13s %s\n' % (name, one_liner))
sys.exit(0)
class HelpCommand(command.Command):
"""print detailed help for another command
"""
def get_parser(self, prog_name):
parser = super(HelpCommand, self).get_parser(prog_name)
parser.add_argument('cmd',
nargs='*',
help='name of the command',
)
return parser
def take_action(self, parsed_args):
if parsed_args.cmd:
try:
the_cmd = self.app.command_manager.find_command(
parsed_args.cmd,
)
cmd_factory, cmd_name, search_args = the_cmd
except ValueError:
# Did not find an exact match
cmd = parsed_args.cmd[0]
fuzzy_matches = [k[0] for k in self.app.command_manager
if k[0].startswith(cmd)
]
if not fuzzy_matches:
raise
self.app.stdout.write('Command "%s" matches:\n' % cmd)
for fm in sorted(fuzzy_matches):
self.app.stdout.write(' %s\n' % fm)
return
self.app_args.cmd = search_args
kwargs = {}
if 'cmd_name' in inspect.getargspec(cmd_factory.__init__).args:
kwargs['cmd_name'] = cmd_name
cmd = cmd_factory(self.app, self.app_args, **kwargs)
full_name = (cmd_name
if self.app.interactive_mode
else ' '.join([self.app.NAME, cmd_name])
)
cmd_parser = cmd.get_parser(full_name)
cmd_parser.print_help(self.app.stdout)
else:
action = HelpAction(None, None, default=self.app)
action(self.app.parser, self.app.options, None, None)
return 0