Compare commits

..

No commits in common. "bc27a98229140546d3ddfdb79345f8dc11755c79" and "ae696e17389dbebde3e6497266b4775154f6ecd6" have entirely different histories.

16 changed files with 20 additions and 134 deletions

View file

@ -1,10 +1,3 @@
## 1.2.0a54 (2026-01-14)
### Fix
- issymlinkoption is not available for an optiondescription
- better error messages
## 1.2.0a53 (2026-01-05) ## 1.2.0a53 (2026-01-05)
### Fix ### Fix

View file

@ -1,6 +1,6 @@
[project] [project]
name = "rougail" name = "rougail"
version = "1.2.0a54" version = "1.2.0a53"
[tool.commitizen] [tool.commitizen]
name = "cz_conventional_commits" name = "cz_conventional_commits"

View file

@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
[project] [project]
name = "rougail-base" name = "rougail-base"
version = "1.2.0a54" version = "1.2.0a53"
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}] authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
readme = "README.md" readme = "README.md"
description = "A consistency handling system that was initially designed in the configuration management" description = "A consistency handling system that was initially designed in the configuration management"

View file

@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
[project] [project]
name = "rougail" name = "rougail"
version = "1.2.0a54" version = "1.2.0a53"
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}] authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
description = "A consistency handling system that was initially designed in the configuration management" description = "A consistency handling system that was initially designed in the configuration management"
classifiers = [ classifiers = [
@ -18,7 +18,7 @@ classifiers = [
dependencies = [ dependencies = [
"ruamel.yaml ~= 0.18.6", "ruamel.yaml ~= 0.18.6",
"pydantic ~= 2.9.2", "pydantic ~= 2.9.2",
"rougail-base == 1.2.0a54", "rougail-base == 1.2.0a53",
] ]
[tool.flit.sdist] [tool.flit.sdist]

View file

@ -1 +1 @@
__version__ = "1.2.0a54" __version__ = "1.2.0a53"

View file

@ -56,12 +56,11 @@ class UserData:
self.errors = [] self.errors = []
self.warnings = [] self.warnings = []
self.invalid_user_data_error = invalid_user_data_error self.invalid_user_data_error = invalid_user_data_error
self.unknown_user_data_error = unknown_user_data_error
if self.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 self.unknown_user_data_error: if unknown_user_data_error:
self.unknowns = self.errors self.unknowns = self.errors
else: else:
self.unknowns = self.warnings self.unknowns = self.warnings
@ -300,14 +299,7 @@ class UserData:
def _display_value(self, option, value): def _display_value(self, option, value):
if not self.show_secrets and option.type() == "password": if not self.show_secrets and option.type() == "password":
if not isinstance(value, list): return "*" * 10
value = "*" * 10
else:
value = ["*" * 10 for val in value]
if isinstance(value, list):
value = display_list(value, add_quote=True)
else:
value = '"' + str(value) + '"'
return value return value
def _populate_error_warnings(self): def _populate_error_warnings(self):
@ -323,11 +315,11 @@ class UserData:
if value: if value:
if self.invalid_user_data_error: if self.invalid_user_data_error:
msg = _( msg = _(
'it\'s a family so we cannot set the value {0}, it has been loading from {1}' 'is a family so we cannot set the value "{0}", it has been loading from {1}'
) )
else: else:
msg = _( msg = _(
'it\'s a family so we cannot set the value {0}, it will be ignored when loading from {1}' 'is a family so we cannot set the value "{0}", it will be ignored when loading from {1}'
) )
self.invalids.append({msg.format( self.invalids.append({msg.format(
self._display_value(option, value), self._display_value(option, value),
@ -335,14 +327,6 @@ class UserData:
): option._subconfig} ): option._subconfig}
) )
continue continue
if option.issymlinkoption():
err = _('it\'s a symlink option so we cannot set the value {0}').format(self._display_value(option, value))
if self.invalid_user_data_error:
msg = _('{0}, it has been loading from {1}').format(err, options["source"])
else:
msg = _('{0}, it will be ignored when loading from {1}').format(err, options["source"])
self.unknowns.append({msg: option._subconfig})
continue
except ConfigError as err: except ConfigError as err:
self.invalids.append({ self.invalids.append({
_("{0}, it has been loaded from {1}").format(err, options["source"]): option._subconfig} _("{0}, it has been loaded from {1}").format(err, options["source"]): option._subconfig}
@ -355,7 +339,7 @@ class UserData:
continue continue
except AttributeOptionError as err: except AttributeOptionError as err:
if err.code == "option-not-found": if err.code == "option-not-found":
if self.unknown_user_data_error: if self.invalid_user_data_error:
msg = _( msg = _(
'variable or family "{0}" does not exist, it has been loading from {1}' 'variable or family "{0}" does not exist, it has been loading from {1}'
) )
@ -408,7 +392,7 @@ class UserData:
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:
if self.unknown_user_data_error: if self.invalid_user_data_error:
msg = _( msg = _(
'variable {0} at index "{1}" is {2}, it has been loading from {3}' 'variable {0} at index "{1}" is {2}, it has been loading from {3}'
) )
@ -425,7 +409,7 @@ class UserData:
): option._subconfig} ): option._subconfig}
) )
else: else:
if self.unknown_user_data_error: if self.invalid_user_data_error:
msg = _( msg = _(
'family {0} is {1}, {2} at index "{3}", it has been loading from {4}' 'family {0} is {1}, {2} at index "{3}", it has been loading from {4}'
) )
@ -444,7 +428,7 @@ class UserData:
) )
else: else:
if path == err_path: if path == err_path:
if self.unknown_user_data_error: if self.invalid_user_data_error:
msg = _( msg = _(
"variable has propery {0}, it has been loading from {1}" "variable has propery {0}, it has been loading from {1}"
) )
@ -458,7 +442,7 @@ class UserData:
): option._subconfig} ): option._subconfig}
) )
else: else:
if self.unknown_user_data_error: if self.invalid_user_data_error:
msg = _( msg = _(
"family {0} has property {1}, so cannot access to {2}, it has been loading from {3}" "family {0} has property {1}, so cannot access to {2}, it has been loading from {3}"
) )
@ -475,29 +459,11 @@ class UserData:
): option._subconfig} ): option._subconfig}
) )
else: else:
if self.unknown_user_data_error:
msg = _(
"{0}, it has been loading from {1}"
)
else:
msg = _(
"{0}, it will be ignored when loading from {1}"
)
self.unknowns.append({ self.unknowns.append({
msg.format(err, options["source"]): option._subconfig} _("{0} in {1}").format(err, options["source"]): option._subconfig}
) )
except LeadershipError as err: except LeadershipError as err:
if self.unknown_user_data_error: self.unknowns.append({_("{0} in {1}").format(err, options["source"]): option._subconfig})
msg = _(
"{0}, it has been loading from {1}"
)
else:
msg = _(
"{0}, it will be ignored when loading from {1}"
)
self.unknowns.append({
msg.format(err, options["source"]): option._subconfig}
)
except ConfigError as err: except ConfigError as err:
err.prefix = "" err.prefix = ""
if self.invalid_user_data_error: if self.invalid_user_data_error:
@ -508,7 +474,7 @@ class UserData:
except ValueError as err: except ValueError as err:
err.prefix = "" err.prefix = ""
type_ = option.type(translation=True) type_ = option.type(translation=True)
msg = _('the value {0} is an invalid {1}, {2}').format( msg = _('the value "{0}" is an invalid {1}, {2}').format(
self._display_value(option, value), self._display_value(option, value),
type_, type_,
err, err,

View file

@ -1,10 +0,0 @@
{
"rougail.family1.var": {
"owner": "default",
"value": null
},
"rougail.family2.var": {
"owner": "default",
"value": null
}
}

View file

@ -1,4 +0,0 @@
{
"rougail.family1.var": null,
"rougail.family2.var": null
}

View file

@ -1,10 +0,0 @@
{
"rougail.family1.var": {
"owner": "default",
"value": null
},
"rougail.family2.var": {
"owner": "default",
"value": null
}
}

View file

@ -1 +0,0 @@
["rougail.family1.var", "rougail.family2.var"]

View file

@ -1,4 +0,0 @@
{
"rougail.family1.var": null,
"rougail.family2.var": null
}

View file

@ -1,18 +0,0 @@
from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('../rougail-tests/funcs/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_3 = StrOption(name="var", doc="var", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/20_7help_family/rougail/00-base.yml'], 'type': 'string'})
optiondescription_2 = OptionDescription(name="family1", doc="the first family", children=[option_3], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/20_7help_family/rougail/00-base.yml'], 'help': 'Multi line\n\nHelp\n\nWith useful information'})
option_5 = StrOption(name="var", doc="var", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/20_7help_family/rougail/00-base.yml'], 'type': 'string'})
optiondescription_4 = OptionDescription(name="family2", doc="the second family", children=[option_5], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/20_7help_family/rougail/00-base.yml'], 'help': 'Multi line\nHelp\nWith useful information'})
optiondescription_1 = OptionDescription(name="rougail", doc="Rougail", group_type=groups.namespace, children=[optiondescription_2, optiondescription_4], properties=frozenset({"basic"}))
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1])

View file

@ -1,17 +0,0 @@
from tiramisu import *
from tiramisu.setting import ALLOWED_LEADER_PROPERTIES
from re import compile as re_compile
from rougail.tiramisu import func, dict_env, load_functions, ConvertDynOptionDescription
load_functions('../rougail-tests/funcs/test.py')
try:
groups.namespace
except:
groups.addgroup('namespace')
ALLOWED_LEADER_PROPERTIES.add("basic")
ALLOWED_LEADER_PROPERTIES.add("standard")
ALLOWED_LEADER_PROPERTIES.add("advanced")
option_2 = StrOption(name="var", doc="var", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/20_7help_family/rougail/00-base.yml'], 'type': 'string'})
optiondescription_1 = OptionDescription(name="family1", doc="the first family", children=[option_2], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/20_7help_family/rougail/00-base.yml'], 'help': 'Multi line\n\nHelp\n\nWith useful information'})
option_4 = StrOption(name="var", doc="var", properties=frozenset({"basic", "mandatory"}), informations={'ymlfiles': ['../rougail-tests/structures/20_7help_family/rougail/00-base.yml'], 'type': 'string'})
optiondescription_3 = OptionDescription(name="family2", doc="the second family", children=[option_4], properties=frozenset({"basic"}), informations={'ymlfiles': ['../rougail-tests/structures/20_7help_family/rougail/00-base.yml'], 'help': 'Multi line\nHelp\nWith useful information'})
option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1, optiondescription_3])

View file

@ -111,10 +111,7 @@ def load_rougail_object(test_dir, rougailconfig, multi=False, namespace=False):
if namespace is False and not multi: if namespace is False and not multi:
return None return None
rougailconfig['extra_namespaces'] = extra_namespaces rougailconfig['extra_namespaces'] = extra_namespaces
try: rougailconfig['tiramisu_cache'] = get_tiramisu_filename(test_dir, 'tmp', multi, namespace)
rougailconfig['tiramisu_cache'] = get_tiramisu_filename(test_dir, 'tmp', multi, namespace)
except:
rougailconfig['cli.tiramisu_cache'] = get_tiramisu_filename(test_dir, 'tmp', multi, namespace)
rougailconfig['custom_types']['custom'] = CustomOption rougailconfig['custom_types']['custom'] = CustomOption
return Rougail(rougailconfig) return Rougail(rougailconfig)

View file

@ -35,10 +35,7 @@ def test_personalize_mode():
rougailconfig['modes_level'] = ['level1', 'level2'] rougailconfig['modes_level'] = ['level1', 'level2']
rougailconfig['default_variable_mode'] = 'level1' rougailconfig['default_variable_mode'] = 'level1'
rougailconfig['default_family_mode'] = 'level1' rougailconfig['default_family_mode'] = 'level1'
try: rougailconfig['tiramisu_cache'] = None
rougailconfig['tiramisu_cache'] = None
except:
rougailconfig['cli.tiramisu_cache'] = None
eolobj = Rougail(rougailconfig=rougailconfig) eolobj = Rougail(rougailconfig=rougailconfig)
eolobj.run() eolobj.run()

View file

@ -17,10 +17,7 @@ def type_variable(test_name):
rougailconfig = RougailConfig.copy() rougailconfig = RougailConfig.copy()
rougailconfig['types'] = [f'tests/types/types/{test_name}'] rougailconfig['types'] = [f'tests/types/types/{test_name}']
rougailconfig['main_structural_directories'] = [f'tests/types/structures/{ test_name }'] rougailconfig['main_structural_directories'] = [f'tests/types/structures/{ test_name }']
try: rougailconfig['tiramisu_cache'] = str(tmp_file)
rougailconfig['tiramisu_cache'] = str(tmp_file)
except:
rougailconfig['cli.tiramisu_cache'] = str(tmp_file)
rougail = Rougail(rougailconfig=rougailconfig) rougail = Rougail(rougailconfig=rougailconfig)
config = rougail.run() config = rougail.run()
# #