/
niceSOFT
/
python3-hatchling
Обзор
Документация
Войти
/
niceSOFT
/
python3-hatchling
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/hatch/cli/env/run.py
147 строк
5 KB
Cary Hawkins
Enable removing environments if there is an error during creation unless keep-env flag is passed in (#2148)
07 янв 2026, 04:05
Не верифицирован
07 янв 2026, 04:05
ca29937
Код
Авторство
О чём код?
from __future__ import annotations import os from typing import TYPE_CHECKING import click from hatch.config.constants import AppEnvVars if TYPE_CHECKING: from hatch.cli.application import Application def filter_environments(environments, filter_data): selected_environments = [] for env_name, env_data in environments.items(): for key, value in filter_data.items(): if key not in env_data or env_data[key] != value: break else: selected_environments.append(env_name) return selected_environments @click.command(short_help="Run commands within project environments") @click.argument("args", required=True, nargs=-1) @click.option("--env", "-e", "env_names", multiple=True, help="The environments to target") @click.option("--include", "-i", "included_variable_specs", multiple=True, help="The matrix variables to include") @click.option("--exclude", "-x", "excluded_variable_specs", multiple=True, help="The matrix variables to exclude") @click.option("--filter", "-f", "filter_json", default=None, help="The JSON data used to select environments") @click.option( "--force-continue", is_flag=True, help="Run every command and if there were any errors exit with the first code" ) @click.option("--ignore-compat", is_flag=True, help="Ignore incompatibility when selecting specific environments") @click.pass_obj def run( app: Application, *, args: tuple[str, ...], env_names: tuple[str, ...], included_variable_specs: tuple[str, ...], excluded_variable_specs: tuple[str, ...], filter_json: str | None, force_continue: bool, ignore_compat: bool, ): """ Run commands within project environments. The `-e`/`--env` option overrides the equivalent [root option](#hatch) and the `HATCH_ENV` environment variable. The `-i`/`--include` and `-x`/`--exclude` options may be used to include or exclude certain variables, optionally followed by specific comma-separated values, and may be selected multiple times. For example, if you have the following configuration: \b ```toml config-example [[tool.hatch.envs.test.matrix]] python = ["3.9", "3.10"] version = ["42", "3.14", "9000"] ``` then running: \b ``` hatch env run -i py=3.10 -x version=9000 test:pytest ``` would execute `pytest` in the environments `test.py3.10-42` and `test.py3.10-3.14`. Note that `py` may be used as an alias for `python`. \b !!! note The inclusion option is treated as an intersection while the exclusion option is treated as a union i.e. an environment must match all of the included variables to be selected while matching any of the excluded variables will prevent selection. """ from hatch.utils.runner import parse_matrix_variables, select_environments try: included_variables = parse_matrix_variables(included_variable_specs) except ValueError as e: app.abort(f"Duplicate included variable: {e}") try: excluded_variables = parse_matrix_variables(excluded_variable_specs) except ValueError as e: app.abort(f"Duplicate excluded variable: {e}") app.ensure_environment_plugin_dependencies() project = app.project if not env_names: env_names = (app.env,) elif "system" in env_names: project.config.config["envs"] = { "system": { "type": "system", "skip-install": True, "scripts": project.config.scripts, } } # Deduplicate ordered_env_names = list(dict.fromkeys(env_names)) environments = [] matrix_selected = False for env_name in ordered_env_names: if env_name in project.config.matrices: matrix_selected = True env_data = project.config.matrices[env_name]["envs"] if not env_data: app.abort(f"No variables defined for matrix: {env_name}") environments.extend(select_environments(env_data, included_variables, excluded_variables)) else: environments.append(env_name) if filter_json: import json filter_data = json.loads(filter_json) if not isinstance(filter_data, dict): app.abort("The --filter/-f option must be a JSON mapping") environments[:] = filter_environments(project.config.envs, filter_data) if not environments: app.abort("No environments were selected") elif not matrix_selected and (included_variables or excluded_variables): app.abort(f"Variable selection is unsupported for non-matrix environments: {', '.join(ordered_env_names)}") for context in app.runner_context( environments, ignore_compat=ignore_compat or matrix_selected, display_header=matrix_selected, keep_env=bool(os.environ.get(AppEnvVars.KEEP_ENV)), ): if context.env.name == "system": context.env.exists = lambda: True # type: ignore[method-assign] context.force_continue = force_continue context.add_shell_command(list(args))