summaryrefslogtreecommitdiff
path: root/src/tox/session/cmd/legacy.py
blob: b3327b08937b8191b18c62f05da5473625734938 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
from __future__ import annotations

from pathlib import Path
from typing import cast

from packaging.requirements import InvalidRequirement, Requirement

from tox.config.cli.parser import DEFAULT_VERBOSITY, Parsed, ToxParser
from tox.config.loader.memory import MemoryLoader
from tox.config.set_env import SetEnv
from tox.plugin import impl
from tox.session.cmd.run.common import env_run_create_flags
from tox.session.cmd.run.parallel import OFF_VALUE, parallel_flags, run_parallel
from tox.session.cmd.run.sequential import run_sequential
from tox.session.state import State
from tox.tox_env.python.pip.req_file import PythonDeps

from ..env_select import CliEnv, EnvSelector, register_env_select_flags
from .devenv import devenv
from .list_env import list_env
from .show_config import show_config


@impl
def tox_add_option(parser: ToxParser) -> None:
    our = parser.add_command("legacy", ["le"], "legacy entry-point command", legacy)
    our.add_argument("--help-ini", "--hi", action="store_true", help="show live configuration", dest="show_config")
    our.add_argument(
        "--showconfig",
        action="store_true",
        help="show live configuration (by default all env, with -l only default targets, specific via TOXENV/-e)",
        dest="show_config",
    )
    our.add_argument(
        "-a",
        "--listenvs-all",
        action="store_true",
        help="show list of all defined environments (with description if verbose)",
        dest="list_envs_all",
    )
    our.add_argument(
        "-l",
        "--listenvs",
        action="store_true",
        help="show list of test environments (with description if verbose)",
        dest="list_envs",
    )
    our.add_argument(
        "--devenv",
        help="sets up a development environment at ENVDIR based on the env's tox configuration specified by"
        "`-e` (-e defaults to py)",
        dest="devenv_path",
        metavar="ENVDIR",
        default=None,
        of_type=Path,
    )
    register_env_select_flags(our, default=CliEnv())
    env_run_create_flags(our, mode="legacy")
    parallel_flags(our, default_parallel=OFF_VALUE, no_args=True)
    our.add_argument(
        "--pre",
        action="store_true",
        help="deprecated use PIP_PRE in set_env instead - install pre-releases and development versions of"
        "dependencies; this will set PIP_PRE=1 environment variable",
    )
    our.add_argument(
        "--force-dep",
        action="append",
        metavar="req",
        default=[],
        help="Forces a certain version of one of the dependencies when configuring the virtual environment. REQ "
        "Examples 'pytest<6.1' or 'django>=2.2'.",
        type=Requirement,
    )
    our.add_argument(
        "--sitepackages",
        action="store_true",
        help="deprecated use VIRTUALENV_SYSTEM_SITE_PACKAGES=1, override sitepackages setting to True in all envs",
        dest="site_packages",
    )
    our.add_argument(
        "--alwayscopy",
        action="store_true",
        help="deprecated use VIRTUALENV_ALWAYS_COPY=1, override always copy setting to True in all envs",
        dest="always_copy",
    )


def legacy(state: State) -> int:
    option = state.conf.options
    if option.show_config:
        option.list_keys_only = []
        option.show_core = not bool(option.env)
    if option.list_envs or option.list_envs_all:
        state.envs.on_empty_fallback_py = False
        option.list_no_description = option.verbosity <= DEFAULT_VERBOSITY
        option.list_default_only = not option.list_envs_all
        option.show_core = False

    _handle_legacy_only_flags(option, state.envs)

    if option.show_config:
        return show_config(state)
    if option.list_envs or option.list_envs_all:
        return list_env(state)
    if option.devenv_path:
        option.devenv_path = Path(option.devenv_path)
        option.env = option.env or CliEnv("py")
        return devenv(state)
    if option.parallel != 0:  # only 0 means sequential
        return run_parallel(state)
    return run_sequential(state)


def _handle_legacy_only_flags(option: Parsed, envs: EnvSelector) -> None:
    override = {}
    if getattr(option, "site_packages", False):
        override["system_site_packages"] = True
    if getattr(option, "always_copy", False):
        override["always_copy"] = True
    set_env = {}
    if getattr(option, "pre", False):
        set_env["PIP_PRE"] = "1"
    forced = {j.name: j for j in getattr(option, "force_dep", [])}
    if override or set_env or forced:
        for env in envs.iter(only_active=True, package=False):
            env_conf = envs[env].conf
            if override:
                env_conf.loaders.insert(0, MemoryLoader(**override))
            if set_env:
                cast(SetEnv, env_conf["set_env"]).update(set_env, override=True)
            if forced:
                to_force = forced.copy()
                deps = cast(PythonDeps, env_conf["deps"])
                as_root_args = deps.as_root_args
                for at, entry in enumerate(as_root_args):
                    try:
                        req = Requirement(entry)
                    except InvalidRequirement:
                        continue
                    if req.name in to_force:
                        as_root_args[at] = str(to_force[req.name])
                        del to_force[req.name]
                as_root_args.extend(str(v) for v in to_force.values())