Compare commits
No commits in common. "06df0923898a02f32ccbf8e30bc7b1e3f4d0cee0" and "97bc49c78549810401fad8409ccfe43945d7a27c" have entirely different histories.
06df092389
...
97bc49c785
11 changed files with 327 additions and 233 deletions
209
CHANGELOG.md
209
CHANGELOG.md
|
|
@ -1,59 +1,228 @@
|
|||
## 1.0.0 (2026-06-21)
|
||||
## 0.2.0a33 (2026-06-15)
|
||||
|
||||
### Fix
|
||||
|
||||
- update tests
|
||||
|
||||
## 0.2.0a32 (2026-06-11)
|
||||
|
||||
### Fix
|
||||
|
||||
- attributeerror
|
||||
|
||||
## 0.2.0a31 (2026-05-04)
|
||||
|
||||
### Feat
|
||||
|
||||
- multi layers
|
||||
- add layers + gitlab
|
||||
- github output
|
||||
- document output
|
||||
- undocumented_modes is now a variable
|
||||
- display layers if actived
|
||||
- support values of differents layers
|
||||
- support user data layers
|
||||
- display error with tree
|
||||
- remove console.read_write option
|
||||
- default value for a calculated variable with an unknown optional variable
|
||||
- update tests for integer type
|
||||
- display loaded_from informations
|
||||
- output return status too
|
||||
- add tests
|
||||
- exporter to console
|
||||
|
||||
## 0.2.0a30 (2026-01-21)
|
||||
|
||||
### Fix
|
||||
|
||||
- rougail dependencies
|
||||
- black
|
||||
- update tests
|
||||
- attributeerror
|
||||
- leadership with smaller default value
|
||||
|
||||
## 0.2.0a29 (2026-01-21)
|
||||
|
||||
### Fix
|
||||
|
||||
- update tests
|
||||
- secret_manager has no real default value
|
||||
|
||||
## 0.2.0a28 (2026-01-16)
|
||||
|
||||
### Fix
|
||||
|
||||
- display with subconfig
|
||||
|
||||
## 0.2.0a27 (2026-01-14)
|
||||
|
||||
### Fix
|
||||
|
||||
- modified value without layer
|
||||
|
||||
## 0.2.0a26 (2026-01-05)
|
||||
|
||||
### Fix
|
||||
|
||||
- enter in layers list
|
||||
|
||||
## 0.2.0a25 (2026-01-01)
|
||||
|
||||
### Fix
|
||||
|
||||
- better layers support
|
||||
|
||||
## 0.2.0a24 (2026-01-01)
|
||||
|
||||
### Fix
|
||||
|
||||
- error only if default
|
||||
|
||||
## 0.2.0a23 (2026-01-01)
|
||||
|
||||
### Feat
|
||||
|
||||
- add layers + gitlab
|
||||
|
||||
## 0.2.0a22 (2025-12-30)
|
||||
|
||||
### Fix
|
||||
|
||||
- update tests
|
||||
|
||||
## 0.2.0a21 (2025-12-22)
|
||||
|
||||
### Fix
|
||||
|
||||
- console => display
|
||||
|
||||
## 0.2.0a20 (2025-12-22)
|
||||
|
||||
### Feat
|
||||
|
||||
- github output
|
||||
- document output
|
||||
|
||||
## 0.2.0a19 (2025-11-21)
|
||||
|
||||
### Feat
|
||||
|
||||
- undocumented_modes is now a variable
|
||||
|
||||
### Fix
|
||||
|
||||
- black
|
||||
- do not display empty console
|
||||
|
||||
## 0.2.0a18 (2025-11-07)
|
||||
|
||||
### Feat
|
||||
|
||||
- display layers if actived
|
||||
|
||||
## 0.2.0a17 (2025-11-06)
|
||||
|
||||
### Feat
|
||||
|
||||
- support values of differents layers
|
||||
|
||||
## 0.2.0a16 (2025-11-03)
|
||||
|
||||
### Feat
|
||||
|
||||
- support user data layers
|
||||
|
||||
## 0.2.0a15 (2025-10-16)
|
||||
|
||||
### Fix
|
||||
|
||||
- error format
|
||||
|
||||
## 0.2.0a14 (2025-10-10)
|
||||
|
||||
### Feat
|
||||
|
||||
- display error with tree
|
||||
|
||||
### Fix
|
||||
|
||||
- update tests
|
||||
- tests for formatter
|
||||
|
||||
## 0.2.0a13 (2025-09-29)
|
||||
|
||||
### Feat
|
||||
|
||||
- remove console.read_write option
|
||||
- default value for a calculated variable with an unknown optional variable
|
||||
- update tests for integer type
|
||||
|
||||
## 0.2.0a12 (2025-09-22)
|
||||
|
||||
### Fix
|
||||
|
||||
- dictionary => structure
|
||||
|
||||
## 0.2.0a11 (2025-05-12)
|
||||
|
||||
### Feat
|
||||
|
||||
- display loaded_from informations
|
||||
|
||||
### Fix
|
||||
|
||||
- black
|
||||
|
||||
## 0.2.0a10 (2025-05-09)
|
||||
|
||||
### Fix
|
||||
|
||||
- the key is the description by default instead of name
|
||||
|
||||
## 0.2.0a9 (2025-04-30)
|
||||
|
||||
### Fix
|
||||
|
||||
- remove negative_description support
|
||||
- add space before ":" in french
|
||||
|
||||
## 0.2.0a8 (2025-04-10)
|
||||
|
||||
### Fix
|
||||
|
||||
- version
|
||||
|
||||
## 0.2.0a7 (2025-04-09)
|
||||
|
||||
### Fix
|
||||
|
||||
- version
|
||||
|
||||
## 0.2.0a6 (2025-04-09)
|
||||
|
||||
### Fix
|
||||
|
||||
- better output for mandatories variables
|
||||
|
||||
## 0.2.0a5 (2025-04-09)
|
||||
|
||||
### Fix
|
||||
|
||||
- better caption + do not display None value
|
||||
|
||||
## 0.2.0a4 (2025-04-01)
|
||||
|
||||
### Fix
|
||||
|
||||
- update translation
|
||||
|
||||
## 0.2.0a3 (2025-02-17)
|
||||
|
||||
### Fix
|
||||
|
||||
- do not display default value with default_value_makes_sense set to False
|
||||
- translate ERRORS
|
||||
|
||||
## 0.2.0a2 (2025-02-10)
|
||||
|
||||
### Feat
|
||||
|
||||
- output return status too
|
||||
- add tests
|
||||
|
||||
## 0.2.0a1 (2024-11-28)
|
||||
|
||||
### Fix
|
||||
|
||||
- separation between run and print function
|
||||
|
||||
## 0.2.0a0 (2024-11-27)
|
||||
|
||||
### Feat
|
||||
|
||||
- exporter to console
|
||||
|
||||
## 0.1.0 (2024-11-06)
|
||||
|
||||
## 0.1.0rc1 (2024-11-06)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
|
|||
|
||||
[project]
|
||||
name = "rougail.output_display"
|
||||
version = "1.0.0"
|
||||
version = "1.0.0rc0"
|
||||
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
||||
readme = "README.md"
|
||||
description = "Rougail output display"
|
||||
|
|
@ -24,7 +24,7 @@ classifiers = [
|
|||
|
||||
]
|
||||
dependencies = [
|
||||
"rougail >= 1.2.0,<2",
|
||||
"rougail >= 1.1,<2",
|
||||
"rich ~= 13.9.3",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -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,7 +15,6 @@ 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__
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -20,12 +20,7 @@ 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
|
||||
|
|
@ -48,7 +43,6 @@ class RougailOutputDisplay:
|
|||
) -> None:
|
||||
if rougailconfig is None:
|
||||
from rougail import RougailConfig
|
||||
|
||||
rougailconfig = RougailConfig
|
||||
self.rougailconfig = rougailconfig
|
||||
self.config = config
|
||||
|
|
@ -67,7 +61,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)
|
||||
|
|
@ -81,36 +75,27 @@ 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
|
||||
|
||||
|
|
@ -131,10 +116,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
|
||||
|
|
@ -156,9 +141,7 @@ 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()):
|
||||
|
|
@ -191,33 +174,25 @@ 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:
|
||||
|
|
@ -225,23 +200,15 @@ 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 = []
|
||||
|
|
@ -252,7 +219,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()
|
||||
|
|
@ -263,7 +230,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
|
||||
|
|
@ -289,9 +256,7 @@ 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)
|
||||
|
|
@ -332,7 +297,11 @@ 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
|
||||
|
|
@ -353,7 +322,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():
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -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,23 +56,14 @@ 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])
|
||||
|
|
@ -91,7 +82,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):
|
||||
|
|
@ -101,7 +92,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:
|
||||
|
|
@ -109,19 +100,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):
|
||||
|
|
@ -129,27 +120,21 @@ 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),
|
||||
|
|
@ -165,13 +150,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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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,18 +42,12 @@ 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:
|
||||
|
|
@ -74,14 +68,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"
|
||||
|
|
@ -99,7 +93,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:
|
||||
|
|
@ -107,7 +101,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
|
||||
|
|
@ -117,22 +111,17 @@ 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),
|
||||
)
|
||||
|
|
@ -140,9 +129,7 @@ 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:
|
||||
|
|
@ -163,7 +150,5 @@ 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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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,7 +15,6 @@ 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
|
||||
|
|
@ -29,7 +28,7 @@ class CommonOutput:
|
|||
def __init__(
|
||||
self,
|
||||
rougailconfig,
|
||||
) -> None:
|
||||
) -> None:
|
||||
self.set_config(rougailconfig)
|
||||
self.variable_default_enable = False
|
||||
self.variable_hidden_enable = False
|
||||
|
|
@ -45,7 +44,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:
|
||||
|
|
@ -56,18 +55,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
|
||||
|
|
@ -88,17 +87,15 @@ 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):
|
||||
|
|
@ -108,14 +105,12 @@ 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:
|
||||
|
|
@ -136,26 +131,18 @@ 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)
|
||||
|
||||
|
|
@ -166,7 +153,7 @@ class CommonOutput:
|
|||
self,
|
||||
family,
|
||||
level,
|
||||
) -> "OutputFamily":
|
||||
) -> 'OutputFamily':
|
||||
properties = family.property.get()
|
||||
if "hidden" in properties:
|
||||
self.root_family.variable_hidden_enable = True
|
||||
|
|
@ -175,20 +162,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(
|
||||
|
|
|
|||
Loading…
Reference in a new issue