mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-17 07:20:53 +07:00
It has different API, so we now have two separate modules. Merge-request: IJ-MR-102673 Merged-by: Ilya Kazakevich <ilya.kazakevich@jetbrains.com> GitOrigin-RevId: 0a2dd2f74376662a34e8b782883f6631dc2a42b1
174 lines
5.4 KiB
Python
174 lines
5.4 KiB
Python
"""
|
|
Runs tox from current directory for tox 4
|
|
|
|
"""
|
|
import dataclasses
|
|
import enum
|
|
import os
|
|
import sys
|
|
from typing import List
|
|
|
|
from tox.config.sets import ConfigSet
|
|
from tox.config.types import Command
|
|
from tox.execute import Outcome
|
|
from tox.plugin import impl
|
|
from tox.plugin.manager import MANAGER
|
|
from tox.run import main
|
|
from tox.session.state import State
|
|
from tox.tox_env.api import ToxEnv
|
|
from tox.tox_env.python.pip.req_file import PythonDeps
|
|
from tox.tox_env.python.virtual_env.runner import VirtualEnvRunner
|
|
|
|
from tcmessages import TeamcityServiceMessages
|
|
|
|
teamcity = TeamcityServiceMessages()
|
|
|
|
helpers_dir = str(os.path.split(__file__)[0])
|
|
|
|
|
|
class Fixer:
|
|
def __init__(self, runner_name):
|
|
self.runner_name = runner_name
|
|
|
|
def fix(self, command: List[str], offset: int):
|
|
return ["python", os.path.join(helpers_dir, self.runner_name), "--offset",
|
|
str(offset), "--"]
|
|
|
|
|
|
class _Unit2(Fixer):
|
|
def __init__(self):
|
|
super(_Unit2, self).__init__("_jb_unittest_runner.py")
|
|
|
|
def fix(self, command: List[str], offset: int):
|
|
if command == ["python", "-m", "unittest", "discover"]:
|
|
return super(_Unit2, self).fix(command, offset) + ["discover"]
|
|
return None
|
|
|
|
|
|
class _PyTest(Fixer):
|
|
def __init__(self):
|
|
super(_PyTest, self).__init__("_jb_pytest_runner.py")
|
|
|
|
def fix(self, command: List[str], offset: int):
|
|
if command[0] not in ["pytest", "py.test"]:
|
|
return None
|
|
return super(_PyTest, self).fix(command, offset) + command[1:]
|
|
|
|
|
|
class _Nose(Fixer):
|
|
def __init__(self):
|
|
super(_Nose, self).__init__("_jb_nosetest_runner.py")
|
|
|
|
def fix(self, command: List[str], offset: int):
|
|
if command[0] != "nosetests":
|
|
return None
|
|
return super(_Nose, self).fix(command, offset) + command[1:]
|
|
|
|
|
|
_RUNNERS = [_Unit2(), _PyTest(), _Nose()]
|
|
|
|
|
|
class EnvState(enum.Enum):
|
|
NOT_STARTED = 0,
|
|
SUCCESS = 1,
|
|
FAILED = 2
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class Env:
|
|
offset: int
|
|
state: EnvState
|
|
|
|
|
|
class JBToxPlugin:
|
|
def __init__(self):
|
|
self.envs: dict[str, Env] = dict()
|
|
self.current_offset: int = 1
|
|
self.duration_strategy = "automatic"
|
|
self.matrix_called = False
|
|
self.skip_missing_interpreters = False
|
|
|
|
@impl
|
|
def tox_env_teardown(self, tox_env: ToxEnv):
|
|
if tox_env.name not in self.envs:
|
|
# Env hasn't been started, lets pretend we started it to skip it later
|
|
self._start_the_env(tox_env)
|
|
|
|
env = self.envs[tox_env.name]
|
|
|
|
if env.state == EnvState.NOT_STARTED:
|
|
if self.skip_missing_interpreters:
|
|
teamcity.testIgnored(tox_env.name, nodeId=env.offset)
|
|
else:
|
|
teamcity.testFailed(tox_env.name, nodeId=env.offset)
|
|
elif env.state == EnvState.FAILED:
|
|
teamcity.testFailed(tox_env.name, nodeId=env.offset, details="")
|
|
else:
|
|
teamcity.testFinished(tox_env.name, nodeId=env.offset)
|
|
|
|
@impl
|
|
def tox_add_core_config(self, core_conf: ConfigSet, state: State):
|
|
if state.conf.options.skip_missing_interpreters == "true":
|
|
self.skip_missing_interpreters = True
|
|
|
|
@impl
|
|
def tox_on_install(self, tox_env: ToxEnv, arguments: PythonDeps, section: str,
|
|
of_type: str):
|
|
try:
|
|
requirements = [str(r) for r in arguments.requirements]
|
|
if "pytest-xdist" in requirements:
|
|
self.duration_strategy = "manual"
|
|
except AttributeError:
|
|
pass # may have no req at all
|
|
|
|
self._start_the_env(tox_env)
|
|
|
|
def _start_the_env(self, tox_env: ToxEnv):
|
|
if tox_env.name in self.envs or tox_env.name == ".pkg":
|
|
return # Might be called several times, and .pkg is technical call
|
|
env_name = tox_env.name
|
|
env = Env(self.current_offset, EnvState.NOT_STARTED)
|
|
self.envs[env_name] = env
|
|
|
|
if not self.matrix_called:
|
|
teamcity.testMatrixEntered(durationStrategy=self.duration_strategy)
|
|
self.matrix_called = True
|
|
|
|
teamcity.testStarted(env_name, location="tox_env://" + env_name,
|
|
parentNodeId="0", nodeId=env.offset)
|
|
self.current_offset += 1000
|
|
|
|
@impl
|
|
def tox_before_run_commands(self, tox_env: VirtualEnvRunner):
|
|
tox_env.environment_variables["_jb_do_not_call_enter_matrix"] = "1"
|
|
commands: List[Command] = tox_env.conf["commands"]
|
|
if "_jb_do_not_patch_test_runners" not in os.environ or isinstance(commands,
|
|
list):
|
|
for command in commands:
|
|
for runner in _RUNNERS:
|
|
env = self.envs[tox_env.name]
|
|
fixed = runner.fix(command.args, env.offset)
|
|
if fixed:
|
|
command.args = fixed
|
|
|
|
@impl
|
|
def tox_after_run_commands(self, tox_env: ToxEnv, exit_code: int,
|
|
outcomes: List[Outcome]):
|
|
success = exit_code == 0 and all(o.exit_code == 0 for o in outcomes)
|
|
self.envs[tox_env.name].state = EnvState.SUCCESS if success else EnvState.FAILED
|
|
|
|
|
|
def patch_plugin_manager():
|
|
old = MANAGER.load_plugins
|
|
|
|
def custom(path):
|
|
old(path)
|
|
MANAGER.manager.register(JBToxPlugin())
|
|
|
|
MANAGER.load_plugins = custom
|
|
|
|
|
|
def run_tox_4():
|
|
patch_plugin_manager()
|
|
return main(sys.argv[1:])
|