diff --git a/CHANGELOG.md b/CHANGELOG.md index 014edad8c..1d6c5f90e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines. +## [0.82.1](https://github.com/robotcodedev/robotcode/compare/v0.82.0..v0.82.1) - 2024-05-09 + +### Bug Fixes + +- **runner:** `--by-longname` and `--exclude-by-longname` now take into account whether a name for the run was set via `--name` command line argument or in the `name` setting robot.toml ([6f5c719](https://github.com/robotcodedev/robotcode/commit/6f5c719832885e524b72a69d47b2ccaf0608f6f9)) + + +### Refactor + +- **debugger:** Some code simplifications ([bc97744](https://github.com/robotcodedev/robotcode/commit/bc977445a5419cdc6ea5ad968298395a538a12bc)) + + ## [0.82.0](https://github.com/robotcodedev/robotcode/compare/v0.81.0..v0.82.0) - 2024-05-05 ### Features diff --git a/package-lock.json b/package-lock.json index baf83107c..596f092a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "robotcode", - "version": "0.82.0", + "version": "0.82.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "robotcode", - "version": "0.82.0", + "version": "0.82.1", "funding": [ { "type": "opencollective", diff --git a/package.json b/package.json index 5b05c12ad..b85d798ae 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Robot Framework IntelliSense, linting, test execution and debugging, code formatting, refactoring, and many more", "icon": "images/icon.png", "publisher": "d-biehl", - "version": "0.82.0", + "version": "0.82.1", "author": { "name": "Daniel Biehl", "url": "https://github.com/robotcodedev/" diff --git a/packages/analyze/pyproject.toml b/packages/analyze/pyproject.toml index 5599cba35..61c9c5ef3 100644 --- a/packages/analyze/pyproject.toml +++ b/packages/analyze/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ ] dependencies = [ "robotframework>=4.1.0", - "robotcode-plugin==0.82.0", - "robotcode-robot==0.82.0", - "robotcode==0.82.0", + "robotcode-plugin==0.82.1", + "robotcode-robot==0.82.1", + "robotcode==0.82.1", ] dynamic = ["version"] diff --git a/packages/analyze/src/robotcode/analyze/__version__.py b/packages/analyze/src/robotcode/analyze/__version__.py index d492f60ff..322309757 100644 --- a/packages/analyze/src/robotcode/analyze/__version__.py +++ b/packages/analyze/src/robotcode/analyze/__version__.py @@ -1 +1 @@ -__version__ = "0.82.0" +__version__ = "0.82.1" diff --git a/packages/core/src/robotcode/core/__version__.py b/packages/core/src/robotcode/core/__version__.py index d492f60ff..322309757 100644 --- a/packages/core/src/robotcode/core/__version__.py +++ b/packages/core/src/robotcode/core/__version__.py @@ -1 +1 @@ -__version__ = "0.82.0" +__version__ = "0.82.1" diff --git a/packages/debugger/pyproject.toml b/packages/debugger/pyproject.toml index 613fbccc5..b4e3bbafa 100644 --- a/packages/debugger/pyproject.toml +++ b/packages/debugger/pyproject.toml @@ -28,8 +28,8 @@ classifiers = [ dynamic = ["version"] dependencies = [ "robotframework>=4.1.0", - "robotcode-jsonrpc2==0.82.0", - "robotcode-runner==0.82.0", + "robotcode-jsonrpc2==0.82.1", + "robotcode-runner==0.82.1", ] [project.optional-dependencies] diff --git a/packages/debugger/src/robotcode/debugger/__version__.py b/packages/debugger/src/robotcode/debugger/__version__.py index d492f60ff..322309757 100644 --- a/packages/debugger/src/robotcode/debugger/__version__.py +++ b/packages/debugger/src/robotcode/debugger/__version__.py @@ -1 +1 @@ -__version__ = "0.82.0" +__version__ = "0.82.1" diff --git a/packages/debugger/src/robotcode/debugger/debugger.py b/packages/debugger/src/robotcode/debugger/debugger.py index af20c8619..bf10dc01a 100644 --- a/packages/debugger/src/robotcode/debugger/debugger.py +++ b/packages/debugger/src/robotcode/debugger/debugger.py @@ -1,6 +1,3 @@ -from __future__ import annotations - -import asyncio import itertools import os import pathlib @@ -157,7 +154,7 @@ def __init__(self, thread_id: Any) -> None: class StackFrameEntry: def __init__( self, - parent: Optional[StackFrameEntry], + parent: Optional["StackFrameEntry"], context: Any, name: str, type: str, @@ -193,7 +190,7 @@ def __init__( def __repr__(self) -> str: return f"StackFrameEntry({self.name!r}, {self.type!r}, {self.source!r}, {self.line!r}, {self.column!r})" - def get_first_or_self(self) -> StackFrameEntry: + def get_first_or_self(self) -> "StackFrameEntry": if self.stack_frames: return self.stack_frames[0] return self @@ -260,14 +257,14 @@ def end_keyword(self, data: running.Keyword, result: result.Keyword) -> None: class Debugger: - __instance: ClassVar[Optional[Debugger]] = None + __instance: ClassVar[Optional["Debugger"]] = None __lock: ClassVar = threading.RLock() __inside_instance: ClassVar = False _logger = LoggingDescriptor() @classmethod - def instance(cls) -> Debugger: + def instance(cls) -> "Debugger": if cls.__instance is not None: return cls.__instance with cls.__lock: @@ -318,7 +315,6 @@ def __init__(self) -> None: self.terminated = False self.attached = False self.path_mappings: List[PathMapping] = [] - self.server_loop: Optional[asyncio.AbstractEventLoop] = None self._keyword_to_evaluate: Optional[Callable[..., Any]] = None self._evaluated_keyword_result: Any = None @@ -917,14 +913,12 @@ def end_suite(self, name: str, attributes: Dict[str, Any]) -> None: status = attributes.get("status", "") if status == "FAIL": - if self.server_loop: - self.process_end_state( - status, - {"failed_suite"}, - "Suite failed.", - f"Suite failed{f': {v}' if (v := attributes.get('message')) else ''}", - ) - + self.process_end_state( + status, + {"failed_suite"}, + "Suite failed.", + f"Suite failed{f': {v}' if (v := attributes.get('message')) else ''}", + ) self.wait_for_running() source = attributes.get("source") diff --git a/packages/debugger/src/robotcode/debugger/protocol.py b/packages/debugger/src/robotcode/debugger/protocol.py index 2310c73d6..47112f486 100644 --- a/packages/debugger/src/robotcode/debugger/protocol.py +++ b/packages/debugger/src/robotcode/debugger/protocol.py @@ -12,6 +12,7 @@ List, Mapping, Optional, + Set, Tuple, Type, TypeVar, @@ -81,6 +82,7 @@ def __init__(self) -> None: self._received_request_lock = threading.RLock() self._received_request: OrderedDict[int, asyncio.Future[Any]] = OrderedDict() self._initialized = False + self._running_handle_message_tasks: Set[asyncio.Future[Any]] = set() @_logger.call def send_message(self, message: ProtocolMessage) -> None: @@ -140,14 +142,10 @@ def _handle_body(self, body: bytes, charset: str) -> None: ) def _handle_messages(self, iterator: Iterator[ProtocolMessage]) -> None: - def done(f: "asyncio.Future[Any]") -> None: - ex = f.exception() - if ex is not None and not isinstance(ex, asyncio.CancelledError): - self._logger.exception(ex, exc_info=ex) - for m in iterator: task = asyncio.create_task(self.handle_message(m), name="handle_message") - task.add_done_callback(done) + self._running_handle_message_tasks.add(task) + task.add_done_callback(self._running_handle_message_tasks.discard) @_logger.call async def handle_message(self, message: ProtocolMessage) -> None: diff --git a/packages/debugger/src/robotcode/debugger/run.py b/packages/debugger/src/robotcode/debugger/run.py index 0cf14c207..5bbf503e8 100644 --- a/packages/debugger/src/robotcode/debugger/run.py +++ b/packages/debugger/src/robotcode/debugger/run.py @@ -230,7 +230,6 @@ def run_debugger( Debugger.instance().colored_output = app.colored Debugger.instance().debug = debug Debugger.instance().set_main_thread(threading.current_thread()) - Debugger.instance().server_loop = server.loop app.verbose("Start the debugger instance") Debugger.instance().start() @@ -267,7 +266,7 @@ def run_debugger( server.protocol.terminate() if not server.protocol.wait_for_disconnected(): - app.warning("Timeout to get disconnected from client") + app.verbose("Timeout to get disconnected from client") server.loop.stop() diff --git a/packages/jsonrpc2/pyproject.toml b/packages/jsonrpc2/pyproject.toml index d8dc7814d..ddcda875c 100644 --- a/packages/jsonrpc2/pyproject.toml +++ b/packages/jsonrpc2/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ "Framework :: Robot Framework", "Framework :: Robot Framework :: Tool", ] -dependencies = ["robotcode-core==0.82.0"] +dependencies = ["robotcode-core==0.82.1"] dynamic = ["version"] [project.urls] diff --git a/packages/jsonrpc2/src/robotcode/jsonrpc2/__version__.py b/packages/jsonrpc2/src/robotcode/jsonrpc2/__version__.py index d492f60ff..322309757 100644 --- a/packages/jsonrpc2/src/robotcode/jsonrpc2/__version__.py +++ b/packages/jsonrpc2/src/robotcode/jsonrpc2/__version__.py @@ -1 +1 @@ -__version__ = "0.82.0" +__version__ = "0.82.1" diff --git a/packages/language_server/pyproject.toml b/packages/language_server/pyproject.toml index 2fee2d20a..ed696026f 100644 --- a/packages/language_server/pyproject.toml +++ b/packages/language_server/pyproject.toml @@ -27,9 +27,9 @@ classifiers = [ ] dependencies = [ "robotframework>=4.1.0", - "robotcode-jsonrpc2==0.82.0", - "robotcode-robot==0.82.0", - "robotcode==0.82.0", + "robotcode-jsonrpc2==0.82.1", + "robotcode-robot==0.82.1", + "robotcode==0.82.1", ] dynamic = ["version"] diff --git a/packages/language_server/src/robotcode/language_server/__version__.py b/packages/language_server/src/robotcode/language_server/__version__.py index d492f60ff..322309757 100644 --- a/packages/language_server/src/robotcode/language_server/__version__.py +++ b/packages/language_server/src/robotcode/language_server/__version__.py @@ -1 +1 @@ -__version__ = "0.82.0" +__version__ = "0.82.1" diff --git a/packages/modifiers/src/robotcode/modifiers/__version__.py b/packages/modifiers/src/robotcode/modifiers/__version__.py index d492f60ff..322309757 100644 --- a/packages/modifiers/src/robotcode/modifiers/__version__.py +++ b/packages/modifiers/src/robotcode/modifiers/__version__.py @@ -1 +1 @@ -__version__ = "0.82.0" +__version__ = "0.82.1" diff --git a/packages/modifiers/src/robotcode/modifiers/longname_modifiers.py b/packages/modifiers/src/robotcode/modifiers/longname_modifiers.py index 33be25dc9..fe091cf55 100644 --- a/packages/modifiers/src/robotcode/modifiers/longname_modifiers.py +++ b/packages/modifiers/src/robotcode/modifiers/longname_modifiers.py @@ -1,23 +1,44 @@ -from typing import Union +from typing import Optional, Union from robot.api import SuiteVisitor from robot.running import TestCase, TestSuite -class ByLongName(SuiteVisitor): - def __init__(self, *included: str) -> None: +class _BaseSuiteVisitor(SuiteVisitor): + def __init__(self, *included: str, root_name: Optional[str] = None) -> None: super().__init__() - self.included = included + self.included = list(included) + + self.root_name = root_name + self.real_root_name: Optional[str] = None def start_suite(self, suite: TestSuite) -> None: - suite.tests = [t for t in suite.tests if self._is_included(t)] + if self.real_root_name is None and self.root_name is not None: + self.real_root_name = suite.longname + new_included = [] + for i in self.included: + if "." in i: + root_name, rest = c if len(c := i.split(".", 1)) > 1 else (c, None) + if root_name == self.root_name: + if rest is not None: + new_included.append(f"{self.real_root_name}.{rest}") + else: + new_included.append(f"{self.real_root_name}'") + else: + new_included.append(i) + else: + new_included.append(i) + self.included = new_included def _is_included(self, test: Union[TestCase, TestSuite]) -> bool: names = [] names.append(test.longname) current = test.parent while current: - names.append(current.longname) + if current.parent is None: + names.append(self.root_name if self.root_name is not None else current.longname) + else: + names.append(current.longname) current = current.parent return any((s in names) for s in self.included) @@ -26,23 +47,15 @@ def end_suite(self, suite: TestSuite) -> None: suite.suites = [s for s in suite.suites if s.test_count > 0] -class ExcludedByLongName(SuiteVisitor): - def __init__(self, *included: str) -> None: - super().__init__() - self.included = included - +class ByLongName(_BaseSuiteVisitor): def start_suite(self, suite: TestSuite) -> None: - suite.tests = [t for t in suite.tests if not self._is_included(t)] + super().start_suite(suite) - def _is_included(self, test: Union[TestCase, TestSuite]) -> bool: - names = [] - names.append(test.longname) - current = test.parent - while current: - names.append(current.longname) - current = current.parent + suite.tests = [t for t in suite.tests if self._is_included(t)] - return any((s in names) for s in self.included) - def end_suite(self, suite: TestSuite) -> None: - suite.suites = [s for s in suite.suites if s.test_count > 0] +class ExcludedByLongName(_BaseSuiteVisitor): + def start_suite(self, suite: TestSuite) -> None: + super().start_suite(suite) + + suite.tests = [t for t in suite.tests if not self._is_included(t)] diff --git a/packages/plugin/src/robotcode/plugin/__version__.py b/packages/plugin/src/robotcode/plugin/__version__.py index d492f60ff..322309757 100644 --- a/packages/plugin/src/robotcode/plugin/__version__.py +++ b/packages/plugin/src/robotcode/plugin/__version__.py @@ -1 +1 @@ -__version__ = "0.82.0" +__version__ = "0.82.1" diff --git a/packages/robot/pyproject.toml b/packages/robot/pyproject.toml index 79c6d6ddc..01a459292 100644 --- a/packages/robot/pyproject.toml +++ b/packages/robot/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "robotframework>=4.1.0", "tomli>=1.1.0; python_version < '3.11'", "platformdirs>=3.2.0,<4.2.0", - "robotcode-core==0.82.0", + "robotcode-core==0.82.1", ] dynamic = ["version"] diff --git a/packages/robot/src/robotcode/robot/__version__.py b/packages/robot/src/robotcode/robot/__version__.py index d492f60ff..322309757 100644 --- a/packages/robot/src/robotcode/robot/__version__.py +++ b/packages/robot/src/robotcode/robot/__version__.py @@ -1 +1 @@ -__version__ = "0.82.0" +__version__ = "0.82.1" diff --git a/packages/runner/pyproject.toml b/packages/runner/pyproject.toml index 3b99e4892..0dbd3b6cf 100644 --- a/packages/runner/pyproject.toml +++ b/packages/runner/pyproject.toml @@ -28,10 +28,10 @@ classifiers = [ dynamic = ["version"] dependencies = [ "robotframework>=4.1.0", - "robotcode-robot==0.82.0", - "robotcode-modifiers==0.82.0", - "robotcode-plugin==0.82.0", - "robotcode==0.82.0", + "robotcode-robot==0.82.1", + "robotcode-modifiers==0.82.1", + "robotcode-plugin==0.82.1", + "robotcode==0.82.1", ] [project.entry-points.robotcode] diff --git a/packages/runner/src/robotcode/runner/__version__.py b/packages/runner/src/robotcode/runner/__version__.py index d492f60ff..322309757 100644 --- a/packages/runner/src/robotcode/runner/__version__.py +++ b/packages/runner/src/robotcode/runner/__version__.py @@ -1 +1 @@ -__version__ = "0.82.0" +__version__ = "0.82.1" diff --git a/packages/runner/src/robotcode/runner/cli/discover/discover.py b/packages/runner/src/robotcode/runner/cli/discover/discover.py index 69e750607..aacee5ac9 100644 --- a/packages/runner/src/robotcode/runner/cli/discover/discover.py +++ b/packages/runner/src/robotcode/runner/cli/discover/discover.py @@ -462,9 +462,7 @@ def handle_options( exclude_by_longname: Tuple[str, ...], robot_options_and_args: Tuple[str, ...], ) -> Tuple[TestSuite, Collector, Optional[Dict[str, List[Diagnostic]]]]: - root_folder, profile, cmd_options = handle_robot_options( - app, by_longname, exclude_by_longname, robot_options_and_args - ) + root_folder, profile, cmd_options = handle_robot_options(app, robot_options_and_args) diagnostics_logger = DiagnosticsLogger() try: @@ -479,6 +477,8 @@ def handle_options( ), app.config.dry, root_folder, + by_longname, + exclude_by_longname, ).parse_arguments((*cmd_options, "--runemptysuite", *robot_options_and_args)) settings = RobotSettings(options) diff --git a/packages/runner/src/robotcode/runner/cli/robot.py b/packages/runner/src/robotcode/runner/cli/robot.py index ea93e5e54..36f559a0e 100644 --- a/packages/runner/src/robotcode/runner/cli/robot.py +++ b/packages/runner/src/robotcode/runner/cli/robot.py @@ -8,6 +8,7 @@ from robot.run import USAGE, RobotFramework from robot.version import get_full_version +import robotcode.modifiers from robotcode.plugin import Application, pass_application from robotcode.plugin.click_helper.aliases import AliasedCommand from robotcode.plugin.click_helper.types import add_options @@ -25,6 +26,8 @@ def __init__( paths: List[str], dry: bool, root_folder: Optional[Path], + by_longname: Tuple[str, ...] = (), + exclude_by_longname: Tuple[str, ...] = (), ) -> None: super().__init__() self.app = app @@ -32,6 +35,8 @@ def __init__( self.dry = dry self.root_folder = root_folder self._orig_cwd = Path.cwd() + self.by_longname = by_longname + self.exclude_by_longname = exclude_by_longname def parse_arguments(self, cli_args: Any) -> Any: if self.root_folder is not None and Path.cwd() != self.root_folder: @@ -61,6 +66,18 @@ def parse_arguments(self, cli_args: Any) -> Any: f'{line_end.join((*(f"{k} = {v!r}" for k, v in options.items()), *arguments))}' ) + modifiers = [] + root_name = options.get("name", None) + + if self.by_longname: + modifiers.append(robotcode.modifiers.ByLongName(*self.by_longname, root_name=root_name)) + + if self.exclude_by_longname: + modifiers.append(robotcode.modifiers.ExcludedByLongName(*self.exclude_by_longname, root_name=root_name)) + + if modifiers: + options["prerunmodifier"] = options.get("prerunmodifier", []) + modifiers + return options, arguments @@ -90,10 +107,7 @@ def parse_arguments(self, cli_args: Any) -> Any: def handle_robot_options( - app: Application, - by_longname: Tuple[str, ...], - exclude_by_longname: Tuple[str, ...], - robot_options_and_args: Tuple[str, ...], + app: Application, robot_options_and_args: Tuple[str, ...] ) -> Tuple[Optional[Path], RobotBaseProfile, List[str]]: robot_arguments: Optional[List[Union[str, Path]]] = None old_sys_path = sys.path.copy() @@ -118,20 +132,6 @@ def handle_robot_options( cmd_options = profile.build_command_line() - if by_longname: - sep = ";" if any(True for l in by_longname if ":" in l) else ":" - cmd_options += ( - "--prerunmodifier", - f"robotcode.modifiers.ByLongName{sep}{sep.join(by_longname)}", - ) - - if exclude_by_longname: - sep = ";" if any(True for l in exclude_by_longname if ":" in l) else ":" - cmd_options += ( - "--prerunmodifier", - f"robotcode.modifiers.ExcludedByLongName{sep}{sep.join(exclude_by_longname)}", - ) - app.verbose( lambda: "Executing robot with following options:\n " + " ".join(f'"{o}"' for o in (cmd_options + list(robot_options_and_args))) @@ -170,9 +170,7 @@ def robot( ``` """ - root_folder, profile, cmd_options = handle_robot_options( - app, by_longname, exclude_by_longname, robot_options_and_args - ) + root_folder, profile, cmd_options = handle_robot_options(app, robot_options_and_args) app.exit( cast( @@ -186,6 +184,8 @@ def robot( ), app.config.dry, root_folder, + by_longname, + exclude_by_longname, ).execute_cli((*cmd_options, *robot_options_and_args), exit=False), ) ) diff --git a/pyproject.toml b/pyproject.toml index 21b5f13ca..4f02a07c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,9 +50,9 @@ classifiers = [ ] requires-python = ">=3.8" dependencies = [ - "robotcode-core==0.82.0", - "robotcode-plugin==0.82.0", - "robotcode-robot==0.82.0", + "robotcode-core==0.82.1", + "robotcode-plugin==0.82.1", + "robotcode-robot==0.82.1", ] dynamic = ["version"] @@ -70,20 +70,20 @@ robotcode = "robotcode.cli.__main__:main" [project.optional-dependencies] -debugger = ["robotcode-debugger==0.82.0"] -languageserver = ["robotcode-language-server==0.82.0"] -runner = ["robotcode-runner==0.82.0"] -analyze = ["robotcode-analyze==0.82.0"] +debugger = ["robotcode-debugger==0.82.1"] +languageserver = ["robotcode-language-server==0.82.1"] +runner = ["robotcode-runner==0.82.1"] +analyze = ["robotcode-analyze==0.82.1"] yaml = ["PyYAML>=5.4"] lint = ["robotframework-robocop>=2.0.0"] tidy = ["robotframework-tidy>=2.0.0"] rest = ["docutils"] colored = ["rich"] all = [ - "robotcode-debugger==0.82.0", - "robotcode-language-server==0.82.0", - "robotcode-runner==0.82.0", - "robotcode-analyze==0.82.0", + "robotcode-debugger==0.82.1", + "robotcode-language-server==0.82.1", + "robotcode-runner==0.82.1", + "robotcode-analyze==0.82.1", "PyYAML>=5.4", "robotframework-robocop>=2.0.0", "robotframework-tidy>=2.0.0", diff --git a/src/robotcode/cli/__version__.py b/src/robotcode/cli/__version__.py index d492f60ff..322309757 100644 --- a/src/robotcode/cli/__version__.py +++ b/src/robotcode/cli/__version__.py @@ -1 +1 @@ -__version__ = "0.82.0" +__version__ = "0.82.1"