Skip to content

Commit 5770364

Browse files
authored
Enable cli tab completion (#317)
1 parent 191e254 commit 5770364

File tree

5 files changed

+67
-1
lines changed

5 files changed

+67
-1
lines changed

.config/requirements-test.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
argcomplete
12
coverage[toml]
23
mypy
34
pip-tools

.pre-commit-config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ repos:
8080
args:
8181
- --output-format=colorized
8282
additional_dependencies:
83+
- argcomplete
8384
- pytest
8485
- pyyaml
8586
- subprocess_tee
@@ -91,6 +92,7 @@ repos:
9192
hooks:
9293
- id: mypy
9394
additional_dependencies:
95+
- argcomplete
9496
- pip
9597
- pytest
9698
- subprocess_tee

src/ansible_dev_environment/arg_parser.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@
1616
from .utils import str_to_bool
1717

1818

19+
try:
20+
import argcomplete
21+
22+
HAS_ARGCOMPLETE = True
23+
except ImportError: # pragma: no cover
24+
HAS_ARGCOMPLETE = False
25+
26+
1927
logger = logging.getLogger(__name__)
2028

2129
if TYPE_CHECKING:
@@ -255,6 +263,9 @@ def parse() -> argparse.Namespace:
255263
err = "The environment variable 'SKIP_UV' is deprecated, use 'ADE_UV' or '--no-uv' instead."
256264
warnings.warn(err, DeprecationWarning, stacklevel=2)
257265

266+
if HAS_ARGCOMPLETE:
267+
argcomplete.autocomplete(parser)
268+
258269
return apply_envvars(args=args, parser=parser)
259270

260271

src/ansible_dev_environment/cli.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# PYTHON_ARGCOMPLETE_OK
12
"""CLI entrypoint."""
23

34
from __future__ import annotations

tests/unit/test_cli.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
from pathlib import Path
66
from typing import TYPE_CHECKING
77

8+
import argcomplete
89
import pytest
910

10-
from ansible_dev_environment.arg_parser import ArgumentParser, apply_envvars
11+
from ansible_dev_environment.arg_parser import ArgumentParser, apply_envvars, parse
1112
from ansible_dev_environment.cli import Cli, main
1213

1314

@@ -385,3 +386,53 @@ def test_env_wrong_choice(
385386
cli.parse_args()
386387
captured = capsys.readouterr()
387388
assert "choose from 'restrictive', 'cfg', 'none'" in captured.err
389+
390+
391+
def test_arg_complete(monkeypatch: pytest.MonkeyPatch) -> None:
392+
"""Test argument completion.
393+
394+
Args:
395+
monkeypatch: Pytest fixture.
396+
"""
397+
inited_parser = None
398+
orig_apply_envvars = apply_envvars
399+
400+
def _apply_envvars(
401+
args: list[str],
402+
parser: ArgumentParser,
403+
) -> None:
404+
"""Apply environment variables to the argument parser.
405+
406+
Args:
407+
args: List of arguments.
408+
parser: Argument parser.
409+
"""
410+
nonlocal inited_parser
411+
inited_parser = parser
412+
orig_apply_envvars(args, parser)
413+
414+
monkeypatch.setattr(
415+
"ansible_dev_environment.arg_parser.apply_envvars",
416+
_apply_envvars,
417+
)
418+
419+
monkeypatch.setattr(
420+
"sys.argv",
421+
["ade", "install"],
422+
)
423+
parse()
424+
425+
cli = "ade ins"
426+
monkeypatch.setenv("_ARGCOMPLETE", "1")
427+
monkeypatch.setenv("_ARGCOMPLETE_IFS", "\013")
428+
monkeypatch.setenv("COMP_LINE", cli)
429+
monkeypatch.setenv("COMP_POINT", str(len(cli)))
430+
import io
431+
432+
str_io = io.StringIO()
433+
434+
argcomplete.autocomplete(inited_parser, exit_method=print, output_stream=str_io) # type: ignore[arg-type]
435+
436+
output = str_io.getvalue()
437+
assert "inspect" in output
438+
assert "install" in output

0 commit comments

Comments
 (0)