WIP: Expand the developer documentation #27
4 changed files with 127 additions and 77 deletions
|
|
@ -78,7 +78,7 @@ class SpaceAnnotator: # pylint: disable=R0903
|
||||||
)
|
)
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
pass
|
pass
|
||||||
for user_data in objectspace.user_datas:
|
for user_data in objectspace.user_data:
|
||||||
try:
|
try:
|
||||||
get_annotators(
|
get_annotators(
|
||||||
ANNOTATORS, f"rougail.user_data_{user_data}", "annotator"
|
ANNOTATORS, f"rougail.user_data_{user_data}", "annotator"
|
||||||
|
|
@ -97,7 +97,7 @@ class SpaceAnnotator: # pylint: disable=R0903
|
||||||
annotators.extend(ANNOTATORS[extra_annotator])
|
annotators.extend(ANNOTATORS[extra_annotator])
|
||||||
for structural in objectspace.structurals:
|
for structural in objectspace.structurals:
|
||||||
annotators.extend(ANNOTATORS[f"rougail.structural_{structural}.annotator"])
|
annotators.extend(ANNOTATORS[f"rougail.structural_{structural}.annotator"])
|
||||||
for user_data in objectspace.user_datas:
|
for user_data in objectspace.user_data:
|
||||||
annotators.extend(ANNOTATORS[f"rougail.user_data_{user_data}.annotator"])
|
annotators.extend(ANNOTATORS[f"rougail.user_data_{user_data}.annotator"])
|
||||||
if objectspace.output:
|
if objectspace.output:
|
||||||
annotators.extend(
|
annotators.extend(
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ from warnings import warn
|
||||||
|
|
||||||
from .convert import RougailConvert
|
from .convert import RougailConvert
|
||||||
from ..config import RougailConfig
|
from ..config import RougailConfig
|
||||||
from ..user_datas import UserDatas
|
from ..user_data import UserData
|
||||||
from ..tiramisu import tiramisu_display_name
|
from ..tiramisu import tiramisu_display_name
|
||||||
|
|
||||||
|
|
||||||
class Rougail(UserDatas):
|
class Rougail(UserData):
|
||||||
"""Main Rougail object"""
|
"""Main Rougail object"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
|
||||||
|
|
@ -180,9 +180,9 @@ class ParserVariable:
|
||||||
]
|
]
|
||||||
self.structurals = rougailconfig["step.structural"]
|
self.structurals = rougailconfig["step.structural"]
|
||||||
try:
|
try:
|
||||||
self.user_datas = rougailconfig["step.user_data"]
|
self.user_data = rougailconfig["step.user_data"]
|
||||||
except:
|
except:
|
||||||
self.user_datas = []
|
self.user_data = []
|
||||||
try:
|
try:
|
||||||
self.output = rougailconfig["step.output"]
|
self.output = rougailconfig["step.output"]
|
||||||
except:
|
except:
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from tiramisu import Calculation, owners
|
from tiramisu import Calculation, Params, ParamValue, owners
|
||||||
from tiramisu.error import (
|
from tiramisu.error import (
|
||||||
PropertiesOptionError,
|
PropertiesOptionError,
|
||||||
AttributeOptionError,
|
AttributeOptionError,
|
||||||
|
|
@ -41,30 +41,31 @@ from .error import DictConsistencyError
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
|
||||||
|
|
||||||
class UserDatas:
|
class UserData:
|
||||||
def __init__(self, config) -> None:
|
def __init__(self, config) -> None:
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
def user_datas(
|
def user_data(
|
||||||
self,
|
self,
|
||||||
user_datas: List[dict],
|
user_data: List[dict],
|
||||||
*,
|
*,
|
||||||
invalid_user_datas_error: bool = False,
|
invalid_user_data_error: bool = False,
|
||||||
unknown_user_datas_error: bool = False,
|
unknown_user_data_error: bool = False,
|
||||||
):
|
):
|
||||||
self.values = {}
|
self.values = {}
|
||||||
self.errors = []
|
self.errors = []
|
||||||
self.warnings = []
|
self.warnings = []
|
||||||
if invalid_user_datas_error:
|
self.invalid_user_data_error = invalid_user_data_error
|
||||||
|
if self.invalid_user_data_error:
|
||||||
self.invalids = self.errors
|
self.invalids = self.errors
|
||||||
else:
|
else:
|
||||||
self.invalids = self.warnings
|
self.invalids = self.warnings
|
||||||
if unknown_user_datas_error:
|
if unknown_user_data_error:
|
||||||
self.unknowns = self.errors
|
self.unknowns = self.errors
|
||||||
else:
|
else:
|
||||||
self.unknowns = self.warnings
|
self.unknowns = self.warnings
|
||||||
self.show_secrets = False
|
self.show_secrets = False
|
||||||
self._populate_values(user_datas)
|
self._populate_values(user_data)
|
||||||
self._auto_configure_dynamics()
|
self._auto_configure_dynamics()
|
||||||
self._populate_config()
|
self._populate_config()
|
||||||
self.properties_to_string = get_properties_to_string()
|
self.properties_to_string = get_properties_to_string()
|
||||||
|
|
@ -74,8 +75,8 @@ class UserDatas:
|
||||||
"warnings": self.warnings,
|
"warnings": self.warnings,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _populate_values(self, user_datas):
|
def _populate_values(self, user_data):
|
||||||
for datas in user_datas:
|
for datas in user_data:
|
||||||
options = datas.get("options", {})
|
options = datas.get("options", {})
|
||||||
source = datas["source"]
|
source = datas["source"]
|
||||||
for name, data in datas.get("values", {}).items():
|
for name, data in datas.get("values", {}).items():
|
||||||
|
|
@ -225,10 +226,10 @@ class UserDatas:
|
||||||
options.get("allow_secrets_variables", True) is False
|
options.get("allow_secrets_variables", True) is False
|
||||||
and option.type() == "password"
|
and option.type() == "password"
|
||||||
):
|
):
|
||||||
self.errors.append(
|
self.errors.append({
|
||||||
_(
|
_(
|
||||||
'the variable "{0}" contains secrets and should not be defined in {1}'
|
'the variable contains secrets and should not be defined in {0}'
|
||||||
).format(path, self.values[values_path]["source"])
|
).format(self.values[values_path]["source"]): option._subconfig}
|
||||||
)
|
)
|
||||||
self.values.pop(path)
|
self.values.pop(path)
|
||||||
continue
|
continue
|
||||||
|
|
@ -257,7 +258,6 @@ class UserDatas:
|
||||||
option.value.pop(idx)
|
option.value.pop(idx)
|
||||||
try:
|
try:
|
||||||
self.set_value(option, value, options)
|
self.set_value(option, value, options)
|
||||||
# option.value.set(value)
|
|
||||||
value_is_set = True
|
value_is_set = True
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
if path != option.path():
|
if path != option.path():
|
||||||
|
|
@ -297,8 +297,8 @@ class UserDatas:
|
||||||
def _populate_error_warnings(self):
|
def _populate_error_warnings(self):
|
||||||
# we don't find variable, apply value just to get error or warning messages
|
# we don't find variable, apply value just to get error or warning messages
|
||||||
for path, options in self.values.items():
|
for path, options in self.values.items():
|
||||||
if "{{ identifier }}" in path:
|
# if "{{ identifier }}" in path:
|
||||||
continue
|
# continue
|
||||||
value = options["values"]
|
value = options["values"]
|
||||||
if options.get("secret_manager"):
|
if options.get("secret_manager"):
|
||||||
option = self.config.forcepermissive.option(path)
|
option = self.config.forcepermissive.option(path)
|
||||||
|
|
@ -307,32 +307,47 @@ class UserDatas:
|
||||||
try:
|
try:
|
||||||
if option.isoptiondescription():
|
if option.isoptiondescription():
|
||||||
if value:
|
if value:
|
||||||
self.invalids.append(
|
if self.invalid_user_data_error:
|
||||||
_(
|
msg = _(
|
||||||
'cannot set the value "{0}" to the family {1}, it will be ignored when loading from {2}'
|
'is a family so we cannot set the value "{0}", it has been loading from {1}'
|
||||||
).format(
|
|
||||||
self._display_value(option, value),
|
|
||||||
option.description(with_quote=True),
|
|
||||||
options["source"],
|
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
msg = _(
|
||||||
|
'is a family so we cannot set the value "{0}", it will be ignored when loading from {1}'
|
||||||
|
)
|
||||||
|
self.invalids.append({msg.format(
|
||||||
|
self._display_value(option, value),
|
||||||
|
options["source"],
|
||||||
|
): option._subconfig}
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
except PropertiesOptionError as err:
|
except (ConfigError, PropertiesOptionError) as err:
|
||||||
self.unknowns.append(
|
self.unknowns.append({
|
||||||
_("{0} loaded from {1}").format(err, options["source"])
|
_("{0}, it has been loaded from {1}").format(err, options["source"]): option._subconfig}
|
||||||
)
|
)
|
||||||
|
continue
|
||||||
except AttributeOptionError as err:
|
except AttributeOptionError as err:
|
||||||
if err.code == "option-not-found":
|
if err.code == "option-not-found":
|
||||||
self.unknowns.append(
|
if self.invalid_user_data_error:
|
||||||
_(
|
msg = _(
|
||||||
'variable or family "{0}" does not exist, it will be ignored when loading from {1}'
|
'variable or family "{0}" does not exist, it has been loading from {1}'
|
||||||
).format(err.path, options["source"])
|
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
msg = _(
|
||||||
|
'variable or family "{0}" does not exist, it will be ignored when loading from {1}'
|
||||||
|
)
|
||||||
|
self.unknowns.append(msg.format(err.path, options["source"]))
|
||||||
elif err.code == "option-dynamic":
|
elif err.code == "option-dynamic":
|
||||||
self.invalids.append(
|
if self.invalid_user_data_error:
|
||||||
_(
|
msg = _(
|
||||||
|
'"{0}" is the name of a dynamic family, it has been loading from {1}'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
msg = _(
|
||||||
'"{0}" is the name of a dynamic family, it will be ignored when loading from {1}'
|
'"{0}" is the name of a dynamic family, it will be ignored when loading from {1}'
|
||||||
).format(option.description(with_quote=True), options["source"])
|
)
|
||||||
|
self.invalids.append(
|
||||||
|
{msg.format(option.description(with_quote=True), options["source"]): option._subconfig}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.invalids.append(
|
self.invalids.append(
|
||||||
|
|
@ -361,86 +376,122 @@ class UserDatas:
|
||||||
properties = display_list(
|
properties = display_list(
|
||||||
[_(prop) for prop in err.proptype], add_quote=False
|
[_(prop) for prop in err.proptype], add_quote=False
|
||||||
)
|
)
|
||||||
err_path = err._subconfig.path
|
err_path = err.subconfig.path
|
||||||
|
err_description = err.subconfig.option.impl_get_display_name(err.subconfig)
|
||||||
display_name = option.description(with_quote=True)
|
display_name = option.description(with_quote=True)
|
||||||
if index is not None:
|
if index is not None:
|
||||||
if path == err_path:
|
if path == err_path:
|
||||||
self.unknowns.append(
|
if self.invalid_user_data_error:
|
||||||
_(
|
msg = _(
|
||||||
'variable {0} at index "{1}" is {2}, it will be ignored when loading from {3}'
|
'variable {0} at index "{1}" is {2}, it has been loading from {3}'
|
||||||
).format(
|
|
||||||
display_name,
|
|
||||||
index,
|
|
||||||
properties,
|
|
||||||
options["source"],
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.unknowns.append(
|
msg = _(
|
||||||
_(
|
'variable {0} at index "{1}" is {2}, it will be ignored when loading from {3}'
|
||||||
'family {0} is {1}, {2} at index "{3}" will be ignored when loading from {4}'
|
)
|
||||||
).format(
|
self.unknowns.append({
|
||||||
err._name,
|
msg.format(
|
||||||
|
display_name,
|
||||||
|
index,
|
||||||
|
properties,
|
||||||
|
options["source"],
|
||||||
|
): option._subconfig}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if self.invalid_user_data_error:
|
||||||
|
msg = _(
|
||||||
|
'family {0} is {1}, {2} at index "{3}", it has been loading from {4}'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
msg = _(
|
||||||
|
'family {0} is {1}, {2} at index "{3}", it will be ignored when loading from {4}'
|
||||||
|
)
|
||||||
|
self.unknowns.append({
|
||||||
|
msg.format(
|
||||||
|
err_description,
|
||||||
properties,
|
properties,
|
||||||
display_name,
|
display_name,
|
||||||
index,
|
index,
|
||||||
options["source"],
|
options["source"],
|
||||||
)
|
): option._subconfig}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if path == err_path:
|
if path == err_path:
|
||||||
self.unknowns.append(
|
if self.invalid_user_data_error:
|
||||||
_(
|
msg = _(
|
||||||
"variable {0} is {1}, it will be ignored when loading from {2}"
|
"variable is {0}, it has been loading from {1}"
|
||||||
).format(
|
|
||||||
display_name, properties, options["source"]
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.unknowns.append(
|
msg = _(
|
||||||
_(
|
"variable is {0}, it will be ignored when loading from {1}"
|
||||||
"family {0} is {1}, {2} will be ignored when loading from {3}"
|
)
|
||||||
).format(
|
self.unknowns.append({
|
||||||
err._name,
|
msg.format(
|
||||||
|
properties, options["source"]
|
||||||
|
): option._subconfig}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if self.invalid_user_data_error:
|
||||||
|
msg = _(
|
||||||
|
"family {0} is {1}, so cannot access to {2}, it has been loading from {3}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
msg = _(
|
||||||
|
"family {0} is {1}, so cannot access to {2}, it will be ignored when loading from {3}"
|
||||||
|
)
|
||||||
|
self.unknowns.append({
|
||||||
|
msg.format(
|
||||||
|
err_description,
|
||||||
properties,
|
properties,
|
||||||
display_name,
|
display_name,
|
||||||
options["source"],
|
options["source"],
|
||||||
)
|
): option._subconfig}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.unknowns.append(
|
self.unknowns.append({
|
||||||
_("{0} in {1}").format(err, options["source"])
|
_("{0} in {1}").format(err, options["source"]): option._subconfig}
|
||||||
)
|
)
|
||||||
except LeadershipError as err:
|
except LeadershipError as err:
|
||||||
self.unknowns.append(_("{0} in {1}").format(err, options["source"]))
|
self.unknowns.append({_("{0} in {1}").format(err, options["source"]): option._subconfig})
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
err.prefix = ""
|
err.prefix = ""
|
||||||
if index is not None:
|
if index is not None:
|
||||||
type_ = option.type(translation=True)
|
type_ = option.type(translation=True)
|
||||||
self.invalids.append(
|
if self.invalid_user_data_error:
|
||||||
_(
|
msg = _(
|
||||||
|
'the value "{0}" is an invalid {1} for {2} at index "{3}", {4}, it has been loading from {5}'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
msg = _(
|
||||||
'the value "{0}" is an invalid {1} for {2} at index "{3}", {4}, it will be ignored when loading from {5}'
|
'the value "{0}" is an invalid {1} for {2} at index "{3}", {4}, it will be ignored when loading from {5}'
|
||||||
).format(
|
)
|
||||||
|
self.invalids.append({
|
||||||
|
msg.format(
|
||||||
self._display_value(option, value),
|
self._display_value(option, value),
|
||||||
type_,
|
type_,
|
||||||
option.description(with_quote=True),
|
option.description(with_quote=True),
|
||||||
index,
|
index,
|
||||||
err,
|
err,
|
||||||
options["source"],
|
options["source"],
|
||||||
)
|
): option._subconfig}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
type_ = option.type(translation=True)
|
type_ = option.type(translation=True)
|
||||||
self.invalids.append(
|
if self.invalid_user_data_error:
|
||||||
_(
|
msg = _(
|
||||||
'the value "{0}" is an invalid {1} for {2}, {3}, it will be ignored when loading from {4}'
|
'the value "{0}" is an invalid {1}, {2}, it has been loading from {3}'
|
||||||
).format(
|
)
|
||||||
|
else:
|
||||||
|
msg = _(
|
||||||
|
'the value "{0}" is an invalid {1}, {2}, it will be ignored when loading from {3}'
|
||||||
|
)
|
||||||
|
self.invalids.append({
|
||||||
|
msg.format(
|
||||||
self._display_value(option, value),
|
self._display_value(option, value),
|
||||||
type_,
|
type_,
|
||||||
option.description(with_quote=True),
|
|
||||||
err,
|
err,
|
||||||
options["source"],
|
options["source"],
|
||||||
)
|
): option._subconfig}
|
||||||
)
|
)
|
||||||
except AttributeOptionError as err:
|
except AttributeOptionError as err:
|
||||||
if err.code == "option-dynamic":
|
if err.code == "option-dynamic":
|
||||||
|
|
@ -451,9 +502,8 @@ class UserDatas:
|
||||||
is_secret_manager = options.get("secret_manager", False)
|
is_secret_manager = options.get("secret_manager", False)
|
||||||
if is_secret_manager and isinstance(value, tuple):
|
if is_secret_manager and isinstance(value, tuple):
|
||||||
# it's a function
|
# it's a function
|
||||||
value = value[0](
|
params = tuple([ParamValue(val) for val in value[1:]])
|
||||||
*value[1:], option=option, warnings=self.warnings, errors=self.errors
|
value = Calculation(value[0], Params(params, kwargs={"option": ParamValue(option)}))
|
||||||
)
|
|
||||||
option.value.set(value)
|
option.value.set(value)
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in a new issue