robotcode-runner 0.86.2__tar.gz → 0.87.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: robotcode-runner
3
- Version: 0.86.2
3
+ Version: 0.87.0
4
4
  Summary: RobotCode runner plugin for Robot Framework
5
5
  Project-URL: Homepage, https://robotcode.io
6
6
  Project-URL: Donate, https://opencollective.com/robotcode
@@ -25,10 +25,10 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
25
25
  Classifier: Topic :: Utilities
26
26
  Classifier: Typing :: Typed
27
27
  Requires-Python: >=3.8
28
- Requires-Dist: robotcode-modifiers==0.86.2
29
- Requires-Dist: robotcode-plugin==0.86.2
30
- Requires-Dist: robotcode-robot==0.86.2
31
- Requires-Dist: robotcode==0.86.2
28
+ Requires-Dist: robotcode-modifiers==0.87.0
29
+ Requires-Dist: robotcode-plugin==0.87.0
30
+ Requires-Dist: robotcode-robot==0.87.0
31
+ Requires-Dist: robotcode==0.87.0
32
32
  Requires-Dist: robotframework>=4.1.0
33
33
  Description-Content-Type: text/markdown
34
34
 
@@ -28,10 +28,10 @@ classifiers = [
28
28
  dynamic = ["version"]
29
29
  dependencies = [
30
30
  "robotframework>=4.1.0",
31
- "robotcode-robot==0.86.2",
32
- "robotcode-modifiers==0.86.2",
33
- "robotcode-plugin==0.86.2",
34
- "robotcode==0.86.2",
31
+ "robotcode-robot==0.87.0",
32
+ "robotcode-modifiers==0.87.0",
33
+ "robotcode-plugin==0.87.0",
34
+ "robotcode==0.87.0",
35
35
  ]
36
36
 
37
37
  [project.entry-points.robotcode]
@@ -0,0 +1 @@
1
+ __version__ = "0.87.0"
@@ -29,6 +29,7 @@ from robot.running.builder.builders import SuiteStructureParser
29
29
  from robot.utils import NormalizedDict, normalize
30
30
  from robot.utils.filereader import FileReader
31
31
 
32
+ from robotcode.core.ignore_spec import GIT_IGNORE_FILE, ROBOT_IGNORE_FILE, iter_files
32
33
  from robotcode.core.lsp.types import (
33
34
  Diagnostic,
34
35
  DiagnosticSeverity,
@@ -546,10 +547,26 @@ def handle_options(
546
547
  add_help_option=True,
547
548
  epilog='Use "-- --help" to see `robot` help.',
548
549
  )
550
+ @click.option(
551
+ "--tags / --no-tags",
552
+ "show_tags",
553
+ default=False,
554
+ show_default=True,
555
+ help="Show the tags that are present.",
556
+ )
549
557
  @add_options(*ROBOT_OPTIONS)
558
+ @click.option(
559
+ "--full-paths / --no-full-paths",
560
+ "full_paths",
561
+ default=False,
562
+ show_default=True,
563
+ help="Show full paths instead of releative.",
564
+ )
550
565
  @pass_application
551
566
  def all(
552
567
  app: Application,
568
+ full_paths: bool,
569
+ show_tags: bool,
553
570
  by_longname: Tuple[str, ...],
554
571
  exclude_by_longname: Tuple[str, ...],
555
572
  robot_options_and_args: Tuple[str, ...],
@@ -582,27 +599,32 @@ def all(
582
599
  )
583
600
 
584
601
  if item.type == "test":
585
- yield f" {type}: {item.longname}{os.linesep}"
602
+ yield " "
603
+ yield type
604
+ yield click.style(f": {item.longname}", bold=True)
605
+ yield click.style(
606
+ f" ({item.source if full_paths else item.rel_source}"
607
+ f":{item.range.start.line + 1 if item.range is not None else 1}){os.linesep}"
608
+ )
609
+ if show_tags and item.tags:
610
+ yield click.style(" Tags:", bold=True, fg="green")
611
+ yield f" {', '. join(normalize(str(tag), ignore='_') for tag in sorted(item.tags))}{os.linesep}"
586
612
  else:
587
- yield f"{type}: {item.longname}{os.linesep}"
588
-
613
+ yield type
614
+ yield f": {item.longname}"
615
+ yield click.style(f" ({item.source if full_paths else item.rel_source}){os.linesep}")
589
616
  for child in item.children or []:
590
617
  yield from print(child, indent + 2)
591
618
 
592
- # type = click.style(
593
- # item.type.capitalize() if item.type == "suite" else tests_or_tasks.capitalize(), fg="green"
594
- # )
595
- # yield (f"{' ' * indent}{type}: {item.name}{os.linesep}")
596
- # if item.children:
597
- # for child in item.children:
598
- # yield from print(child, indent + 2)
599
-
600
619
  if indent == 0:
601
620
  yield os.linesep
602
- yield f"Summary:{os.linesep}"
603
- yield f" Suites: {collector.statistics.suites}{os.linesep}"
604
- yield f" Suites with {tests_or_tasks}: {collector.statistics.suites_with_tests}{os.linesep}"
605
- yield f" {tests_or_tasks}: {collector.statistics.tests}{os.linesep}"
621
+
622
+ yield click.style("Suites: ", underline=True, bold=True, fg="blue")
623
+ yield f"{collector.statistics.suites}{os.linesep}"
624
+ yield click.style(f"Suites with {tests_or_tasks}: ", underline=True, bold=True, fg="blue")
625
+ yield f"{collector.statistics.suites_with_tests}{os.linesep}"
626
+ yield click.style(f"{tests_or_tasks}: ", underline=True, bold=True, fg="blue")
627
+ yield f"{collector.statistics.tests}{os.linesep}"
606
628
 
607
629
  app.echo_via_pager(print(collector.all.children[0]))
608
630
 
@@ -654,24 +676,27 @@ def tests(
654
676
  ```
655
677
  """
656
678
 
657
- _suite, collector, diagnostics = handle_options(app, by_longname, exclude_by_longname, robot_options_and_args)
679
+ suite, collector, diagnostics = handle_options(app, by_longname, exclude_by_longname, robot_options_and_args)
658
680
 
659
681
  if collector.all.children:
660
682
  if app.config.output_format is None or app.config.output_format == OutputFormat.TEXT:
661
683
 
684
+ tests_or_tasks = "Task" if suite.rpa else "Test"
685
+
662
686
  def print(items: List[TestItem]) -> Iterable[str]:
663
687
  for item in items:
664
- yield click.style(
665
- f"{item.longname}",
666
- bold=True,
667
- fg="green" if show_tags else None,
688
+ type = click.style(
689
+ item.type.capitalize() if item.type == "suite" else tests_or_tasks.capitalize(),
690
+ fg="blue",
668
691
  )
692
+ yield type
693
+ yield click.style(f": {item.longname}", bold=True)
669
694
  yield click.style(
670
695
  f" ({item.source if full_paths else item.rel_source}"
671
696
  f":{item.range.start.line + 1 if item.range is not None else 1}){os.linesep}"
672
697
  )
673
698
  if show_tags and item.tags:
674
- yield click.style(" Tags:", bold=True)
699
+ yield click.style(" Tags:", bold=True, fg="green")
675
700
  yield f" {', '. join(normalize(str(tag), ignore='_') for tag in sorted(item.tags))}{os.linesep}"
676
701
 
677
702
  if collector.tests:
@@ -687,9 +712,17 @@ def tests(
687
712
  epilog='Use "-- --help" to see `robot` help.',
688
713
  )
689
714
  @add_options(*ROBOT_OPTIONS)
715
+ @click.option(
716
+ "--full-paths / --no-full-paths",
717
+ "full_paths",
718
+ default=False,
719
+ show_default=True,
720
+ help="Show full paths instead of releative.",
721
+ )
690
722
  @pass_application
691
723
  def suites(
692
724
  app: Application,
725
+ full_paths: bool,
693
726
  by_longname: Tuple[str, ...],
694
727
  exclude_by_longname: Tuple[str, ...],
695
728
  robot_options_and_args: Tuple[str, ...],
@@ -716,7 +749,12 @@ def suites(
716
749
 
717
750
  def print(items: List[TestItem]) -> Iterable[str]:
718
751
  for item in items:
719
- yield f"{item.longname}{os.linesep}"
752
+ # yield f"{item.longname}{os.linesep}"
753
+ yield click.style(
754
+ f"{item.longname}",
755
+ bold=True,
756
+ )
757
+ yield click.style(f" ({item.source if full_paths else item.rel_source}){os.linesep}")
720
758
 
721
759
  if collector.suites:
722
760
  app.echo_via_pager(print(collector.suites))
@@ -878,3 +916,78 @@ def info(app: Application) -> None:
878
916
  # app.print_data(info, remove_defaults=True)
879
917
  else:
880
918
  app.print_data(info, remove_defaults=True)
919
+
920
+
921
+ @discover.command(add_help_option=True)
922
+ @click.option(
923
+ "--full-paths / --no-full-paths",
924
+ "full_paths",
925
+ default=False,
926
+ show_default=True,
927
+ help="Show full paths instead of releative.",
928
+ )
929
+ @click.argument(
930
+ "paths",
931
+ nargs=-1,
932
+ type=click.Path(exists=True, file_okay=True, dir_okay=True),
933
+ )
934
+ @pass_application
935
+ def files(app: Application, full_paths: bool, paths: Iterable[Path]) -> None:
936
+ """\
937
+ Shows all files that are used to discover the tests.
938
+
939
+ Note: At the moment only `.robot` and `.resource` files are shown.
940
+ \b
941
+ Examples:
942
+ ```
943
+ robotcode discover files .
944
+ ```
945
+ """
946
+
947
+ root_folder, profile, cmd_options = handle_robot_options(app, ())
948
+
949
+ search_paths = set(
950
+ (
951
+ (
952
+ [*(app.config.default_paths if app.config.default_paths else ())]
953
+ if profile.paths is None
954
+ else profile.paths if isinstance(profile.paths, list) else [profile.paths]
955
+ )
956
+ if not paths
957
+ else [str(p) for p in paths]
958
+ )
959
+ )
960
+ if not search_paths:
961
+ raise click.UsageError("Expected at least 1 argument.")
962
+
963
+ def filter_extensions(p: Path) -> bool:
964
+ return p.suffix in [".robot", ".resource"]
965
+
966
+ result: List[str] = list(
967
+ map(
968
+ lambda p: os.path.abspath(p) if full_paths else (get_rel_source(str(p)) or str(p)),
969
+ filter(
970
+ filter_extensions,
971
+ iter_files(
972
+ (Path(s) for s in search_paths),
973
+ root=root_folder,
974
+ ignore_files=[ROBOT_IGNORE_FILE, GIT_IGNORE_FILE],
975
+ include_hidden=False,
976
+ verbose_callback=app.verbose,
977
+ ),
978
+ ),
979
+ )
980
+ )
981
+ if app.config.output_format is None or app.config.output_format == OutputFormat.TEXT:
982
+
983
+ def print() -> Iterable[str]:
984
+ for p in result:
985
+ yield f"{p}{os.linesep}"
986
+
987
+ yield os.linesep
988
+ yield click.style("Total: ", underline=True, bold=True, fg="blue")
989
+ yield click.style(f"{len(result)} file(s){os.linesep}")
990
+
991
+ app.echo_via_pager(print())
992
+ else:
993
+ app.print_data(result, remove_defaults=True)
@@ -98,7 +98,6 @@ def _is_ignored(builder: SuiteStructureBuilder, path: Path) -> bool:
98
98
  if not path_is_relative_to(dir, cache_data.base_path):
99
99
  break
100
100
  else:
101
- # TODO: we are in a different folder
102
101
  if curr_dir.parent in cache_data.data:
103
102
  parent_data = cache_data.data[curr_dir.parent]
104
103
  parent_spec_dir = curr_dir.parent
@@ -121,7 +120,10 @@ def _is_ignored(builder: SuiteStructureBuilder, path: Path) -> bool:
121
120
  if ignore_file is not None:
122
121
  parent_data.ignore_files = [ignore_file.name]
123
122
 
124
- parent_data.spec = parent_data.spec + IgnoreSpec.from_gitignore(parent_spec_dir / ignore_file)
123
+ if _app is not None:
124
+ _app.verbose(f"using ignore file: '{ignore_file}'")
125
+
126
+ parent_data.spec = parent_data.spec + IgnoreSpec.from_gitignore(ignore_file)
125
127
  cache_data.data[parent_spec_dir] = parent_data
126
128
 
127
129
  if parent_data is not None and parent_data.spec is not None and parent_spec_dir != curr_dir:
@@ -130,7 +132,10 @@ def _is_ignored(builder: SuiteStructureBuilder, path: Path) -> bool:
130
132
  if ignore_file is not None:
131
133
  curr_data = BuilderCacheData()
132
134
 
133
- curr_data.spec = parent_data.spec + IgnoreSpec.from_gitignore(curr_dir / ignore_file)
135
+ if _app is not None:
136
+ _app.verbose(f"using ignore file: '{ignore_file}'")
137
+
138
+ curr_data.spec = parent_data.spec + IgnoreSpec.from_gitignore(ignore_file)
134
139
  curr_data.ignore_files = [ignore_file.name]
135
140
 
136
141
  cache_data.data[curr_dir] = curr_data
@@ -1 +0,0 @@
1
- __version__ = "0.86.2"