feat: github output

This commit is contained in:
egarette@silique.fr 2025-12-03 21:49:02 +01:00
parent 62fb0eab60
commit a23857e700
5561 changed files with 72257 additions and 1247 deletions

View file

@ -13,10 +13,22 @@ include_toc: true
> *`désactivé`*\
> **Désactivé** : si display n'est pas défini dans "[Sélection pour sortie](#step.output)"
| Variable | Description | Valeur par défaut | Type | Validateur |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|--------------------------|
| **<a id="display.show_secrets" name="display.show_secrets">display.show_secrets</a>**<br/>**Ligne de commande** : <br/>&nbsp;--display.show_secrets<br/>&nbsp;--display.no-show_secrets<br/>**Variable d'environnement** : ROUGAILCLI_DISPLAY.SHOW_SECRETS | Voir les secrets plutôt que de les obscurcir. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | |
| **<a id="display.mandatory" name="display.mandatory">display.mandatory</a>**<br/>**Ligne de commande** : <br/>&nbsp;--display.mandatory<br/>&nbsp;--display.no-mandatory<br/>**Variable d'environnement** : ROUGAILCLI_DISPLAY.MANDATORY | Test les variables obligatoires avant de les afficher dans la display. | ne pas tester si "[Configuration in output step is in read_write mode](#cli.read_write)" est activé | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | |
| **<a id="display.max_width" name="display.max_width">display.max_width</a>**<br/>**Ligne de commande** : --display.max_width<br/>**Variable d'environnement** : ROUGAILCLI_DISPLAY.MAX_WIDTH | Nombre maximal de caractères par ligne.<br/>Null signifie illimité. | | [`integer`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) | The minimum value is 50. |
| Variable | Description | Valeur par défaut | Type | Validateur |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|---------------------------------------------------|
| **<a id="display.output_format" name="display.output_format">display.output_format</a>**<br/>**Ligne de commande** : --display.output_format<br/>**Variable d'environnement** : DISPLAY.OUTPUT_FORMAT | Le format de sortie pour afficher des variables. | console | [`choice`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | **Choix** : <br/>&nbsp;console<br/>&nbsp;github |
| **<a id="display.show_secrets" name="display.show_secrets">display.show_secrets</a>**<br/>**Ligne de commande** : <br/>&nbsp;--display.show_secrets<br/>&nbsp;--display.no-show_secrets<br/>**Variable d'environnement** : DISPLAY.SHOW_SECRETS | Voir les secrets plutôt que de les obscurcir. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | |
| **<a id="display.mandatory" name="display.mandatory">display.mandatory</a>**<br/>**Ligne de commande** : <br/>&nbsp;--display.mandatory<br/>&nbsp;--display.no-mandatory<br/>**Variable d'environnement** : DISPLAY.MANDATORY | Tester les variables obligatoires avant de les afficher. | ne pas tester si "[Configuration in output step is in read_write mode](#cli.read_write)" est activé | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `obligatoire` | |
### Configuration spécifique pour la sortie console
> [!NOTE]
>
> **Chemin** : display.console\
> *`désactivé`*\
> **Désactivé** : lorsque la variable "[Le format de sortie pour afficher des variables](#display.output_format)" n'a pas la valeur "console"
| Variable | Description | Type | Validateur |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------|-------------------------------------------------------------------------------------|--------------------------|
| **<a id="display.console.max_width" name="display.console.max_width">display.console.max_width</a>**<br/>**Ligne de commande** : --display.console.max_width<br/>**Variable d'environnement** : DISPLAY.CONSOLE.MAX_WIDTH | Nombre maximal de caractères par ligne.<br/>Null signifie illimité. | [`integer`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) | The minimum value is 50. |

View file

