robotcode 0.78.1__py3-none-any.whl → 0.106.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
robotcode/cli/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  from pathlib import Path
3
- from typing import List, Optional
3
+ from typing import Any, List, Literal, Optional
4
4
 
5
5
  import click
6
6
 
@@ -19,6 +19,25 @@ from robotcode.plugin.manager import PluginManager
19
19
  from .__version__ import __version__
20
20
  from .commands import config, profiles
21
21
 
22
+ old_make_metavar = click.Parameter.make_metavar
23
+
24
+
25
+ def my_make_metavar(self: click.Parameter) -> str:
26
+ metavar = old_make_metavar(self)
27
+
28
+ if isinstance(self, click.Option) and self.multiple:
29
+ metavar += " *"
30
+
31
+ return metavar
32
+
33
+
34
+ click.Parameter.make_metavar = my_make_metavar # type: ignore[method-assign]
35
+
36
+
37
+ class RobotCodeFormatter(logging.Formatter):
38
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
39
+ super().__init__(*args, **kwargs)
40
+
22
41
 
23
42
  @click.group(
24
43
  cls=AliasedGroup,
@@ -33,8 +52,7 @@ from .commands import config, profiles
33
52
  multiple=True,
34
53
  show_envvar=True,
35
54
  help="""\
36
- Config file to use. Can be specified multiple times.
37
- If not specified, the default config file is used.
55
+ Config file to use. If not specified, the default config file is used.
38
56
  """,
39
57
  )
40
58
  @click.option(
@@ -45,10 +63,23 @@ from .commands import config, profiles
45
63
  multiple=True,
46
64
  show_envvar=True,
47
65
  help="""\
48
- The Execution Profile to use. Can be specified multiple times.
49
- If not specified, the default profile is used.
66
+ The Execution Profile to use. If not specified, the default profile is used.
50
67
  """,
51
68
  )
69
+ @click.option(
70
+ "-r",
71
+ "--root",
72
+ "root",
73
+ type=click.Path(exists=True, path_type=Path, dir_okay=True, file_okay=False, resolve_path=True),
74
+ show_envvar=True,
75
+ help="Specifies the root path to be used for the project. It will be automatically detected if not provided.",
76
+ )
77
+ @click.option(
78
+ "--no-vcs",
79
+ is_flag=True,
80
+ show_envvar=True,
81
+ help="Ignore version control system directories (e.g., .git, .hg) when detecting the project root.",
82
+ )
52
83
  @click.option(
53
84
  "-f",
54
85
  "--format",
@@ -95,6 +126,22 @@ from .commands import config, profiles
95
126
  show_default=True,
96
127
  show_envvar=True,
97
128
  )
