fix: black

This commit is contained in:
egarette@silique.fr 2026-06-21 16:54:18 +02:00
parent 97bc49c785
commit 90ae5951f8
7 changed files with 211 additions and 136 deletions

View file

@ -1,7 +1,7 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2025-2026
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
@ -15,6 +15,7 @@ details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from .display import RougailOutputDisplay
from .__version__ import __version__

View file

@ -41,9 +41,9 @@ def get_outputs() -> None:
level = obj_class.level
if level in outputs:
raise ImportError(
_('duplicated level in rougail-output-display for output "{0}": {1} and {2}').format(
level, obj_class.name, outputs[level].name
)
_(
'duplicated level in rougail-output-display for output "{0}": {1} and {2}'
).format(level, obj_class.name, outputs[level].name)
)
if obj_class.name in names:
raise ImportError(

View file

@ -20,7 +20,12 @@ from typing import Optional, Any
from ruamel.yaml import YAML
from io import BytesIO
from tiramisu.error import PropertiesOptionError, LeadershipError, ConfigError, AttributeOptionError
from tiramisu.error import (
PropertiesOptionError,
LeadershipError,
ConfigError,
AttributeOptionError,
)
from tiramisu import owners, groups
from .config import OutPuts
@ -43,6 +48,7 @@ class RougailOutputDisplay:
) -> None:
if rougailconfig is None:
from rougail import RougailConfig
rougailconfig = RougailConfig
self.rougailconfig = rougailconfig
self.config = config
@ -61,7 +67,7 @@ class RougailOutputDisplay:
if user_data_warnings is None:
user_data_warnings = []
self.user_data_warnings = user_data_warnings
# self.out = []
# self.out = []
self.nodes = None
self.yaml = YAML()
self.yaml.indent(mapping=2, sequence=4, offset=2)
@ -75,27 +81,36 @@ class RougailOutputDisplay:
errors_warnings_dict = {}
if not errors and self.nodes is None:
show_secrets = self.rougailconfig["display.show_secrets"]
self.nodes = Node(self.yaml, show_secrets, self.config, self.root_config, self.config_owner_is_path, errors)
self.nodes = Node(
self.yaml,
show_secrets,
self.config,
self.root_config,
self.config_owner_is_path,
errors,
)
if warnings:
level = "warnings"
#output.display_warnings(errors_warnings_dict, warnings)
# output.display_warnings(errors_warnings_dict, warnings)
for warning in warnings:
output.error_warn_to_dict(warning, errors_warnings_dict, 'warning')
output.error_warn_to_dict(warning, errors_warnings_dict, "warning")
if errors:
level = "errors"
for error in errors:
output.error_warn_to_dict(error, errors_warnings_dict, 'error')
output.error_warn_to_dict(error, errors_warnings_dict, "error")
if level:
if level == "errors":
tree = output.error_header()
else:
tree = output.warning_header()
ret = output.parse_error_warning(tree, errors_warnings_dict, output.display_error, level)
ret = output.parse_error_warning(
tree, errors_warnings_dict, output.display_error, level
)
if errors:
return False, ret
ret += "\n"
else:
ret = ''
ret = ""
code, run = output.run(self.nodes, self.layer_datas)
return code, ret + run
@ -116,10 +131,10 @@ class Node:
errors,
*,
node=None,
values: Optional[dict]=None,
level: int=0,
leader_index: Optional[int]=None,
) -> None:
values: Optional[dict] = None,
level: int = 0,
leader_index: Optional[int] = None,
) -> None:
self.yaml = yaml
self.show_secrets = show_secrets
self.config = config
@ -141,7 +156,9 @@ class Node:
if node and node.isoptiondescription() and node.isleadership():
values_iter = iter(values.items())
leader, leader_values = next(values_iter)
followers_values = {idx: {leader: value} for idx, value in enumerate(leader_values)}
followers_values = {
idx: {leader: value} for idx, value in enumerate(leader_values)
}
for follower, follower_value in values_iter:
followers_values[follower.index()][follower] = follower_value
for idx, fvalues in enumerate(followers_values.values()):
@ -174,25 +191,33 @@ class Node:
option,
values,
*,
leader_index: Optional[int]=None,
) -> 'Node':
self.children.append({"type": "node",
"node": Node(
self.yaml,
self.show_secrets,
self.config,
self.root_config,
self.config_owner_is_path,
self.errors,
node=option,
values=values,
level=self.level + 1,
leader_index=leader_index,
),
})
leader_index: Optional[int] = None,
) -> "Node":
self.children.append(
{
"type": "node",
"node": Node(
self.yaml,
self.show_secrets,
self.config,
self.root_config,
self.config_owner_is_path,
self.errors,
node=option,
values=values,
level=self.level + 1,
leader_index=leader_index,
),
}
)
def add_leaf(
self, option, value: Any, *, leader_index: Optional[int] = None, description: Optional[str] = None
self,
option,
value: Any,
*,
leader_index: Optional[int] = None,
description: Optional[str] = None,
):
properties = option.property.get()
if description is None:
@ -200,15 +225,23 @@ class Node:
icon = "leaf"
else:
icon = "node"
self.children.append({"type": "leaf",
"description": description,
"values": self.get_values(option, value, leader_index, properties),
"icon": icon,
"hidden": "hidden" in properties,
},
)
self.children.append(
{
"type": "leaf",
"description": description,
"values": self.get_values(option, value, leader_index, properties),
"icon": icon,
"hidden": "hidden" in properties,
},
)
def get_values(self, option: "Option", value: Any, leader_index: Optional[int], properties: list[str]) -> None:
def get_values(
self,
option: "Option",
value: Any,
leader_index: Optional[int],
properties: list[str],
) -> None:
if option.isoptiondescription():
return [{"is_default": True, "value": value, "loaded_from": None}]
values = []
@ -219,7 +252,7 @@ class Node:
loaded_from_key = f"loaded_from_{index}"
else:
loaded_from_key = "loaded_from"
#default = option.owner.isdefault() or not option.information.get("default_value_makes_sense", True)
# default = option.owner.isdefault() or not option.information.get("default_value_makes_sense", True)
force_store_value = "force_store_value" in properties
is_default = option.owner.isdefault()
option_path = option.path()
@ -230,7 +263,7 @@ class Node:
else:
true_default = is_default and meta_option.owner.get() == default_owner
added = not is_default or true_default
secret_manager = option.information.get('secret_manager', False)
secret_manager = option.information.get("secret_manager", False)
while True:
if values and true_default and (value in [None, []] or secret_manager):
break
@ -256,7 +289,9 @@ class Node:
if is_default and (not meta_config_path or "." not in meta_config_path):
# we are in root metaconfig and we have default value
break
new_meta_config = self.get_metaconfig_with_default_value(meta_config, meta_option)
new_meta_config = self.get_metaconfig_with_default_value(
meta_config, meta_option
)
if not new_meta_config:
break
meta_option = new_meta_config.option(option_path, index)
@ -297,11 +332,7 @@ class Node:
value: Any,
) -> str:
"""Dump variable, means transform bool, ... to yaml string"""
if (
value is not None
and not self.show_secrets
and option.type() == "password"
):
if value is not None and not self.show_secrets and option.type() == "password":
return "*" * 10
if isinstance(value, str):
return value
@ -322,7 +353,7 @@ class Node:
return self.config
if not self.config_owner_is_path:
while True:
if meta_config.type() != 'metaconfig':
if meta_config.type() != "metaconfig":
return None
meta_config = meta_config.parent()
if not meta_config.owner.isdefault():

