-
-
Notifications
You must be signed in to change notification settings - Fork 504
/
single.py
124 lines (108 loc) · 4.32 KB
/
single.py
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
"""
Defines how to run a single tox environment.
"""
from __future__ import annotations
import logging
import time
from pathlib import Path
from typing import NamedTuple, cast
from tox.config.types import Command
from tox.execute.api import Outcome, StdinSource
from tox.tox_env.api import ToxEnv
from tox.tox_env.errors import Fail, Skip
from tox.tox_env.python.virtual_env.package.pyproject import ToxBackendFailed
from tox.tox_env.runner import RunToxEnv
LOGGER = logging.getLogger(__name__)
class ToxEnvRunResult(NamedTuple):
name: str
skipped: bool
code: int
outcomes: list[Outcome]
duration: float
ignore_outcome: bool = False
def run_one(tox_env: RunToxEnv, no_test: bool, suspend_display: bool) -> ToxEnvRunResult:
start_one = time.monotonic()
name = tox_env.conf.name
with tox_env.display_context(suspend_display):
skipped, code, outcomes = _evaluate(tox_env, no_test)
duration = time.monotonic() - start_one
return ToxEnvRunResult(name, skipped, code, outcomes, duration, tox_env.conf["ignore_outcome"])
def _evaluate(tox_env: RunToxEnv, no_test: bool) -> tuple[bool, int, list[Outcome]]:
skipped = False
code: int = 0
outcomes: list[Outcome] = []
try:
try:
tox_env.setup()
code, outcomes = run_commands(tox_env, no_test)
except Skip as exception:
LOGGER.warning("skipped because %s", exception)
code = 0
skipped = True
except ToxBackendFailed as exception:
LOGGER.error("%s", exception)
raise SystemExit(exception.code)
except Fail as exception:
LOGGER.error("failed with %s", exception)
code = 1
except Exception: # pragma: no cover
LOGGER.exception("internal error") # pragma: no cover
code = 2 # pragma: no cover
finally:
tox_env.teardown()
except SystemExit as exception: # setup command fails (interrupted or via invocation)
code = cast(int, exception.code)
return skipped, code, outcomes
def run_commands(tox_env: RunToxEnv, no_test: bool) -> tuple[int, list[Outcome]]:
outcomes: list[Outcome] = []
if no_test:
exit_code = Outcome.OK
else:
from tox.plugin.manager import MANAGER # importing this here to avoid circular import
chdir: Path = tox_env.conf["change_dir"]
chdir.mkdir(exist_ok=True, parents=True)
ignore_errors: bool = tox_env.conf["ignore_errors"]
MANAGER.tox_before_run_commands(tox_env)
status_pre, status_main, status_post = -1, -1, -1
try:
try:
status_pre = run_command_set(tox_env, "commands_pre", chdir, ignore_errors, outcomes)
if status_pre == Outcome.OK or ignore_errors:
status_main = run_command_set(tox_env, "commands", chdir, ignore_errors, outcomes)
else:
status_main = Outcome.OK
finally:
status_post = run_command_set(tox_env, "commands_post", chdir, ignore_errors, outcomes)
finally:
exit_code = status_pre or status_main or status_post # first non-success
MANAGER.tox_after_run_commands(tox_env, exit_code, outcomes)
return exit_code, outcomes
def run_command_set(tox_env: ToxEnv, key: str, cwd: Path, ignore_errors: bool, outcomes: list[Outcome]) -> int:
exit_code = Outcome.OK
command_set: list[Command] = tox_env.conf[key]
for at, cmd in enumerate(command_set):
current_outcome = tox_env.execute(
cmd.args,
cwd=cwd,
stdin=StdinSource.user_only(),
show=True,
run_id=f"{key}[{at}]",
)
outcomes.append(current_outcome)
try:
current_outcome.assert_success()
except SystemExit as exception:
if cmd.ignore_exit_code:
logging.warning("command failed but is marked ignore outcome so handling it as success")
continue
if ignore_errors:
if exit_code == Outcome.OK:
exit_code = cast(int, exception.code) # ignore errors continues ahead but saves the exit code
continue
return cast(int, exception.code)
return exit_code
__all__ = (
"run_one",
"run_command_set",
"ToxEnvRunResult",
)