11import os
2+ import platform
23import re
34import sys
45from collections import defaultdict
@@ -45,7 +46,7 @@ def _patch() -> None:
4546 __patched = True
4647
4748 if get_robot_version () <= (6 , 1 ):
48- if get_robot_version () > (5 , 0 ) and get_robot_version () < (6 , 0 , 0 ) or get_robot_version () < (5 , 0 ):
49+ if get_robot_version () > (5 , 0 ) and get_robot_version () < (6 , 0 ) or get_robot_version () < (5 , 0 ):
4950 from robot .running .builder .testsettings import TestDefaults # pyright: ignore[reportMissingImports]
5051 else :
5152 from robot .running .builder .settings import Defaults as TestDefaults # pyright: ignore[reportMissingImports]
@@ -82,6 +83,16 @@ def build_suite(self: SuiteStructureParser, structure: Any) -> Tuple[TestSuite,
8283
8384 SuiteStructureParser ._build_suite = build_suite
8485
86+ old_validate_execution_mode = SuiteStructureParser ._validate_execution_mode
87+
88+ def _validate_execution_mode (self : SuiteStructureParser , suite : TestSuite ) -> None :
89+ try :
90+ old_validate_execution_mode (self , suite )
91+ except DataError as e :
92+ LOGGER .error (f"Parsing '{ suite .source } ' failed: { e .message } " )
93+
94+ SuiteStructureParser ._validate_execution_mode = _validate_execution_mode
95+
8596 elif get_robot_version () >= (6 , 1 ):
8697 from robot .parsing .suitestructure import SuiteDirectory , SuiteFile
8798 from robot .running .builder .settings import TestDefaults # pyright: ignore[reportMissingImports]
@@ -124,6 +135,16 @@ def build_suite_directory(
124135
125136 SuiteStructureParser ._build_suite_directory = build_suite_directory
126137
138+ old_validate_execution_mode = SuiteStructureParser ._validate_execution_mode
139+
140+ def _validate_execution_mode (self : SuiteStructureParser , suite : TestSuite ) -> None :
141+ try :
142+ old_validate_execution_mode (self , suite )
143+ except DataError as e :
144+ LOGGER .error (f"Parsing '{ suite .source } ' failed: { e .message } " )
145+
146+ SuiteStructureParser ._validate_execution_mode = _validate_execution_mode
147+
127148 old_get_file = FileReader ._get_file
128149
129150 def get_file (self : FileReader , source : Union [str , Path , IOBase ], accept_text : bool ) -> Any :
@@ -145,6 +166,8 @@ class TestItem:
145166 name : str
146167 longname : str
147168 uri : Optional [DocumentUri ] = None
169+ rel_source : Optional [str ] = None
170+ needs_parse_include : bool = False
148171 children : Optional [List ["TestItem" ]] = None
149172 description : Optional [str ] = None
150173 range : Optional [Range ] = None
@@ -165,15 +188,25 @@ class Statistics:
165188 tests : int = 0
166189
167190
191+ def get_rel_source (source : Optional [str ]) -> Optional [str ]:
192+ if source is None :
193+ return None
194+ try :
195+ return str (Path (source ).relative_to (Path .cwd ()).as_posix ())
196+ except ValueError :
197+ return str (source )
198+
199+
168200class Collector (SuiteVisitor ):
169201 def __init__ (self ) -> None :
170202 super ().__init__ ()
171203 self .all : TestItem = TestItem (
172204 type = "workspace" ,
173- id = str (Path .cwd ().absolute ()),
205+ id = str (Path .cwd ().resolve ()),
174206 name = Path .cwd ().name ,
175207 longname = Path .cwd ().name ,
176208 uri = str (Uri .from_path (Path .cwd ())),
209+ needs_parse_include = get_robot_version () >= (6 , 1 ),
177210 )
178211 self ._current = self .all
179212 self .suites : List [TestItem ] = []
@@ -185,10 +218,11 @@ def visit_suite(self, suite: TestSuite) -> None:
185218 try :
186219 item = TestItem (
187220 type = "suite" ,
188- id = f"{ Path (suite .source ).absolute () if suite .source is not None else '' } ;{ suite .longname } " ,
221+ id = f"{ Path (suite .source ).resolve () if suite .source is not None else '' } ;{ suite .longname } " ,
189222 name = suite .name ,
190223 longname = suite .longname ,
191- uri = str (Uri .from_path (Path (suite .source ).absolute ())) if suite .source else None ,
224+ uri = str (Uri .from_path (Path (suite .source ).resolve ())) if suite .source else None ,
225+ rel_source = get_rel_source (suite .source ),
192226 range = Range (
193227 start = Position (line = 0 , character = 0 ),
194228 end = Position (line = 0 , character = 0 ),
@@ -224,10 +258,11 @@ def visit_test(self, test: TestCase) -> None:
224258 try :
225259 item = TestItem (
226260 type = "test" ,
227- id = f"{ Path (test .source ).absolute () if test .source is not None else '' } ;{ test .longname } ;{ test .lineno } " ,
261+ id = f"{ Path (test .source ).resolve () if test .source is not None else '' } ;{ test .longname } ;{ test .lineno } " ,
228262 name = test .name ,
229263 longname = test .longname ,
230- uri = str (Uri .from_path (Path (test .source ).absolute ())) if test .source else None ,
264+ uri = str (Uri .from_path (Path (test .source ).resolve ())) if test .source else None ,
265+ rel_source = get_rel_source (test .source ),
231266 range = Range (
232267 start = Position (line = test .lineno - 1 , character = 0 ),
233268 end = Position (line = test .lineno - 1 , character = 0 ),
@@ -287,7 +322,7 @@ def build_diagnostics(messages: List[Message]) -> Dict[str, List[Diagnostic]]:
287322 def add_diagnostic (
288323 message : Message , source_uri : Optional [str ] = None , line : Optional [int ] = None , text : Optional [str ] = None
289324 ) -> None :
290- source_uri = str (Uri .from_path (Path (source_uri ).absolute () if source_uri else Path .cwd ()))
325+ source_uri = str (Uri .from_path (Path (source_uri ).resolve () if source_uri else Path .cwd ()))
291326
292327 if source_uri not in result :
293328 result [source_uri ] = []
@@ -360,7 +395,7 @@ def handle_options(
360395 lang = settings .languages ,
361396 allow_empty_suite = settings .run_empty_suite ,
362397 )
363- elif get_robot_version () >= (6 , 0 , 0 ):
398+ elif get_robot_version () >= (6 , 0 ):
364399 builder = TestSuiteBuilder (
365400 settings ["SuiteNames" ],
366401 included_extensions = settings .extension ,
@@ -583,7 +618,7 @@ def tags(
583618 ```
584619 """
585620
586- suite , diagnostics = handle_options (app , by_longname , exclude_by_longname , robot_options_and_args )
621+ suite , _diagnostics = handle_options (app , by_longname , exclude_by_longname , robot_options_and_args )
587622
588623 collector = Collector ()
589624 suite .visit (collector )
@@ -594,16 +629,89 @@ def tags(
594629 def print (tags : Dict [str , List [TestItem ]]) -> Iterable [str ]:
595630 for tag , items in tags .items ():
596631 yield f"{ tag } { os .linesep } "
597- # for item in items:
598- # yield f" {item.longname}{os.linesep}"
599- # if item.uri:
600- # yield (
601- # f" ({Uri(item.uri).to_path()}{f':{item.range.start.line+1}' if item.range else ''})"
602- # f"{os.linesep}"
603- # )
604632
605633 if collector .suites :
606634 app .echo_via_pager (print (collector .tags ))
607635
608636 else :
609637 app .print_data (TagsResult (collector .tags ), remove_defaults = True )
638+
639+
640+ @dataclass
641+ class RobotVersion :
642+ major : int
643+ minor : int
644+ patch : Optional [int ] = None
645+ pre_id : Optional [str ] = None
646+ pre_number : Optional [int ] = None
647+ dev : Optional [int ] = None
648+
649+
650+ @dataclass
651+ class PythonVersion :
652+ major : int
653+ minor : int
654+ micro : int
655+ releaselevel : str
656+ serial : int
657+
658+
659+ @dataclass
660+ class Info :
661+ robot_version : RobotVersion
662+ robot_version_string : str
663+ robot_env : Dict [str , str ]
664+ python_version : PythonVersion
665+ python_version_string : str
666+ machine : str
667+ processor : str
668+ platform : str
669+ system : str
670+ system_version : str
671+
672+
673+ @discover .command (
674+ add_help_option = True ,
675+ )
676+ @pass_application
677+ def info (
678+ app : Application ,
679+ ) -> None :
680+ """\
681+ Shows some informations about the current *robot* environment.
682+
683+ \b
684+ Examples:
685+ ```
686+ robotcode discover info
687+ ```
688+ """
689+ from robot .version import get_version as get_version
690+
691+ robot_env : Dict [str , str ] = {}
692+ if "ROBOT_OPTIONS" in os .environ :
693+ robot_env ["ROBOT_OPTIONS" ] = os .environ ["ROBOT_OPTIONS" ]
694+ if "ROBOT_SYSLOG_FILE" in os .environ :
695+ robot_env ["ROBOT_SYSLOG_FILE" ] = os .environ ["ROBOT_SYSLOG_FILE" ]
696+ if "ROBOT_SYSLOG_LEVEL" in os .environ :
697+ robot_env ["ROBOT_SYSLOG_LEVEL" ] = os .environ ["ROBOT_SYSLOG_LEVEL" ]
698+ if "ROBOT_INTERNAL_TRACES" in os .environ :
699+ robot_env ["ROBOT_INTERNAL_TRACES" ] = os .environ ["ROBOT_INTERNAL_TRACES" ]
700+
701+ info = Info (
702+ RobotVersion (* get_robot_version ()),
703+ get_version (),
704+ robot_env ,
705+ PythonVersion (* sys .version_info ),
706+ platform .python_version (),
707+ platform .machine (),
708+ platform .processor (),
709+ sys .platform ,
710+ platform .system (),
711+ platform .version (),
712+ )
713+
714+ if app .config .output_format is None or app .config .output_format == OutputFormat .TEXT :
715+ app .print_data (info , remove_defaults = True )
716+ else :
717+ app .print_data (info , remove_defaults = True )
0 commit comments