Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: more option argument completions #707

Merged
merged 10 commits into from
Feb 20, 2024
45 changes: 42 additions & 3 deletions nox/_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,18 @@

import argparse
import functools
import itertools
import os
import sys
from collections.abc import Iterable
from typing import Any, Callable, Sequence

from argcomplete.completers import (
ChoicesCompleter,
DirectoriesCompleter,
FilesCompleter,
)

from nox import _option_set
from nox.tasks import discover_manifest, filter_manifest, load_nox_module

Expand Down Expand Up @@ -225,19 +233,43 @@ def _posargs_finalizer(
return posargs[dash_index + 1 :]


def _python_completer(
prefix: str, parsed_args: argparse.Namespace, **kwargs: Any
) -> Iterable[str]:
global_config = parsed_args
scop marked this conversation as resolved.
Show resolved Hide resolved
module = load_nox_module(global_config)
scop marked this conversation as resolved.
Show resolved Hide resolved
manifest = discover_manifest(module, global_config)
scop marked this conversation as resolved.
Show resolved Hide resolved
return (
scop marked this conversation as resolved.
Show resolved Hide resolved
session.func.python
for session, _ in manifest.list_all_sessions()
if session.func.python
)


def _session_completer(
prefix: str, parsed_args: argparse.Namespace, **kwargs: Any
) -> list[str]:
) -> Iterable[str]:
global_config = parsed_args
global_config.list_sessions = True
module = load_nox_module(global_config)
scop marked this conversation as resolved.
Show resolved Hide resolved
manifest = discover_manifest(module, global_config)
scop marked this conversation as resolved.
Show resolved Hide resolved
filtered_manifest = filter_manifest(manifest, global_config)
if isinstance(filtered_manifest, int):
return []
return [
return (
session.friendly_name for session, _ in filtered_manifest.list_all_sessions()
]
)


def _tag_completer(
prefix: str, parsed_args: argparse.Namespace, **kwargs: Any
) -> Iterable[str]:
global_config = parsed_args
scop marked this conversation as resolved.
Show resolved Hide resolved
module = load_nox_module(global_config)
scop marked this conversation as resolved.
Show resolved Hide resolved
manifest = discover_manifest(module, global_config)
scop marked this conversation as resolved.
Show resolved Hide resolved
return itertools.chain.from_iterable(
scop marked this conversation as resolved.
Show resolved Hide resolved
session.tags for session, _ in manifest.list_all_sessions() if session.tags
)


options.add_options(
Expand Down Expand Up @@ -296,6 +328,7 @@ def _session_completer(
nargs="*",
default=default_env_var_list_factory("NOXPYTHON"),
help="Only run sessions that use the given python interpreter versions.",
completer=_python_completer,
),
_option_set.Option(
"keywords",
Expand All @@ -305,6 +338,7 @@ def _session_completer(
noxfile=True,
merge_func=functools.partial(_sessions_and_keywords_merge_func, "keywords"),
help="Only run sessions that match the given expression.",
completer=ChoicesCompleter(()),
),
_option_set.Option(
"tags",
Expand All @@ -314,6 +348,7 @@ def _session_completer(
noxfile=True,
nargs="*",
help="Only run sessions with the given tags.",
completer=_tag_completer,
),
_option_set.Option(
"posargs",
Expand Down Expand Up @@ -418,6 +453,7 @@ def _session_completer(
merge_func=_envdir_merge_func,
group=options.groups["environment"],
help="Directory where Nox will store virtualenvs, this is ``.nox`` by default.",
completer=DirectoriesCompleter(),
),
_option_set.Option(
"extra_pythons",
Expand All @@ -427,6 +463,7 @@ def _session_completer(
nargs="*",
default=default_env_var_list_factory("NOXEXTRAPYTHON"),
help="Additionally, run sessions using the given python interpreter versions.",
completer=_python_completer,
),
_option_set.Option(
"force_pythons",
Expand All @@ -440,6 +477,7 @@ def _session_completer(
" Noxfile. This is a shorthand for ``--python=X.Y --extra-python=X.Y``."
),
finalizer_func=_force_pythons_finalizer,
completer=_python_completer,
),
*_option_set.make_flag_pair(
"stop_on_first_error",
Expand Down Expand Up @@ -491,6 +529,7 @@ def _session_completer(
group=options.groups["reporting"],
noxfile=True,
help="Output a report of all sessions to the given filename.",
completer=FilesCompleter(("json",)),
),
_option_set.Option(
"non_interactive",
Expand Down
2 changes: 1 addition & 1 deletion tests/test__option_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def test_session_completer(self):
)

expected_sessions = ["testytest", "lintylint", "typeytype"]
assert expected_sessions == actual_sessions_from_file
assert expected_sessions == list(actual_sessions_from_file)

def test_session_completer_invalid_sessions(self):
parsed_args = _options.options.namespace(
Expand Down