From af7588e8fb8d6c0e9dfe57b30c9a09b86f690892 Mon Sep 17 00:00:00 2001 From: Facundo Batista Date: Wed, 10 Feb 2021 12:54:16 -0300 Subject: [PATCH] Back to 'status' for the command, and autocompletion improvement. --- charmcraft/commands/store/__init__.py | 2 +- completion.bash | 108 +++++++++++--------------- tests/test_infra.py | 22 +++++- 3 files changed, 68 insertions(+), 64 deletions(-) diff --git a/charmcraft/commands/store/__init__.py b/charmcraft/commands/store/__init__.py index 5b09feac3..95a6d14bd 100644 --- a/charmcraft/commands/store/__init__.py +++ b/charmcraft/commands/store/__init__.py @@ -417,7 +417,7 @@ def run(self, parsed_args): class StatusCommand(BaseCommand): """Show channel status for a charm.""" - name = 'channels' + name = 'status' help_msg = "Show channel and released revisions" overview = textwrap.dedent(""" Show channels and released revisions in Charmhub diff --git a/completion.bash b/completion.bash index 0dde2425e..816b05797 100644 --- a/completion.bash +++ b/completion.bash @@ -19,57 +19,44 @@ _charmcraft() { local cur prev words cword cmd cmds - cmds=(build version login logout whoami names upload revisions status release) + cmds=( + build + create-lib + fetch-lib + help init + list-lib + login + logout + names + pack + publish-lib + register + release + revisions + status + upload + version + whoami + ) _init_completion || return # only offer long options, as they should be self-explanatory (and # it's not like it's more typing for the user) + globals=(--help --verbose --quiet --project-dir) - if [ "$cword" -eq 1 ]; then - COMPREPLY=( $(compgen -W "--help --verbose --quiet ${cmds[*]}" -- "$cur") ) + # if user just wrote --project-dir, only offer directories + if [ "$prev" = "--project-dir" ] || [ "$prev" = "-p" ]; then + _filedir -d return fi - case "$prev" in - --help) - return - ;; - --verbose|--quiet) - COMPREPLY=( $(compgen -W "${cmds[*]}" -- "$cur") ) - return - ;; - login|logout|whoami|version|names|register|create-lib|publish-lib|fetch-lib|list-lib) - COMPREPLY=( $(compgen -W "--help" -- "$cur") ) - return - ;; - build) - COMPREPLY=( $(compgen -W "--help --from --entrypoint --requirement" -- "$cur") ) - return - ;; - upload) - COMPREPLY=( $(compgen -W "--help --charm-file" -- "$cur") ) - return - ;; - revisions|status|release) - COMPREPLY=( $(compgen -W "--help --name" -- "$cur") ) - return - ;; - init) - COMPREPLY=( $(compgen -W "--help --project-dir --name --author --series --force" -- "$cur") ) - return - ;; - pack) - COMPREPLY=( $(compgen -W "--help --from" -- "$cur") ) - return - ;; - esac - - # we're inside a command; which one? - local u w + # check if any of the words is a command: if yes, offer the options for that + # command (and the global ones), else offer the commands and global options + local w c for w in "${words[@]}"; do - for u in "${cmds[@]}"; do - if [ "$u" = "$w" ]; then - cmd="$u" + for c in "${cmds[@]}"; do + if [ "$c" = "$w" ]; then + cmd="$c" break fi done @@ -78,10 +65,15 @@ _charmcraft() fi done - # NOTE cmd can be empty + if [ -z "$cmd" ]; then + # no command yet! show global options and the commands + COMPREPLY=( $(compgen -W "${globals[*]} ${cmds[*]}" -- "$cur") ) + return + fi + # offer the options for the given command (and global ones, always available) case "$cmd" in - "build") + build) case "$prev" in -r|--requirement) _filedir txt @@ -92,28 +84,20 @@ _charmcraft() -f|--from) _filedir -d ;; - esac - ;; - "upload") - case "$prev" in - --charm-file) - _filedir charm + *) + COMPREPLY=( $(compgen -W "${globals[*]} --from --entrypoint --requirement" -- "$cur") ) ;; esac ;; - "init") - case "$prev" in - --project-dir) - _filedir -d - ;; - esac + release) + COMPREPLY=( $(compgen -W "${globals[*]} --revision --channel" -- "$cur") ) ;; - "pack") - case "$prev" in - -f|--from) - _filedir -d - ;; - esac + init) + COMPREPLY=( $(compgen -W "${globals[*]} --name --author --series --force" -- "$cur") ) + ;; + *) + # by default just the global options + COMPREPLY=( $(compgen -W "${globals[*]}" -- "$cur") ) ;; esac } diff --git a/tests/test_infra.py b/tests/test_infra.py index a2e8a12df..afe257646 100644 --- a/tests/test_infra.py +++ b/tests/test_infra.py @@ -25,7 +25,7 @@ import pytest from flake8.api.legacy import get_style_guide -from charmcraft import __version__ +from charmcraft import __version__, main def get_python_filepaths(*, roots=None, python_paths=None): @@ -112,3 +112,23 @@ def test_setup_version(): proc = subprocess.run(cmd, stdout=subprocess.PIPE) output = proc.stdout.decode('utf8') assert output.strip() == __version__ + + +def test_bashcompletion_all_commands(): + """Verify that all commands are represented in the bash completion file.""" + # get the line where all commands are specified in the completion file; this is custom + # to our file, but simple and good enough + completed_commands = None + with open('completion.bash', 'rt', encoding='utf8') as fh: + completion_text = fh.read() + m = re.search(r"cmds=\((.*?)\)", completion_text, re.DOTALL) + if m: + completed_commands = set(m.groups()[0].split()) + else: + pytest.fail("Failed to find commands in the bash completion file") + + real_command_names = set() + for _, _, cmds in main.COMMAND_GROUPS: + real_command_names.update(cmd.name for cmd in cmds) + + assert completed_commands == real_command_names