Skip to content

Commit edc4ee5

Browse files
committed
feat(robotcode): Add commands to get informations about configurations and profiles
1 parent 90c6c25 commit edc4ee5

File tree

12 files changed

+303
-109
lines changed

12 files changed

+303
-109
lines changed

hatch.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ dependencies = [
2525
"tomli-w",
2626
"rich",
2727
]
28-
features = ["yaml", "rest", "lint", "tidy"]
28+
features = ["all"]
2929
pre-install-commands = ["python ./scripts/install_packages.py"]
3030

3131

@@ -39,7 +39,6 @@ create_json_schema = "python ./scripts/create_robot_toml_json_schema.py"
3939

4040
[envs.devel]
4141
python = "38"
42-
features = ["yaml", "rest", "lint", "tidy"]
4342

4443
[[envs.devel.matrix]]
4544
python = ["38", "39", "310", "311"]

packages/analyze/robotcode/analyze/cli/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
context_settings={
1010
"allow_extra_args": True,
1111
"ignore_unknown_options": True,
12-
"help_option_names": ["-h", "--help"],
1312
},
1413
add_help_option=True,
1514
)
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
from dataclasses import dataclass
2+
from enum import Enum
23
from pathlib import Path
34
from typing import Any, Callable, List, Optional, TypeVar, cast
45

56
import click
67
import pluggy
78

8-
__all__ = ["hookimpl", "CommonConfig", "pass_common_config"]
9+
__all__ = ["hookimpl", "ClickCommonConfig", "pass_common_config"]
910

1011
F = TypeVar("F", bound=Callable[..., Any])
1112
hookimpl = cast(Callable[[F], F], pluggy.HookimplMarker("robotcode"))
1213

1314

15+
class ColoredOutput(str, Enum):
16+
AUTO = "auto"
17+
YES = "yes"
18+
NO = "no"
19+
20+
1421
@dataclass
15-
class CommonConfig:
22+
class ClickCommonConfig:
1623
config_file: Optional[Path] = None
1724
profiles: Optional[List[str]] = None
1825
dry: bool = False
1926
verbose: bool = False
27+
colored_output: ColoredOutput = ColoredOutput.AUTO
2028

2129

22-
pass_common_config = click.make_pass_decorator(CommonConfig, ensure=True)
30+
pass_common_config = click.make_pass_decorator(ClickCommonConfig, ensure=True)

packages/robot/robotcode/robot/config/loader.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class ConfigType(str, Enum):
3131
PYPROJECT_TOML = PYPROJECT_TOML
3232
ROBOT_TOML = ROBOT_TOML
3333
LOCAL_ROBOT_TOML = LOCAL_ROBOT_TOML
34+
CUSTOM_TOML = ".toml"
3435

3536

3637
def loads_config_from_robot_toml(__s: str) -> RobotConfig:

packages/robot/robotcode/robot/config/model.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,20 @@ def get_profile(self, *names: str, verbose_callback: Callable[..., None] = None)
420420

421421
profiles = self.profiles or {}
422422

423+
if not names:
424+
if verbose_callback:
425+
verbose_callback('No profiles given, try to check if there are default profiles specified".')
426+
427+
default_profile = [self.default_profile] if isinstance(self.default_profile, str) else self.default_profile
428+
429+
if verbose_callback and default_profile:
430+
verbose_callback(f"Using default profiles {', '.join( default_profile)}.")
431+
432+
names = (*(default_profile or ()),)
433+
423434
for profile_name in names:
424435
if profile_name not in profiles:
425-
raise ValueError(f'Unknown profile "{profile_name}".')
436+
raise ValueError(f'Profile "{profile_name}" is not defined.')
426437

427438
profile = profiles[profile_name]
428439

packages/runner/robotcode/runner/cli/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from robot.run import USAGE, RobotFramework
99
from robot.version import get_full_version
1010

11-
from robotcode.plugin import CommonConfig, pass_common_config
11+
from robotcode.plugin import ClickCommonConfig, pass_common_config
1212
from robotcode.robot.config.loader import find_project_root, get_config_files_from_folder, load_config_from_path
1313
from robotcode.robot.config.model import BaseProfile
1414

