feat: exporter to console
This commit is contained in:
parent
a1113ddff2
commit
3283d85829
12 changed files with 208 additions and 377 deletions
|
@ -1,2 +1,2 @@
|
||||||
# rougail-exporter
|
# rougail-output-console
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"POT-Creation-Date: 2024-11-01 11:03+0100\n"
|
"POT-Creation-Date: 2024-11-27 16:46+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -15,43 +15,43 @@ msgstr ""
|
||||||
"Generated-By: pygettext.py 1.5\n"
|
"Generated-By: pygettext.py 1.5\n"
|
||||||
|
|
||||||
|
|
||||||
#: src/rougail/output_exporter/__init__.py:73
|
#: src/rougail/output_console/__init__.py:82
|
||||||
msgid "The following variables are mandatory but have no value:"
|
msgid "The following variables are mandatory but have no value:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/rougail/output_exporter/__init__.py:84
|
#: src/rougail/output_console/__init__.py:93
|
||||||
msgid "The following variables are inaccessible but are empty and mandatory :"
|
msgid "The following variables are inaccessible but are empty and mandatory :"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/rougail/output_exporter/output/console.py:53
|
#: src/rougail/output_console/__init__.py:170
|
||||||
msgid "Undocumented variable"
|
msgid "Undocumented variable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/rougail/output_exporter/output/console.py:54
|
#: src/rougail/output_console/__init__.py:171
|
||||||
msgid "Undocumented but modified variable"
|
msgid "Undocumented but modified variable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/rougail/output_exporter/output/console.py:57
|
#: src/rougail/output_console/__init__.py:174
|
||||||
msgid "Unmodifiable variable"
|
msgid "Unmodifiable variable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/rougail/output_exporter/output/console.py:61
|
#: src/rougail/output_console/__init__.py:178
|
||||||
msgid "Default value"
|
msgid "Default value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/rougail/output_exporter/output/console.py:62
|
#: src/rougail/output_console/__init__.py:179
|
||||||
msgid "Modified value"
|
msgid "Modified value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/rougail/output_exporter/output/console.py:63
|
#: src/rougail/output_console/__init__.py:180
|
||||||
msgid "Original default value"
|
msgid "Original default value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/rougail/output_exporter/output/console.py:67
|
#: src/rougail/output_console/__init__.py:184
|
||||||
msgid "Caption"
|
msgid "Caption"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/rougail/output_exporter/output/console.py:92
|
#: src/rougail/output_console/__init__.py:209
|
||||||
msgid "Variables:"
|
msgid "Variables:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -3,11 +3,11 @@ build-backend = "flit_core.buildapi"
|
||||||
requires = ["flit_core >=3.8.0,<4"]
|
requires = ["flit_core >=3.8.0,<4"]
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "rougail.output_exporter"
|
name = "rougail.output_console"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
description = "Rougail output exporter"
|
description = "Rougail output console"
|
||||||
requires-python = ">=3.8"
|
requires-python = ">=3.8"
|
||||||
license = {file = "LICENSE"}
|
license = {file = "LICENSE"}
|
||||||
classifiers = [
|
classifiers = [
|
||||||
|
@ -30,12 +30,12 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
Home = "https://forge.cloud.silique.fr/stove/rougail-output-exporter"
|
Home = "https://forge.cloud.silique.fr/stove/rougail-output-console"
|
||||||
|
|
||||||
[tool.commitizen]
|
[tool.commitizen]
|
||||||
name = "cz_conventional_commits"
|
name = "cz_conventional_commits"
|
||||||
tag_format = "$version"
|
tag_format = "$version"
|
||||||
version_scheme = "pep440"
|
version_scheme = "pep440"
|
||||||
version_provider = "pep621"
|
version_provider = "pep621"
|
||||||
#update_changelog_on_bump = true
|
update_changelog_on_bump = true
|
||||||
changelog_merge_prerelease = true
|
changelog_merge_prerelease = true
|
||||||
|
|
|
@ -17,19 +17,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Any, List, Optional
|
from typing import Any, List, Optional
|
||||||
|
|
||||||
from rich.tree import Tree
|
from rich.tree import Tree
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
|
|
||||||
from tiramisu import undefined
|
from tiramisu import undefined
|
||||||
from ...i18n import _
|
from tiramisu.error import PropertiesOptionError, ConfigError
|
||||||
|
|
||||||
|
from .i18n import _
|
||||||
|
|
||||||
|
|
||||||
class Formater:
|
class RougailOutputConsole:
|
||||||
name = "console"
|
|
||||||
level = 10
|
|
||||||
variable_hidden_color = "orange1"
|
variable_hidden_color = "orange1"
|
||||||
variable_advanced_color = "bright_blue"
|
variable_advanced_color = "bright_blue"
|
||||||
variable_advanced_and_modified_color = "red1"
|
variable_advanced_and_modified_color = "red1"
|
||||||
|
@ -38,13 +37,131 @@ class Formater:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
rougailconfig: "RougailConfig",
|
config: "Config",
|
||||||
|
rougailconfig: "RougailConfig" = None,
|
||||||
|
user_data_errors: Optional[list] = None,
|
||||||
|
user_data_warnings: Optional[list] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.console = Console(force_terminal=True)
|
if rougailconfig is None:
|
||||||
|
from rougail import RougailConfig
|
||||||
|
|
||||||
|
rougailconfig = RougailConfig
|
||||||
self.rougailconfig = rougailconfig
|
self.rougailconfig = rougailconfig
|
||||||
self.read_write = self.rougailconfig["exporter.read_write"]
|
self.config = config
|
||||||
self.show_secrets = self.rougailconfig["exporter.show_secrets"]
|
self.read_write = self.rougailconfig["console.read_write"]
|
||||||
|
self.is_mandatory = self.rougailconfig["console.mandatory"]
|
||||||
|
self.show_secrets = self.rougailconfig["console.show_secrets"]
|
||||||
|
self.errors = []
|
||||||
|
self.warnings = []
|
||||||
|
if user_data_errors is None:
|
||||||
|
user_data_errors = []
|
||||||
|
self.user_data_errors = user_data_errors
|
||||||
|
if user_data_warnings is None:
|
||||||
|
user_data_warnings = []
|
||||||
|
self.user_data_warnings = user_data_warnings
|
||||||
|
self.console = Console(force_terminal=True)
|
||||||
self.out = []
|
self.out = []
|
||||||
|
self.root = self.get_root()
|
||||||
|
|
||||||
|
def mandatory(self):
|
||||||
|
if not self.is_mandatory:
|
||||||
|
return
|
||||||
|
title = False
|
||||||
|
options_with_error = []
|
||||||
|
try:
|
||||||
|
mandatories = self.config.value.mandatory()
|
||||||
|
except (ConfigError, PropertiesOptionError) as err:
|
||||||
|
self.errors.append(f"Error in config: {err}")
|
||||||
|
return
|
||||||
|
for option in mandatories:
|
||||||
|
try:
|
||||||
|
option.value.get()
|
||||||
|
if not title:
|
||||||
|
# self.errors.append("Les variables suivantes sont obligatoires mais n'ont pas de valeur :")
|
||||||
|
self.errors.append(
|
||||||
|
_("The following variables are mandatory but have no value:")
|
||||||
|
)
|
||||||
|
title = True
|
||||||
|
self.errors.append(f" - {option.description()}")
|
||||||
|
except PropertiesOptionError:
|
||||||
|
options_with_error.append(option)
|
||||||
|
if not title:
|
||||||
|
for idx, option in enumerate(options_with_error):
|
||||||
|
if not idx:
|
||||||
|
# self.errors.append("Les variables suivantes sont inaccessibles mais sont vides et obligatoires :")
|
||||||
|
self.errors.append(
|
||||||
|
_(
|
||||||
|
"The following variables are inaccessible but are empty and mandatory :"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.errors.append(f" - {option.description()}")
|
||||||
|
|
||||||
|
def exporter(self) -> bool:
|
||||||
|
self.config.property.read_write()
|
||||||
|
self.mandatory()
|
||||||
|
if self.read_write:
|
||||||
|
self.config.property.read_write()
|
||||||
|
else:
|
||||||
|
self.config.property.read_only()
|
||||||
|
errors = self.user_data_errors + self.errors
|
||||||
|
if errors:
|
||||||
|
self.display_errors(errors)
|
||||||
|
if self.errors:
|
||||||
|
return False
|
||||||
|
warnings = self.user_data_warnings + self.warnings
|
||||||
|
if warnings:
|
||||||
|
self.display_warnings(warnings)
|
||||||
|
self.header()
|
||||||
|
self.parse_options(
|
||||||
|
self.config,
|
||||||
|
self.root,
|
||||||
|
)
|
||||||
|
self.end()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def run(self) -> None:
|
||||||
|
self.exporter()
|
||||||
|
return self.print()
|
||||||
|
|
||||||
|
def parse_options(
|
||||||
|
self,
|
||||||
|
conf,
|
||||||
|
parent,
|
||||||
|
):
|
||||||
|
for option in conf:
|
||||||
|
if option.isoptiondescription():
|
||||||
|
family = parent.add_family(option)
|
||||||
|
if option.isleadership():
|
||||||
|
self.parse_leadership(
|
||||||
|
option,
|
||||||
|
family,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.parse_options(
|
||||||
|
option,
|
||||||
|
family,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
parent.add_variable(option)
|
||||||
|
|
||||||
|
def parse_leadership(
|
||||||
|
self,
|
||||||
|
conf,
|
||||||
|
parent,
|
||||||
|
):
|
||||||
|
leader, *followers = list(conf)
|
||||||
|
leader_values = leader.value.get()
|
||||||
|
for idx, leader_value in enumerate(leader_values):
|
||||||
|
leader_obj = parent.add_family(leader)
|
||||||
|
leader_obj.add_variable(
|
||||||
|
leader,
|
||||||
|
value=leader_value,
|
||||||
|
leader_index=idx,
|
||||||
|
)
|
||||||
|
for follower in followers:
|
||||||
|
if follower.index() != idx:
|
||||||
|
continue
|
||||||
|
leader_obj.add_variable(follower)
|
||||||
|
|
||||||
def header(self):
|
def header(self):
|
||||||
header_variable = "Variable\n"
|
header_variable = "Variable\n"
|
||||||
|
@ -66,7 +183,7 @@ class Formater:
|
||||||
header.add_row(header_variable, header_value)
|
header.add_row(header_variable, header_value)
|
||||||
self.out.append(Panel.fit(header, title=_("Caption")))
|
self.out.append(Panel.fit(header, title=_("Caption")))
|
||||||
|
|
||||||
def errors(
|
def display_errors(
|
||||||
self,
|
self,
|
||||||
errors,
|
errors,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -78,7 +195,7 @@ class Formater:
|
||||||
tree.add(error)
|
tree.add(error)
|
||||||
self.out.append(tree)
|
self.out.append(tree)
|
||||||
|
|
||||||
def warnings(
|
def display_warnings(
|
||||||
self,
|
self,
|
||||||
warnings: list,
|
warnings: list,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -87,7 +204,7 @@ class Formater:
|
||||||
tree.add(warning)
|
tree.add(warning)
|
||||||
self.out.append(tree)
|
self.out.append(tree)
|
||||||
|
|
||||||
def root(self) -> None:
|
def get_root(self) -> None:
|
||||||
self.output = OutputFamily(
|
self.output = OutputFamily(
|
||||||
_("Variables:"),
|
_("Variables:"),
|
||||||
None,
|
None,
|
||||||
|
@ -129,68 +246,6 @@ class OutputFamily:
|
||||||
)
|
)
|
||||||
self.root = root
|
self.root = root
|
||||||
|
|
||||||
#
|
|
||||||
# def parse_option(self,
|
|
||||||
# option,
|
|
||||||
# value,
|
|
||||||
# variables,
|
|
||||||
# ):
|
|
||||||
# if '.' in line:
|
|
||||||
# # it's a dict
|
|
||||||
# family, variable = line.split('.', 1)
|
|
||||||
# current_path = parent_path
|
|
||||||
# if current_path:
|
|
||||||
# current_path += '.'
|
|
||||||
# current_path += family
|
|
||||||
# if for_doc:
|
|
||||||
# if 'hidden' in self.conf.option(current_path).property.get() or family_hidden:
|
|
||||||
# family_hidden = True
|
|
||||||
# family = f'[orange1]{family}[/orange1]'
|
|
||||||
# elif 'advanced' in self.conf.option(current_path).property.get():
|
|
||||||
# family = f'[bright_blue]{family}[/bright_blue]'
|
|
||||||
# if '.' not in variable and self.conf.option(full_path.rsplit('.', 1)[0]).isleadership():
|
|
||||||
# dico.setdefault(family, [])
|
|
||||||
# leadership = True
|
|
||||||
# else:
|
|
||||||
# dico.setdefault(family, {})
|
|
||||||
# leadership = False
|
|
||||||
# self.parse_option(full_path,
|
|
||||||
# variable,
|
|
||||||
# value,
|
|
||||||
# )
|
|
||||||
# elif leadership:
|
|
||||||
# # it's a leadership
|
|
||||||
# for idx, val in enumerate(value):
|
|
||||||
# dic = {k.rsplit('.', 1)[-1]: v for k, v in val.items()}
|
|
||||||
# if for_doc:
|
|
||||||
# leader = True
|
|
||||||
# for k, v in val.items():
|
|
||||||
# if leader:
|
|
||||||
# is_default = self.conf.option(k).owner.isdefault()
|
|
||||||
# properties = self.conf.option(k).property.get()
|
|
||||||
# else:
|
|
||||||
# is_default = self.conf.option(k, idx).owner.isdefault()
|
|
||||||
# properties = self.conf.option(k, idx).property.get()
|
|
||||||
# if self.conf.option(k).type() == _('password') and not self.args.show_secrets:
|
|
||||||
# v = "*" * 10
|
|
||||||
# subpath = k.rsplit('.', 1)[-1]
|
|
||||||
# if 'hidden' in properties or family_hidden:
|
|
||||||
# subpath = f'[orange1]{subpath}[/orange1]'
|
|
||||||
# elif 'advanced' in properties:
|
|
||||||
# if isdefault:
|
|
||||||
# subpath = f'[bright_blue]{subpath}[/bright_blue]'
|
|
||||||
# else:
|
|
||||||
# subpath = f'[red1]{subpath}[/red1]'
|
|
||||||
# if is_default:
|
|
||||||
# v = '[gold1]' + str(v) + '[/gold1]'
|
|
||||||
# dico.append(f'{subpath}: {v}')
|
|
||||||
# leader = False
|
|
||||||
# else:
|
|
||||||
# dico.append(dic)
|
|
||||||
# else:
|
|
||||||
# # it's a variable
|
|
||||||
# self.parse_variable(option, value)
|
|
||||||
#
|
|
||||||
def add_family(
|
def add_family(
|
||||||
self,
|
self,
|
||||||
option,
|
option,
|
||||||
|
@ -316,3 +371,9 @@ class OutputFamily:
|
||||||
if not self.root.show_secrets and option.type() == "password":
|
if not self.root.show_secrets and option.type() == "password":
|
||||||
return "*" * 10
|
return "*" * 10
|
||||||
return str(value)
|
return str(value)
|
||||||
|
|
||||||
|
|
||||||
|
RougailOutput = RougailOutputConsole
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ("RougailOutputConsole",)
|
56
src/rougail/output_console/config.py
Normal file
56
src/rougail/output_console/config.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
"""
|
||||||
|
Silique (https://www.silique.fr)
|
||||||
|
Copyright (C) 2024
|
||||||
|
|
||||||
|
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 pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def get_rougail_config(
|
||||||
|
*,
|
||||||
|
backward_compatibility=True,
|
||||||
|
) -> dict:
|
||||||
|
options = """
|
||||||
|
console:
|
||||||
|
description: Configuration rougail-console
|
||||||
|
disabled:
|
||||||
|
type: jinja
|
||||||
|
jinja: |
|
||||||
|
{% if step.output != 'console' %}
|
||||||
|
disabled
|
||||||
|
{% endif %}
|
||||||
|
read_write:
|
||||||
|
description: Display variables available in read_write mode
|
||||||
|
negative_description: Display variables available in read_only mode
|
||||||
|
default: false
|
||||||
|
show_secrets:
|
||||||
|
description: Show secrets instead of obscuring them
|
||||||
|
negative_description: Obscuring secrets instead of show them
|
||||||
|
default: false
|
||||||
|
mandatory:
|
||||||
|
description: Test mandatories variable before display in console
|
||||||
|
negative_description: Do not test mandatories variable before display in console
|
||||||
|
default: true
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"name": "console",
|
||||||
|
"process": "output",
|
||||||
|
"options": options,
|
||||||
|
"level": 40,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ("get_rougail_config",)
|
|
@ -19,6 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
from gettext import translation
|
from gettext import translation
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
t = translation("rougail_output_exporter", str(Path(__file__).parent / "locale"), fallback=True)
|
t = translation("rougail_output_console", str(Path(__file__).parent / "locale"), fallback=True)
|
||||||
|
|
||||||
_ = t.gettext
|
_ = t.gettext
|
|
@ -1,164 +0,0 @@
|
||||||
"""
|
|
||||||
Silique (https://www.silique.fr)
|
|
||||||
Copyright (C) 2022-2024
|
|
||||||
|
|
||||||
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 typing import Optional
|
|
||||||
from tiramisu.error import PropertiesOptionError, ConfigError
|
|
||||||
from .config import OutPuts
|
|
||||||
from .i18n import _
|
|
||||||
|
|
||||||
|
|
||||||
class RougailOutputExporter:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config: "Config",
|
|
||||||
rougailconfig: "RougailConfig" = None,
|
|
||||||
user_data_errors: Optional[list] = None,
|
|
||||||
user_data_warnings: Optional[list] = None,
|
|
||||||
) -> None:
|
|
||||||
if rougailconfig is None:
|
|
||||||
from rougail import RougailConfig
|
|
||||||
|
|
||||||
rougailconfig = RougailConfig
|
|
||||||
outputs = OutPuts().get()
|
|
||||||
output = rougailconfig["exporter.output_format"]
|
|
||||||
if output not in outputs:
|
|
||||||
raise Exception(
|
|
||||||
f'cannot find output "{output}", available outputs: {list(outputs)}'
|
|
||||||
)
|
|
||||||
self.rougailconfig = rougailconfig
|
|
||||||
self.config = config
|
|
||||||
self.read_write = self.rougailconfig["exporter.read_write"]
|
|
||||||
self.errors = []
|
|
||||||
self.warnings = []
|
|
||||||
if user_data_errors is None:
|
|
||||||
user_data_errors = []
|
|
||||||
self.user_data_errors = user_data_errors
|
|
||||||
if user_data_warnings is None:
|
|
||||||
user_data_warnings = []
|
|
||||||
self.user_data_warnings = user_data_warnings
|
|
||||||
self.formater = outputs[output](self.rougailconfig)
|
|
||||||
self.root = self.formater.root()
|
|
||||||
|
|
||||||
def mandatory(self):
|
|
||||||
if not self.rougailconfig["exporter.mandatory"]:
|
|
||||||
return
|
|
||||||
title = False
|
|
||||||
options_with_error = []
|
|
||||||
try:
|
|
||||||
mandatories = self.config.value.mandatory()
|
|
||||||
except (ConfigError, PropertiesOptionError) as err:
|
|
||||||
self.errors.append(f"Error in config: {err}")
|
|
||||||
return
|
|
||||||
for option in mandatories:
|
|
||||||
try:
|
|
||||||
option.value.get()
|
|
||||||
if not title:
|
|
||||||
# self.errors.append("Les variables suivantes sont obligatoires mais n'ont pas de valeur :")
|
|
||||||
self.errors.append(
|
|
||||||
_("The following variables are mandatory but have no value:")
|
|
||||||
)
|
|
||||||
title = True
|
|
||||||
self.errors.append(f" - {option.description()}")
|
|
||||||
except PropertiesOptionError:
|
|
||||||
options_with_error.append(option)
|
|
||||||
if not title:
|
|
||||||
for idx, option in enumerate(options_with_error):
|
|
||||||
if not idx:
|
|
||||||
# self.errors.append("Les variables suivantes sont inaccessibles mais sont vides et obligatoires :")
|
|
||||||
self.errors.append(
|
|
||||||
_(
|
|
||||||
"The following variables are inaccessible but are empty and mandatory :"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.errors.append(f" - {option.description()}")
|
|
||||||
|
|
||||||
def exporter(self) -> bool:
|
|
||||||
self.config.property.read_write()
|
|
||||||
self.mandatory()
|
|
||||||
if self.read_write:
|
|
||||||
self.config.property.read_write()
|
|
||||||
else:
|
|
||||||
self.config.property.read_only()
|
|
||||||
errors = self.user_data_errors + self.errors
|
|
||||||
if errors:
|
|
||||||
self.formater.errors(errors)
|
|
||||||
if self.errors:
|
|
||||||
return False
|
|
||||||
warnings = self.user_data_warnings + self.warnings
|
|
||||||
if warnings:
|
|
||||||
self.formater.warnings(warnings)
|
|
||||||
self.formater.header()
|
|
||||||
self.parse_options(
|
|
||||||
self.config,
|
|
||||||
self.root,
|
|
||||||
)
|
|
||||||
self.formater.end()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def print(self) -> None:
|
|
||||||
return self.formater.print()
|
|
||||||
|
|
||||||
def run(self) -> None:
|
|
||||||
self.exporter()
|
|
||||||
return self.print()
|
|
||||||
|
|
||||||
def parse_options(
|
|
||||||
self,
|
|
||||||
conf,
|
|
||||||
parent,
|
|
||||||
):
|
|
||||||
for option in conf:
|
|
||||||
if option.isoptiondescription():
|
|
||||||
family = parent.add_family(option)
|
|
||||||
if option.isleadership():
|
|
||||||
self.parse_leadership(
|
|
||||||
option,
|
|
||||||
family,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.parse_options(
|
|
||||||
option,
|
|
||||||
family,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
parent.add_variable(option)
|
|
||||||
|
|
||||||
def parse_leadership(
|
|
||||||
self,
|
|
||||||
conf,
|
|
||||||
parent,
|
|
||||||
):
|
|
||||||
leader, *followers = list(conf)
|
|
||||||
leader_values = leader.value.get()
|
|
||||||
for idx, leader_value in enumerate(leader_values):
|
|
||||||
leader_obj = parent.add_family(leader)
|
|
||||||
leader_obj.add_variable(
|
|
||||||
leader,
|
|
||||||
value=leader_value,
|
|
||||||
leader_index=idx,
|
|
||||||
)
|
|
||||||
for follower in followers:
|
|
||||||
if follower.index() != idx:
|
|
||||||
continue
|
|
||||||
leader_obj.add_variable(follower)
|
|
||||||
|
|
||||||
|
|
||||||
RougailOutput = RougailOutputExporter
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ("RougailOutputExporter",)
|
|
|
@ -1,108 +0,0 @@
|
||||||
"""
|
|
||||||
Config file for Rougail-exporter
|
|
||||||
|
|
||||||
Silique (https://www.silique.fr)
|
|
||||||
Copyright (C) 2024
|
|
||||||
|
|
||||||
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 pathlib import Path
|
|
||||||
from rougail.utils import load_modules
|
|
||||||
|
|
||||||
|
|
||||||
OUTPUTS = None
|
|
||||||
|
|
||||||
|
|
||||||
def get_outputs() -> None:
|
|
||||||
module_name = "rougail.output_exporter.output"
|
|
||||||
outputs = {}
|
|
||||||
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, str(path))
|
|
||||||
if "Formater" not in dir(module):
|
|
||||||
continue
|
|
||||||
level = module.Formater.level
|
|
||||||
if level in outputs:
|
|
||||||
raise Exception(
|
|
||||||
f'duplicated level rougail-exporter for output "{level}": {module.Formater.name} and {outputs[level].name}'
|
|
||||||
)
|
|
||||||
outputs[module.Formater.level] = module.Formater
|
|
||||||
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:
|
|
||||||
return OUTPUTS
|
|
||||||
|
|
||||||
|
|
||||||
def get_rougail_config(
|
|
||||||
*,
|
|
||||||
backward_compatibility=True,
|
|
||||||
) -> dict:
|
|
||||||
outputs = tuple(OutPuts().get())
|
|
||||||
options = """
|
|
||||||
exporter:
|
|
||||||
description: Configuration rougail-exporter
|
|
||||||
disabled:
|
|
||||||
type: jinja
|
|
||||||
jinja: |
|
|
||||||
{% if step.output != 'exporter' %}
|
|
||||||
disabled
|
|
||||||
{% endif %}
|
|
||||||
read_write:
|
|
||||||
description: Display variables available in read_write mode
|
|
||||||
negative_description: Display variables available in read_only mode
|
|
||||||
alternative_name: er
|
|
||||||
default: false
|
|
||||||
show_secrets:
|
|
||||||
description: Show secrets instead of obscuring them
|
|
||||||
negative_description: Obscuring secrets instead of show them
|
|
||||||
alternative_name: es
|
|
||||||
default: false
|
|
||||||
mandatory:
|
|
||||||
description: Test mandatories variable before export
|
|
||||||
negative_description: Do not test mandatories variable before export
|
|
||||||
alternative_name: em
|
|
||||||
default: true
|
|
||||||
output_format:
|
|
||||||
description: Generate document in format
|
|
||||||
alternative_name: eo
|
|
||||||
default: DEFAULT
|
|
||||||
choices:
|
|
||||||
""".replace(
|
|
||||||
"DEFAULT", outputs[0]
|
|
||||||
)
|
|
||||||
for output in outputs:
|
|
||||||
options += f" - {output}\n"
|
|
||||||
return {
|
|
||||||
"name": "exporter",
|
|
||||||
"process": "output",
|
|
||||||
"options": options,
|
|
||||||
"level": 40,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ("OutPuts", "get_rougail_config")
|
|
Binary file not shown.
|
@ -1,14 +0,0 @@
|
||||||
"""
|
|
||||||
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/>.
|
|
||||||
"""
|
|
Loading…
Reference in a new issue