View file

@ -1,7 +1,7 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2022-2026
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
@ -33,7 +33,7 @@ class OutputFamily(CommonOutput):
value_unmodified_color = "gold1"
value_modified_color = "green"
value_default_color = None
error_color = 'bright_red'
error_color = "bright_red"
error_icon = "stop_sign"
warning_color = "bright_yellow"
warning_icon = "bell"
@ -56,14 +56,23 @@ class OutputFamily(CommonOutput):
if self.variable_default_enable:
caption_line += _("Variable") + "\n"
if self.variable_hidden_enable:
caption_line += self.set_color(self.variable_hidden_color, _("Unmodifiable variable")) + "\n"
caption_line += (
self.set_color(self.variable_hidden_color, _("Unmodifiable variable"))
+ "\n"
)
header_value = ""
if self.value_unmodified_enable:
header_value += self.set_color(self.value_unmodified_color, _("Default value")) + "\n"
header_value += (
self.set_color(self.value_unmodified_color, _("Default value")) + "\n"
)
if self.value_modified_enable:
header_value += self.set_color(self.value_modified_color, _("Modified value")) + "\n"
header_value += (
self.set_color(self.value_modified_color, _("Modified value")) + "\n"
)
if self.value_default_enable:
header_value += f'(:hourglass_flowing_sand: {_("Original default value")})\n'
header_value += (
f'(:hourglass_flowing_sand: {_("Original default value")})\n'
)
caption = Table.grid(padding=1, collapse_padding=True)
caption.pad_edge = False
caption.add_row(caption_line[:-1], header_value[:-1])
@ -82,7 +91,7 @@ class OutputFamily(CommonOutput):
f"[bold][{self.error_color}]:{self.error_icon}: {_('Caution')}[/{self.error_color}][/bold]",
guide_style=f"bold {self.error_color}",
)
# self.out.append(tree)
# self.out.append(tree)
return tree
def display_error(self, level, tree, msg, default_color):
@ -92,7 +101,7 @@ class OutputFamily(CommonOutput):
color = self.warning_color
if isinstance(msg, tuple):
if len(msg) == 3:
if msg[2] == 'error':
if msg[2] == "error":
color = self.error_color
icon = self.error_icon
else:
@ -100,19 +109,19 @@ class OutputFamily(CommonOutput):
icon = self.warning_icon
msg = f"{msg[0]}: [{color}]:{icon}: {msg[1]}[/{color}]"
else:
if msg[1] == 'error':
if msg[1] == "error":
icon = self.error_icon
else:
color = self.warning_color
icon = self.warning_icon
msg = f"[{color}]:{icon}: {msg[0]}[/{color}]"
tree.guide_style = f'bold {color}'
tree.guide_style = f"bold {color}"
return tree.add(msg, guide_style=f"bold {color}")
def display(self, tree):
console = Console(force_terminal=True, width=self.max_width)
with console.capture() as capture:
console.print(tree)
console.print(tree)
return capture.get()
def warning_header(self):
@ -120,21 +129,27 @@ class OutputFamily(CommonOutput):
f"[bold][{self.warning_color}]:{self.warning_icon}: {_('Warning')}[/{self.warning_color}][/bold]",
guide_style=f"bold {self.warning_color}",
)
# self.out.append(tree)
# self.out.append(tree)
return tree
#
# def display_warning(self, level, tree, msg):
# if isinstance(msg, tuple):
# msg = f"{msg[0]}: [{self.warning_color}]:{self.warning_icon}: {msg[1]}[/{self.warning_color}]"
# return tree.add(msg, guide_style=f"bold {self.warning_color}")
#
# def display_warning(self, level, tree, msg):
# if isinstance(msg, tuple):
# msg = f"{msg[0]}: [{self.warning_color}]:{self.warning_icon}: {msg[1]}[/{self.warning_color}]"
# return tree.add(msg, guide_style=f"bold {self.warning_color}")
def add_variable(
self, parent, description, value, icon, level,
self,
parent,
description,
value,
icon,
level,
):
if icon == 'leaf':
icon = 'notebook'
if icon == "leaf":
icon = "notebook"
else:
icon = 'open_file_folder'
icon = "open_file_folder"
if isinstance(value, list):
subtree = parent.add(
f":{icon}: " + _("{0}:").format(description),
@ -150,13 +165,13 @@ class OutputFamily(CommonOutput):
return msg
return f"[{color}]{msg}[/{color}]"
def get_parent(self, parent, description, level):
if parent is None:
return Tree(description,
guide_style=self.guide_style,
)
return Tree(
description,
guide_style=self.guide_style,
)
return parent.add(
f":open_file_folder: {description}",
guide_style=self.guide_style,
)
f":open_file_folder: {description}",
guide_style=self.guide_style,
)