@@ -59,7 +59,6 @@ def main(self, arguments: Any, **options: Any) -> Any:
5959
context_settings={
6060
"allow_extra_args": True,
6161
"ignore_unknown_options": True,
62-
"help_option_names": ["-h", "--help"],
6362
},
6463
add_help_option=True,
6564
short_help='Runs "robot" with the selected configuration, profiles, options and arguments.',
@@ -74,7 +73,7 @@ def main(self, arguments: Any, **options: Any) -> Any:
7473
@click.pass_context
7574
@pass_common_config
7675
def run(
77-
common_config: CommonConfig,
76+
common_config: ClickCommonConfig,
7877
ctx: click.Context,
7978
robot_options_and_args: Tuple[str, ...],
8079
) -> Union[str, int, None]:

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ yaml = ["PyYAML>=5.4", "types-PyYAML>=5.4"]
7474
lint = ["robotframework-robocop>=2.0.0"]
7575
tidy = ["robotframework-tidy>=2.0.0"]
7676
rest = ["docutils"]
77+
colored = ["rich"]
7778
all = [
7879
"runner",
7980
"debugger",
@@ -82,6 +83,8 @@ all = [
8283
"yaml",
8384
"lint",
8485
"tidy",
86+
"colored",
87+
"rest",
8588
]
8689

8790

robotcode/cli/__init__.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33

44
import click
55

6-
from robotcode.plugin import CommonConfig, pass_common_config
6+
from robotcode.plugin import ClickCommonConfig, ColoredOutput, pass_common_config
77
from robotcode.plugin.manager import PluginManager
88

99
from .__version__ import __version__
10-
from .commands import config
10+
from .commands import config, profiles
1111

1212

1313
@click.group(
14-
context_settings={"help_option_names": ["-h", "--help"], "auto_envvar_prefix": "ROBOTCODE"},
14+
context_settings={"auto_envvar_prefix": "ROBOTCODE"},
1515
invoke_without_command=False,
1616
)
1717
@click.version_option(version=__version__, prog_name="robotcode")
@@ -36,16 +36,24 @@
3636
""",
3737
)
3838
@click.option("-d", "--dry", is_flag=True, show_envvar=True, help="Dry run, do not execute any commands.")
39+
@click.option(
40+
"--color / --no-color",
41+
"color",
42+
default=None,
43+
help="Whether or not to display colored output (default is auto-detection).",
44+
show_envvar=True,
45+
)
3946
@click.option("-v", "--verbose", is_flag=True, help="Enables verbose mode.")
4047
@click.pass_context
4148
@pass_common_config
4249
def robotcode(
43-
common_config: CommonConfig,
50+
common_config: ClickCommonConfig,
4451
ctx: click.Context,
4552
config_file: Optional[Path],
4653
profiles: Optional[List[str]],
47-
dry: bool = False,
48-
verbose: bool = False,
54+
dry: bool,
55+
verbose: bool,
56+
color: Optional[bool],
4957
) -> None:
5058
"""\b
5159
_____ _ _ _____ _
@@ -60,9 +68,16 @@ def robotcode(
6068
common_config.profiles = profiles
6169
common_config.dry = dry
6270
common_config.verbose = verbose
71+
if color is None:
72+
common_config.colored_output = ColoredOutput.AUTO
73+
elif color:
74+
common_config.colored_output = ColoredOutput.YES
75+
else:
76+
common_config.colored_output = ColoredOutput.NO
6377

6478

6579
robotcode.add_command(config)
80+
robotcode.add_command(profiles)
6681

6782
for p in PluginManager().cli_commands:
6883
for c in p:

robotcode/cli/commands/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
from .config import config
2+
from .profiles import profiles
23

3-
__all__ = ["config"]
4+
__all__ = ["config", "profiles"]

robotcode/cli/commands/_common.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
from pathlib import Path
2+
from typing import Any, Dict, List, Sequence, Tuple
3+
4+
import click
5+
6+
from robotcode.core.dataclasses import as_json
7+
from robotcode.plugin import ClickCommonConfig, ColoredOutput
8+
from robotcode.robot.config.loader import (
9+
ConfigType,
10+
find_project_root,
11+
get_config_files_from_folder,
12+
)
13+
14+
15+
def print_dict(config: Dict[str, Any], format: str, color: ColoredOutput) -> None:
16+
text = None
17+
if format == "toml":
18+
try:
19+
import tomli_w
20+
21+
text = tomli_w.dumps(config)
22+
except ImportError:
23+
click.secho("tomli-w is required to output toml.", fg="red", err=True)
24+
25+
format = "json"
26+
27+
if text is None:
28+
text = as_json(config, indent=True)
29+
30+
if not text:
31+
return
32+
33+
if color in [ColoredOutput.AUTO, ColoredOutput.YES]:
34+
try:
35+
from rich.console import Console
36+
from rich.syntax import Syntax
37+
38+
Console().print(Syntax(text, format, background_color="default"))
39+
40+
return
41+
except ImportError as e:
42+
if color == "yes":
43+
raise click.ClickException('Package "rich" is required to use colored output.') from e
44+
45+
click.echo(text)
46+
47+
return
48+
49+
50+
def get_config_files(common_config: ClickCommonConfig, paths: List[Path]) -> Sequence[Tuple[Path, ConfigType]]:
51+
if common_config.config_file is not None:
52+
if common_config.verbose:
53+
click.secho(f"Using config file: {common_config.config_file}", fg="bright_black")
54+
55+
return [(common_config.config_file, ConfigType.CUSTOM_TOML)]
56+
57+
root_folder, discovered_by = find_project_root(*(paths or []))
58+
59+
if root_folder is None:
60+
raise click.ClickException("Cannot detect root folder for project. 😥")
61+
62+
if common_config.verbose:
63+
click.secho(f"Found project root at:\n {root_folder} ({discovered_by})", fg="bright_black")
64+
65+
result = get_config_files_from_folder(root_folder)
66+
67+
if result:
68+
if common_config.verbose:
69+
click.secho(
70+
"Found configuration files:\n " + "\n ".join(str(f[0]) for f in result),
71+
fg="bright_black",
72+
)
73+
74+
return result

0 commit comments

Comments
 (0)