Fix galaxy's parsing of the command line. (#17569)

Also make the parsing of the action in both galaxy and vault more
robust.

Fixes #17534
May Fix #17563
This commit is contained in:
Toshio Kuratomi 2016-09-14 11:49:54 -07:00 committed by GitHub
commit f4cd1c6321
3 changed files with 95 additions and 60 deletions

View file

@ -1,4 +1,5 @@
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
# (c) 2016, Toshio Kuratomi <tkuratomi@ansible.com>
#
# This file is part of Ansible
#
@ -52,6 +53,42 @@ class SortedOptParser(optparse.OptionParser):
return optparse.OptionParser.format_help(self, formatter=None)
# Note: Inherit from SortedOptParser so that we get our format_help method
class InvalidOptsParser(SortedOptParser):
'''Ignore invalid options.
Meant for the special case where we need to take care of help and version
but may not know the full range of options yet. (See it in use in set_action)
'''
def __init__(self, parser):
# Since this is special purposed to just handle help and version, we
# take a pre-existing option parser here and set our options from
# that. This allows us to give accurate help based on the given
# option parser.
SortedOptParser.__init__(self, usage=parser.usage,
option_list=parser.option_list,
option_class=parser.option_class,
conflict_handler=parser.conflict_handler,
description=parser.description,
formatter=parser.formatter,
add_help_option=False,
prog=parser.prog,
epilog=parser.epilog)
self.version=parser.version
def _process_long_opt(self, rargs, values):
try:
optparse.OptionParser._process_long_opt(self, rargs, values)
except optparse.BadOptionError:
pass
def _process_short_opts(self, rargs, values):
try:
optparse.OptionParser._process_short_opts(self, rargs, values)
except optparse.BadOptionError:
pass
class CLI(object):
''' code behind bin/ansible* programs '''
@ -82,7 +119,7 @@ class CLI(object):
"""
Get the action the user wants to execute from the sys argv list.
"""
for i in range(0,len(self.args)):
for i in range(0, len(self.args)):
arg = self.args[i]
if arg in self.VALID_ACTIONS:
self.action = arg
@ -90,8 +127,13 @@ class CLI(object):
break
if not self.action:
# if no need for action if version/help
tmp_options, tmp_args = self.parser.parse_args()
# if we're asked for help or version, we don't need an action.
# have to use a special purpose Option Parser to figure that out as
# the standard OptionParser throws an error for unknown options and
# without knowing action, we only know of a subset of the options
# that could be legal for this command
tmp_parser = InvalidOptsParser(self.parser)
tmp_options, tmp_args = tmp_parser.parse_args(self.args)
if not(hasattr(tmp_options, 'help') and tmp_options.help) or (hasattr(tmp_options, 'version') and tmp_options.version):
raise AnsibleOptionsError("Missing required action")

View file

@ -120,7 +120,7 @@ class GalaxyCLI(CLI):
if self.action in ("init","install"):
self.parser.add_option('-f', '--force', dest='force', action='store_true', default=False, help='Force overwriting an existing role')
self.options, self.args =self.parser.parse_args()
self.options, self.args = self.parser.parse_args(self.args[1:])
display.verbosity = self.options.verbosity
self.galaxy = Galaxy(self.options)
return True