ansible-test - Fix option filtering (#85182)

pull/85191/head
Matt Clay 7 months ago committed by GitHub
parent 1e64707592
commit feda0a5c6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
bugfixes:
- ansible-test - Fix incorrect handling of options with optional args (e.g. ``--color``),
when followed by other options which are omitted during arg filtering (e.g. ``--docker``).
Previously it was possible for non-option arguments to be incorrectly omitted in these cases.
(https://github.com/ansible/ansible/issues/85173)

@ -254,12 +254,29 @@ def filter_args(args: list[str], filters: dict[str, int]) -> list[str]:
"""Return a filtered version of the given command line arguments.""" """Return a filtered version of the given command line arguments."""
remaining = 0 remaining = 0
result = [] result = []
pass_through_args: list[str] = []
pass_through_explicit = False
pass_through_implicit = False
for arg in args: for arg in args:
if pass_through_explicit:
pass_through_args.append(arg)
continue
if arg == '--':
pass_through_explicit = True
continue
if not arg.startswith('-') and remaining: if not arg.startswith('-') and remaining:
remaining -= 1 remaining -= 1
pass_through_implicit = not remaining
continue continue
if not arg.startswith('-') and pass_through_implicit:
pass_through_args.append(arg)
continue
pass_through_implicit = False
remaining = 0 remaining = 0
parts = arg.split('=', 1) parts = arg.split('=', 1)
@ -271,6 +288,9 @@ def filter_args(args: list[str], filters: dict[str, int]) -> list[str]:
result.append(arg) result.append(arg)
if pass_through_args:
result += ['--'] + pass_through_args
return result return result

@ -34,3 +34,48 @@ def test_failed_interactive_command() -> None:
assert error.value.stdout is None assert error.value.stdout is None
assert error.value.stderr is None assert error.value.stderr is None
@pytest.mark.parametrize("args,filters,expected", (
(
# args after a known option must be separated from existing args
['--color', '--docker', 'default', 'ping', 'split'],
{'--docker': 1},
['--color', '--', 'ping', 'split'],
),
(
# args after '--' are not options
['--', '--color'],
{'--color': 1},
['--', '--color'],
),
(
# args after a known option must be separated from existing args without conflicting with an explicit '--'
['--color', '--docker', 'default', 'ping', '--', 'split'],
{'--docker': 1},
['--color', '--', 'ping', 'split'],
),
(
# args before options are properly handled
['ping', '--docker', 'default', '-v'],
{'--docker': 1},
['ping', '-v'],
),
(
# no options
['ping', 'split'],
{'--docker': 1},
['ping', 'split'],
),
(
# only options
['--color', '--docker', 'default', '-v'],
{'--docker': 1},
['--color', '-v'],
)
))
def test_filter_args(args: list[str], filters: dict[str, int], expected: list[str]) -> None:
"""Verify arg filtering properly handles various scenarios."""
from ansible_test._internal.util import filter_args
assert filter_args(args, filters) == expected

Loading…
Cancel
Save