diff options
Diffstat (limited to 'src/test_stages/cmd.py')
-rw-r--r-- | src/test_stages/cmd.py | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/src/test_stages/cmd.py b/src/test_stages/cmd.py index 68e9723..4c90cdb 100644 --- a/src/test_stages/cmd.py +++ b/src/test_stages/cmd.py @@ -65,9 +65,10 @@ class Config: filename: pathlib.Path get_all_envs: Callable[[Config], list[TestEnv]] + match_spec: parse.BoolExpr | None = None stages: list[Stage] = dataclasses.field(default_factory=list) utf8_env: dict[str, str] = dataclasses.field( - default_factory=lambda: utf8_locale.UTF8Detect().detect().env + default_factory=lambda: utf8_locale.UTF8Detect().detect().env, ) @@ -93,7 +94,8 @@ def select_stages(cfg: Config, all_stages: list[TestEnv]) -> list[TestStage]: """Group the stages as specified.""" def process_stage( - acc: tuple[list[TestStage], list[TestEnv]], stage: Stage + acc: tuple[list[TestStage], list[TestEnv]], + stage: Stage, ) -> tuple[list[TestStage], list[TestEnv]]: """Stash the environments matched by a stage specification.""" res, current = acc @@ -106,7 +108,19 @@ def select_stages(cfg: Config, all_stages: list[TestEnv]) -> list[TestStage]: return res, left res_init: Final[list[TestStage]] = [] - return functools.reduce(process_stage, cfg.stages, (res_init, list(all_stages)))[0] + selected: Final = functools.reduce(process_stage, cfg.stages, (res_init, list(all_stages)))[0] + match_spec: Final = cfg.match_spec + if match_spec is None: + return selected + + matched_all: Final = [ + stage._replace(envlist=[env for env in stage.envlist if match_spec.evaluate(env)]) + for stage in selected + ] + matched: Final = [stage for stage in matched_all if stage.envlist] + if not matched: + sys.exit("None of the selected environments satisfied the additional match condition") + return matched def extract_cfg(ctx: click.Context) -> Config: @@ -175,6 +189,12 @@ def click_run() -> Callable[[Callable[[Config, list[TestStage], list[str]], None ), ) @click.option( + "-m", + "--match-spec", + type=str, + help="additional stage specifications for the tests to run", + ) + @click.option( "-p", "--parallel", type=StagesList, @@ -183,7 +203,11 @@ def click_run() -> Callable[[Callable[[Config, list[TestStage], list[str]], None @click.argument("stages_spec", nargs=-1, required=False, type=str) @click.pass_context def real_run( - ctx: click.Context, arg: list[str], parallel: StagesList | None, stages_spec: list[str] + ctx: click.Context, + arg: list[str], + match_spec: str | None, + parallel: StagesList | None, + stages_spec: list[str], ) -> None: """Run the test environments in stages.""" cfg_base: Final = extract_cfg(ctx) @@ -196,6 +220,7 @@ def click_run() -> Callable[[Callable[[Config, list[TestStage], list[str]], None pstages: Final = set(range(len(stages_spec))) if parallel is None else parallel.stages cfg: Final = dataclasses.replace( cfg_base, + match_spec=parse.parse_spec(match_spec) if match_spec is not None else None, stages=[ Stage(spec, parse.parse_spec(spec), idx in pstages) for idx, spec in enumerate(stages_spec) |