View file

@ -1,7 +1,7 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2025-2026
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
@ -42,12 +42,18 @@ class OutputFamily(CommonOutput):
if self.variable_default_enable:
variables.append(_("Variable"))
if self.variable_hidden_enable:
variables.append(self.set_color(self.variable_hidden_color, _("Unmodifiable variable")))
variables.append(
self.set_color(self.variable_hidden_color, _("Unmodifiable variable"))
)
values = []
if self.value_unmodified_enable:
values.append(self.set_color(self.value_unmodified_color, _("Default value")))
values.append(
self.set_color(self.value_unmodified_color, _("Default value"))
)
if self.value_modified_enable:
values.append(self.set_color(self.value_modified_color, _("Modified value")))
values.append(
self.set_color(self.value_modified_color, _("Modified value"))
)
if self.value_default_enable:
values.append(f'(:hourglass_flowing_sand: {_("Original default value")})')
if not variables and not values:
@ -68,14 +74,14 @@ class OutputFamily(CommonOutput):
def title(self, msg):
caption = "> [!NOTE]" + "\n>\n"
caption += f'> **{msg}**\n'
caption += f"> **{msg}**\n"
return caption
def error_header(self):
return ['> [!CAUTION]\n> ']
return ["> [!CAUTION]\n> "]
def warning_header(self):
return ['> [!WARNING]\n> ']
return ["> [!WARNING]\n> "]
def error_end(self):
self.out[-1] += "\n"
@ -93,7 +99,7 @@ class OutputFamily(CommonOutput):
color = self.warning_color
if isinstance(msg, tuple):
if len(msg) == 3:
if msg[2] == 'error':
if msg[2] == "error":
color = self.error_color
icon = self.error_icon
else:
@ -101,7 +107,7 @@ class OutputFamily(CommonOutput):
icon = self.warning_icon
msg = f"{msg[0]}: :{icon}: {self.set_color(color, msg[1])}"
else:
if msg[1] == 'error':
if msg[1] == "error":
icon = self.error_icon
else:
color = self.warning_color
@ -111,17 +117,22 @@ class OutputFamily(CommonOutput):
return tree
def add_variable(
self, parent, description, value, icon, level,
self,
parent,
description,
value,
icon,
level,
):
if parent is None:
parent = []
if icon == 'leaf':
icon = 'notebook'
if icon == "leaf":
icon = "notebook"
else:
icon = 'open_file_folder'
icon = "open_file_folder"
before = " " * (level - 1) * 2 + "- "
if isinstance(value, list):
description = description.replace('', '')
description = description.replace("", "")
subtree = parent.append(
f"{before}:{icon}: " + _("{0}:").format(description),
)
@ -129,7 +140,9 @@ class OutputFamily(CommonOutput):
for val in value:
parent.append(before + str(val))
else:
parent.append(before + f":{icon}: " + _("{0}: {1}").format(description, value))
parent.append(
before + f":{icon}: " + _("{0}: {1}").format(description, value)
)
def set_color(self, color, msg):
if not color:
@ -150,5 +163,7 @@ class OutputFamily(CommonOutput):
parent = []
parent.append(description)
else:
parent.append(" " * (level - 1) * 2 + "- " + ":open_file_folder: " + description)
parent.append(
" " * (level - 1) * 2 + "- " + ":open_file_folder: " + description
)
return parent