@ -8,15 +8,27 @@ include_toc: true
> [!NOTE]
>
> Find all the variables and their values in your configuration (structural and user datas). Additional informations are available, such as the default value, the location where the value is loaded, etc.\
> Find all the variables and their values in your configuration (structural and user data). Additional informations are available, such as the default value, the location where the value is loaded, etc.\
> **Path**: display\
> *`disabled`*\
> **Disabled**: if display is not set in "[Select for output](#step.output)"
| Variable | Description | Default value | Type | Validator |
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|--------------------------|
| **<a id="display.show_secrets" name="display.show_secrets">display.show_secrets</a>**<br/>**Command line**: <br/>&nbsp;--display.show_secrets<br/>&nbsp;--display.no-show_secrets<br/>**Environment variable**: ROUGAILCLI_DISPLAY.SHOW_SECRETS | Show secrets instead of obscuring them. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | |
| **<a id="display.mandatory" name="display.mandatory">display.mandatory</a>**<br/>**Command line**: <br/>&nbsp;--display.mandatory<br/>&nbsp;--display.no-mandatory<br/>**Environment variable**: ROUGAILCLI_DISPLAY.MANDATORY | Test mandatories variables before display in display. | do not test if "[Configuration in output step is in read_write mode](#cli.read_write)" is true | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | |
| **<a id="display.max_width" name="display.max_width">display.max_width</a>**<br/>**Command line**: --display.max_width<br/>**Environment variable**: ROUGAILCLI_DISPLAY.MAX_WIDTH | Maximum number of characters per line.<br/>Null means unlimited. | | [`integer`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) | The minimum value is 50. |
| Variable | Description | Default value | Type | Validator |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|----------------------------------------------------|
| **<a id="display.output_format" name="display.output_format">display.output_format</a>**<br/>**Command line**: --display.output_format<br/>**Environment variable**: DISPLAY.OUTPUT_FORMAT | The output format for displaying variables. | console | [`choice`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | **Choices**: <br/>&nbsp;console<br/>&nbsp;github |
| **<a id="display.show_secrets" name="display.show_secrets">display.show_secrets</a>**<br/>**Command line**: <br/>&nbsp;--display.show_secrets<br/>&nbsp;--display.no-show_secrets<br/>**Environment variable**: DISPLAY.SHOW_SECRETS | Show secrets instead of obscuring them. | false | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | |
| **<a id="display.mandatory" name="display.mandatory">display.mandatory</a>**<br/>**Command line**: <br/>&nbsp;--display.mandatory<br/>&nbsp;--display.no-mandatory<br/>**Environment variable**: DISPLAY.MANDATORY | Test mandatories variables before display in display. | do not test if "[Configuration in output step is in read_write mode](#cli.read_write)" is true | [`boolean`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) `mandatory` | |
### Specific configuration for console output
> [!NOTE]
>
> **Path**: display.console\
> *`disabled`*\
> **Disabled**: when the variable "[The output format for displaying variables](#display.output_format)" hasn't the value "console"
| Variable | Description | Type | Validator |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------|-------------------------------------------------------------------------------------|--------------------------|
| **<a id="display.console.max_width" name="display.console.max_width">display.console.max_width</a>**<br/>**Command line**: --display.console.max_width<br/>**Environment variable**: DISPLAY.CONSOLE.MAX_WIDTH | Maximum number of characters per line.<br/>Null means unlimited. | [`integer`](https://rougail.readthedocs.io/en/latest/variable.html#variables-types) | The minimum value is 50. |

View file

@ -5,8 +5,8 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2025-12-03 21:05+0100\n"
"PO-Revision-Date: 2025-12-03 21:06+0100\n"
"POT-Creation-Date: 2025-12-17 21:54+0100\n"
"PO-Revision-Date: 2025-12-17 21:55+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr\n"
@ -16,14 +16,25 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.8\n"
#: src/rougail/output_display/config.py:30
#: src/rougail/output_display/config.py:44
msgid ""
"duplicated level in rougail-output-display for output \"{0}\": {1} and {2}"
msgstr ""
"niveau dupliqué dans rougail-output-display pour la sortie \"{0}\" : {1} et "
"{2}"
#: src/rougail/output_display/config.py:50
msgid "duplicated name \"{0}\" in rougail-output-display"
msgstr "nom dupliqué \"{0}\" dans rougail-output-display"
#: src/rougail/output_display/config.py:82
msgid "Display variables and values"
msgstr "Afficher les variables et les valeurs"
#: src/rougail/output_display/config.py:31
#: src/rougail/output_display/config.py:84
msgid ""
"Find all the variables and their values in your configuration (structural "
"and user datas). Additional informations are available, such as the default "
"and user data). Additional informations are available, such as the default "
"value, the location where the value is loaded, etc."
msgstr ""
"Retrouver toutes les variables et leurs valeurs de votre configuration "
@ -31,91 +42,122 @@ msgstr ""
"disponibles, comme la valeur par défaut, le lieu de chargement de la "
"valeur, ..."
#: src/rougail/output_display/config.py:40
#: src/rougail/output_display/config.py:93
msgid "if display is not set in \"step.output\""
msgstr "si display n'est pas défini dans \"step.output\""
#: src/rougail/output_display/config.py:42
#: src/rougail/output_display/config.py:96
msgid "The output format for displaying variables"
msgstr "Le format de sortie pour afficher des variables"
#: src/rougail/output_display/config.py:103
msgid "Show secrets instead of obscuring them"
msgstr "Voir les secrets plutôt que de les obscurcir"
#: src/rougail/output_display/config.py:45
#: src/rougail/output_display/config.py:106
msgid "test mandatories variables before display in display"
msgstr "test les variables obligatoires avant de les afficher dans la display"
msgstr "tester les variables obligatoires avant de les afficher"
#: src/rougail/output_display/config.py:54
#: src/rougail/output_display/config.py:115
msgid "do not test if \"cli.read_write\" is true"
msgstr "ne pas tester si \"cli.read_write\" est activé"
#: src/rougail/output_display/config.py:57
#: src/rougail/output_display/config.py:118
msgid "Specific configuration for console output"
msgstr "Configuration spécifique pour la sortie console"
#: src/rougail/output_display/config.py:124
msgid "Maximum number of characters per line"
msgstr "Nombre maximal de caractères par ligne"
#: src/rougail/output_display/config.py:58
#: src/rougail/output_display/config.py:125
msgid "null means unlimited"
msgstr "null signifie illimité"
#: src/rougail/output_display/display.py:77
#: src/rougail/output_display/display.py:151
msgid "mandatory variable but is inaccessible and has no value"
msgstr "variable obligatoire mais est inaccessible et n'a pas de valeur"
#: src/rougail/output_display/display.py:157
msgid "mandatory variable but has no value"
msgstr "variable obligatoire mais n'a pas de valeur"
#: src/rougail/output_display/display.py:183
msgid "Variables:"
msgstr "Variables :"
#: src/rougail/output_display/display.py:114
msgid "Error in config: {0}"
msgstr "Erreur dans la config : {0}"
#: src/rougail/output_display/display.py:132
msgid "The following variables are mandatory but have no value:"
msgstr "Les variables suivantes sont obligatoire mais n'ont pas de valeur :"
#: src/rougail/output_display/display.py:137
msgid "The following variables are inaccessible but are empty and mandatory:"
msgstr ""
"Les variables suivantes sont inaccessibles mais sont vides et obligatoires :"
#: src/rougail/output_display/output/console.py:50
#: src/rougail/output_display/output/console.py:55
#: src/rougail/output_display/output/github.py:43
msgid "Variable"
msgstr "Variable"
#: src/rougail/output_display/output/console.py:52
#: src/rougail/output_display/output/console.py:57
#: src/rougail/output_display/output/github.py:45
msgid "Unmodifiable variable"
msgstr "Variable non modifiable"
#: src/rougail/output_display/output/console.py:55
#: src/rougail/output_display/output/console.py:60
#: src/rougail/output_display/output/github.py:48
msgid "Default value"
msgstr "Valeur par défaut"
#: src/rougail/output_display/output/console.py:57
#: src/rougail/output_display/output/console.py:62
#: src/rougail/output_display/output/github.py:50
msgid "Modified value"
msgstr "Valeur modifiée"
#: src/rougail/output_display/output/console.py:59
#: src/rougail/output_display/output/console.py:64
#: src/rougail/output_display/output/github.py:52
msgid "Original default value"
msgstr "Valeur par défaut d'origine"
#: src/rougail/output_display/output/console.py:63
#: src/rougail/output_display/output/console.py:68
msgid "Caption"
msgstr "Légende"
#: src/rougail/output_display/output/console.py:82
msgid "Layers"
msgstr "Couches"
#: src/rougail/output_display/output/console.py:93
msgid "Caution"
msgstr "Attention"
#: src/rougail/output_display/output/console.py:86
msgid "ERRORS"
msgstr "ERREURS"
#: src/rougail/output_display/output/console.py:131
msgid "Warning"
msgstr "Avertissement"
#: src/rougail/output_display/output/console.py:98
msgid "WARNINGS"
msgstr "AVERTISSEMENTS"
#: src/rougail/output_display/output/console.py:111
#: src/rougail/output_display/output/console.py:151
#: src/rougail/output_display/output/github.py:141
msgid "{0}:"
msgstr "{0} :"
#: src/rougail/output_display/output/console.py:117
#: src/rougail/output_display/output/console.py:157
#: src/rougail/output_display/output/github.py:147
msgid "{0}: {1}"
msgstr "{0} : {1}"
#: src/rougail/output_display/output/github.py:56
msgid "Caption:"
msgstr "Attention :"
#~ msgid "Error in config: {0}"
#~ msgstr "Erreur dans la config : {0}"
#~ msgid "The following variables are mandatory but have no value:"
#~ msgstr "Les variables suivantes sont obligatoire mais n'ont pas de valeur :"
#~ msgid ""
#~ "The following variables are inaccessible but are empty and mandatory:"
#~ msgstr ""
#~ "Les variables suivantes sont inaccessibles mais sont vides et "
#~ "obligatoires :"
#~ msgid "Layers"
#~ msgstr "Couches"
#~ msgid "ERRORS"
#~ msgstr "ERREURS"
#~ msgid "WARNINGS"
#~ msgstr "AVERTISSEMENTS"
#~ msgid ""
#~ "In tree the key is the family or variable description inside of it's name"
#~ msgstr ""

View file

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2025-12-03 21:30+0100\n"
"POT-Creation-Date: 2025-12-17 21:55+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -15,95 +15,114 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n"
#: src/rougail/output_display/config.py:30
#: src/rougail/output_display/config.py:44
msgid "duplicated level in rougail-output-display for output \"{0}\": {1} and {2}"
msgstr ""
#: src/rougail/output_display/config.py:50
msgid "duplicated name \"{0}\" in rougail-output-display"
msgstr ""
#: src/rougail/output_display/config.py:82
msgid "Display variables and values"
msgstr ""
#: src/rougail/output_display/config.py:31
msgid "Find all the variables and their values in your configuration (structural and user datas). Additional informations are available, such as the default value, the location where the value is loaded, etc."
#: src/rougail/output_display/config.py:84
msgid "Find all the variables and their values in your configuration (structural and user data). Additional informations are available, such as the default value, the location where the value is loaded, etc."
msgstr ""
#: src/rougail/output_display/config.py:40
#: src/rougail/output_display/config.py:93
msgid "if display is not set in \"step.output\""
msgstr ""
#: src/rougail/output_display/config.py:42
#: src/rougail/output_display/config.py:96
msgid "The output format for displaying variables"
msgstr ""
#: src/rougail/output_display/config.py:103
msgid "Show secrets instead of obscuring them"
msgstr ""
#: src/rougail/output_display/config.py:45
#: src/rougail/output_display/config.py:106
msgid "test mandatories variables before display in display"
msgstr ""
#: src/rougail/output_display/config.py:54
#: src/rougail/output_display/config.py:115
msgid "do not test if \"cli.read_write\" is true"
msgstr ""
#: src/rougail/output_display/config.py:57
#: src/rougail/output_display/config.py:118
msgid "Specific configuration for console output"
msgstr ""
#: src/rougail/output_display/config.py:124
msgid "Maximum number of characters per line"
msgstr ""
#: src/rougail/output_display/config.py:58
#: src/rougail/output_display/config.py:125
msgid "null means unlimited"
msgstr ""
#: src/rougail/output_display/display.py:77
#: src/rougail/output_display/display.py:151
msgid "mandatory variable but is inaccessible and has no value"
msgstr ""
#: src/rougail/output_display/display.py:157
msgid "mandatory variable but has no value"
msgstr ""
#: src/rougail/output_display/display.py:183
msgid "Variables:"
msgstr ""
#: src/rougail/output_display/display.py:114
msgid "Error in config: {0}"
msgstr ""
#: src/rougail/output_display/display.py:132
msgid "The following variables are mandatory but have no value:"
msgstr ""
#: src/rougail/output_display/display.py:137
msgid "The following variables are inaccessible but are empty and mandatory:"
msgstr ""
#: src/rougail/output_display/output/console.py:50
#: src/rougail/output_display/output/console.py:55
#: src/rougail/output_display/output/github.py:43
msgid "Variable"
msgstr ""
#: src/rougail/output_display/output/console.py:52
#: src/rougail/output_display/output/console.py:57
#: src/rougail/output_display/output/github.py:45
msgid "Unmodifiable variable"
msgstr ""
#: src/rougail/output_display/output/console.py:55
#: src/rougail/output_display/output/console.py:60
#: src/rougail/output_display/output/github.py:48
msgid "Default value"
msgstr ""
#: src/rougail/output_display/output/console.py:57
#: src/rougail/output_display/output/console.py:62
#: src/rougail/output_display/output/github.py:50
msgid "Modified value"
msgstr ""
#: src/rougail/output_display/output/console.py:59
#: src/rougail/output_display/output/console.py:64
#: src/rougail/output_display/output/github.py:52
msgid "Original default value"
msgstr ""
#: src/rougail/output_display/output/console.py:63
#: src/rougail/output_display/output/console.py:68
msgid "Caption"
msgstr ""
#: src/rougail/output_display/output/console.py:82
msgid "Layers"
#: src/rougail/output_display/output/console.py:93
msgid "Caution"
msgstr ""
#: src/rougail/output_display/output/console.py:86
msgid "ERRORS"
#: src/rougail/output_display/output/console.py:131
msgid "Warning"
msgstr ""
#: src/rougail/output_display/output/console.py:98
msgid "WARNINGS"
msgstr ""
#: src/rougail/output_display/output/console.py:111
#: src/rougail/output_display/output/console.py:151
#: src/rougail/output_display/output/github.py:141
msgid "{0}:"
msgstr ""
#: src/rougail/output_display/output/console.py:117
#: src/rougail/output_display/output/console.py:157
#: src/rougail/output_display/output/github.py:147
msgid "{0}: {1}"
msgstr ""
#: src/rougail/output_display/output/github.py:56
msgid "Caption:"
msgstr ""

View file

@ -17,18 +17,71 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from pathlib import Path
from rougail.utils import load_modules
from .i18n import _
OUTPUTS = None
def get_outputs() -> None:
"""Load all outputs"""
module_name = f"rougail.output_display.output"
outputs = {}
names = []
for path in (Path(__file__).parent / "output").iterdir():
name = path.name
if not name.endswith(".py") or name.endswith("__.py"):
continue
module = load_modules(module_name + "." + name[:-3], str(path))
if "OutputFamily" not in dir(module):
continue
obj_class = module.OutputFamily
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
)
)
if obj_class.name in names:
raise ImportError(
_('duplicated name "{0}" in rougail-output-display').format(
obj_class.name
)
)
names.append(obj_class.name)
outputs[level] = obj_class
return {outputs[level].name: outputs[level] for level in sorted(outputs)}
class OutPuts: # pylint: disable=R0903
"""Transformations applied on a object instance"""
def __init__(
self,
) -> None:
global OUTPUTS
if OUTPUTS is None:
OUTPUTS = get_outputs()
def get(self) -> dict:
"""Get all outputs"""
return OUTPUTS
def get_rougail_config(
*,
backward_compatibility=True,
) -> dict:
outputs = list(OutPuts().get())
output_format_default = outputs[0]
options = f"""
display:
description: {_('Display variables and values')}
help: {_('Find all the variables and their values in your configuration (structural and user datas). Additional informations are available, such as the default value, the location where the value is loaded, etc.')}
help: |-
{_('Find all the variables and their values in your configuration (structural and user data). Additional informations are available, such as the default value, the location where the value is loaded, etc.')}
disabled:
jinja: |-
{{% if step.output is propertyerror or step.output != 'display' %}}
@ -39,6 +92,14 @@ display:
return_type: boolean
description: {_('if display is not set in "step.output"')}
output_format:
description: {_('The output format for displaying variables')}
default: { output_format_default }
choices:
"""
for output in outputs:
options += f" - {output}\n"
options += f"""
show_secrets: false # {_('Show secrets instead of obscuring them')}
mandatory:
@ -53,13 +114,19 @@ display:
{{% endif %}}
description: {_('do not test if "cli.read_write" is true')}
max_width:
description: {_("Maximum number of characters per line")}
help: {_('null means unlimited')}
type: integer
mandatory: false
params:
min_integer: 50
console:
description: {_("Specific configuration for console output")}
disabled:
variable: _.output_format
when_not: console
max_width:
description: {_("Maximum number of characters per line")}
help: {_('null means unlimited')}
type: integer
mandatory: false
params:
min_integer: 50
"""
return {
"name": "display",

View file

@ -16,23 +16,24 @@ 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 Optional
from typing import Optional, Any
from ruamel.yaml import YAML
from io import BytesIO
from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu import owners, groups
from .config import OutPuts
from .i18n import _
from .output.console import OutputFamily
class RougailOutputDisplay:
def __init__(
self,
config: "Config",
metaconfig=None,
*,
rougailconfig: "RougailConfig" = None,
root_config=None,
user_data_errors: Optional[list] = None,
user_data_warnings: Optional[list] = None,
config_owner_is_path: bool = False,
@ -44,7 +45,7 @@ class RougailOutputDisplay:
rougailconfig = RougailConfig
self.rougailconfig = rougailconfig
self.config = config
self.metaconfig = metaconfig
self.root_config = root_config
self.layer_datas = layer_datas
self.config_owner_is_path = config_owner_is_path
self.errors = []
@ -55,147 +56,297 @@ class RougailOutputDisplay:
if user_data_warnings is None:
user_data_warnings = []
self.user_data_warnings = user_data_warnings
self.out = []
self.root = None
# self.out = []
self.nodes = None
self.yaml = YAML()
self.yaml.indent(mapping=2, sequence=4, offset=2)
def run(self) -> str:
if self.root is None:
self.root = self.get_root()
self.is_mandatory = self.rougailconfig["display.mandatory"]
self.show_secrets = self.rougailconfig["display.show_secrets"]
return self.output.run()
def print(self) -> None:
ret = self.exporter()
self.output.print()
return ret
def get_root(self) -> None:
yaml = YAML()
yaml.indent(mapping=2, sequence=4, offset=2)
self.output = OutputFamily(
_("Variables:"),
None,
self,
yaml,
self.out,
no_icon=True,
)
return self.output
def exporter(self) -> bool:
if self.is_mandatory:
ori_properties = self.config.property.exportation()
self.config.property.read_write()
if not self.user_data_errors and not self.errors:
self.mandatories()
self.config.property.importation(ori_properties)
output_format = self.rougailconfig["display.output_format"]
output = OutPuts().get()[output_format](self.rougailconfig)
warnings = self.user_data_warnings + self.warnings
if warnings:
self.display_warnings(warnings)
errors = self.user_data_errors + self.errors
level = None
errors_warnings_dict = {}
if warnings:
level = "warnings"
#output.display_warnings(errors_warnings_dict, warnings)
for warning in warnings:
output.error_warn_to_dict(warning, errors_warnings_dict, 'warning')
if errors:
self.output.display_errors(errors)
return False
self.parse_options(
self.config,
self.root,
)
if self.output.tree and self.output.tree.children:
self.output.header()
self.end()
return True
level = "errors"
for error in errors:
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)
if errors:
return False, ret
ret += "\n"
else:
ret = ''
show_secrets = self.rougailconfig["display.show_secrets"]
if self.nodes is None:
self.nodes = Node(self.yaml, show_secrets, self.config, self.root_config, self.config_owner_is_path)
code, run = output.run(self.nodes)
return code, ret + run
def print(self) -> None:
status, ret = self.run()
print(ret)
return status
#
# def exporter(self) -> bool:
# if self.is_mandatory:
# ori_properties = self.config.property.exportation()
# self.config.property.read_write()
# if not self.user_data_errors and not self.errors:
# self.mandatories()
# self.config.property.importation(ori_properties)
# warnings = self.user_data_warnings + self.warnings
# if warnings:
# self.output.display_warnings(warnings)
#
# errors = self.user_data_errors + self.errors
# if errors:
# self.output.display_errors(errors)
# return False
# self.output.out = []
# if self.output.has_variable():
# self.output.header()
# self.output.end()
# return True
def mandatories(self) -> None:
try:
mandatories = self.config.value.mandatory()
except (ConfigError, PropertiesOptionError) as err:
self.errors.append(_("Error in config: {0}").format(err))
except ValueError as err:
self.errors.append(str(err))
except (ConfigError, PropertiesOptionError, ValueError) as err:
try:
subconfig = err.subconfig
except AttributeError:
subconfig = None
if subconfig:
err.prefix = ""
self.errors.append({str(err): subconfig})
else:
self.errors.append(str(err))
else:
self.check_mandatories(mandatories)
self.populate_mandatories(mandatories)
def check_mandatories(self, mandatories: list) -> None:
options_with_error = []
options = []
def populate_mandatories(self, mandatories: list) -> None:
for option in mandatories:
try:
option.value.get()
except PropertiesOptionError:
options_with_error.append(option)
else:
options.append(option)
if options:
self.errors.append(
{_("The following variables are mandatory but have no value:"): self.options_to_dict(options)}
)
elif options_with_error:
self.errors.append(
{
_(
"The following variables are inaccessible but are empty and mandatory:"
): self.options_to_dict(options_with_error),
}
)
def options_to_dict(self, mandatories: list):
options = {}
for option in mandatories:
parents = [option]
parent = option
while True:
parent = parent.parent()
if parent.path() is None:
break
parents.insert(0, parent)
current_options = options
for child in parents:
if child.isoptiondescription():
current_options = current_options.setdefault(child.description(), {})
else:
current_options.setdefault(None, []).append(child.description())
return options
def parse_options(
self,
conf,
parent,
):
for child in conf:
if child.isoptiondescription():
if child.isleadership():
func = self.parse_leadership
else:
func = self.parse_options
family = parent.add_family(child)
func(
child,
family,
self.errors.append(
{
_(
"mandatory variable but is inaccessible and has no value"
): option._subconfig,
}
)
else:
parent.add_variable(child)
self.errors.append({_("mandatory variable but has no value"): option._subconfig})
def parse_leadership(
class Node:
def __init__(
self,
leadership,
parent,
) -> None:
leader, *followers = list(leadership)
leader_values = leader.value.get()
followers_values = {idx: [] for idx in range(len(leader_values))}
for follower in followers:
followers_values[follower.index()].append(follower)
for idx in followers_values:
leader_obj = parent.add_family(leader)
leader_obj.add_variable(
leader,
value=leader_values[idx],
leader_index=idx,
)
for follower in followers_values[idx]:
leader_obj.add_variable(follower)
yaml,
show_secrets,
config,
root_config,
config_owner_is_path,
*,
node=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
self.root_config = root_config
self.config_owner_is_path = config_owner_is_path
if node is None:
values = self.config.value.get()
self.level = level
if node:
self.hidden = "hidden" in node.property.get()
self.description = node.description()
else:
self.hidden = None
self.description = _("Variables:")
self.level = level
self.children = []
def end(self):
self.out.append(self.output.tree)
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)}
for follower, follower_value in values_iter:
followers_values[follower.index()][follower] = follower_value
for idx, fvalues in enumerate(followers_values.values()):
self.add_node(leader, fvalues, leader_index=idx)
else:
for option, value in values.items():
if option.isoptiondescription():
if option.group_type() == groups.namespace and not value:
continue
if option.isleadership():
leader, leader_values = next(iter(value.items()))
if not leader_values:
self.add_leaf(leader, [], description=option.description())
else:
self.add_node(option, value)
else:
if value == {}:
self.add_leaf(option, "{}")
else:
self.add_node(option, value)
else:
if option.isleader():
index = leader_index
else:
index = None
self.add_leaf(option, value, leader_index=index)
def add_node(
self,
option,
values,
*,
leader_index: Optional[int]=None,
) -> 'Node':
self.children.append({"type": "node",
"node": self.__class__(
self.yaml,
self.show_secrets,
self.config,
self.root_config,
self.config_owner_is_path,
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
):
properties = option.property.get()
if description is None:
description = option.description()
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,
},
)
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 = []
meta_config = self.config
meta_option = option
index = option.index()
if index is not None:
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)
force_store_value = "force_store_value" in properties
is_default = option.owner.isdefault()
option_path = option.path()
while True:
if values and value in [None, []]:
break
if is_default and (not meta_config.path() or "." not in meta_config.path()):
loaded_from = None
else:
loaded_from = meta_option.information.get(loaded_from_key, None)
if isinstance(value, list):
value = [self.convert_value(meta_option, val) for val in value]
else:
value = self.convert_value(meta_option, value)
values.append(
{
"value": value,
"is_default": is_default,
"loaded_from": loaded_from,
}
)
meta_config_path = meta_config.path()
if (is_default and (not meta_config_path or "." not in meta_config_path)) or force_store_value:
break
new_meta_config = self.get_metaconfig_with_default_value(meta_config, meta_option)
if not meta_config:
break
meta_option = new_meta_config.option(option_path, index)
if new_meta_config == meta_config:
is_default = True
value = meta_option.value.default()
else:
is_default = meta_option.owner.isdefault()
value = meta_option.value.get()
meta_config = new_meta_config
if leader_index is not None:
if len(value) > leader_index:
value = value[leader_index]
else:
value = None
return values
def convert_value(
self,
option,
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"
):
return "*" * 10
if isinstance(value, str):
return value
with BytesIO() as ymlfh:
self.yaml.dump(value, ymlfh)
ret = ymlfh.getvalue().decode("utf-8").strip()
if ret.endswith("..."):
ret = ret[:-3].strip()
return ret
def get_metaconfig_with_default_value(self, meta_config, option):
default_owner = option.owner.default()
if default_owner == owners.default:
if self.root_config:
return self.root_config
return self.config
if not self.config_owner_is_path:
while True:
meta_config = meta_config.parent()
if not meta_config.owner.isdefault():
break
else:
meta_config = self.root_config
for child in default_owner.split(".")[1:]:
meta_config = meta_config.config(child)
return meta_config

