robotcode-runner 2.7.0__py3-none-any.whl → 2.8.0.dev548__py3-none-any.whl

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,7 +1,7 @@
1
1
  import os
2
2
  import weakref
3
3
  from pathlib import Path
4
- from typing import Any, Dict, List, Optional, Set, Tuple, Union, cast
4
+ from typing import Any, Dict, List, Optional, Tuple, Union, cast
5
5
 
6
6
  import click
7
7
  from robot.errors import DataError, Information
@@ -12,6 +12,7 @@ from robot.version import get_full_version
12
12
  import robotcode.modifiers
13
13
  from robotcode.core.ignore_spec import DEFAULT_SPEC_RULES, GIT_IGNORE_FILE, ROBOT_IGNORE_FILE, IgnoreSpec
14
14
  from robotcode.core.utils.path import path_is_relative_to
15
+ from robotcode.modifiers.metadata_modifiers import MetadataPattern
15
16
  from robotcode.plugin import Application, pass_application
16
17
  from robotcode.plugin.click_helper.aliases import AliasedCommand
17
18
  from robotcode.plugin.click_helper.types import add_options
@@ -22,6 +23,7 @@ from robotcode.robot.config.utils import get_config_files
22
23
  from robotcode.robot.utils import RF_VERSION
23
24
 
24
25
  from ..__version__ import __version__
26
+ from ._robot_version import RobotVersionOption
25
27
  from ._search import SearchMatcher, SearchModifier
26
28
 
27
29
  _app: Optional[Application] = None
@@ -160,6 +162,8 @@ class RobotFrameworkEx(RobotFramework):
160
162
  by_longname: Tuple[str, ...] = (),
161
163
  exclude_by_longname: Tuple[str, ...] = (),
162
164
  search_matcher: Optional[SearchMatcher] = None,
165
+ by_test_metadata: Tuple[str, ...] = (),
166
+ exclude_by_test_metadata: Tuple[str, ...] = (),
163
167
  ) -> None:
164
168
  super().__init__()
165
169
  self.app = app
@@ -170,6 +174,8 @@ class RobotFrameworkEx(RobotFramework):
170
174
  self.by_longname = by_longname
171
175
  self.exclude_by_longname = exclude_by_longname
172
176
  self.search_matcher = search_matcher
177
+ self.by_test_metadata = by_test_metadata
178
+ self.exclude_by_test_metadata = exclude_by_test_metadata
173
179
 
174
180
  def parse_arguments(self, cli_args: Any) -> Any:
175
181
  try:
@@ -179,7 +185,13 @@ class RobotFrameworkEx(RobotFramework):
179
185
  if Path(arg).is_absolute():
180
186
  continue
181
187
 
182
- arguments[i] = str((self._orig_cwd / Path(arg)).absolute().relative_to(self.root_folder))
188
+ absolute = (self._orig_cwd / Path(arg)).absolute()
189
+ try:
190
+ arguments[i] = str(absolute.relative_to(self.root_folder))
191
+ except ValueError:
192
+ # The path lies outside the project root, which the run changes into,
193
+ # so it stays valid only as an absolute path.
194
+ arguments[i] = str(absolute)
183
195
 
184
196
  except DataError:
185
197
  options, arguments = super().parse_arguments((*cli_args, *self.paths))
@@ -187,6 +199,11 @@ class RobotFrameworkEx(RobotFramework):
187
199
  if not arguments:
188
200
  arguments = self.paths
189
201
 
202
+ # Parsed before anything runs: an invalid pattern raises `DataError`,
203
+ # which Robot reports like an invalid option.
204
+ test_metadata_patterns = [MetadataPattern(p) for p in self.by_test_metadata]
205
+ excluded_test_metadata_patterns = [MetadataPattern(p) for p in self.exclude_by_test_metadata]
206
+
190
207
  if self.dry:
191
208
  line_end = "\n"