View file

@ -1,7 +1,7 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2025-2026
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
@ -32,7 +32,7 @@ class OutputFamily(GHOutputFamily):
def set_color(self, color, msg):
if not color:
return msg
return f'[{color} {msg} {color}]'
return f"[{color} {msg} {color}]"
def title(self, msg):
return f"> [!note] {msg}" + "\n>\n"

View file

@ -1,7 +1,7 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2022-2026
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
@ -15,6 +15,7 @@ details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from typing import Any, Optional
# from tiramisu import owners
@ -28,7 +29,7 @@ class CommonOutput:
def __init__(
self,
rougailconfig,
) -> None:
) -> None:
self.set_config(rougailconfig)
self.variable_default_enable = False
self.variable_hidden_enable = False
@ -44,7 +45,7 @@ class CommonOutput:
if nodes.children:
root = self.parse(nodes)
return self._run(root)
return 0, ''
return 0, ""
def parse(self, node, parent=None, level=0):
if node.hidden:
@ -55,18 +56,18 @@ class CommonOutput:
self.variable_default_enable = True
color = self.variable_normal_color
family_output = self.colorize(
[
{
"value": node.description,
"color": color,
"loaded_from": None,
}
]
)
[
{
"value": node.description,
"color": color,
"loaded_from": None,
}
]
)
subparent = self.get_parent(parent, family_output, level)
for child in node.children:
if child["type"] == "node":
self.parse(child["node"], subparent, level+1)
self.parse(child["node"], subparent, level + 1)
else:
if child["hidden"]:
self.variable_hidden_enable = True
@ -87,15 +88,17 @@ class CommonOutput:
child["values"],
)
description = self.colorize(
[
{
"value": child["description"],
"color": variable_color,
"loaded_from": None,
}
]
)
self.add_variable(subparent, description, value, child["icon"], level+1)
[
{
"value": child["description"],
"color": variable_color,
"loaded_from": None,
}
]
)
self.add_variable(
subparent, description, value, child["icon"], level + 1
)
return subparent
def header(self):
@ -105,12 +108,14 @@ class CommonOutput:
if isinstance(error, dict):
for msg, subconfig in error.items():
description = subconfig.option.impl_get_display_name(subconfig)
self.subconfig_to_dict(subconfig, errors_dict).setdefault(None, {}).setdefault(description, []).append((msg, level))
self.subconfig_to_dict(subconfig, errors_dict).setdefault(
None, {}
).setdefault(description, []).append((msg, level))
else:
errors_dict.setdefault(None, []).append(error)
def subconfig_to_dict(self, subconfig: "Subconfig", errors_dict: dict) -> dict:
#FIXME a tester : mandatories dans une arborescence (voir si ca n'ecrase pas)
# FIXME a tester : mandatories dans une arborescence (voir si ca n'ecrase pas)
parents = []
parent = subconfig
while True:
@ -131,18 +136,26 @@ class CommonOutput:
def _parse_error_warning(self, tree, error, display, level, default_color):
if isinstance(error, list):
for err in error:
self._parse_error_warning(tree, err, display, level+1, default_color)
self._parse_error_warning(tree, err, display, level + 1, default_color)
elif isinstance(error, dict):
for key, value in error.items():
if key is None:
# it's variables, no more families
self._parse_error_warning(tree, value, display, level, default_color)
self._parse_error_warning(
tree, value, display, level, default_color
)
else:
if isinstance(value, list) and len(value) == 1:
self._parse_error_warning(tree, (key, *value[0]), display, level+1, default_color)
self._parse_error_warning(
tree, (key, *value[0]), display, level + 1, default_color
)
else:
sub_tree = self._parse_error_warning(tree, key, display, level+1, default_color)
self._parse_error_warning(sub_tree, value, display, level+1, default_color)
sub_tree = self._parse_error_warning(
tree, key, display, level + 1, default_color
)
self._parse_error_warning(
sub_tree, value, display, level + 1, default_color
)
else:
return display(level, tree, error, default_color)
@ -153,7 +166,7 @@ class CommonOutput:
self,
family,
level,
) -> 'OutputFamily':
) -> "OutputFamily":
properties = family.property.get()
if "hidden" in properties:
self.root_family.variable_hidden_enable = True
@ -162,20 +175,20 @@ class CommonOutput:
self.root_family.variable_default_enable = True
color = None
family_output = self.colorize(
[
{
"value": family.description(),
"color": color,
"loaded_from": None,
}
]
)
[
{
"value": family.description(),
"color": color,
"loaded_from": None,
}
]
)
return self.__class__(
family_output,
self.get_tree(),
self.root,
level + 1,
root_family = self.root_family,
root_family=self.root_family,
)
def colorize(