summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--glanceclient/shell.py28
-rw-r--r--tests/test_shell.py38
-rw-r--r--tools/glance.bash_completion25
3 files changed, 91 insertions, 0 deletions
diff --git a/glanceclient/shell.py b/glanceclient/shell.py
index c529b6e..99dcc5a 100644
--- a/glanceclient/shell.py
+++ b/glanceclient/shell.py
@@ -286,6 +286,8 @@ class OpenStackImagesShell(object):
self._find_actions(subparsers, submodule)
self._find_actions(subparsers, self)
+ self._add_bash_completion_subparser(subparsers)
+
return parser
def _find_actions(self, subparsers, actions_module):
@@ -312,6 +314,13 @@ class OpenStackImagesShell(object):
subparser.add_argument(*args, **kwargs)
subparser.set_defaults(func=callback)
+ def _add_bash_completion_subparser(self, subparsers):
+ subparser = subparsers.add_parser('bash_completion',
+ add_help=False,
+ formatter_class=HelpFormatter)
+ self.subcommands['bash_completion'] = subparser
+ subparser.set_defaults(func=self.do_bash_completion)
+
def _get_image_url(self, args):
"""Translate the available url-related options into a single string.
@@ -567,6 +576,9 @@ class OpenStackImagesShell(object):
if args.func == self.do_help:
self.do_help(args)
return 0
+ elif args.func == self.do_bash_completion:
+ self.do_bash_completion(args)
+ return 0
LOG = logging.getLogger('glanceclient')
LOG.addHandler(logging.StreamHandler())
@@ -605,6 +617,22 @@ class OpenStackImagesShell(object):
else:
self.parser.print_help()
+ def do_bash_completion(self, _args):
+ """
+ Prints all of the commands and options to stdout so that the
+ glance.bash_completion script doesn't have to hard code them.
+ """
+ commands = set()
+ options = set()
+ for sc_str, sc in self.subcommands.items():
+ commands.add(sc_str)
+ for option in sc._optionals._option_string_actions.keys():
+ options.add(option)
+
+ commands.remove('bash_completion')
+ commands.remove('bash-completion')
+ print(' '.join(commands | options))
+
class HelpFormatter(argparse.HelpFormatter):
def start_section(self, heading):
diff --git a/tests/test_shell.py b/tests/test_shell.py
index 5c80e49..d4b1ddf 100644
--- a/tests/test_shell.py
+++ b/tests/test_shell.py
@@ -16,8 +16,10 @@
import argparse
import os
+import sys
import mock
+import six
from glanceclient import exc
from glanceclient import shell as openstack_shell
@@ -79,6 +81,26 @@ class ShellTest(utils.TestCase):
global _old_env
os.environ = _old_env
+ def shell(self, argstr, exitcodes=(0,)):
+ orig = sys.stdout
+ orig_stderr = sys.stderr
+ try:
+ sys.stdout = six.StringIO()
+ sys.stderr = six.StringIO()
+ _shell = openstack_shell.OpenStackImagesShell()
+ _shell.main(argstr.split())
+ except SystemExit:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.assertIn(exc_value.code, exitcodes)
+ finally:
+ stdout = sys.stdout.getvalue()
+ sys.stdout.close()
+ sys.stdout = orig
+ stderr = sys.stderr.getvalue()
+ sys.stderr.close()
+ sys.stderr = orig_stderr
+ return (stdout, stderr)
+
def test_help_unknown_command(self):
shell = openstack_shell.OpenStackImagesShell()
argstr = 'help foofoo'
@@ -285,6 +307,22 @@ class ShellTestWithKeystoneV3Auth(ShellTest):
glance_shell = openstack_shell.OpenStackImagesShell()
self.assertRaises(exc.CommandError, glance_shell.main, args.split())
+ def test_bash_completion(self):
+ stdout, stderr = self.shell('bash_completion')
+ # just check we have some output
+ required = [
+ '--status',
+ 'image-create',
+ 'help',
+ '--size']
+ for r in required:
+ self.assertIn(r, stdout.split())
+ avoided = [
+ 'bash_completion',
+ 'bash-completion']
+ for r in avoided:
+ self.assertNotIn(r, stdout.split())
+
class ShellCacheSchemaTest(utils.TestCase):
def setUp(self):
diff --git a/tools/glance.bash_completion b/tools/glance.bash_completion
new file mode 100644
index 0000000..1e7f72c
--- /dev/null
+++ b/tools/glance.bash_completion
@@ -0,0 +1,25 @@
+_glance_opts="" # lazy init
+_glance_flags="" # lazy init
+_glance_opts_exp="" # lazy init
+_glance()
+{
+ local cur prev nbc cflags
+ COMPREPLY=()
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
+
+ if [ "x$_glance_opts" == "x" ] ; then
+ nbc="`glance bash-completion | sed -e "s/ *-h */ /" -e "s/ *-i */ /"`"
+ _glance_opts="`echo "$nbc" | sed -e "s/--[a-z0-9_-]*//g" -e "s/ */ /g"`"
+ _glance_flags="`echo " $nbc" | sed -e "s/ [^-][^-][a-z0-9_-]*//g" -e "s/ */ /g"`"
+ _glance_opts_exp="`echo "$_glance_opts" | sed 's/^ *//' | tr ' ' '|'`"
+ fi
+
+ if [[ " ${COMP_WORDS[@]} " =~ " "($_glance_opts_exp)" " && "$prev" != "help" ]] ; then
+ COMPREPLY=($(compgen -W "${_glance_flags}" -- ${cur}))
+ else
+ COMPREPLY=($(compgen -W "${_glance_opts}" -- ${cur}))
+ fi
+ return 0
+}
+complete -F _glance glance \ No newline at end of file