123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- # Copyright 2024 Google LLC
- #
- # 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 inspect
- import sys
- from .. import PebbleCommander, exceptions, parsers
- def trim_docstring(var):
- return inspect.getdoc(var) or ''
- def get_help_short(cmdr, cmd_name, help_output=None):
- """
- cmd_name is the command's name.
- help_output is the raw output of the `!help` command.
- """
- output = None
- func = cmdr.get_command(cmd_name)
- if func: # Host command
- # cmdstr is the actual function name
- cmdstr = func.name
- spec = inspect.getargspec(func)
- if len(spec.args) > 1:
- maxargs = len(spec.args) - 1
- if spec.defaults is None:
- cmdstr += " {%d args}" % maxargs
- else:
- minargs = maxargs - len(spec.defaults)
- cmdstr += " {%d~%d args}" % (minargs, maxargs)
- if func.__doc__ is not None:
- output = "%-30s - %s" % (cmdstr, trim_docstring(func).splitlines()[0])
- else:
- output = cmdstr
- else: # Prompt command
- if cmd_name[0] == '!': # Strip the bang if it's there
- cmd_name = cmd_name[1:]
- # Get the output if it wasn't provided
- if help_output is None:
- help_output = cmdr.send_prompt_command("help")
- for prompt_cmd in help_output[1:]:
- # Match, even with argument count provided
- if prompt_cmd == cmd_name or prompt_cmd.startswith(cmd_name+" "):
- # Output should be the full argument string with the bang
- output = '!' + prompt_cmd
- break
- return output
- def help_arginfo_nodefault(arg):
- return "%s" % arg.upper()
- def help_arginfo_default(arg, dflt):
- return "[%s (default: %s)]" % (arg.upper(), str(dflt))
- def get_help_long(cmdr, cmd_name):
- output = ""
- func = cmdr.get_command(cmd_name)
- if func:
- spec = inspect.getargspec(func)
- specstr = []
- for i, arg in enumerate(spec.args[1:]):
- if spec.defaults is not None:
- minargs = len(spec.args[1:]) - len(spec.defaults)
- if i >= minargs:
- specstr.append(help_arginfo_default(arg, spec.defaults[i - minargs]))
- else:
- specstr.append(help_arginfo_nodefault(arg))
- else:
- specstr.append(help_arginfo_nodefault(arg))
- specstr = ' '.join(specstr)
- cmdstr = func.name + " " + specstr
- if func.__doc__ is None:
- output = "%s\n\nNo help available." % cmdstr
- else:
- output = "%s - %s" % (cmdstr, trim_docstring(func))
- else: # Prompt command
- cmdstr = get_help_short(cmdr, cmd_name)
- if cmdstr is None:
- output = None
- else:
- output = "%s\n\nNo help available, due to being a prompt command." % cmdstr
- return output
- @PebbleCommander.command()
- def help(cmdr, cmd=None):
- """ Show help.
- You're lookin' at it, dummy!
- """
- out = []
- if cmd is not None:
- helpstr = get_help_long(cmdr, cmd)
- if helpstr is None:
- raise exceptions.ParameterError("No command '%s' found." % cmd)
- out.append(helpstr)
- else: # List commands
- out.append("===Host commands===")
- # Bonus, this list is sorted for us already
- for cmd_name in dir(cmdr):
- if cmdr.get_command(cmd_name):
- out.append(get_help_short(cmdr, cmd_name))
- out.append("\n===Prompt commands===")
- ret = cmdr.send_prompt_command("help")
- if ret[0] != 'Available Commands:':
- raise exceptions.PromptResponseError("'help' prompt command output invalid")
- for cmd_name in ret[1:]:
- out.append(get_help_short(cmdr, "!" + cmd_name, ret))
- return out
|