33import sys
44from dataclasses import dataclass
55from pathlib import Path
6- from typing import Any , Dict , Iterable , List , Optional , Tuple
6+ from typing import Any , Dict , Iterable , List , Optional , Tuple , Union
77
88import click
99import robot .running .model as running_model
1414from robot .output import LOGGER , Message
1515from robot .running .builder import TestSuiteBuilder
1616from robot .running .builder .builders import SuiteStructureParser
17+ from robotcode .core .dataclasses import from_json
1718from robotcode .core .lsp .types import Diagnostic , DiagnosticSeverity , DocumentUri , Position , Range
1819from robotcode .core .uri import Uri
1920from robotcode .plugin import Application , OutputFormat , UnknownError , pass_application
@@ -31,13 +32,18 @@ def __init__(self, *args: Any, error_message: str, **kwargs: Any) -> None:
3132__patched = False
3233
3334
35+ _stdin_data : Optional [Dict [str , str ]] = None
36+
37+
3438def _patch () -> None :
3539 global __patched
3640 if __patched :
3741 return
3842 __patched = True
3943
4044 if get_robot_version () <= (6 , 1 , 0 , "a" , 1 , None ):
45+ from robot .running .builder .parsers import RobotParser
46+
4147 if get_robot_version () > (5 , 0 ) and get_robot_version () < (6 , 0 , 0 ) or get_robot_version () < (5 , 0 ):
4248 from robot .running .builder .testsettings import TestDefaults # pyright: ignore[reportMissingImports]
4349 else :
@@ -75,8 +81,20 @@ def build_suite(self: SuiteStructureParser, structure: Any) -> Tuple[TestSuite,
7581
7682 SuiteStructureParser ._build_suite = build_suite
7783
84+ old_get_source = RobotParser ._get_source
85+
86+ def _get_source (self : RobotParser , path : Path ) -> Union [Path , str ]:
87+ if _stdin_data is not None and (data := _stdin_data .get (str (path ))) is not None :
88+ if data is not None :
89+ return data
90+
91+ return old_get_source (self , path ) # type: ignore
92+
93+ RobotParser ._get_source = _get_source
94+
7895 elif get_robot_version () >= (6 , 1 , 0 , "a" , 1 , None ):
7996 from robot .parsing .suitestructure import SuiteDirectory , SuiteFile
97+ from robot .running .builder .parsers import RobotParser
8098 from robot .running .builder .settings import TestDefaults # pyright: ignore[reportMissingImports]
8199
82100 old_validate_not_empty = TestSuiteBuilder ._validate_not_empty
@@ -117,6 +135,17 @@ def build_suite_directory(
117135
118136 SuiteStructureParser ._build_suite_directory = build_suite_directory
119137
138+ old_get_source = RobotParser ._get_source
139+
140+ def _get_source (self : RobotParser , path : Path ) -> Union [Path , str ]:
141+ if _stdin_data is not None and (data := _stdin_data .get (str (path ))) is not None :
142+ if data is not None :
143+ return data
144+
145+ return old_get_source (self , path ) # type: ignore
146+
147+ RobotParser ._get_source = _get_source
148+
120149
121150@dataclass
122151class TestItem :
@@ -217,8 +246,9 @@ def visit_test(self, test: TestCase) -> None:
217246
218247
219248@click .group (invoke_without_command = False )
249+ @click .option ("--read-from-stdin" , is_flag = True , help = "Read file contents from stdin. This is an internal option." )
220250@pass_application
221- def discover (app : Application ) -> None :
251+ def discover (app : Application , read_from_stdin : bool ) -> None :
222252 """\
223253 Commands to discover informations about the current project.
224254
@@ -229,6 +259,10 @@ def discover(app: Application) -> None:
229259 robotcode --profile regression discover tests
230260 ```
231261 """
262+ if read_from_stdin :
263+ global _stdin_data
264+ _stdin_data = from_json (sys .stdin .buffer .read (), Dict [str , str ], strict = True )
265+ app .verbose (f"Read data from stdin: { repr (_stdin_data )} " )
232266
233267
234268RE_IN_FILE_LINE_MATCHER = re .compile (r".+\sin\sfile\s'(?P<file>.*)'\son\sline\s(?P<line>\d+):(?P<message>.*)" )
0 commit comments