192
209
  raise Information(
@@ -204,6 +221,12 @@ class RobotFrameworkEx(RobotFramework):
204
221
  if self.exclude_by_longname:
205
222
  modifiers.append(robotcode.modifiers.ExcludedByLongName(*self.exclude_by_longname, root_name=root_name))
206
223
 
224
+ if test_metadata_patterns:
225
+ modifiers.append(robotcode.modifiers.ByTestMetadata(*test_metadata_patterns))
226
+
227
+ if excluded_test_metadata_patterns:
228
+ modifiers.append(robotcode.modifiers.ExcludedByTestMetadata(*excluded_test_metadata_patterns))
229
+
207
230
  if self.search_matcher is not None:
208
231
  modifiers.append(SearchModifier(self.search_matcher))
209
232
 
@@ -214,21 +237,21 @@ class RobotFrameworkEx(RobotFramework):
214
237
 
215
238
 
216
239
  # mypy: disable-error-code="arg-type"
217
- ROBOT_VERSION_OPTIONS = {
240
+ ROBOT_VERSION_OPTIONS = [
218
241
  click.version_option(
219
242
  version=__version__,
220
243
  package_name="robotcode.runner",
221
244
  prog_name="RobotCode Runner",
222
245
  message=f"%(prog)s %(version)s\n{USAGE.splitlines()[0].split(' -- ')[0].strip()} {get_full_version()}",
223
246
  ),
224
- }
247
+ ]
225
248
 
226
- ROBOT_SIMPLE_OPTIONS: Set[click.Command] = {
249
+ ROBOT_SIMPLE_OPTIONS = [
227
250
  *ROBOT_VERSION_OPTIONS,
228
251
  click.argument("robot_options_and_args", nargs=-1, type=click.Path()),
229
- }
252
+ ]
230
253
 
231
- ROBOT_OPTIONS: Set[click.Command] = {
254
+ ROBOT_OPTIONS = [
232
255
  click.option(
233
256
  "--by-longname",
234
257
  "-bl",
@@ -243,8 +266,29 @@ ROBOT_OPTIONS: Set[click.Command] = {
243
266
  multiple=True,
244
267
  help="Excludes tests/tasks or suites by longname.",
245
268
  ),
269
+ # test metadata exists since Robot Framework 7.5
270
+ click.option(
271
+ "--by-test-metadata",
272
+ "-btm",
273
+ cls=RobotVersionOption,
274
+ since=(7, 5),
275
+ type=str,
276
+ multiple=True,
277
+ metavar="PATTERN",
278
+ help="Select tests/tasks by their metadata, for example `Issue:4409 AND Author:Hans*`.",
279
+ ),
280
+ click.option(
281
+ "--exclude-by-test-metadata",
282
+ "-ebtm",
283
+ cls=RobotVersionOption,
284
+ since=(7, 5),
285
+ type=str,
286
+ multiple=True,
287
+ metavar="PATTERN",
288
+ help="Excludes tests/tasks by their metadata. Same patterns as `--by-test-metadata`.",
289
+ ),
246
290
  *ROBOT_SIMPLE_OPTIONS,
247
- }
291
+ ]
248
292
 
249
293
 
250
294
  def handle_robot_options(
@@ -308,6 +352,8 @@ def robot(
308
352
  app: Application,
309
353
  by_longname: Tuple[str, ...],
310
354
  exclude_by_longname: Tuple[str, ...],
355
+ by_test_metadata: Tuple[str, ...],
356
+ exclude_by_test_metadata: Tuple[str, ...],
311
357
  robot_options_and_args: Tuple[str, ...],
312
358
  ) -> None:
313
359
  """Runs `robot` with the selected configuration, profiles, options and arguments.
@@ -354,6 +400,8 @@ def robot(
354
400
  orig_folder,
355
401
  by_longname,
356
402
  exclude_by_longname,
403
+ by_test_metadata=by_test_metadata,
404
+ exclude_by_test_metadata=exclude_by_test_metadata,
357
405
  ).execute_cli((*cmd_options, *console_links_args, *robot_options_and_args), exit=False),
358
406
  )
359
407
  )
@@ -6,6 +6,7 @@ from robot.testdoc import USAGE, TestDoc
6
6
  from robot.version import get_full_version
7
7
 
8
8
  from robotcode.plugin import Application, pass_application
9
+ from robotcode.plugin.click_helper.exit_codes import robot_exit_codes
9
10
  from robotcode.robot.config.loader import load_robot_config_from_path
10
11
  from robotcode.robot.config.model import TestDocProfile
11
12
  from robotcode.robot.config.utils import get_config_files
@@ -35,6 +36,7 @@ class TestDocEx(TestDoc):
35
36
  return super().main(arguments, **options)
36
37
 
37
38
 
39
+ @robot_exit_codes
38
40
  @click.command(
39
41
  context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
40
42
  add_help_option=True,
@@ -80,11 +82,12 @@ def testdoc(app: Application, robot_options_and_args: Tuple[str, ...]) -> None:
80
82
  except (TypeError, ValueError) as e:
81
83
  raise click.ClickException(str(e)) from e
82
84
 
83
- testdoc_options = profile.testdoc
84
- if testdoc_options is None:
85
- testdoc_options = TestDocProfile()
86
-
85
+ # `testdoc` gets the settings outside of `[testdoc]` that it shares with `robot`. `[testdoc]` comes last, so
86
+ # it wins and its `extend-` settings add to them.
87
+ testdoc_options = TestDocProfile()
87
88
  testdoc_options.add_options(profile)
89
+ if profile.testdoc is not None:
90
+ testdoc_options.add_options(profile.testdoc)
88
91
 
89
92
  options = testdoc_options.build_command_line()
90
93
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: robotcode-runner
3
- Version: 2.7.0
3
+ Version: 2.8.0-dev.548
4
4
  Summary: RobotCode runner for Robot Framework
5
5
  Project-URL: Homepage, https://robotcode.io
6
6
  Project-URL: Donate, https://opencollective.com/robotcode
@@ -20,15 +20,16 @@ Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Programming Language :: Python :: 3.13
22
22
  Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Programming Language :: Python :: 3.15
23
24
  Classifier: Programming Language :: Python :: Implementation :: CPython
24
25
  Classifier: Programming Language :: Python :: Implementation :: PyPy
25
26
  Classifier: Topic :: Utilities
26
27
  Classifier: Typing :: Typed
27
28
  Requires-Python: >=3.10
28
- Requires-Dist: robotcode-modifiers==2.7.0
29
- Requires-Dist: robotcode-plugin==2.7.0
30
- Requires-Dist: robotcode-robot==2.7.0
31
- Requires-Dist: robotcode==2.7.0
29
+ Requires-Dist: robotcode-modifiers==2.8.0-dev.548
30
+ Requires-Dist: robotcode-plugin==2.8.0-dev.548
31
+ Requires-Dist: robotcode-robot==2.8.0-dev.548
32
+ Requires-Dist: robotcode==2.8.0-dev.548
32
33
  Requires-Dist: robotframework>=5.0.0
33
34
  Provides-Extra: html
34
35
  Requires-Dist: html-to-markdown>=2.0; extra == 'html'
@@ -0,0 +1,25 @@
1
+ robotcode/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ robotcode/runner/__version__.py,sha256=4qGR5Sg7VszfoERVpnszHJ_tsWJ0G_bUZdheH0_dqx4,30
3
+ robotcode/runner/hooks.py,sha256=MSqEHc3wQIBgCXf9U9B0sA_zE8vbiTdoAlfaWz_3uIo,270
4
+ robotcode/runner/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
5
+ robotcode/runner/cli/__init__.py,sha256=ozQtrMXxWIlJz3QKZhaGEIDjSCL0TPtF1XeP8WL8HrE,240
6
+ robotcode/runner/cli/_markdown.py,sha256=4tHR4514XiHZiat-eMzxMclO_E7bwtdMTIo11rap80Q,12474
7
+ robotcode/runner/cli/_robot_version.py,sha256=aXpMkrA4IHtCvqi_Dv9hr2D6UqBEI7j8PwsMgMJ0P-E,961
8
+ robotcode/runner/cli/_search.py,sha256=JhKCDAdu_Mv89ug0p6nMumxdMAAwgbtdLt2CoJEZjsI,15874
9
+ robotcode/runner/cli/libdoc.py,sha256=IanGjNOkm45VESVO_3pNoMpXtjpXMX9Li-J8lhPL2X8,3782
10
+ robotcode/runner/cli/rebot.py,sha256=QIKYJD-4w7wquv46EygylNhBWXq1hj7-jV7vZvAHuHw,4922
11
+ robotcode/runner/cli/robot.py,sha256=jJc26J3jYhbvZjzRILiyK4s-yjQDir-dxwwDoPHTrOc,13930
12
+ robotcode/runner/cli/testdoc.py,sha256=UMpa1GOuyAIENGziepSprM4vHmR0QNfyBYWKN9cqd38,3756
13
+ robotcode/runner/cli/discover/__init__.py,sha256=CRFSvVDlOX1avV3kx-d2QUOugDvgKPy8RBApsAUq15s,55
14
+ robotcode/runner/cli/discover/_models.py,sha256=mkRwJTyQUWLVGbupCtYMVAHFhUouuMJ3TfR7_gz_lZI,2127
15
+ robotcode/runner/cli/discover/_render.py,sha256=3GYv0bNPVOLDAabg6FYXmbCDLLztjeLFrEhj-1inUvY,20091
16
+ robotcode/runner/cli/discover/discover.py,sha256=joZHF2UPdJ8v6b3OxfBkhl4Z2aGtaxzRObVLEZTxM3U,46621
17
+ robotcode/runner/cli/results/__init__.py,sha256=aEyNen0WWvq3kF_VTRLz99_B5CMChM0aelpzWKW6Rac,52
18
+ robotcode/runner/cli/results/_html.py,sha256=MD_6RZMeYNORFOINB8RJA8UhKEgXl6pldCToF51Y3qo,19422
19
+ robotcode/runner/cli/results/_models.py,sha256=ESn9VKIF-mySCnE144wNoYMmYMKuniZKQW5O61lko5I,7458
20
+ robotcode/runner/cli/results/_render.py,sha256=9DNk1d7F01bGQBCKBgtcqw_asvmnX1pJ02-kU02ptss,32471
21
+ robotcode/runner/cli/results/results.py,sha256=CljvnJ_k2qJAYAubspLq-b7s3GNYsuXE42C5lzJ6K6k,73723
22
+ robotcode_runner-2.8.0.dev548.dist-info/METADATA,sha256=WCMmPwAz0l6ts9mO40ULysTr0gC3ZhBrewgC9s6P0Q0,3059
23
+ robotcode_runner-2.8.0.dev548.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
24
+ robotcode_runner-2.8.0.dev548.dist-info/entry_points.txt,sha256=igwjQYHlUfgCN-SohGVeQOnxOtqUzd2Jq94Ie8Se1Aw,44
25
+ robotcode_runner-2.8.0.dev548.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.31.0
2
+ Generator: hatchling 1.32.4
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,24 +0,0 @@
1
- robotcode/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- robotcode/runner/__version__.py,sha256=EtKWW0Hnl5oWglRNH0HZigvcDT2FEs58ek8buJdwW1E,22
3
- robotcode/runner/hooks.py,sha256=MSqEHc3wQIBgCXf9U9B0sA_zE8vbiTdoAlfaWz_3uIo,270
4
- robotcode/runner/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
5
- robotcode/runner/cli/__init__.py,sha256=ozQtrMXxWIlJz3QKZhaGEIDjSCL0TPtF1XeP8WL8HrE,240
6
- robotcode/runner/cli/_markdown.py,sha256=6zXGB3wYngaKg5tu-GuwCuZvvRKSxfl97jUxjRSkfEU,12022
7
- robotcode/runner/cli/_search.py,sha256=r6Uh-0ftc8WnkNOfkIgNBgJ2tSRWzgO0M_bM6cPFnxY,14421
8
- robotcode/runner/cli/libdoc.py,sha256=VOKb0Xpct9mGgZkCdUng13o3ZpvxnPg_LqWNP13BEJU,3468
9
- robotcode/runner/cli/rebot.py,sha256=LhMvkn92PQBQaniA1vRlu9J_XJ9N_wj95v48sdIvlG4,3943
10
- robotcode/runner/cli/robot.py,sha256=syHOpewghJg0EjdYe4hZCfPCvSMa38dA2pa4qeIplZc,11868
11
- robotcode/runner/cli/testdoc.py,sha256=qc11KKwgGVXUydqsPS1M6x-j69wrtkFACeZEBeGXZBk,3479
12
- robotcode/runner/cli/discover/__init__.py,sha256=CRFSvVDlOX1avV3kx-d2QUOugDvgKPy8RBApsAUq15s,55
13
- robotcode/runner/cli/discover/_models.py,sha256=YsJ9zn5KZH9TmsocAS3IeioU8-K3KqEl63TQa4HVAuc,1768
14
- robotcode/runner/cli/discover/_render.py,sha256=C1tee_gitlS4JsF1NVIuYczzqnTTKXOnTiEAJfGtCW0,16523
15
- robotcode/runner/cli/discover/discover.py,sha256=q-XAMG1pz4emyKNZOe66bIWU6awa5PxUQPBI2KpcSl0,38673
16
- robotcode/runner/cli/results/__init__.py,sha256=aEyNen0WWvq3kF_VTRLz99_B5CMChM0aelpzWKW6Rac,52
17
- robotcode/runner/cli/results/_html.py,sha256=MD_6RZMeYNORFOINB8RJA8UhKEgXl6pldCToF51Y3qo,19422
18
- robotcode/runner/cli/results/_models.py,sha256=1zo-LoR-_lLIrnEwZh61qAryCgirQWkJNcZ5yzognKo,7271
19
- robotcode/runner/cli/results/_render.py,sha256=IVQiD_plufMyEU3WIDntGx_aqTiFc-Pg10jtS0dfXFk,32104
20
- robotcode/runner/cli/results/results.py,sha256=Vofh1RAYxM_uTJAjAyjYB7vJFROOHD6S9KkQzeGyzHI,67126
21
- robotcode_runner-2.7.0.dist-info/METADATA,sha256=_PxtY6zq5PTEwHaNQN9rh84nY0SG1Jq_rfrdNf40bW8,2968
22
- robotcode_runner-2.7.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
23
- robotcode_runner-2.7.0.dist-info/entry_points.txt,sha256=igwjQYHlUfgCN-SohGVeQOnxOtqUzd2Jq94Ie8Se1Aw,44
24
- robotcode_runner-2.7.0.dist-info/RECORD,,