robotcode-runner 2.6.2__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,15 +12,18 @@ 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
19
+ from robotcode.plugin.click_helper.wrappable import wrappable
18
20
  from robotcode.robot.config.loader import load_robot_config_from_path
19
21
  from robotcode.robot.config.model import RobotBaseProfile
20
22
  from robotcode.robot.config.utils import get_config_files
21
23
  from robotcode.robot.utils import RF_VERSION
22
24
 
23
25
  from ..__version__ import __version__
26
+ from ._robot_version import RobotVersionOption
24
27
  from ._search import SearchMatcher, SearchModifier
25
28
 
26
29
  _app: Optional[Application] = None
@@ -159,6 +162,8 @@ class RobotFrameworkEx(RobotFramework):
159
162
  by_longname: Tuple[str, ...] = (),
160
163
  exclude_by_longname: Tuple[str, ...] = (),
161
164
  search_matcher: Optional[SearchMatcher] = None,
165
+ by_test_metadata: Tuple[str, ...] = (),
166
+ exclude_by_test_metadata: Tuple[str, ...] = (),
162
167
  ) -> None:
163
168
  super().__init__()
164
169
  self.app = app
@@ -169,6 +174,8 @@ class RobotFrameworkEx(RobotFramework):
169
174
  self.by_longname = by_longname
170
175
  self.exclude_by_longname = exclude_by_longname
171
176
  self.search_matcher = search_matcher
177
+ self.by_test_metadata = by_test_metadata
178
+ self.exclude_by_test_metadata = exclude_by_test_metadata
172
179
 
173
180
  def parse_arguments(self, cli_args: Any) -> Any:
174
181
  try:
@@ -178,7 +185,13 @@ class RobotFrameworkEx(RobotFramework):
178
185
  if Path(arg).is_absolute():
179
186
  continue
180
187
 
181
- 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)
182
195
 
183
196
  except DataError:
184
197
  options, arguments = super().parse_arguments((*cli_args, *self.paths))
@@ -186,6 +199,11 @@ class RobotFrameworkEx(RobotFramework):
186
199
  if not arguments:
187
200
  arguments = self.paths
188
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
+
189
207
  if self.dry:
190
208
  line_end = "\n"
191
209
  raise Information(
@@ -203,6 +221,12 @@ class RobotFrameworkEx(RobotFramework):
203
221
  if self.exclude_by_longname:
204
222
  modifiers.append(robotcode.modifiers.ExcludedByLongName(*self.exclude_by_longname, root_name=root_name))
205
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
+
206
230
  if self.search_matcher is not None:
207
231
  modifiers.append(SearchModifier(self.search_matcher))
208
232
 
@@ -213,21 +237,21 @@ class RobotFrameworkEx(RobotFramework):
213
237
 
214
238
 
215
239
  # mypy: disable-error-code="arg-type"
216
- ROBOT_VERSION_OPTIONS = {
240
+ ROBOT_VERSION_OPTIONS = [
217
241
  click.version_option(
218
242
  version=__version__,
219
243
  package_name="robotcode.runner",
220
244
  prog_name="RobotCode Runner",
221
245
  message=f"%(prog)s %(version)s\n{USAGE.splitlines()[0].split(' -- ')[0].strip()} {get_full_version()}",
222
246
  ),
223
- }
247
+ ]
224
248
 
225
- ROBOT_SIMPLE_OPTIONS: Set[click.Command] = {
249
+ ROBOT_SIMPLE_OPTIONS = [
226
250
  *ROBOT_VERSION_OPTIONS,
227
251
  click.argument("robot_options_and_args", nargs=-1, type=click.Path()),
228
- }
252
+ ]
229
253
 
230
- ROBOT_OPTIONS: Set[click.Command] = {
254
+ ROBOT_OPTIONS = [
231
255
  click.option(
232
256
  "--by-longname",
233
257
  "-bl",
@@ -242,8 +266,29 @@ ROBOT_OPTIONS: Set[click.Command] = {
242
266
  multiple=True,
243
267
  help="Excludes tests/tasks or suites by longname.",
244
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
+ ),
245
290
  *ROBOT_SIMPLE_OPTIONS,
246
- }
291
+ ]
247
292
 
248
293
 
249
294
  def handle_robot_options(
@@ -293,6 +338,7 @@ def handle_robot_options(
293
338
  return root_folder, profile, cmd_options
294
339
 
295
340
 
341
+ @wrappable
296
342
  @click.command(
297
343
  cls=AliasedCommand,
298
344
  aliases=["run"],
@@ -306,6 +352,8 @@ def robot(
306
352
  app: Application,
307
353
  by_longname: Tuple[str, ...],
308
354
  exclude_by_longname: Tuple[str, ...],
355
+ by_test_metadata: Tuple[str, ...],
356
+ exclude_by_test_metadata: Tuple[str, ...],
309
357
  robot_options_and_args: Tuple[str, ...],
310
358
  ) -> None:
311
359
  """Runs `robot` with the selected configuration, profiles, options and arguments.
@@ -352,6 +400,8 @@ def robot(
352
400
  orig_folder,
353
401
  by_longname,
354
402
  exclude_by_longname,
403
+ by_test_metadata=by_test_metadata,
404
+ exclude_by_test_metadata=exclude_by_test_metadata,
355
405
  ).execute_cli((*cmd_options, *console_links_args, *robot_options_and_args), exit=False),
356
406
  )
357
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.6.2
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.6.2
29
- Requires-Dist: robotcode-plugin==2.6.2
30
- Requires-Dist: robotcode-robot==2.6.2
31
- Requires-Dist: robotcode==2.6.2
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.30.1
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=53Sii4w6BIWn-1RhaTyqUO46gDe4nDCRQDAcpsWFH24,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=B-uQgqeU61LSqfAiDGR-Xp3L8NIlFBYrvhXSVDJkSbI,11795
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=IUDmpWFUjYVvUmnynCvrf_daHrmf_4tagUoK_e-dtIA,1762
14
- robotcode/runner/cli/discover/_render.py,sha256=C1tee_gitlS4JsF1NVIuYczzqnTTKXOnTiEAJfGtCW0,16523
15
- robotcode/runner/cli/discover/discover.py,sha256=ly9_aJ3YPGepKN2u5WU9zb_Qr3CpWq8cOcwoco5kHS0,38122
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.6.2.dist-info/METADATA,sha256=HxDngjvRChNRYG_657BPm-DXFOfdYTrTA3AJ2x1ZXx0,2968
22
- robotcode_runner-2.6.2.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
23
- robotcode_runner-2.6.2.dist-info/entry_points.txt,sha256=igwjQYHlUfgCN-SohGVeQOnxOtqUzd2Jq94Ie8Se1Aw,44
24
- robotcode_runner-2.6.2.dist-info/RECORD,,