View file

@ -26,165 +26,146 @@ from ..util import CommonOutput
class OutputFamily(CommonOutput):
level = 10
name = "console"
variable_hidden_color = "orange1"
variable_normal_color = None
value_unmodified_color = "gold1"
value_modified_color = "green"
value_default_color = None
error_color = 'bright_red'
error_icon = "stop_sign"
warning_color = "bright_yellow"
warning_icon = "bell"
guide_style = "bold bright_blue"
def set_config(self, rougailconfig):
self.max_width = rougailconfig["display.console.max_width"]
def run(self):
max_width = self.root.rougailconfig["display.max_width"]
self.console = Console(force_terminal=True, width=max_width)
with self.console.capture() as capture:
ret = self.root.print()
return ret, capture.get()
def print(self) -> None:
for out in self.out:
self.console.print(out)
def _run(self, root):
console = Console(force_terminal=True, width=self.max_width)
with console.capture() as capture:
console.print(self.header())
console.print(root)
return True, capture.get()
def header(self):
caption_line = ""
if self.root_family.variable_default_enable:
if self.variable_default_enable:
caption_line += _("Variable") + "\n"
if self.root_family.variable_hidden_enable:
caption_line += f'[{self.variable_hidden_color}]{_("Unmodifiable variable")}[/{self.variable_hidden_color}]\n'
if self.variable_hidden_enable:
caption_line += self.set_color(self.variable_hidden_color, _("Unmodifiable variable")) + "\n"
header_value = ""
if self.root_family.value_unmodified_enable:
header_value = f'[{self.value_unmodified_color}]{_("Default value")}[/{self.value_unmodified_color}]\n'
if self.root_family.value_modified_enable:
header_value += f'[{self.value_modified_color}]{_("Modified value")}[/{self.value_modified_color}]\n'
if self.root_family.value_default_enable:
if self.value_unmodified_enable:
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"
if self.value_default_enable:
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])
self.out.append(Panel.fit(caption, title=_("Caption")))
data = Panel.fit(caption, title=_("Caption"))
#
layers = Table.grid(padding=1, collapse_padding=True)
caption.pad_edge = False
if self.root.layer_datas:
max_len = 0
for datas in self.root.layer_datas.values():
for data in datas.values():
max_len = max(max_len, len(data))
display_layers = ["" for i in range(max_len)]
for datas in self.root.layer_datas.values():
for data in datas.values():
last_index = len(data) - 1
for idx in range(max_len):
if last_index < idx:
display_layers[idx] += "\n"
else:
display_layers[idx] += data[idx] + "\n"
layers.add_row(*[layer[:-1] for layer in display_layers])
self.out.append(Panel.fit(layers, title=_("Layers")))
# FIXME
# layers = Table.grid(padding=1, collapse_padding=True)
# caption.pad_edge = False
# if self.root.layer_datas:
# max_len = 0
# for datas in self.root.layer_datas.values():
# for data in datas.values():
# max_len = max(max_len, len(data))
# display_layers = ["" for i in range(max_len)]
# for datas in self.root.layer_datas.values():
# for data in datas.values():
# last_index = len(data) - 1
# for idx in range(max_len):
# if last_index < idx:
# display_layers[idx] += "\n"
# else:
# display_layers[idx] += data[idx] + "\n"
# layers.add_row(*[layer[:-1] for layer in display_layers])
# self.out.append(Panel.fit(layers, title=_("Layers")))
return data
def error_header(self):
return Tree(
f"[bold][bright_red]:stop_sign: {_('ERRORS')}[/bright_red][/bold]",
guide_style="bold bright_red",
)
def display_error(self, tree, error):
return tree.add(error)
def display_warnings(
self,
warnings: list,
) -> None:
tree = Tree(
f"[bold][bright_yellow]:bell: {_('WARNINGS')}[/bright_yellow][/bold]",
guide_style="bold bright_yellow",
f"[bold][{self.error_color}]:{self.error_icon}: {_('Caution')}[/{self.error_color}][/bold]",
guide_style=f"bold {self.error_color}",
)
for warning in warnings:
tree.add(warning)
self.out.append(tree)
# self.out.append(tree)
return tree
def display_error(self, level, tree, msg, default_color):
if default_color == "errors":
color = self.error_color
else:
color = self.warning_color
if isinstance(msg, tuple):
if len(msg) == 3:
if msg[2] == 'error':
color = self.error_color
icon = self.error_icon
else:
color = self.warning_color
icon = self.warning_icon
msg = f"{msg[0]}: [{color}]:{icon}: {msg[1]}[/{color}]"
else:
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}'
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)
return capture.get()
def warning_header(self):
tree = Tree(
f"[bold][{self.warning_color}]:{self.warning_icon}: {_('Warning')}[/{self.warning_color}][/bold]",
guide_style=f"bold {self.warning_color}",
)
# 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 add_variable(
self, *args, **kwargs,
self, parent, description, value, icon, level,
):
key, value = super().add_variable(*args, **kwargs)
if icon == 'leaf':
icon = 'notebook'
else:
icon = 'open_file_folder'
if isinstance(value, list):
subtree = self.get_tree().add(
":notebook: " + _("{0}:").format(key),
guide_style="bold bright_blue",
subtree = parent.add(
f":{icon}: " + _("{0}:").format(description),
guide_style=self.guide_style,
)
for val in value:
subtree.add(str(val))
else:
self.get_tree().add(":notebook: " + _("{0}: {1}").format(key, value))
parent.add(f":{icon}: " + _("{0}: {1}").format(description, value))
def colorize(
self,
values,
option=None,
) -> str:
multi = False
ret = []
default = []
for idx, data in enumerate(values):
value = data["value"]
if isinstance(value, list):
multi = True
else:
value = [value]
for vidx, val in enumerate(value):
if len(ret) == vidx:
ret.append("")
default.append(False)
if idx:
if not default[vidx]:
if ret[vidx]:
ret[vidx] += " "
ret[vidx] += "("
default[vidx] = True
else:
ret[vidx] += " "
ret[vidx] += ":hourglass_flowing_sand: "
if option:
val = self.convert_value(
option,
val,
)
color = data["color"]
if color is not None:
ret[vidx] += f"[{color}]{val}[/{color}]"
else:
ret[vidx] += val
loaded_from = data["loaded_from"]
if loaded_from:
ret[vidx] += f" :arrow_backward: {loaded_from}"
for idx in range(len(ret)):
if default[idx]:
ret[idx] += ")"
if not multi:
if not ret:
return ""
return ret[0]
return ret
def set_color(self, color, msg):
return f"[{color}]{msg}[/{color}]"
def get_tree(self):
if self.tree is None:
if self.parent is None:
tree = Tree
else:
tree = self.parent.add
# if self.is_leader:
# self.tree = tree(
# ":notebook: " + _("{0}:").format(self.family),
# guide_style="bold bright_blue",
# )
# elif self.no_icon:
if self.no_icon:
self.tree = tree(
self.family,
guide_style="bold bright_blue",
def get_parent(self, parent, description, level):
if parent is None:
return Tree(description,
guide_style=self.guide_style,
)
return parent.add(
f":open_file_folder: {description}",
guide_style=self.guide_style,
)
else:
self.tree = tree(
f":open_file_folder: {self.family}",
guide_style="bold bright_blue",
)
return self.tree

View file

@ -0,0 +1,164 @@
"""
Silique (https://www.silique.fr)
Copyright (C) 2025
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
option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
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 ..i18n import _
from ..util import CommonOutput
class OutputFamily(CommonOutput):
level = 20
name = "github"
variable_hidden_color = "#A52A2A"
variable_normal_color = None
value_unmodified_color = "#B8860B"
value_modified_color = "#006400"
value_default_color = None
error_color = "#C23636"
error_icon = "stop_sign"
warning_color = "#EFBF04"
warning_icon = "bell"
def _run(self, root):
ret = self.header() + "\n".join(root) + "\n"
return True, ret
def header(self):
variables = []
if self.variable_default_enable:
variables.append(_("Variable"))
if self.variable_hidden_enable:
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")))
if self.value_modified_enable:
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:
return ""
caption = "> [!NOTE]" + "\n>\n"
caption += f'> **{_("Caption:")}**\n'
if variables:
caption += "> - " + "\n> - ".join(variables) + "\n"
if values:
caption += "> - " + "\n> - ".join(values) + "\n"
# if self.root.layer_datas:
# raise Exception('unsupported layers')
# max_len = 0
# for datas in self.root.layer_datas.values():
# for data in datas.values():
# max_len = max(max_len, len(data))
# display_layers = ["" for i in range(max_len)]
# for datas in self.root.layer_datas.values():
# for data in datas.values():
# last_index = len(data) - 1
# for idx in range(max_len):
# if last_index < idx:
# display_layers[idx] += "\n"
# else:
# display_layers[idx] += data[idx] + "\n"
# layers.add_row(*[layer[:-1] for layer in display_layers])
# self.out.append(Panel.fit(layers, title=_("Layers")))
return caption + "\n"
def error_header(self):
return ['> [!CAUTION]\n> ']
def warning_header(self):
return ['> [!WARNING]\n> ']
def error_end(self):
self.out[-1] += "\n"
def warning_end(self):
self.out[-1] += "\n"
def display(self, tree):
return "\n".join(tree) + "\n"
def display_error(self, level, tree, msg, default_color):
if default_color == "errors":
color = self.error_color
else:
color = self.warning_color
if isinstance(msg, tuple):
if len(msg) == 3:
if msg[2] == 'error':
color = self.error_color
icon = self.error_icon
else:
color = self.warning_color
icon = self.warning_icon
msg = f"{msg[0]}: :{icon}: {self.set_color(color, msg[1])}"
else:
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.append("> " + " " * (level - 1) * 2 + "- " + msg)
return tree
# def msg_to_error(self, msg):
# return f':stop_sign: {self.set_color(self.error_color, msg)}'
#
# def display_warning(self, tree, warning, level):
# self.out.append("> " + " " * (level - 1) * 2 + "- " + warning)
#
# def msg_to_warning(self, msg):
# return f':bell: {self.set_color(self.warning_color, msg)}'
#
def add_variable(
self, parent, description, value, icon, level,
):
if parent is None:
parent = []
if icon == 'leaf':
icon = 'notebook'
else:
icon = 'open_file_folder'
before = " " * (level - 1) * 2 + "- "
if isinstance(value, list):
subtree = parent.append(
f"{before}:{icon}: " + _("{0}:").format(description),
)
before = " " * (level * 2) + "- "
for val in value:
parent.append(before + str(val))
else:
parent.append(before + f":{icon}: " + _("{0}: {1}").format(description, value))
def set_color(self, color, msg):
return f'<span style="color: {color}">{msg}</span>'
def get_tree(self):
return None
def has_variable(self):
return self.out != []
def get_parent(self, parent, description, level):
if parent is None:
parent = []
parent.append(description)
else:
parent.append(" " * (level - 1) * 2 + "- " + ":open_file_folder: " + description)
return parent

View file

@ -16,77 +16,168 @@ 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 io import BytesIO
from tiramisu import owners
# from tiramisu import owners
from rougail.utils import undefined
from .i18n import _
class CommonOutput:
def __init__(
self,
family,
parent,
root,
_yaml,
out,
*,
# is_leader: bool = False,
root_family: Optional["OutputFamily"] = None,
no_icon: bool = False,
rougailconfig,
) -> None:
self.tree = None
self.root = root
self.parent = parent
if isinstance(family, tuple):
raise Exception()
self.family = family
# self.is_leader = is_leader
self.no_icon = no_icon
self._yaml = _yaml
self.out = out
if root_family is None:
root_family = self
self.variable_default_enable = False
self.variable_hidden_enable = False
self.value_modified_enable = False
self.value_unmodified_enable = False
self.value_default_enable = False
self.root_family = root_family
self.set_config(rougailconfig)
self.variable_default_enable = False
self.variable_hidden_enable = False
self.value_modified_enable = False
self.value_unmodified_enable = False
self.value_default_enable = False
def set_config(self, rougailconfig):
pass
def run(self, nodes):
if nodes.children:
root = self.parse(nodes)
return self._run(root)
return 0, ''
def parse(self, node, parent=None, level=0):
if node.hidden:
self.variable_hidden_enable = True
color = self.variable_hidden_color
else:
if node.hidden != None:
self.variable_default_enable = True
color = self.variable_normal_color
family_output = self.colorize(
[
{
"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)
else:
if child["hidden"]:
self.variable_hidden_enable = True
variable_color = self.variable_hidden_color
else:
self.variable_default_enable = True
variable_color = self.variable_normal_color
if child["values"][0]["is_default"]:
self.value_unmodified_enable = True
color = self.value_unmodified_color
else:
self.value_modified_enable = True
color = self.value_modified_color
child["values"][0]["color"] = color
if len(child["values"]) > 1:
self.value_default_enable = True
value = self.colorize(
child["values"],
)
description = self.colorize(
[
{
"value": child["description"],
"color": variable_color,
"loaded_from": None,
}
]
)
self.add_variable(subparent, description, value, child["icon"], level+1)
return subparent
def header(self):
raise NotImplementedError()
#
# def display_errors(
# self,
# tree,
# errors,
# ) -> None:
# errors_dict = {}
# for error in errors:
# self.error_warn_to_dict(error, errors_dict, self.msg_to_error)
# self.parse_error_warning(tree, errors_dict, self.display_error)
# return self.pouet(tree)
# self.error_end()
#
# def display_warnings(
# self,
# warnings_dict,
# warnings,
# ) -> None:
###### self.parse_error_warning(tree, warnings_dict, self.display_warning)
## self.warning_end()
def display_errors(
self,
errors,
) -> None:
tree = self.error_header()
for error in errors:
self.parse_error(tree, error)
self.out.append(tree)
def error_warn_to_dict(self, error, errors_dict, level):
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))
else:
errors_dict.setdefault(None, []).append(error)
#
# def msg_to_error(self, msg):
# return msg
#
# def msg_to_warning(self, msg):
# return msg
def parse_error(self, tree, 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)
parents = []
parent = subconfig
while True:
parent = parent.parent
if parent is None:
break
parents.insert(0, parent)
current_dict = errors_dict
for child in parents[1:]:
description = child.option.impl_get_display_name(child)
current_dict = current_dict.setdefault(description, {})
return current_dict
def parse_error_warning(self, tree, error, display, default_color, level=0):
self._parse_error_warning(tree, error, display, level, default_color)
return self.display(tree)
def _parse_error_warning(self, tree, error, display, level, default_color):
if isinstance(error, list):
for err in error:
self.parse_error(tree, err)
return tree
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(tree, value)
self._parse_error_warning(tree, value, display, level, default_color)
else:
sub_tree = self.parse_error(tree, key)
self.parse_error(sub_tree, value)
if isinstance(value, list) and len(value) == 1:
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)
else:
return self.display_error(tree, error)
return display(level, tree, error, default_color)
def warning_end(self):
pass
def add_family(
self,
family,
level,
) -> 'OutputFamily':
properties = family.property.get()
if "hidden" in properties:
@ -108,173 +199,62 @@ class CommonOutput:
family_output,
self.get_tree(),
self.root,
self._yaml,
self.out,
level + 1,
root_family = self.root_family,
)
def add_variable(
self, option, value: Any = undefined, leader_index: Optional[int] = None
):
values = []
properties = option.property.get()
if not option.owner.isdefault() and option.information.get(
"default_value_makes_sense", True
):
self.get_modified_value(option, value, values)
if "force_store_value" not in properties or not values:
self.get_default_values(option, values, leader_index)
#
if "hidden" in properties:
self.root_family.variable_hidden_enable = True
variable_color = self.variable_hidden_color
else:
self.root_family.variable_default_enable = True
variable_color = self.variable_normal_color
key = self.colorize(
[
{
"value": option.description(),
"color": variable_color,
"loaded_from": None,
}
]
)
value = self.colorize(
values,
option,
)
return key, value
def get_modified_value(self, option: "Option", value: Any, values: list) -> None:
self.root_family.value_modified_enable = True
follower_index = option.index()
if follower_index is not None:
loaded_from = option.information.get(
f"loaded_from_{follower_index}", None
)
else:
loaded_from = option.information.get("loaded_from", None)
if value is undefined:
value = option.value.get()
values.append(
{
"value": value,
"color": self.value_modified_color,
"loaded_from": loaded_from,
}
)
def get_default_values(self, option: "Option", values: list, leader_index: Optional[int]) -> None:
meta_config = self.root.config
meta_option = option
index = option.index()
while True:
default_value = meta_option.value.default()
if leader_index is not None:
if len(default_value) > leader_index:
default_value = default_value[leader_index]
else:
default_value = None
is_root_metaconfig = False
if (
meta_config is None
or not meta_config.path()
or "." not in meta_config.path()
):
is_root_metaconfig = True
if (
(values and default_value is None) or default_value == []
) and is_root_metaconfig:
break
if not values:
self.root_family.value_unmodified_enable = True
color = self.value_unmodified_color
else:
self.root_family.value_default_enable = True
color = self.value_default_color
meta_config = self.get_subconfig_with_default_value(meta_option)
meta_option = meta_config.option(option.path(), index)
if is_root_metaconfig:
loaded_from = None
else:
if index is not None:
key = f"loaded_from_{index}"
else:
key = "loaded_from"
loaded_from = meta_option.information.get(key, None)
values.append(
{
"value": default_value,
"color": color,
"loaded_from": loaded_from,
}
)
if is_root_metaconfig:
break
#
# def get_default_value(self, option: "Option", values: list, leader_index: Optional[int]) -> None:
# follower_index = option.index()
## if leader_index is None and follower_index is not None:
## if not option.isfollower() or not option.issubmulti():
## default_value = None
## else:
## default_value = []
## else:
## default_value = None
# if not values:
# self.root_family.value_unmodified_enable = True
# color = self.value_unmodified_color
# else:
# self.root_family.value_default_enable = True
# color = self.value_default_color
# if follower_index is not None:
# loaded_from = option.information.get(
# f"loaded_from_{follower_index}", None
# )
# else:
# loaded_from = option.information.get("loaded_from", None)
# values.append(
# {
# "value": default_value,
# "color": color,
# "loaded_from": loaded_from,
# }
# )
def get_subconfig_with_default_value(self, config):
default_owner = config.owner.default()
if default_owner == owners.default:
return self.root.config
if not self.root.config_owner_is_path:
meta_config = self.root.config
while True:
meta_config = meta_config.parent()
if not meta_config.owner.isdefault():
break
else:
meta_config = self.root.metaconfig
for child in default_owner.split(".")[1:]:
meta_config = meta_config.config(child)
return meta_config
def convert_value(
def colorize(
self,
option,
value: Any,
values,
option=None,
) -> str:
"""Dump variable, means transform bool, ... to yaml string"""
if (
value is not None
and not self.root.show_secrets
and option.type() == "password"
):
return "*" * 10
if isinstance(value, str):
return value
with BytesIO() as ymlfh:
self._yaml.dump(value, ymlfh)
ret = ymlfh.getvalue().decode("utf-8").strip()
if ret.endswith("..."):
ret = ret[:-3].strip()
multi = False
ret = []
default = []
empty_multi = False
for idx, data in enumerate(values):
value = data["value"]
if isinstance(value, list):
multi = True
if not value:
empty_multi = True
value = ["[]"]
else:
value = [value]
for vidx, val in enumerate(value):
if len(ret) == vidx:
ret.append("")
default.append(False)
if idx:
if not default[vidx]:
if ret[vidx]:
ret[vidx] += " "
ret[vidx] += "("
default[vidx] = True
else:
ret[vidx] += " "
ret[vidx] += ":hourglass_flowing_sand: "
if option:
val = self.convert_value(
option,
val,
)
color = data.get("color", self.value_default_color)
if color is not None:
ret[vidx] += self.set_color(color, val)
else:
ret[vidx] += val
loaded_from = data["loaded_from"]
if loaded_from:
ret[vidx] += f"{loaded_from}"
for idx in range(len(ret)):
if default[idx]:
ret[idx] += ")"
if not multi or empty_multi:
if not ret:
return ""
return ret[0]
return ret
def end(self):
pass

22
test.md Normal file
View file

@ -0,0 +1,22 @@
<pre>
Variables:
┗━ 📂 A family
┣━ 📓 The first variable: string1 ◀ loaded from rougail-test
┗━ 📓 The second variable: string1 ◀ loaded from rougail-test
</pre>
<pre>
Variables:
<span style="color: #5c5cff">┣━━ </span>📓 <span style="color: #ff0000">Configure Proxy Access to the Internet</span>: <span style="color: #ffd700">No proxy</span>
<span style="color: #5c5cff">┗━━ </span>📂 Manual proxy configuration
<span style="color: #5c5cff"> </span><span style="color: #5c5cff">┗━━ </span>📂 HTTP Proxy
<span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span><span style="color: #5c5cff">┗━━ </span>📓 <span style="color: #ff0000">HTTP address</span>: <span style="color: #00aa00">example.net</span> ◀ loaded from the YAML file
<span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span><span style="color: #5c5cff"> </span>"config/03/config.yml"
</pre>
> Variables:
> - 📂 A family
> - 📓 The first variable: string1 ◀ loaded from rougail-test
> - 📓 The second variable: <span style="color: #5c5cff">string1</span> ◀ loaded from rougail-test

View file

@ -1,3 +0,0 @@
🛑 ERRORS
┗━━ The following variables are inaccessible but are empty and mandatory:
 ┗━━ mandatory_variable (please set a value)

View file

@ -0,0 +1,3 @@
> [!CAUTION]
>
> - please set a value: :stop_sign: <span style="color: #C23636">mandatory variable but is inaccessible and has no value</span>

View file

@ -1,3 +1,2 @@
🛑 ERRORS
┗━━ The following variables are inaccessible but are empty and mandatory:
 ┗━━ please set a value
🛑 Caution
┗━━ please set a value: 🛑 mandatory variable but is inaccessible and has no value

View file

@ -0,0 +1,5 @@
> [!CAUTION]
>
> - family1
> - family2
> - please set a value: :stop_sign: <span style="color: #C23636">mandatory variable but is inaccessible and has no value</span>

View file

@ -1,5 +1,4 @@
🛑 ERRORS
┗━━ The following variables are inaccessible but are empty and mandatory:
 ┗━━ family1
  ┗━━ family2
   ┗━━ please set a value
🛑 Caution
┗━━ family1
 ┗━━ family2
  ┗━━ please set a value: 🛑 mandatory variable but is inaccessible and has no value

View file

@ -0,0 +1,5 @@
> [!CAUTION]
>
> - family1
> - family2
> - please set a value: :stop_sign: <span style="color: #C23636">mandatory variable but has no value</span>

View file

@ -1,5 +1,4 @@
🛑 ERRORS
┗━━ The following variables are mandatory but have no value:
 ┗━━ family1
  ┗━━ family2
   ┗━━ please set a value
🛑 Caution
┗━━ family1
 ┗━━ family2
  ┗━━ please set a value: 🛑 mandatory variable but has no value

View file

@ -0,0 +1,5 @@
> [!CAUTION]
>
> - family1
> - family2
> - A variable: :stop_sign: <span style="color: #C23636">"not_an_integer" is an invalid integer</span>

View file

@ -0,0 +1,4 @@
🛑 Caution
┗━━ family1
 ┗━━ family2
  ┗━━ A variable: 🛑 "not_an_integer" is an invalid integer

View file

@ -0,0 +1,15 @@
%YAML 1.2
---
version: 1.1
family1:
family2:
variable:
description: A variable
type: integer
default:
jinja: |-
not_an_integer
...

View file

@ -0,0 +1,16 @@
> [!WARNING]
>
> - my family1
> - my integer: :bell: <span style="color: #EFBF04">the value "not_an_integer" is an invalid integer, it's not an integer, it will be ignored when loading from fake user data</span>
> - my string: :bell: <span style="color: #EFBF04">the value "3" is an invalid string, it's not a string, it will be ignored when loading from fake user data</span>
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #B8860B">Default value</span>
Variables:
- :open_file_folder: my family1
- :notebook: my integer: <span style="color: #B8860B">null</span>
- :notebook: my string: <span style="color: #B8860B">null</span>

View file

@ -0,0 +1,12 @@
🔔 Warning
┗━━ my family1
 ┣━━ my integer: 🔔 the value "not_an_integer" is an invalid integer, it's not an integer, it will be ignored when loading from fake user data
 ┗━━ my string: 🔔 the value "3" is an invalid string, it's not a string, it will be ignored when loading from fake user data
╭─────── Caption ────────╮
│ Variable Default value │
╰────────────────────────╯
Variables:
┗━━ 📂 my family1
 ┣━━ 📓 my integer: null
 ┗━━ 📓 my string: null

View file

@ -0,0 +1,5 @@
> [!CAUTION]
>
> - my family1
> - my integer: :stop_sign: <span style="color: #C23636">the value "not_an_integer" is an invalid integer, it's not an integer, it has been loading from fake user data</span>
> - my string: :stop_sign: <span style="color: #C23636">the value "3" is an invalid string, it's not a string, it has been loading from fake user data</span>

View file

@ -0,0 +1,4 @@
🛑 Caution
┗━━ my family1
 ┣━━ my integer: 🛑 the value "not_an_integer" is an invalid integer, it's not an integer, it has been loading from fake user data
 ┗━━ my string: 🛑 the value "3" is an invalid string, it's not a string, it has been loading from fake user data

View file

@ -0,0 +1,15 @@
%YAML 1.2
---
version: 1.1
family1: # my family1
integer:
description: my integer
type: integer
mandatory: false
string:
description: my string
mandatory: false
...

View file

@ -0,0 +1,4 @@
> [!CAUTION]
>
> - cannot load variable path "dynVal3.val", the identifier "Val3" is not valid in fake user data
> - variable or family "dynVal3" does not exist, it has been loading from fake user data

View file

@ -0,0 +1,3 @@
🛑 Caution
┣━━ cannot load variable path "dynVal3.val", the identifier "Val3" is not valid in fake user data
┗━━ variable or family "dynVal3" does not exist, it has been loading from fake user data

View file

@ -0,0 +1,13 @@
%YAML 1.2
---
version: 1.1
dyn{{ identifier }}:
description: A dynamic with {{ identifier }}
dynamic:
- val1
- val2
val:
description: val with {{ identifier }}
...

View file

@ -0,0 +1,4 @@
> [!CAUTION]
>
> - family1
> - this variable is in fact a family: :stop_sign: <span style="color: #C23636">is a family so we cannot set the value "value", it has been loading from fake user data</span>

View file

@ -0,0 +1,3 @@
🛑 Caution
┗━━ family1
 ┗━━ this variable is in fact a family: 🛑 is a family so we cannot set the value "value", it has been loading from fake user data

View file

@ -0,0 +1,6 @@
> [!CAUTION]
>
> - family1
> - this variable is in fact a family: :bell: <span style="color: #EFBF04">is a family so we cannot set the value "value", it will be ignored when loading from fake user data</span>
> - this variable is in fact a family
> - a true variable: :stop_sign: <span style="color: #C23636">mandatory variable but has no value</span>

View file

@ -0,0 +1,5 @@
🛑 Caution
┗━━ family1
 ┣━━ this variable is in fact a family: 🔔 is a family so we cannot set the value "value", it will be ignored when loading from fake user data
 ┗━━ this variable is in fact a family
  ┗━━ a true variable: 🛑 mandatory variable but has no value

View file

@ -0,0 +1,10 @@
%YAML 1.2
---
version: 1.1
family1:
variable: # this variable is in fact a family
true_variable: # a true variable
...

View file

@ -0,0 +1,3 @@
> [!CAUTION]
>
> - variable or family "dyn{{ identifier }}.var" does not exist, it has been loading from fake user data

View file

@ -0,0 +1,2 @@
🛑 Caution
┗━━ variable or family "dyn{{ identifier }}.var" does not exist, it has been loading from fake user data

View file

@ -0,0 +1,6 @@
> [!CAUTION]
>
> - my family1
> - my family2
> - my integer: :stop_sign: <span style="color: #C23636">the value "not_an_integer" is an invalid integer, it's not an integer, it has been loading from fake user data</span>
> - my string: :stop_sign: <span style="color: #C23636">the value "3" is an invalid string, it's not a string, it has been loading from fake user data</span>

View file

@ -0,0 +1,5 @@
🛑 Caution
┗━━ my family1
 ┣━━ my family2
 ┃ ┗━━ my integer: 🛑 the value "not_an_integer" is an invalid integer, it's not an integer, it has been loading from fake user data
 ┗━━ my string: 🛑 the value "3" is an invalid string, it's not a string, it has been loading from fake user data

View file

@ -0,0 +1,14 @@
%YAML 1.2
---
version: 1.1
family1: # my family1
family2: # my family2
integer:
description: my integer
type: integer
string: # my string
...

View file

View file

View file

@ -0,0 +1,8 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,8 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: empty: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,13 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: no)
- :notebook: a second variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,16 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a first variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: no)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: yes)
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: maybe)
- :notebook: a second variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string2)
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string3)

View file

@ -0,0 +1,15 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #A52A2A">Unmodifiable variable</span>
> - <span style="color: #B8860B">Default value</span>
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :open_file_folder: <span style="color: #A52A2A">leadership</span>
- :open_file_folder: <span style="color: #A52A2A">a first variable</span>
- :notebook: <span style="color: #A52A2A">a first variable</span>: <span style="color: #B8860B">a_value</span>
- :notebook: <span style="color: #A52A2A">a first variable</span>: <span style="color: #B8860B">a_value</span>
- :notebook: a second variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: a_value)

View file

@ -0,0 +1,14 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a first variable:
- <span style="color: #006400">domain1.lan</span> ◀ loaded from rougail-test
- <span style="color: #006400">domain2.lan</span> ◀ loaded from rougail-test
- :notebook: a second variable:
- <span style="color: #006400">domain1.lan</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: domain1.lan)
- <span style="color: #006400">domain2.lan</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: domain2.lan)

View file

@ -0,0 +1,10 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: a second variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)

View file

@ -0,0 +1,11 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: a second variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)
- :notebook: a new variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,14 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a first variable:
- <span style="color: #006400">domain1.lan</span> ◀ loaded from rougail-test
- <span style="color: #006400">domain2.lan</span> ◀ loaded from rougail-test
- :notebook: a second variable:
- <span style="color: #006400">domain1.lan</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: domain1.lan)
- <span style="color: #006400">domain2.lan</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: domain2.lan)

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: non)

View file

@ -0,0 +1,14 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">true</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: true)
- :notebook: the second variable: <span style="color: #006400">true</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: true)
- :notebook: the third variable: <span style="color: #006400">true</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: true)
- :notebook: the forth variable: <span style="color: #006400">true</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: false)
- :notebook: the fifth variable: <span style="color: #006400">true</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: false)
- :notebook: the sixth variable: <span style="color: #006400">true</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: false)

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a variable: <span style="color: #006400">true</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: true)

View file

@ -0,0 +1,14 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">a</span> ◀ loaded from rougail-test
- :notebook: the second variable: <span style="color: #006400">a</span> ◀ loaded from rougail-test
- :notebook: the third variable: <span style="color: #006400">a</span> ◀ loaded from rougail-test
- :notebook: the forth variable: <span style="color: #006400">null</span> ◀ loaded from rougail-test
- :notebook: the fifth variable: <span style="color: #006400">a</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: a)
- :notebook: the sixth variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 1)

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a variable: <span style="color: #006400">0</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 9)

View file

@ -0,0 +1,10 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">a</span> ◀ loaded from rougail-test
- :notebook: the second variable: <span style="color: #006400">a</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: a)

View file

@ -0,0 +1,13 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a second variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: a)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: b)
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: c)
- :notebook: a first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: a)

View file

@ -0,0 +1,14 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a second variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: a)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: b)
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: c)
- :notebook: a first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: a)
- :notebook: a third variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)

View file

@ -0,0 +1,15 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a second variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: a)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: b)
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: c)
- :notebook: a first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: a)
- :open_file_folder: family
- :notebook: a third variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)

View file

@ -0,0 +1,10 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: the seconf variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: value)

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a domain name variable: <span style="color: #006400">domain1.lan</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: my.domain.name)

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a domain name variable: <span style="color: #006400">domain1.lan</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: my.domain.name)

View file

@ -0,0 +1,14 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">1.1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 0.0)
- :notebook: the second variable: <span style="color: #006400">1.1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 0.0)
- :notebook: the third variable: <span style="color: #006400">1.1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 0.0)
- :notebook: the forth variable: <span style="color: #006400">1.1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 10.1)
- :notebook: the fifth variable: <span style="color: #006400">1.1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 10.1)
- :notebook: the sixth variable: <span style="color: #006400">1.1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 10.1)

View file

@ -0,0 +1,14 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 0)
- :notebook: the second variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 0)
- :notebook: the third variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 0)
- :notebook: this forth variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 10)
- :notebook: the fifth variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 10)
- :notebook: the sixth variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 10)

View file

@ -0,0 +1,11 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: an IP: <span style="color: #006400">192.168.1.6</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 1.1.1.1)
- :notebook: an IP in CIDR format: <span style="color: #006400">192.168.1.6/24</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 1.1.1.1/24)
- :notebook: an IP in CIDR format with obsolete CIDR type: <span style="color: #006400">192.168.1.6/24</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 1.1.1.1/24)

View file

@ -0,0 +1,11 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: an network: <span style="color: #006400">192.168.1.0</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 1.1.1.0)
- :notebook: an network in CIDR format: <span style="color: #006400">192.168.1.6/32</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 1.1.1.0/24)
- :notebook: an network in CIDR format with obsolete CIDR type: <span style="color: #006400">192.168.1.6/32</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 1.1.1.0/24)

View file

@ -0,0 +1,14 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 0)
- :notebook: the second variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 0)
- :notebook: the third variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 0)
- :notebook: this forth variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 10)
- :notebook: the fifth variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 10)
- :notebook: the sixth variable: <span style="color: #006400">1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 10)

View file

@ -0,0 +1,11 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a port variable: <span style="color: #006400">80</span> ◀ loaded from rougail-test
- :notebook: a port variable with default value: <span style="color: #006400">80</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 8080)
- :notebook: a port variable with integer default value: <span style="color: #006400">80</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 8080)

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a first variable: <span style="color: #006400">#b1b1b1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: #a1a1a1)

View file

@ -0,0 +1,10 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a first variable: <span style="color: #006400">#b1b1b1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: #a1a1a1)
- :notebook: a second variable: <span style="color: #006400">#b2b1b1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: #b1b1b1)

View file

@ -0,0 +1,10 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">onE7vaLues_len1</span> ◀ loaded from rougail-test
- :notebook: the second variable: <span style="color: #006400">onE7vaLues_len1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: value)

View file

@ -0,0 +1,11 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">onE7vaLues_len1</span> ◀ loaded from rougail-test
- :notebook: the second variable: <span style="color: #006400">onE7vaLues</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: value)
- :notebook: the third variable: <span style="color: #006400">onE7vaLues</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: value)

View file

@ -0,0 +1,16 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: the second variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: the third variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: the forth variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: value)
- :notebook: the fifth variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: value)
- :notebook: the sixth variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: value)
- :notebook: the seventh variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 8080)
- :notebook: the height variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: true)

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: A choice: <span style="color: #006400">quote'</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: quote')

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: the first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: the second variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: the first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: the second variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: the first <variable>: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: the second <variable>: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: quote")

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: quote'")

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: quote\"\')

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: quote')

View file

@ -0,0 +1,8 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,16 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first variable: <span style="color: #006400">test</span> ◀ loaded from rougail-test
- :notebook: the second variable: <span style="color: #006400">test</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: value)
- :notebook: the third variable: <span style="color: #006400">test1</span> ◀ loaded from rougail-test
- :notebook: the forth variable: <span style="color: #006400">null</span> ◀ loaded from rougail-test
- :notebook: the fifth variable: <span style="color: #006400">false</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: true)
- :notebook: the sixth variable:
- <span style="color: #006400">test1</span> ◀ loaded from rougail-test
- <span style="color: #006400">test2</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,13 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: a first variable:
- <span style="color: #006400">val1</span> ◀ loaded from rougail-test
- <span style="color: #006400">val2</span> ◀ loaded from rougail-test
- :notebook: a second variable:
- <span style="color: #006400">val1</span> ◀ loaded from rougail-test
- <span style="color: #006400">val2</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,11 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: the first source variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: val1)
- :notebook: the second source variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: val2)
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: val1)

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string_1_True_)

View file

@ -0,0 +1,8 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: a variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: a first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: a second variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,13 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: my_variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: val1)
- :notebook: my_calculated_variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,13 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: my_variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: val1)
- :notebook: my_calculated_variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,13 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: my_variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: val1)
- :notebook: my_calculated_variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: value)
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,11 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: my_calculated_variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,16 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: my_variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: val1)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: val2)
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test
- :notebook: my_calculated_variable:
- <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)
- <span style="color: #006400">string2</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string2)
- <span style="color: #006400">string3</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string3)

View file

@ -0,0 +1,10 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: string1)
- :notebook: a second variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: no)

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: a first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: a second variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
Variables:
- :notebook: a first variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test
- :notebook: a second variable: <span style="color: #006400">string1</span> ◀ loaded from rougail-test

View file

@ -0,0 +1,9 @@
> [!NOTE]
>
> **Caption:**
> - Variable
> - <span style="color: #006400">Modified value</span>
> - (:hourglass_flowing_sand: Original default value)
Variables:
- :notebook: a variable: <span style="color: #006400">0</span> ◀ loaded from rougail-test (:hourglass_flowing_sand: 9)

Some files were not shown because too many files have changed in this diff Show more