129
+ @click.option(
130
+ "--log-format",
131
+ type=str,
132
+ help="Sets the log format. See python logging documentation for more information.",
133
+ default=logging.BASIC_FORMAT,
134
+ show_default=True,
135
+ show_envvar=True,
136
+ )
137
+ @click.option(
138
+ "--log-style",
139
+ type=click.Choice(["%", "{", "$"]),
140
+ help="Sets the log style. See python logging documentation for more information.",
141
+ default="%",
142
+ show_default=True,
143
+ show_envvar=True,
144
+ )
98
145
  @click.option(
99
146
  "--log-filename",
100
147
  type=click.Path(
@@ -121,8 +168,8 @@ from .commands import config, profiles
121
168
  type=click.Path(exists=False, resolve_path=False, path_type=str),
122
169
  multiple=True,
123
170
  hidden=show_hidden_arguments(),
124
- help="Default path to use if no path is given or defined in a profile. Can be specified multiple times. "
125
- "**This is an internal option for running in vscode",
171
+ help="Default path to use if no path is given or defined in a profile. "
172
+ "**This is an internal option for running in vscode**",
126
173
  )
127
174
  @click.option(
128
175
  "--launcher-script",
@@ -160,6 +207,8 @@ def robotcode(
160
207
  app: Application,
161
208
  config_files: Optional[List[Path]],
162
209
  profiles: Optional[List[str]],
210
+ root: Optional[Path],
211
+ no_vcs: bool,
163
212
  format: Optional[OutputFormat],
164
213
  dry: bool,
165
214
  verbose: bool,
@@ -167,6 +216,8 @@ def robotcode(
167
216
  pager: Optional[bool],
168
217
  log: bool,
169
218
  log_level: str,
219
+ log_format: str,
220
+ log_style: Literal["%", "{", "$"],
170
221
  log_filename: Optional[str],
171
222
  log_calls: bool,
172
223
  default_path: Optional[List[str]],
@@ -189,6 +240,8 @@ def robotcode(
189
240
  app.config.profiles = profiles
190
241
  app.config.dry = dry
191
242
  app.config.verbose = verbose
243
+ app.config.root = root
244
+ app.config.no_vcs = no_vcs
192
245
 
193
246
  if color is None:
194
247
  app.config.colored_output = ColoredOutput.AUTO
@@ -210,10 +263,18 @@ def robotcode(
210
263
 
211
264
  logging.basicConfig(
212
265
  level=log_level,
213
- format="%(name)s:%(levelname)s: %(message)s",
266
+ format=log_format,
267
+ style=log_style,
214
268
  filename=log_filename,
215
269
  )
216
270
 
271
+ try:
272
+ logging.root.handlers[0].formatter = RobotCodeFormatter(
273
+ fmt=log_format, style=log_style, defaults={"indent": ""}
274
+ )
275
+ except TypeError:
276
+ pass
277
+
217
278
  if debugpy:
218
279
  from robotcode.core.utils.debugpy import (
219
280
  start_debugpy,
@@ -240,9 +301,8 @@ def robotcode(
240
301
  robotcode.add_command(config)
241
302
  robotcode.add_command(profiles)
242
303
 
243
- for p in PluginManager().cli_commands:
244
- for c in p:
245
- robotcode.add_command(c)
304
+ for c in PluginManager.instance().cli_commands:
305
+ robotcode.add_command(c)
246
306
 
247
307
 
248
308
  @robotcode.command()
@@ -1 +1 @@
1
- __version__ = "0.78.1"
1
+ __version__ = "0.106.0"
@@ -2,7 +2,7 @@ import dataclasses
2
2
  import os
3
3
  from fnmatch import fnmatchcase
4
4
  from pathlib import Path
5
- from typing import Any, Dict, List, Optional
5
+ from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Type, Union, get_args, get_origin
6
6
 
7
7
  import click
8
8
 
@@ -20,11 +20,9 @@ from robotcode.robot.config.loader import (
20
20
  load_robot_config_from_path,
21
21
  )
22
22
  from robotcode.robot.config.model import (
23
- LibDocProfile,
24
- RebotProfile,
23
+ BaseOptions,
25
24
  RobotConfig,
26
25
  RobotProfile,
27
- TestDocProfile,
28
26
  )
29
27
  from robotcode.robot.config.utils import get_config_files
30
28
 
@@ -66,11 +64,21 @@ def show(app: Application, single: bool, paths: List[Path]) -> None:
66
64
  ```
67
65
  """
68
66
  try:
69
- config_files, _, _ = get_config_files(paths, app.config.config_files, verbose_callback=app.verbose)
67
+ config_files, _, _ = get_config_files(
68
+ paths,
69
+ app.config.config_files,
70
+ root_folder=app.config.root,
71
+ no_vcs=app.config.no_vcs,
72
+ verbose_callback=app.verbose,
73
+ )
70
74
 
71
75
  if single:
72
76
  for file, _ in config_files:
73
- config = load_robot_config_from_path(file)
77
+ config = load_robot_config_from_path(
78
+ file,
79
+ extra_tools={k: v for k, v in PluginManager.instance().tool_config_classes},
80
+ verbose_callback=app.verbose,
81
+ )
74
82
  click.secho(f"File: {file}")
75
83
  app.print_data(
76
84
  config,
@@ -80,7 +88,11 @@ def show(app: Application, single: bool, paths: List[Path]) -> None:
80
88
 
81
89
  return
82
90
 
83
- config = load_robot_config_from_path(*config_files)
91
+ config = load_robot_config_from_path(
92
+ *config_files,
93
+ extra_tools={k: v for k, v in PluginManager.instance().tool_config_classes},
94
+ verbose_callback=app.verbose,
95
+ )
84
96
 
85
97
  app.print_data(
86
98
  config,
@@ -117,7 +129,13 @@ def files(app: Application, paths: List[Path], user: bool = False) -> None:
117
129
  """
118
130
 
119
131
  try:
120
- config_files, _, discovered_by = get_config_files(paths, app.config.config_files, verbose_callback=app.verbose)
132
+ config_files, _, discovered_by = get_config_files(
133
+ paths,
134
+ app.config.config_files,
135
+ root_folder=app.config.root,
136
+ no_vcs=app.config.no_vcs,
137
+ verbose_callback=app.verbose,
138
+ )
121
139
 
122
140
  result: Dict[str, Any] = {"files": [{"path": str(file), "type": type} for file, type in config_files]}
123
141
 
@@ -147,7 +165,7 @@ def files(app: Application, paths: List[Path], user: bool = False) -> None:
147
165
  required=False,
148
166
  )
149
167
  @pass_application
150
- def root(app: Application, paths: List[Path]) -> None:
168
+ def root(app: Application, paths: Tuple[Path, ...]) -> None:
151
169
  """\
152
170
  Searches for the root folder of the project and prints them.
153
171
 
@@ -162,7 +180,9 @@ def root(app: Application, paths: List[Path]) -> None:
162
180
  ```
163
181
  """
164
182
 
165
- root_folder, discovered_by = find_project_root(*(paths or []))
183
+ root_folder, discovered_by = find_project_root(
184
+ *(paths or []), root_folder=app.config.root, no_vcs=app.config.no_vcs
185
+ )
166
186
 
167
187
  if root_folder is None and (app.config.output_format is None or app.config.output_format == OutputFormat.TEXT):
168
188
  raise click.ClickException("Cannot detect root folder. 😥")
@@ -193,55 +213,51 @@ def info(app: Application) -> None:
193
213
  """Shows informations about possible configuration settings."""
194
214
 
195
215
 
196
- def get_config_fields() -> Dict[str, Dict[str, str]]:
197
- result = {}
198
- for field in dataclasses.fields(RobotConfig):
199
- field_name_encoded = encode_case_for_field_name(RobotConfig, field)
200
- result[field_name_encoded] = {
201
- "type": str(field.type),
202
- "description": field.metadata.get("description", "").strip(),
203
- }
216
+ def type_to_str(t: Union[Type[Any], str]) -> str:
217
+ if isinstance(t, str):
218
+ return f"'{t}'"
219
+
220
+ origin = get_origin(t)
221
+ if origin is None:
222
+ return t.__name__
223
+
224
+ if origin is Union:
225
+ return " | ".join(type_to_str(a) for a in get_args(t))
204
226
 
205
- for field in dataclasses.fields(RobotProfile):
206
- field_name_encoded = encode_case_for_field_name(RobotProfile, field)
207
- if field_name_encoded in result:
227
+ return f"{origin.__name__}[{', '.join(type_to_str(a) for a in get_args(t))}]"
228
+
229
+
230
+ def _get_config_fields_for_type(
231
+ prefix: str, cls: Type[Any], filter: Optional[Callable[[str], bool]] = None
232
+ ) -> Dict[str, Dict[str, str]]:
233
+ result = {}
234
+ for field in dataclasses.fields(cls):
235
+ field_name_encoded = encode_case_for_field_name(cls, field)
236
+ if filter and not filter(field_name_encoded):
208
237
  continue
209
238
 
210
- result["[profile]." + field_name_encoded] = {
211
- "type": str(field.type),
239
+ result[prefix + field_name_encoded] = {
240
+ "type": type_to_str(field.type),
212
241
  "description": field.metadata.get("description", "").strip(),
213
242
  }
243
+ args = get_args(field.type)
214
244
 
215
- for field in dataclasses.fields(RebotProfile):
216
- field_name_encoded = encode_case_for_field_name(RebotProfile, field)
217
- result["rebot." + field_name_encoded] = {
218
- "type": str(field.type),
219
- "description": field.metadata.get("description", "").strip(),
220
- }
245
+ p = f"{prefix}{'' if prefix[-1]=='.' else '.'}" if prefix else ""
246
+ for a in args:
247
+ origin = get_origin(a)
248
+ if origin is None and issubclass(a, BaseOptions):
249
+ result.update(_get_config_fields_for_type(f"{p}{field_name_encoded}.", a, filter))
250
+ return result
221
251
 
222
- for field in dataclasses.fields(LibDocProfile):
223
- field_name_encoded = encode_case_for_field_name(LibDocProfile, field)
224
- result["libdoc." + field_name_encoded] = {
225
- "type": str(field.type),
226
- "description": field.metadata.get("description", "").strip(),
227
- }
228
252
 
229
- for field in dataclasses.fields(TestDocProfile):
230
- field_name_encoded = encode_case_for_field_name(TestDocProfile, field)
231
- result["testdoc." + field_name_encoded] = {
232
- "type": str(field.type),
233
- "description": field.metadata.get("description", "").strip(),
234
- }
253
+ def get_config_fields() -> Dict[str, Dict[str, str]]:
254
+ result = {}
255
+ result.update(_get_config_fields_for_type("", RobotConfig))
235
256
 
236
- for entry in PluginManager().config_classes:
237
- for s, cls in entry:
238
- if dataclasses.is_dataclass(cls):
239
- for field in dataclasses.fields(cls):
240
- field_name_encoded = encode_case_for_field_name(TestDocProfile, field)
241
- result[f"{s}." + field_name_encoded] = {
242
- "type": str(field.type),
243
- "description": field.metadata.get("description", "").strip(),
244
- }
257
+ result.update(_get_config_fields_for_type("[profile].", RobotProfile, lambda x: x not in result))
258
+ for entry in PluginManager.instance().tool_config_classes:
259
+ if dataclasses.is_dataclass(entry.config_class):
260
+ result.update(_get_config_fields_for_type(f"tool.{entry.tool_name}.", entry.config_class))
245
261
 
246
262
  return {k: v for k, v in sorted(result.items(), key=lambda item: item[0])}
247
263
 
@@ -275,7 +291,15 @@ def list(app: Application, name: Optional[List[str]] = None) -> None:
275
291
  result.append(field)
276
292
 
277
293
  if app.config.output_format is None or app.config.output_format == OutputFormat.TEXT:
278
- app.echo_via_pager(os.linesep.join(result))
294
+
295
+ def output() -> Iterable[str]:
296
+ for r in result:
297
+ yield r + os.linesep
298
+
299
+ yield os.linesep
300
+ yield f"Total: {len(result)}"
301
+
302
+ app.echo_via_pager(output())
279
303
  else:
280
304
  app.print_data({"names": result})
281
305
 
@@ -307,7 +331,7 @@ def desc(app: Application, name: Optional[List[str]] = None) -> None:
307
331
  ]
308
332
 
309
333
  if app.config.output_format is None or app.config.output_format == OutputFormat.TEXT:
310
- output = ""
334
+ output = "# robot.toml configuration settings\n\n"
311
335
  for field, value in config_fields:
312
336
  output += f"## {field}\n\n"
313
337
  type = (
@@ -316,7 +340,7 @@ def desc(app: Application, name: Optional[List[str]] = None) -> None:
316
340
  .replace("robotcode.robot.config.model.", "")
317
341
  .replace("NoneType", "None")
318
342
  )
319
- output += f"Type: {type}\n\n"
343
+ output += f"Type: `{type}`\n\n"
320
344
  output += value["description"] + "\n\n"
321
345
 
322
346
  app.echo_as_markdown(output)
@@ -40,9 +40,11 @@ def profiles() -> None:
40
40
  def show(app: Application, no_evaluate: bool, paths: List[Path]) -> None:
41
41
  """Shows the given profile configuration."""
42
42
  try:
43
- config_files, _, _ = get_config_files(paths, app.config.config_files, verbose_callback=app.verbose)
43
+ config_files, _, _ = get_config_files(
44
+ paths, app.config.config_files, root_folder=app.config.root, verbose_callback=app.verbose
45
+ )
44
46
 
45
- config = load_robot_config_from_path(*config_files).combine_profiles(
47
+ config = load_robot_config_from_path(*config_files, verbose_callback=app.verbose).combine_profiles(
46
48
  *(app.config.profiles or []), verbose_callback=app.verbose, error_callback=app.error
47
49
  )
48
50
 
@@ -73,9 +75,15 @@ def list(app: Application, paths: List[Path], show_hidden: bool = False, sort_by
73
75
  """Lists the defined profiles in the current configuration."""
74
76
 
75
77
  try:
76
- config_files, _, discovered_by = get_config_files(paths, app.config.config_files, verbose_callback=app.verbose)
78
+ config_files, _, discovered_by = get_config_files(
79
+ paths,
80
+ app.config.config_files,
81
+ root_folder=app.config.root,
82
+ no_vcs=app.config.no_vcs,
83
+ verbose_callback=app.verbose,
84
+ )
77
85
 
78
- config = load_robot_config_from_path(*config_files)
86
+ config = load_robot_config_from_path(*config_files, verbose_callback=app.verbose)
79
87
 
80
88
  _, selected_profiles, enabled_names = config.combine_profiles_ex(
81
89
  *(app.config.profiles or []), verbose_callback=app.verbose, error_callback=app.error
@@ -94,7 +102,7 @@ def list(app: Application, paths: List[Path], show_hidden: bool = False, sort_by
94
102
  "precedence": v.precedence,
95
103
  }
96
104
  for k, v in (config.profiles or {}).items()
97
- if show_hidden or not k.startswith("_") and not v.hidden
105
+ if show_hidden or (not k.startswith("_") and not v.hidden)
98
106
  ],
99
107
  key=(
100
108
  (lambda v: cast(Any, str(v.get("name", ""))))
@@ -0,0 +1,152 @@
1
+ Metadata-Version: 2.4
2
+ Name: robotcode
3
+ Version: 0.106.0
4
+ Summary: Command line interface for RobotCode
5
+ Project-URL: Homepage, https://robotcode.io
6
+ Project-URL: Donate, https://opencollective.com/robotcode
7
+ Project-URL: Documentation, https://github.com/robotcodedev/robotcode#readme
8
+ Project-URL: Changelog, https://github.com/robotcodedev/robotcode/blob/main/CHANGELOG.md
9
+ Project-URL: Issues, https://github.com/robotcodedev/robotcode/issues
10
+ Project-URL: Source, https://github.com/robotcodedev/robotcode
11
+ Author-email: Daniel Biehl <dbiehl@live.de>
12
+ License: Apache-2.0
13
+ License-File: LICENSE.txt
14
+ Keywords: Acceptance Test Driven Development,Acceptance Testing,BDD,BDT,Behavior Driven Testing,Data Driven,Debug Adapter Protocol,Keyword Driven,Language Server Protocol,RPA,RobotFramework,Robotic Process Automation,Test,Testing,Visual Studio Code
15
+ Classifier: Development Status :: 5 - Production/Stable
16
+ Classifier: Framework :: Robot Framework
17
+ Classifier: Framework :: Robot Framework :: Tool
18
+ Classifier: Intended Audience :: Developers
19
+ Classifier: License :: OSI Approved :: Apache Software License
20
+ Classifier: Operating System :: OS Independent
21
+ Classifier: Programming Language :: Python :: 3.8
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Classifier: Programming Language :: Python :: 3.13
27
+ Classifier: Programming Language :: Python :: Implementation :: CPython
28
+ Classifier: Topic :: Software Development :: Debuggers
29
+ Classifier: Topic :: Software Development :: Quality Assurance
30
+ Classifier: Topic :: Software Development :: Testing
31
+ Classifier: Topic :: Software Development :: Testing :: Acceptance
32
+ Classifier: Topic :: Software Development :: Testing :: BDD
33
+ Classifier: Topic :: Text Editors :: Integrated Development Environments (IDE)
34
+ Classifier: Topic :: Utilities
35
+ Classifier: Typing :: Typed
36
+ Requires-Python: >=3.8
37
+ Requires-Dist: robotcode-core==0.106.0
38
+ Requires-Dist: robotcode-plugin==0.106.0
39
+ Requires-Dist: robotcode-robot==0.106.0
40
+ Provides-Extra: all
41
+ Requires-Dist: docutils; extra == 'all'
42
+ Requires-Dist: pyyaml>=5.4; extra == 'all'
43
+ Requires-Dist: rich; extra == 'all'
44
+ Requires-Dist: robotcode-analyze==0.106.0; extra == 'all'
45
+ Requires-Dist: robotcode-debugger==0.106.0; extra == 'all'
46
+ Requires-Dist: robotcode-language-server==0.106.0; extra == 'all'
47
+ Requires-Dist: robotcode-repl-server==0.106.0; extra == 'all'
48
+ Requires-Dist: robotcode-repl==0.106.0; extra == 'all'
49
+ Requires-Dist: robotcode-runner==0.106.0; extra == 'all'
50
+ Requires-Dist: robotframework-robocop>=2.0.0; extra == 'all'
51
+ Requires-Dist: robotframework-tidy>=2.0.0; extra == 'all'
52
+ Provides-Extra: analyze
53
+ Requires-Dist: robotcode-analyze==0.106.0; extra == 'analyze'
54
+ Provides-Extra: colored
55
+ Requires-Dist: rich; extra == 'colored'
56
+ Provides-Extra: debugger
57
+ Requires-Dist: robotcode-debugger==0.106.0; extra == 'debugger'
58
+ Provides-Extra: languageserver
59
+ Requires-Dist: robotcode-language-server==0.106.0; extra == 'languageserver'
60
+ Provides-Extra: lint
61
+ Requires-Dist: robotframework-robocop>=2.0.0; extra == 'lint'
62
+ Provides-Extra: repl
63
+ Requires-Dist: robotcode-repl==0.106.0; extra == 'repl'
64
+ Provides-Extra: replserver
65
+ Requires-Dist: robotcode-repl-server==0.106.0; extra == 'replserver'
66
+ Provides-Extra: rest
67
+ Requires-Dist: docutils; extra == 'rest'
68
+ Provides-Extra: runner
69
+ Requires-Dist: robotcode-runner==0.106.0; extra == 'runner'
70
+ Provides-Extra: tidy
71
+ Requires-Dist: robotframework-tidy>=2.0.0; extra == 'tidy'
72
+ Provides-Extra: yaml
73
+ Requires-Dist: pyyaml>=5.4; extra == 'yaml'
74
+ Description-Content-Type: text/markdown
75
+
76
+
77
+ # RobotCode - Language Support for Robot Framework in Visual Studio Code
78
+
79
+ [![License](https://img.shields.io/github/license/robotcodedev/robotcode?style=flat&logo=apache)](https://github.com/robotcodedev/robotcode/blob/master/LICENSE)
80
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/robotcodedev/robotcode/build-test-package-publish.yml?branch=main&style=flat&logo=github)](https://github.com/robotcodedev/robotcode/actions?query=workflow:build_test_package_publish)
81
+
82
+ [![VS Code Marketplace](https://img.shields.io/visual-studio-marketplace/v/d-biehl.robotcode?style=flat&label=VS%20Marketplace&logo=visual-studio-code)](https://marketplace.visualstudio.com/items?itemName=d-biehl.robotcode)
83
+ [![Installs](https://img.shields.io/visual-studio-marketplace/i/d-biehl.robotcode?style=flat)](https://marketplace.visualstudio.com/items?itemName=d-biehl.robotcode)
84
+
85
+ [![JETBRAINS Marketplace](https://img.shields.io/jetbrains/plugin/v/26216.svg)](https://plugins.jetbrains.com/plugin/26216)
86
+ [![Downloads](https://img.shields.io/jetbrains/plugin/d/26216.svg)](https://plugins.jetbrains.com/plugin/26216)
87
+
88
+
89
+ [![PyPI - Version](https://img.shields.io/pypi/v/robotcode.svg?style=flat)](https://pypi.org/project/robotcode)
90
+ [![Python Version](https://img.shields.io/pypi/pyversions/robotcode.svg?style=flat)](https://pypi.org/project/robotcode)
91
+ [![Downloads](https://img.shields.io/pypi/dm/robotcode.svg?style=flat&label=downloads)](https://pypi.org/project/robotcode)
92
+
93
+ ---
94
+
95
+ **RobotCode** is a Visual Studio Code extension that enhances your workflow with [Robot Framework](https://robotframework.org/).
96
+ It provides a rich set of features to help you write, run, and debug your Robot Framework tests directly within Visual Studio Code.
97
+
98
+ ## Why RobotCode?
99
+
100
+ **Built on Robot Framework Core**
101
+ RobotCode is based on the Robot Framework Core and uses its parser, ensuring complete compatibility and consistency. This means you get the same syntax validation, error messages, and behavior as if you were running Robot Framework directly.
102
+
103
+ **Powered by the Language Server Protocol**
104
+ RobotCode is built on the Language Server Protocol (LSP), a modern standard for implementing language support across multiple editors and IDEs. This ensures a seamless and responsive user experience, while making it easier to maintain compatibility with evolving IDE features.
105
+
106
+ **Powerful Command Line Tools**
107
+ RobotCode extends the Robot Framework CLI with enhanced tools for test execution, analysis, and debugging. It supports [`robot.toml`](https://robotcode.io/03_reference/) configurations, integrates a Debug Adapter Protocol (DAP) compatible debugger, and provides an interactive REPL environment for experimenting with Robot Framework commands. Modular and flexible, these tools streamline your workflow for both development and production.
108
+
109
+ ## Key Features
110
+
111
+ - **Code Editing**: Enjoy code auto-completion, navigation and more.
112
+ - **IntelliSense**: Get code completion suggestions for keywords, variables, and more.
113
+ - **Refactoring**: Rename variables, keywords, arguments and more with ease and project wide.
114
+ - **Enhanced Syntax Highlighting**: Easily identify and read your Robot Framework code with support highlight embedded arguments, python expressions, environment variables with default values, and more.
115
+ - **Code Snippets**: Quickly insert common Robot Framework code snippets.
116
+ - **Test Discovery**: Discover and run Robot Framework test cases directly within VS Code.
117
+ - **Test Execution**: Execute Robot Framework test cases and suites directly within VS Code.
118
+ - **Test Reports**: View test reports directly within VS Code.
119
+ - **Debugging**: Debug your Robot Framework tests with ease.
120
+ - **Command Line Tools**: A wide array of tools to assist in setting up and managing Robot Framework environments.
121
+ - **Code Analysis with Robocop**: Install [Robocop](https://robocop.readthedocs.io/) for additional code analysis.
122
+ - **Code Formatting**: Format your code using Robot Framework’s built-in tools like `robot.tidy` or [Robotidy](https://robotidy.readthedocs.io/).
123
+ - **Multi-root Workspace Support**: Manage multiple Robot Framework projects with different Python environments simultaneously.
124
+ - **Customizable Settings**: Configure the extension to fit your needs.
125
+ - **RobotCode Repl and Notebooks**: Play with Robot Framework in a Jupyter Notebook-like environment.
126
+ - **And More!**: Check out the [official documentation](https://robotcode.io) for more details.
127
+
128
+ ## Requirements
129
+
130
+ - Python 3.8 or newer
131
+ - Robot Framework 4.1 or newer
132
+ - Visual Studio Code 1.86 or newer
133
+
134
+ ## Getting Started
135
+
136
+ 1. Install the [RobotCode extension](https://marketplace.visualstudio.com/items?itemName=d-biehl.robotcode) from the Visual Studio Marketplace.
137
+ 2. Configure your Robot Framework environment with the command-line tools provided by the extension.
138
+ 3. Start writing and running your Robot Framework tests!
139
+
140
+ For a more detailed guide, check out the [Let's get started](https://robotcode.io/02_get_started/) Guide on the [RobotCode](https://robotcode.io) website.
141
+
142
+ ## Extensions
143
+
144
+ RobotCode automatically installs the [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) and the [Python Debugger](https://marketplace.visualstudio.com/items?itemName=ms-python.debugpy) extension. Additional extensions may be required depending on your project needs.
145
+
146
+ ## Documentation
147
+
148
+ For more details on installation, setup, and usage, refer to the [official RobotCode documentation](https://robotcode.io).
149
+
150
+ ## License
151
+
152
+ This project is licensed under the [Apache 2.0 License](https://spdx.org/licenses/Apache-2.0.html).
@@ -0,0 +1,12 @@
1
+ robotcode/cli/__init__.py,sha256=zEodZQq94XygNMUJ26-CYMiiqHSpQO1GRPqaqKQcjX8,8763
2
+ robotcode/cli/__main__.py,sha256=hX3nwROMTnsYGT1KS0rXUYrslu9sFzctYdAh66Rcckw,153
3
+ robotcode/cli/__version__.py,sha256=9-VLSgQwHYpdKCSbee2vraHcyCwruf0TMoqU4VeK8K0,24
4
+ robotcode/cli/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
5
+ robotcode/cli/commands/__init__.py,sha256=XJHRt_YwMO2Ni2EfL2aj4jkJXMVG6NGFTpzvSVgIRnQ,92
6
+ robotcode/cli/commands/config.py,sha256=84gG4LrIynfPbEQkQDYA3ZClg50ck32NZyUvAWw9g6w,10479
7
+ robotcode/cli/commands/profiles.py,sha256=urgcIcDa6luObHrh7Qdz1UXpvs776Cq5UM9LbsJ8V8o,5899
8
+ robotcode-0.106.0.dist-info/METADATA,sha256=p0SwQ57HIwk41HjeiRvlB9R5385JrhH1KPN8q1Y6Y4U,9260
9
+ robotcode-0.106.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
10
+ robotcode-0.106.0.dist-info/entry_points.txt,sha256=Pb4DKVVdJb5PboVl48njwk3DkKQHBJOL1A8KkpemqA8,58
11
+ robotcode-0.106.0.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
12
+ robotcode-0.106.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.21.1
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,349 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: robotcode
3
- Version: 0.78.1
4
- Summary: Command line interface for RobotCode
5
- Project-URL: Homepage, https://robotcode.io
6
- Project-URL: Donate, https://github.com/sponsors/d-biehl
7
- Project-URL: Documentation, https://github.com/d-biehl/robotcode#readme
8
- Project-URL: Changelog, https://github.com/d-biehl/robotcode/blob/main/CHANGELOG.md
9
- Project-URL: Issues, https://github.com/d-biehl/robotcode/issues
10
- Project-URL: Source, https://github.com/d-biehl/robotcode
11
- Author-email: Daniel Biehl <dbiehl@live.de>
12
- License: Apache-2.0
13
- License-File: LICENSE.txt
14
- Keywords: Acceptance Test Driven Development,Acceptance Testing,BDD,BDT,Behavior Driven Testing,Data Driven,Debug Adapter Protocol,Keyword Driven,Language Server Protocol,RPA,RobotFramework,Robotic Process Automation,Test,Testing,Visual Studio Code
15
- Classifier: Development Status :: 5 - Production/Stable
16
- Classifier: Framework :: Robot Framework
17
- Classifier: Framework :: Robot Framework :: Tool
18
- Classifier: Intended Audience :: Developers
19
- Classifier: License :: OSI Approved :: Apache Software License
20
- Classifier: Operating System :: OS Independent
21
- Classifier: Programming Language :: Python :: 3.8
22
- Classifier: Programming Language :: Python :: 3.9
23
- Classifier: Programming Language :: Python :: 3.10
24
- Classifier: Programming Language :: Python :: 3.11
25
- Classifier: Programming Language :: Python :: 3.12
26
- Classifier: Programming Language :: Python :: Implementation :: CPython
27
- Classifier: Topic :: Software Development :: Debuggers
28
- Classifier: Topic :: Software Development :: Quality Assurance
29
- Classifier: Topic :: Software Development :: Testing
30
- Classifier: Topic :: Software Development :: Testing :: Acceptance
31
- Classifier: Topic :: Software Development :: Testing :: BDD
32
- Classifier: Topic :: Text Editors :: Integrated Development Environments (IDE)
33
- Classifier: Topic :: Utilities
34
- Classifier: Typing :: Typed
35
- Requires-Python: >=3.8
36
- Requires-Dist: robotcode-core==0.78.1
37
- Requires-Dist: robotcode-plugin==0.78.1
38
- Provides-Extra: all
39
- Requires-Dist: docutils; extra == 'all'
40
- Requires-Dist: pyyaml>=5.4; extra == 'all'
41
- Requires-Dist: rich; extra == 'all'
42
- Requires-Dist: robotcode-analyze==0.78.1; extra == 'all'
43
- Requires-Dist: robotcode-debugger==0.78.1; extra == 'all'
44
- Requires-Dist: robotcode-language-server==0.78.1; extra == 'all'
45
- Requires-Dist: robotcode-runner==0.78.1; extra == 'all'
46
- Requires-Dist: robotframework-robocop>=2.0.0; extra == 'all'
47
- Requires-Dist: robotframework-tidy>=2.0.0; extra == 'all'
48
- Provides-Extra: analyze
49
- Requires-Dist: robotcode-analyze==0.78.1; extra == 'analyze'
50
- Provides-Extra: colored
51
- Requires-Dist: rich; extra == 'colored'
52
- Provides-Extra: debugger
53
- Requires-Dist: robotcode-debugger==0.78.1; extra == 'debugger'
54
- Provides-Extra: languageserver
55
- Requires-Dist: robotcode-language-server==0.78.1; extra == 'languageserver'
56
- Provides-Extra: lint
57
- Requires-Dist: robotframework-robocop>=2.0.0; extra == 'lint'
58
- Provides-Extra: rest
59
- Requires-Dist: docutils; extra == 'rest'
60
- Provides-Extra: runner
61
- Requires-Dist: robotcode-runner==0.78.1; extra == 'runner'
62
- Provides-Extra: tidy
63
- Requires-Dist: robotframework-tidy>=2.0.0; extra == 'tidy'
64
- Provides-Extra: yaml
65
- Requires-Dist: pyyaml>=5.4; extra == 'yaml'
66
- Description-Content-Type: text/markdown
67
-
68
- # RobotCode - Language support for Robot Framework for Visual Studio Code
69
-
70
- [![Visual Studio Marketplace](https://img.shields.io/visual-studio-marketplace/v/d-biehl.robotcode?style=flat&label=VS%20Marketplace&logo=visual-studio-code)](https://marketplace.visualstudio.com/items?itemName=d-biehl.robotcode)
71
- [![Installs](https://img.shields.io/visual-studio-marketplace/i/d-biehl.robotcode?style=flat)](https://marketplace.visualstudio.com/items?itemName=d-biehl.robotcode)
72
- [![Build Status](https://img.shields.io/github/actions/workflow/status/d-biehl/robotcode/build-test-package-publish.yml?branch=main&style=flat&logo=github)](https://github.com/d-biehl/robotcode/actions?query=workflow:build_test_package_publish)
73
- [![License](https://img.shields.io/github/license/d-biehl/robotcode?style=flat&logo=apache)](https://github.com/d-biehl/robotcode/blob/master/LICENSE)
74
-
75
- [![PyPI - Version](https://img.shields.io/pypi/v/robotcode.svg?style=flat)](https://pypi.org/project/robotcode)
76
- [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/robotcode.svg?style=flat)](https://pypi.org/project/robotcode)
77
- [![PyPI - Downloads](https://img.shields.io/pypi/dm/robotcode.svg?style=flat&label=downloads)](https://pypi.org/project/robotcode/)
78
-
79
- ----
80
-
81
- An [extension](https://marketplace.visualstudio.com/VSCode) which brings support for [RobotFramework](https://robotframework.org/)
82
- to [Visual Studio Code](https://code.visualstudio.com/), including [features](#features) like code completion, debugging, test explorer, refactoring and more!
83
-
84
- ## Quick start
85
-
86
- 1. [Install a supported version of Python on your system](https://code.visualstudio.com/docs/python/python-tutorial#_prerequisites)
87
- (note: only Python 3.8 and above are supported)
88
-
89
- 2. [Install a supported version of RobotFramwork on your system](https://github.com/robotframework/robotframework/blob/master/INSTALL.rst) (note: only RobotFramework 4.0 and above are supported)
90
-
91
- 3. [Install the RobotCode extension for Visual Studio Code](https://code.visualstudio.com/docs/editor/extension-gallery).
92
- 4. Open or create a robot file and start coding! 😉
93
-
94
-
95
- ## Requirements
96
-
97
- * Python 3.8 or above
98
- * Robotframework 4.1 and above
99
- * VSCode version 1.82 and above
100
-
101
-
102
- ## Features
103
-
104
- With RobotCode you can edit your code with auto-completion, code navigation, syntax checking and many more.
105
- Here is a list of Features:
106
-
107
- - [Autocomplete and IntelliSense](#Autocomplete-and-IntelliSense)
108
- - [Code Navigation](#code-navigation)
109
- - [Diagnostics and Linting](#diagnostics-and-linting)
110
- - [Code Formatting](#code-formatting)
111
- - [Running and Debugging](#running-and-debugging)
112
- - [Multi-root Workspace folders](#multi-root-workspace-folders)
113
- - Find implementations and references of keywords, variables, libraries, resource and variable files
114
- - Show codelenses for keyword definitions
115
- - Test Explorer
116
- - Refactorings
117
- - renaming keywords, variables, tags
118
-
119
- ### Autocomplete and IntelliSense
120
-
121
- Autocompletion for:
122
- - Libraries with parameters
123
- - Resources,
124
- - Variables
125
- - Keywords with parameters
126
- - Namespaces
127
-
128
- ![Autocomplete Libraries and Keywords](./docs/images/autocomplete1.gif)
129
-
130
- Autocompletion supports all supported variables types
131
- - local variables
132
- - variables from resource files
133
- - variables from variables file (.py and .yaml)
134
- - static and dynamic
135
- - command line variables
136
- - builtin variables
137
-
138
- ![Autocomplete Variables](./docs/images/autocomplete2.gif)
139
-
140
- ### Code Navigation
141
-
142
- - Symbols
143
- - Goto definitions and implementations
144
- - Keywords
145
- - Variables
146
- - Libraries
147
- - Resources
148
- - Find references
149
- - Keywords
150
- - Variables
151
- - Imports
152
- - Libraries
153
- - Resources
154
- - Variables
155
- - Tags
156
- - Errors and Warnings
157
-
158
- ### Diagnostics and Linting
159
-
160
- RobotCode analyse your code and show diagnostics for:
161
- - Syntax Errors
162
- - Unknown keywords
163
- - Duplicate keywords
164
- - Missing libraries, resource and variable imports
165
- - Duplicate libraries, resource and variable imports
166
- - ... and many more
167
-
168
- For most things RobotCode uses the installed RobotFramework version to parse and analyse the code, so you get the same errors as when you run it.
169
-
170
-
171
- Get additional code analysis with [Robocop](https://robocop.readthedocs.io/). Just install it in your python environment.
172
-
173
- ### Code Formatting
174
-
175
- RobotCode can format your code with the internal RobotFramework robot.tidy tool (deprecated), but also with [Robotidy](https://robotidy.readthedocs.io/). Just install it.
176
-
177
- ### Running and Debugging
178
-
179
- RobotCode supports running and debugging of RobotFramework testcases and tasks out of the box, directly from the definition of the test or suite.
180
-
181
- ![Running Tests](./docs/images/running_tests.gif)
182
-
183
- In the debug console you can see all log messages of the current run and navigate to the keyword the message was written by.
184
-
185
- ### Multi-root Workspace folders
186
-
187
- RobotCodes support for [Multi-root Workspaces](https://code.visualstudio.com/docs/editor/multi-root-workspaces), enables loading and editing different Robotframework projects/folders with different RobotFramework/Python environments and settings at the same time or you can share the same RobotFramework/Python environment and settings for all folders in the workspace.
188
-
189
-
190
- ## Installed extensions
191
-
192
- RobotCode will automatically install [Python extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python).
193
-
194
- Extensions installed through the marketplace are subject to the [Marketplace Terms of Use](https://cdn.vsassets.io/v/M146_20190123.39/_content/Microsoft-Visual-Studio-Marketplace-Terms-of-Use.pdf).
195
-
196
-
197
- ## Setting up your environment
198
-
199
- You can alway use your local python environment, just select the correct python interpreter in Visual Studio Code.
200
-
201
- ### With pipenv
202
-
203
- This is the simpliest way to create an running environment.
204
-
205
- - As a prerequisite you need to install [pipenv](https://pipenv.pypa.io/) like this:
206
-
207
- ```bash
208
- python -m pip install pipenv
209
- ```
210
-
211
-
212
- - Create your project directory (robottest is just an example)
213
- ```bash
214
- mkdir robottest
215
- cd robottest
216
- ```
217
- - Install robotframework
218
- ```bash
219
- python -m pipenv install robotframework
220
- ```
221
- - Open project in VSCode
222
- - Set the python interpreter to the created virtual environment
223
-
224
-
225
- ## Customization
226
-
227
- ### Editor Style
228
-
229
- You can change some stylings for RobotFramework files in VSCode editor, independently of the current theme. (see [Customizing a Color Theme](https://code.visualstudio.com/docs/getstarted/themes#_customizing-a-color-theme))
230
-
231
- See the difference:
232
-
233
- | Before | After |
234
- | ---------------------------------------------------------------- | ---------------------------------------------------------- |
235
- | ![Without customization](./docs/images/without_customization.gif) | ![With customization](./docs/images/with_customization.gif) |
236
-
237
-
238
- As a template you can put the following code to your user settings of VSCode.
239
-
240
- Open the user `settings.json` like this:
241
-
242
- <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> or <kbd>F1</kbd> or <kbd>CMD</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>
243
-
244
- and then type:
245
-
246
- `Preferences: Open Settings (JSON)`
247
-
248
- put this to the `settings.json`
249
-
250
- ```jsonc
251
- "editor.tokenColorCustomizations": {
252
- "textMateRules": [
253
- {
254
- "scope": "variable.function.keyword-call.inner.robotframework",
255
- "settings": {
256
- "fontStyle": "italic"
257
- }
258
- },
259
- {
260
- "scope": "variable.function.keyword-call.robotframework",
261
- "settings": {
262
- //"fontStyle": "bold"
263
- }
264
- },
265
- {
266
- "scope": "string.unquoted.embeddedArgument.robotframework",
267
- "settings": {
268
- "fontStyle": "italic"
269
- }
270
- },
271
- {
272
- "scope": "entity.name.function.testcase.name.robotframework",
273
- "settings": {
274
- "fontStyle": "bold underline"
275
- }
276
- },
277
- {
278
- "scope": "entity.name.function.keyword.name.robotframework",
279
- "settings": {
280
- "fontStyle": "bold italic"
281
- }
282
- },
283
- {
284
- "scope": "variable.name.readwrite.robotframework",
285
- "settings": {
286
- //"fontStyle": "italic",
287
- }
288
- },
289
- {
290
- "scope": "keyword.control.import.robotframework",
291
- "settings": {
292
- "fontStyle": "italic"
293
- }
294
- },
295
- {
296
- "scope": "keyword.other.header.setting.robotframework",
297
- "settings": {
298
- "fontStyle": "bold underline"
299
- }
300
- },
301
- {
302
- "scope": "keyword.other.header.variable.robotframework",
303
- "settings": {
304
- "fontStyle": "bold underline"
305
- }
306
- },
307
- {
308
- "scope": "keyword.other.header.testcase.robotframework",
309
- "settings": {
310
- "fontStyle": "bold underline"
311
- }
312
- },
313
- {
314
- "scope": "keyword.other.header.keyword.robotframework",
315
- "settings": {
316
- "fontStyle": "bold underline"
317
- }
318
- },
319
- {
320
- "scope": "keyword.other.header.setting.robotframework",
321
- "settings": {
322
- "fontStyle": "bold underline"
323
- }
324
- },
325
- {
326
- "scope": "keyword.other.header.comment.robotframework",
327
- "settings": {
328
- "fontStyle": "bold italic underline"
329
- }
330
- },
331
- {
332
- "scope": "string.unquoted.escape.robotframework",
333
- "settings": {
334
- //"foreground": "#FF0000",
335
- }
336
- }
337
- ]
338
- },
339
-
340
- "editor.semanticTokenColorCustomizations": {
341
- "rules": {
342
- "*.documentation:robotframework": {
343
- "fontStyle": "italic",
344
- //"foreground": "#aaaaaa"
345
- }
346
- }
347
- }
348
-
349
- ```
@@ -1,12 +0,0 @@
1
- robotcode/cli/__init__.py,sha256=6c-evRLgJ0NR08YvynBQzKxAesAbXB0fnrzZ7MvBDM0,7115
2
- robotcode/cli/__main__.py,sha256=hX3nwROMTnsYGT1KS0rXUYrslu9sFzctYdAh66Rcckw,153
3
- robotcode/cli/__version__.py,sha256=HinYe1V3FgUaLri1gy6R6_VuKh3sB-UYTNM51cV6k4I,23
4
- robotcode/cli/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
5
- robotcode/cli/commands/__init__.py,sha256=XJHRt_YwMO2Ni2EfL2aj4jkJXMVG6NGFTpzvSVgIRnQ,92
6
- robotcode/cli/commands/config.py,sha256=vLKm8WjAa3nLLZVgCeFY40kbyjq5hjy_gFKRPCDwVr8,10020
7
- robotcode/cli/commands/profiles.py,sha256=HUCsNMaK75AVSG_A6F1I209xtQH2AICaoLcqpIO7Vjs,5660
8
- robotcode-0.78.1.dist-info/METADATA,sha256=G_dG4zoxki9k0TahW1YawbUh4NLV1j5vYDeJKFwfaZ0,13107
9
- robotcode-0.78.1.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
10
- robotcode-0.78.1.dist-info/entry_points.txt,sha256=Pb4DKVVdJb5PboVl48njwk3DkKQHBJOL1A8KkpemqA8,58
11
- robotcode-0.78.1.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
12
- robotcode-0.78.1.dist-info/RECORD,,