Compare commits

..

48 commits

Author SHA1 Message Date
6f18fbb701 bump: version 0.1.0a16 → 0.1.0a17 2025-09-29 11:50:23 +02:00
deee4acd79 feat: param line size 2025-09-29 11:49:35 +02:00
164f8c5a60 fix: support numeric string 2025-09-29 11:30:23 +02:00
87b24e7367 bump: version 0.1.0a15 → 0.1.0a16 2025-09-29 11:00:48 +02:00
68c4baa634 feat: variable with an index is an integer variable 2025-09-28 16:32:46 +02:00
af6d11f457 feat: default value for a calculated variable with an unknown optional variable 2025-09-28 15:50:26 +02:00
f2259653f7 feat(#26): convert cidr and network_cidr format 2025-09-24 20:58:13 +02:00
3c33c1927a feat: add integer type which will replace number type 2025-09-23 21:37:23 +02:00
319f9eab1f bump: version 0.1.0a14 → 0.1.0a15 2025-09-22 14:24:35 +02:00
264e8f7000 fix: dictionary => structure 2025-09-22 14:24:23 +02:00
368f7c2882 bump: version 0.1.0a13 → 0.1.0a14 2025-06-18 07:57:42 +03:00
3c88a274e5 fix: rougail separation 2025-06-18 07:39:39 +03:00
e94d8facd7 bump: version 0.1.0a12 → 0.1.0a13 2025-05-15 13:13:28 +02:00
d52401b5a7 fix: no multi empty line when a variable finish by a multi line description 2025-05-15 13:12:59 +02:00
919775ba27 bump: version 0.1.0a11 → 0.1.0a12 2025-05-12 09:10:52 +02:00
125cc9546b fix: black 2025-05-11 19:12:45 +02:00
ece9c98782 bump: version 0.1.0a10 → 0.1.0a11 2025-05-09 08:22:19 +02:00
34348c086e fix: format with default_dictionary_format_version configuration 2025-05-08 12:06:15 +02:00
7cc9426750 bump: version 0.1.0a9 → 0.1.0a10 2025-05-02 08:22:57 +02:00
7cc4efe1af fix: do not load use_data with rougail cli 2025-05-02 08:22:40 +02:00
dfbcd84a00 fix: support {{ suffix }} name in 1.1 format version 2025-05-02 08:22:12 +02:00
697669bc47 bump: version 0.1.0a8 → 0.1.0a9 2025-04-30 09:04:56 +02:00
c151d1829e feat: add yamllint validation 2025-04-27 09:27:04 +02:00
1c06587ba9 fix: update tests 2025-04-25 22:55:05 +02:00
4f083b47b5 fix: add version 2025-04-25 22:54:20 +02:00
e4b045ab75 bump: version 0.1.0a7 → 0.1.0a8 2025-04-01 22:18:44 +02:00
d5f46d305b fix: update tests 2025-04-01 22:01:54 +02:00
1abdf419e6 bump: version 0.1.0a6 → 0.1.0a7 2025-03-30 19:39:44 +02:00
307c2933c5 feat: support multi lines for help 2025-03-30 19:39:29 +02:00
b2f2aa4406 bump: version 0.1.0a5 → 0.1.0a6 2025-03-28 08:32:12 +01:00
5f46162790 fix: do not add multi \n at ends of export 2025-03-28 08:32:02 +01:00
66f044bee3 bump: version 0.1.0a4 → 0.1.0a5 2025-03-27 21:45:52 +01:00
c09800521c fix: if and for in 3 lines 2025-03-27 21:45:29 +01:00
4e9e8b082e bump: version 0.1.0a3 → 0.1.0a4 2025-03-27 08:36:55 +01:00
a4eab14564 feat: format jinja template 2025-03-27 08:36:49 +01:00
88f837aa07 bump: version 0.1.0a2 → 0.1.0a3 2025-03-27 08:29:18 +01:00
03d24af05c fix: do not add namespace in param 2025-03-26 19:34:49 +01:00
2adef78db3 feat: add secret_manager support 2025-03-26 19:34:24 +01:00
9159f44efa fix: an empty variable is [] 2025-03-26 19:34:00 +01:00
75fc04c501 feat: add Namespace(Param|Calculation) support 2025-03-26 19:32:30 +01:00
99a41bd4e5 bump: version 0.1.0a1 → 0.1.0a2 2025-03-26 14:32:00 +01:00
ec8a9c0aab fix: pyproject.toml 2025-03-26 14:31:50 +01:00
232a8385a3 bump: version 0.1.0a0 → 0.1.0a1 2025-03-26 14:30:25 +01:00
ad4e3ffd6e fix: add pyproject.toml 2025-03-26 14:29:46 +01:00
29c1941993 bump: version 0.0.1a0 → 0.1.0a0 2025-02-10 09:46:36 +01:00
9c55b5aa25 feat: output return status too 2025-02-10 09:46:31 +01:00
ad707df62d bump: version 0.0.0 → 0.0.1a0 2025-01-04 11:50:39 +01:00
2227438899 fix: remove prefix_path 2025-01-04 11:50:19 +01:00
319 changed files with 2778 additions and 502 deletions

132
CHANGELOG.md Normal file
View file

@ -0,0 +1,132 @@
## 0.1.0a17 (2025-09-29)
### Feat
- param line size
### Fix
- support numeric string
## 0.1.0a16 (2025-09-29)
### Feat
- variable with an index is an integer variable
- default value for a calculated variable with an unknown optional variable
- **#26**: convert cidr and network_cidr format
- add integer type which will replace number type
## 0.1.0a15 (2025-09-22)
### Fix
- dictionary => structure
## 0.1.0a14 (2025-06-18)
### Fix
- rougail separation
## 0.1.0a13 (2025-05-15)
### Fix
- no multi empty line when a variable finish by a multi line description
## 0.1.0a12 (2025-05-12)
### Fix
- black
## 0.1.0a11 (2025-05-09)
### Fix
- format with default_dictionary_format_version configuration
## 0.1.0a10 (2025-05-02)
### Fix
- do not load use_data with rougail cli
- support {{ suffix }} name in 1.1 format version
## 0.1.0a9 (2025-04-30)
### Feat
- add yamllint validation
### Fix
- update tests
- add version
## 0.1.0a8 (2025-04-01)
### Fix
- update tests
## 0.1.0a7 (2025-03-30)
### Feat
- support multi lines for help
## 0.1.0a6 (2025-03-28)
### Fix
- do not add multi \n at ends of export
## 0.1.0a5 (2025-03-27)
### Fix
- if and for in 3 lines
## 0.1.0a4 (2025-03-27)
### Feat
- format jinja template
## 0.1.0a3 (2025-03-27)
### Feat
- add secret_manager support
- add Namespace(Param|Calculation) support
### Fix
- do not add namespace in param
- an empty variable is []
## 0.1.0a2 (2025-03-26)
### Fix
- pyproject.toml
## 0.1.0a1 (2025-03-26)
### Fix
- add pyproject.toml
## 0.1.0a0 (2025-02-10)
### Feat
- output return status too
## 0.0.1a0 (2025-01-04)
### Fix
- remove prefix_path

View file

@ -0,0 +1,37 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2025-09-29 11:38+0200\n"
"PO-Revision-Date: 2025-09-29 11:46+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.7\n"
#: src/rougail/output_formatter/__init__.py:105
msgid "the \"step.output\" is not set to \"{0}\""
msgstr "\"step.output\" n'est pas défini pour \"{0}\""
#: src/rougail/output_formatter/__init__.py:155
msgid "only one file is allowed"
msgstr "seulement un fichier est autorisé"
#: src/rougail/output_formatter/__init__.py:158
msgid "only a file is allowed"
msgstr "seulement un fichier est autorisé"
#: src/rougail/output_formatter/config.py:59
msgid "Configuration for rougail-ouput-formatter"
msgstr "Configuration pour rougail-ouput-formatter"
#: src/rougail/output_formatter/config.py:61
msgid "Line size"
msgstr "Taille des lignes"

View file

@ -0,0 +1,37 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2025-09-29 11:47+0200\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"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: src/rougail/output_formatter/__init__.py:105
msgid "the \"step.output\" is not set to \"{0}\""
msgstr ""
#: src/rougail/output_formatter/__init__.py:155
msgid "only one file is allowed"
msgstr ""
#: src/rougail/output_formatter/__init__.py:158
msgid "only a file is allowed"
msgstr ""
#: src/rougail/output_formatter/config.py:59
msgid "Configuration for rougail-ouput-formatter"
msgstr ""
#: src/rougail/output_formatter/config.py:61
msgid "Line size"
msgstr ""

47
pyproject.toml Normal file
View file

@ -0,0 +1,47 @@
[build-system]
build-backend = "flit_core.buildapi"
requires = ["flit_core >=3.8.0,<4"]
[project]
name = "rougail.output_formatter"
version = "0.1.0a17"
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
readme = "README.md"
description = "Rougail output formatter"
requires-python = ">=3.8"
license = {file = "LICENSE"}
classifiers = [
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
"Programming Language :: Python",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3",
"Operating System :: OS Independent",
"Natural Language :: English",
"Natural Language :: French",
]
dependencies = [
"rougail >= 1.1,<2",
"djlint == 1.36.4",
]
[project.urls]
Home = "https://forge.cloud.silique.fr/stove/rougail-output-formatter"
[tool.commitizen]
name = "cz_conventional_commits"
tag_format = "$version"
version_scheme = "pep440"
version_provider = "pep621"
version_files = [
"src/rougail/output_formatter/__version__.py",
"pyproject.toml:version"
]
update_changelog_on_bump = true
changelog_merge_prerelease = true

View file

@ -1,7 +1,7 @@
""" """
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2024 Copyright (C) 2024-2025
This program is free software: you can redistribute it and/or modify it 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 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 Free Software Foundation, either version 3 of the License, or (at your
@ -16,33 +16,69 @@ 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from ruamel.yaml import YAML, CommentedMap from ruamel.yaml import YAML, CommentedMap
from ruamel.yaml.representer import RoundTripRepresenter
from ruamel.yaml.tokens import CommentToken from ruamel.yaml.tokens import CommentToken
from ruamel.yaml.error import CommentMark from ruamel.yaml.error import CommentMark
from ruamel.yaml.comments import CommentedSeq from ruamel.yaml.comments import CommentedSeq
from ruamel.yaml.scalarstring import LiteralScalarString, FoldedScalarString from ruamel.yaml.scalarstring import (
LiteralScalarString,
FoldedScalarString,
ScalarString,
)
from djlint.settings import Config
from djlint.reformat import formatter
from tiramisu import undefined
from tiramisu.config import get_common_path from tiramisu.config import get_common_path
from rougail.convert import RougailConvert from rougail.convert import RougailConvert
from rougail.object_model import Variable, Family, Calculation, JinjaCalculation, IdentifierCalculation, IdentifierPropertyCalculation, IdentifierParam, IndexCalculation, IndexParam, Param from rougail.convert.object_model import (
from rougail.utils import normalize_family Variable,
Family,
Calculation,
JinjaCalculation,
IdentifierCalculation,
IdentifierPropertyCalculation,
NamespaceCalculation,
IdentifierParam,
IndexCalculation,
VariableCalculation,
IndexParam,
NamespaceParam,
Param,
AnyParam,
)
from rougail.tiramisu import normalize_family, RENAME_TYPE
from rougail.utils import undefined
from .upgrade import RougailUpgrade from .upgrade import RougailUpgrade
from .i18n import _
from .__version__ import __version__
def _(text): # XXX explicit null
return text def represent_none(self, data):
return self.represent_scalar("tag:yaml.org,2002:null", "null")
def represent_str(self, data):
if data == "":
return self.represent_scalar("tag:yaml.org,2002:null", "")
return self.represent_scalar("tag:yaml.org,2002:str", data)
RoundTripRepresenter.add_representer(type(None), represent_none)
RoundTripRepresenter.add_representer(str, represent_str)
# XXX
class RougailOutputFormatter: class RougailOutputFormatter:
output_name = 'formatter' output_name = "formatter"
def __init__( def __init__(
self, self,
@ -54,27 +90,78 @@ class RougailOutputFormatter:
) -> None: ) -> None:
self.basic_types = { self.basic_types = {
str: "string", str: "string",
int: "number", int: "integer",
bool: "boolean", bool: "boolean",
float: "float", float: "float",
} }
if rougailconfig is None: if rougailconfig is None:
from rougail import RougailConfig from rougail import RougailConfig
rougailconfig = RougailConfig rougailconfig = RougailConfig
rougailconfig["step.output"] = self.output_name rougailconfig["step.output"] = self.output_name
if rougailconfig["step.output"] != self.output_name: self.rougailconfig = rougailconfig
raise ExtentionError(_('the "step.output" is not set to "{0}"').format(self.output_name)) if self.rougailconfig["step.output"] != self.output_name:
raise ExtentionError(
_('the "step.output" is not set to "{0}"').format(self.output_name)
)
# yaml.top_level_colon_align = True # yaml.top_level_colon_align = True
self.main_namespace = rougailconfig["main_namespace"] self.main_namespace = normalize_family(self.rougailconfig["main_namespace"])
filenames = rougailconfig["main_dictionaries"] self.has_default_structural_format_version = (
if len(rougailconfig["main_dictionaries"]) > 1: self.rougailconfig["default_structural_format_version"] is not None
raise Exception(_('only one file is allowed')) )
self.config = Config()
self.config.profile = "jinja"
self.config.line_break_after_multiline_tag = True
self.config.indent = " "
self.attributes = {}
self.yaml = YAML()
self.yaml.width = self.rougailconfig["formatter.line_width"]
self.conv_yaml = YAML()
def run(self):
self.upgrade()
self.families = {self.main_namespace: CommentedMap()}
self.parse()
self.yaml.indent(mapping=2, sequence=4, offset=2)
self.yaml.version = "1.2"
self.yaml.explicit_start = True
self.yaml.explicit_end = True
self.default_flow_style = False
with BytesIO() as ymlfh:
families = self.families[self.main_namespace]
if not families:
self.yaml.dump("", ymlfh)
else:
self.yaml.dump(families, ymlfh)
ret = ymlfh.getvalue().decode("utf-8").strip()
return True, ret
def get_attributes(self, obj, excludes=[]) -> dict:
type_name = obj.__name__
if type_name == "Variable" and excludes == []:
raise Exception("pff")
if type_name not in self.attributes:
self.attributes[type_name] = {
str(attr): o.default
for attr, o in obj.model_fields.items()
if str(attr) not in excludes
}
return self.attributes[type_name]
def upgrade(self) -> None:
filenames = self.rougailconfig["main_structural_directories"]
if len(filenames) > 1:
raise Exception(_("only one file is allowed"))
filename = Path(filenames[0]) filename = Path(filenames[0])
if not filename.is_file(): if not filename.is_file():
raise Exception(_('only a file is allowed')) raise Exception(_("only a file is allowed"))
self.original_yaml = RougailUpgrade(rougailconfig).run(filename)
datas = RougailUpgrade(rougailconfig).run(filename) self.version_name, self.original_yaml = RougailUpgrade(self.rougailconfig).run(
self.rougail = RougailConvert(rougailconfig) filename
)
self.version_name, datas = RougailUpgrade(self.rougailconfig).run(filename)
self.rougail = RougailConvert(self.rougailconfig)
self.rougail.load_config() self.rougail.load_config()
self.rougail.init() self.rougail.init()
self.filename_str = str(filename) self.filename_str = str(filename)
@ -93,54 +180,35 @@ class RougailOutputFormatter:
"1.1", "1.1",
datas, datas,
) )
self.yaml = YAML()
def run(self):
self.families_attributes = {attr: obj.get("default") for attr, obj in self.rougail.family.model_json_schema()["properties"].items()}
self.dynamics_attributes = {attr: obj.get("default") for attr, obj in self.rougail.dynamic.model_json_schema()["properties"].items()}
self.variables_attributes = {attr: obj.get("default") for attr, obj in self.rougail.variable.model_json_schema()["properties"].items()}
self.families = {None: CommentedMap()}
self.parse()
self.yaml.indent(mapping=2, sequence=4, offset=2)
self.yaml.explicit_start=True
self.default_flow_style = False
with BytesIO() as ymlfh:
self.yaml.dump(self.families[None], ymlfh)
ret = ymlfh.getvalue().decode("utf-8").strip() + '\n'
return ret
def print(self): def print(self):
print(self.run()) ret, data = self.run()
print(data)
return ret
def parse(self): def parse(self):
# FIXME path to relative ! self.families[self.main_namespace][self.version_name] = float(
if self.rougail.namespace: self.rougail.version
version_path = f'{self.rougail.namespace}.version' )
else: self.remaining = len(self.rougail.paths._data)
version_path = 'version'
if version_path in self.rougail.paths._data:
version_name = '_version'
else:
version_name = 'version'
self.families[None][version_name] = None
self.families[None].yaml_value_comment_extend(version_name, [CommentToken('\n\n', CommentMark(0)), None])
version = None
for path, obj in self.rougail.paths._data.items(): for path, obj in self.rougail.paths._data.items():
if version is None or version == '': self.remaining -= 1
version = obj.version
if path == self.rougail.namespace: if path == self.rougail.namespace:
self.families[path] = self.families[None] # self.families[path] = self.families[None]
continue continue
if isinstance(obj, Family): if isinstance(obj, Family):
self.parse_family(path, obj) self.parse_family(path, obj)
if isinstance(obj, Variable): elif isinstance(obj, Variable):
self.parse_variable(path, obj) self.parse_variable(path, obj)
if not version: if list(self.families[self.main_namespace]) != [self.version_name]:
raise Exception(_(f'no variables in file {self.filename_str}')) self.families[self.main_namespace].yaml_value_comment_extend(
self.families[None][version_name] = float(version) self.version_name, [CommentToken("\n\n", CommentMark(0)), None]
)
if self.has_default_structural_format_version:
del self.families[self.main_namespace][self.version_name]
def parse_family(self, path, obj): def parse_family(self, path, obj):
children = [p.rsplit('.', 1)[-1] for p in self.rougail.parents[path]] children = [p.rsplit(".", 1)[-1] for p in self.rougail.parents[path]]
parent, name = self.get_parent_name(path) parent, name = self.get_parent_name(path)
ret = self.families[parent] ret = self.families[parent]
family = CommentedMap() family = CommentedMap()
@ -155,11 +223,11 @@ class RougailOutputFormatter:
force_keys = list(yaml_data) force_keys = list(yaml_data)
type_ = obj.type type_ = obj.type
if type_ == "dynamic": if type_ == "dynamic":
attributes = self.dynamics_attributes attributes = self.get_attributes(self.rougail.dynamic)
else: else:
attributes = self.families_attributes attributes = self.get_attributes(self.rougail.family)
for attr, default_value in attributes.items(): for attr, default_value in attributes.items():
if attr in ["name", "path", "namespace", "version", "path_prefix", "xmlfiles"]: if attr in ["name", "path", "namespace", "version", "xmlfiles"]:
continue continue
try: try:
value = getattr(obj, attr) value = getattr(obj, attr)
@ -168,21 +236,31 @@ class RougailOutputFormatter:
if attr != "type" and attr not in force_keys and value == default_value: if attr != "type" and attr not in force_keys and value == default_value:
continue continue
if attr in children: if attr in children:
attr = f'_{attr}' attr = f"_{attr}"
value = self.object_to_yaml(attr, type_, value, False, path) family[attr] = self.object_to_yaml(attr, type_, value, False, path)
family[attr] = value if type_ == "dynamic" or (children and type_ == "family"):
if type_ == "dynamic" or (children and type_ == 'family'):
if "_type" in family: if "_type" in family:
del family["_type"] del family["_type"]
else: else:
del family["type"] del family["type"]
if not set(family): if not set(family):
ret[name] = CommentedMap() ret[name] = CommentedMap()
ret.yaml_value_comment_extend(name, [CommentToken('\n\n', CommentMark(0)), None]) ret.yaml_value_comment_extend(
elif not set(family) - {'description'}: name, [CommentToken("\n\n", CommentMark(0)), None]
# )
elif not set(family) - {"description"}:
#
ret[name] = CommentedMap() ret[name] = CommentedMap()
ret.yaml_add_eol_comment(family["description"] + '\n\n', name) add_column = 3
path_len = path.count(".")
if self.rougail.namespace:
path_len -= 1
column = path_len * 2 + len(name) + add_column
if self.remaining:
description = family["description"].strip() + "\n\n"
else:
description = family["description"].strip()
ret.yaml_add_eol_comment(description, name, column=column)
else: else:
self.add_space(family) self.add_space(family)
ret[name] = family ret[name] = family
@ -203,61 +281,140 @@ class RougailOutputFormatter:
force_keys = list(yaml_data) force_keys = list(yaml_data)
multi = obj.multi or isinstance(obj.default, list) multi = obj.multi or isinstance(obj.default, list)
type_ = obj.type type_ = obj.type
for attr, default_value in self.variables_attributes.items(): if type_ in RENAME_TYPE:
if attr in ["name", "path", "namespace", "version", "path_prefix", "xmlfiles"]: type_ = RENAME_TYPE[type_]
continue if type_ == 'cidr' or type_ == 'network_cidr':
try: if type_ == 'cidr':
value = getattr(obj, attr) type_ = 'ip'
except AttributeError: else:
continue type_ = 'network'
if not obj.params:
obj.params = []
key = 'cidr'
param = AnyParam(
key='cidr',
value=True,
type="any",
path=None,
attribute=None,
family_is_dynamic=None,
namespace=self.rougail.namespace,
xmlfiles=obj.xmlfiles,
)
obj.params.append(param)
for attr, default_value in self.get_attributes(
self.rougail.variable, ["name", "path", "namespace", "version", "xmlfiles"]
).items():
if attr == "type":
value = type_
else:
try:
value = getattr(obj, attr)
except AttributeError:
continue
if attr not in force_keys and value == default_value: if attr not in force_keys and value == default_value:
continue continue
value = self.object_to_yaml(attr, type_, value, multi, path) value = self.object_to_yaml(attr, type_, value, multi, path)
variable[attr] = value variable[attr] = value
if variable.get("mandatory") is True and None not in variable.get("choices", []): if variable.get("mandatory") is True and None not in variable.get(
"choices", []
):
del variable["mandatory"] del variable["mandatory"]
if "default" in variable: if "default" in variable:
if "type" in variable and variable["type"] in ["string", "boolean", "number", "float"]: if isinstance(obj.default, VariableCalculation):
is_multi = "multi" in variable and variable["multi"] is True
if "type" in variable or is_multi:
other_path = self.rougail.paths.get_full_path(obj.default.variable, path)
if other_path in self.rougail.paths:
other_obj = self.rougail.paths[other_path]
if "type" in variable and variable["type"] == other_obj.type:
del variable["type"]
if is_multi and obj.multi:
del variable["multi"]
if "type" in variable and isinstance(obj.default, IndexCalculation) and variable["type"] == "integer":
del variable["type"]
if "type" in variable and variable["type"] in [
"string",
"boolean",
"integer",
"float",
]:
if variable["default"] and isinstance(variable["default"], list): if variable["default"] and isinstance(variable["default"], list):
tested_value = variable["default"][0] tested_value = variable["default"][0]
else: else:
tested_value = variable["default"] tested_value = variable["default"]
if variable["type"] == self.basic_types.get(type(tested_value), None): if variable["type"] == self.basic_types.get(type(tested_value), None):
del variable["type"] del variable["type"]
if "multi" in variable and variable["multi"] is True and isinstance(variable["default"], list): if (
"multi" in variable
and variable["multi"] is True
and isinstance(variable["default"], list)
):
del variable["multi"] del variable["multi"]
elif variable.get("type") == "choice" and "choices" in variable: elif variable.get("type") == "choice" and "choices" in variable:
del variable["type"] del variable["type"]
elif variable.get("type") == "string": elif variable.get("type") == "string":
# default type is string # default type is string
del variable["type"] del variable["type"]
if set(variable) in [{"multi"}, {'multi', 'description'}]: if set(variable) in [{"multi"}, {"multi", "description"}]:
variable["default"] = [] variable["default"] = []
variable.pop("multi") variable.pop("multi")
elif variable.get("type") == "boolean" and not multi: elif variable.get("type") == "boolean" and not multi:
# if boolean, the default value is True # if boolean, the default value is True
del variable["type"] del variable["type"]
variable["default"] = True variable["default"] = True
if not isinstance(variable.get("default"), dict) and not set(variable) - {'default', 'description'}: if (
"default" not in variable
and variable.get("multi") is True
and not set(variable) - {"default", "description", "multi"}
):
variable["default"] = []
del variable["multi"]
if not isinstance(variable.get("default"), dict) and not set(variable) - {
"default",
"description",
}:
# shorthand notation # shorthand notation
default = variable.get('default') default = variable.get("default")
ret[name] = default ret[name] = default
add_column = 3
if isinstance(default, list): if isinstance(default, list):
ret[name] = CommentedSeq() ret[name] = CommentedSeq()
if not default:
add_column += 3
for d in default: for d in default:
ret[name].append(d) ret[name].append(d)
else: else:
ret[name] = default if default is None:
ret[name] = ""
else:
ret[name] = default
add_column += len(str(default)) + 1
if isinstance(default, str):
# some entries have ' (like '8080') those characters are not count, so add it
with BytesIO() as ymlfh:
self.conv_yaml.dump(default, ymlfh)
ret2 = ymlfh.getvalue().decode("utf-8").strip()
if ret2.endswith("..."):
ret2 = ret2[:-3].strip()
if default != ret2:
add_column += len(ret2) - len(default)
if "description" in variable: if "description" in variable:
description = variable["description"] description = variable["description"].strip()
if not multi or not default: if self.remaining and (not multi or not default):
description += "\n\n" description += "\n\n"
ret.yaml_add_eol_comment(description, name) path_len = path.count(".")
if self.rougail.namespace:
path_len -= 1
column = path_len * 2 + len(name) + add_column
ret.yaml_add_eol_comment(description, name, column=column)
if multi and default: if multi and default:
self.add_space(ret) self.add_space(ret)
else: else:
self.add_space(ret) self.add_space(ret)
else: else:
if "default" in variable and variable["default"] is None:
variable["default"] = ""
ret[name] = variable ret[name] = variable
self.add_space(variable) self.add_space(variable)
@ -265,85 +422,141 @@ class RougailOutputFormatter:
def _get_last_obj(o, parent, param, typ): def _get_last_obj(o, parent, param, typ):
if isinstance(o, CommentedMap): if isinstance(o, CommentedMap):
param = list(o)[-1] param = list(o)[-1]
return _get_last_obj(o[param], o, param, 'map') return _get_last_obj(o[param], o, param, "map")
if isinstance(o, CommentedSeq): if isinstance(o, CommentedSeq):
param = len(o) - 1 param = len(o) - 1
return _get_last_obj(o[param], o, param, 'seq') return _get_last_obj(o[param], o, param, "seq")
return typ, parent, param return typ, parent, param
param = list(obj)[-1] param = list(obj)[-1]
typ, parent, param = _get_last_obj(obj[param], obj, param, 'map') typ, parent, param = _get_last_obj(obj[param], obj, param, "map")
if typ == 'seq': if isinstance(parent[param], ScalarString):
enter = "\n"
else:
enter = "\n\n"
if typ == "seq":
func = parent.yaml_key_comment_extend func = parent.yaml_key_comment_extend
else: else:
func = parent.yaml_value_comment_extend func = parent.yaml_value_comment_extend
func(param, [CommentToken('\n\n', CommentMark(0)), None]) if self.remaining:
func(param, [CommentToken(enter, CommentMark(0)), None])
def object_to_yaml(self, key, type_, value, multi, object_path): def object_to_yaml(self, key, type_, value, multi, object_path):
if isinstance(value, list): if isinstance(value, list):
if key == 'params': if key == "params":
new_values = CommentedMap() new_values = CommentedMap()
else: else:
new_values = CommentedSeq() new_values = CommentedSeq()
for v in value: for v in value:
new_value = self.object_to_yaml(key, type_, v, multi, object_path) new_value = self.object_to_yaml(key, type_, v, multi, object_path)
if key == 'params': if key == "params":
if "min_number" in new_value:
new_value["min_integer"] = new_value.pop("min_number")
if "max_number" in new_value:
new_value["max_integer"] = new_value.pop("max_number")
new_values.update(new_value) new_values.update(new_value)
else: else:
new_values.append(new_value) new_values.append(new_value)
return new_values return new_values
if isinstance(value, JinjaCalculation): if isinstance(value, JinjaCalculation):
jinja = CommentedMap() jinja = CommentedMap()
# replace \n to space a add index of \n (now a space) to fold_pos jinja_values = formatter(self.config, value.jinja.strip())[:-1]
jinja_values = value.jinja.strip() if key == "default" and not multi:
if key == 'default' and not multi: jinja["jinja"] = FoldedScalarString(jinja_values)
jinja["jinja"] = FoldedScalarString(jinja_values.replace('\n', ' ')) fold_pos = []
jinja["jinja"].fold_pos = [i for i, ltr in enumerate(jinja_values) if ltr == '\n'] old_i = 0
for i, ltr in enumerate(jinja_values):
if ltr == "\n":
fold_pos.append(i - old_i)
old_i = 1
jinja["jinja"].fold_pos = fold_pos
elif key == "secret_manager":
return self.object_to_yaml(
"params", type_, value.params, multi, object_path
)
else: else:
jinja["jinja"] = LiteralScalarString(jinja_values) jinja["jinja"] = LiteralScalarString(jinja_values)
if value.return_type: if value.return_type:
jinja["return_type"] = value.return_type return_type = value.return_type
if return_type in RENAME_TYPE:
return_type = RENAME_TYPE[return_type]
jinja["return_type"] = return_type
if value.description: if value.description:
jinja["description"] = value.description if "\n" in value.description:
jinja["description"] = LiteralScalarString(value.description.strip())
else:
jinja["description"] = value.description.strip()
if value.params: if value.params:
jinja["params"] = self.object_to_yaml("params", type_, value.params, multi, object_path) jinja["params"] = self.object_to_yaml(
"params", type_, value.params, multi, object_path
)
return jinja return jinja
elif isinstance(value, Calculation): elif isinstance(value, Calculation):
variable_attributes = self.get_object_informations(value, ['path', 'inside_list', 'version', 'xmlfiles', 'attribute_name', 'namespace']) variable_attributes = self.get_attributes(
value.__class__,
[
"path",
"inside_list",
"version",
"xmlfiles",
"attribute_name",
"namespace",
],
)
variable = CommentedMap() variable = CommentedMap()
if isinstance(value, (IdentifierCalculation, IdentifierPropertyCalculation)): if isinstance(
value, (IdentifierCalculation, IdentifierPropertyCalculation)
):
variable["type"] = "identifier" variable["type"] = "identifier"
if isinstance(value, IndexCalculation): elif isinstance(value, IndexCalculation):
variable["type"] = "index" variable["type"] = "index"
elif isinstance(value, NamespaceCalculation):
variable["type"] = "namespace"
for key, default in variable_attributes.items(): for key, default in variable_attributes.items():
val = getattr(value, key) val = getattr(value, key)
if val != default and val is not undefined: if val != default and val is not undefined:
variable[key] = val variable[key] = val
if "variable" in variable: if "variable" in variable:
variable["variable"] = self.calc_variable_path(object_path, variable["variable"]) variable["variable"] = self.calc_variable_path(
if variable.get('type') == 'identifier' and 'identifier' in variable: object_path, variable["variable"]
)
if variable.get("type") == "identifier" and "identifier" in variable:
del variable["type"] del variable["type"]
if value.description:
if "\n" in value.description:
variable["description"] = LiteralScalarString(value.description.strip())
else:
variable["description"] = value.description.strip()
return variable return variable
elif isinstance(value, Param): elif isinstance(value, Param):
param_attributes = self.get_object_informations(value, ["type", "key"]) param_attributes = self.get_attributes(
if list(param_attributes) == ['value']: value.__class__, ["type", "key", "namespace"]
)
if list(param_attributes) == ["value"]:
variable = value.value variable = value.value
else: else:
variable = CommentedMap() variable = CommentedMap()
if isinstance(value, IdentifierParam): if isinstance(value, IdentifierParam):
variable["type"] = "identifier" variable["type"] = "identifier"
if isinstance(value, IndexParam): elif isinstance(value, IndexParam):
variable["type"] = "index" variable["type"] = "index"
elif isinstance(value, NamespaceParam):
variable["type"] = "namespace"
for key, default in param_attributes.items(): for key, default in param_attributes.items():
val = getattr(value, key) val = getattr(value, key)
if val != default and val is not undefined: if val != default and val is not undefined:
variable[key] = val variable[key] = val
if variable.get('type') == 'identifier' and 'identifier' in variable: if variable.get("type") == "identifier" and "identifier" in variable:
del variable["type"] del variable["type"]
if "variable" in variable: if "variable" in variable:
variable["variable"] = self.calc_variable_path(object_path, variable["variable"]) variable["variable"] = self.calc_variable_path(
object_path, variable["variable"]
)
return {value.key: variable} return {value.key: variable}
elif type_ == 'port' and isinstance(value, str) and value.isnumeric(): elif type_ == "port" and isinstance(value, str) and value.isnumeric():
return int(value) return int(value)
elif key == "help" and "\n" in value:
return LiteralScalarString(value.strip())
return value return value
def calc_variable_path(self, object_path, variable_path): def calc_variable_path(self, object_path, variable_path):
@ -355,13 +568,14 @@ class RougailOutputFormatter:
else: else:
len_common_path = len(common_path) + 1 len_common_path = len(common_path) + 1
relative_object_path = object_path[len_common_path:] relative_object_path = object_path[len_common_path:]
final_path = "_" * (relative_object_path.count(".") + 1) + '.' final_path = "_" * (relative_object_path.count(".") + 1) + "."
return "_" * (relative_object_path.count(".") + 1) + '.' + variable_path[len_common_path:] return (
"_" * (relative_object_path.count(".") + 1)
+ "."
+ variable_path[len_common_path:]
)
return variable_path return variable_path
def get_object_informations(self, value, excludes=[]):
return {attr: obj.get("default") for attr, obj in value.__class__.model_json_schema()["properties"].items() if attr not in excludes}
def get_parent_name(self, path): def get_parent_name(self, path):
if "." in path: if "." in path:
return path.rsplit(".", 1) return path.rsplit(".", 1)
@ -372,13 +586,17 @@ class RougailOutputFormatter:
if not subpath: if not subpath:
return y return y
name = subpath.pop(0) name = subpath.pop(0)
if name not in y and name.endswith('{{ identifier }}'): if name not in y and name.endswith("{{ identifier }}"):
name = name[:-16] search_name = name[:-16]
if search_name not in y:
search_name = name.replace("{{ identifier }}", "{{ suffix }}")
name = search_name
return _yaml(y[name]) return _yaml(y[name])
if self.main_namespace: if self.main_namespace:
subpath = path.split('.')[1:] subpath = path.split(".")[1:]
else: else:
subpath = path.split('.') subpath = path.split(".")
return _yaml(self.original_yaml) return _yaml(self.original_yaml)

View file

@ -0,0 +1 @@
__version__ = "0.1.0a17"

View file

@ -1,6 +1,6 @@
""" """
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2024 Copyright (C) 2024-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -17,33 +17,54 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
from pathlib import Path from pathlib import Path
from .i18n import _
def get_rougail_config( def get_rougail_config(
*, *,
backward_compatibility=True, backward_compatibility=True,
) -> dict: ) -> dict:
options = """ options = f"""
load_unexist_redefine: load_unexist_redefine:
redefine: true redefine: true
type: boolean type: boolean
default: default:
jinja: >- jinja: >-
{% if step.output == 'formatter' %} {{% if step.output is not propertyerror and step.output == 'formatter' %}}
true true
{% else %} {{% else %}}
false false
{% endif %} {{% endif %}}
hidden: hidden:
jinja: >- jinja: >-
{% if step.output == 'formatter' %} {{% if step.output is not propertyerror and step.output == 'formatter' %}}
load_unexist_redefine is always true with 'formatter' output load_unexist_redefine is always true with 'formatter' output
{% endif %} {{% endif %}}
cli:
load_config:
exists: true
redefine: true
type: boolean
default:
jinja: >-
{{% if step.output is not propertyerror and step.output == 'formatter' %}}
false
{{% else %}}
true
{{% endif %}}
formatter:
description: {_('Configuration for rougail-ouput-formatter')}
line_width: 120 # {_('Line size')}
""" """
return { return {
"name": "formatter", "name": "formatter",
"process": "output", "process": "output",
"options": options, "options": options,
"allow_user_data": False,
"level": 90, "level": 90,
} }

View file

@ -0,0 +1,27 @@
"""Internationalisation utilities
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 gettext import translation
from pathlib import Path
t = translation(
"rougail_output_formatter", str(Path(__file__).parent / "locale"), fallback=True
)
_ = t.gettext

View file

@ -4,7 +4,7 @@ Cadoles (http://www.cadoles.com)
Copyright (C) 2021 Copyright (C) 2021
Silique (https://www.silique.fr) Silique (https://www.silique.fr)
Copyright (C) 2022-2024 Copyright (C) 2022-2025
This program is free software: you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by the
@ -45,22 +45,33 @@ class RougailUpgrade:
def run( def run(
self, self,
file, file: str,
): ) -> dict:
with file.open() as file_fh: with file.open() as file_fh:
root = YAML().load(file_fh) root = YAML().load(file_fh)
search_function_name = get_function_name(str(root["version"])) if not root:
root = {}
if "_version" in root:
version_name = "_version"
format_version = str(root.pop("_version"))
elif "version" in root:
version_name = "version"
format_version = str(root.pop("version"))
else:
version_name = None
format_version = self.rougailconfig["default_structural_format_version"]
if format_version not in VERSIONS:
raise Exception(f'version "{format_version}" is not a valid version')
search_function_name = get_function_name(format_version)
function_found = False function_found = False
for version, function_version in FUNCTION_VERSIONS: for version, function_version in FUNCTION_VERSIONS:
if function_found and hasattr(self, function_version): if function_found and hasattr(self, function_version):
root = getattr(self, function_version)(root) root = getattr(self, function_version)(root)
if function_version == search_function_name: if function_version == search_function_name:
function_found = True function_found = True
if '_version' in root: if version_name:
root["_version"] = float(version) root[version_name] = float(version)
elif 'version' in root: return version_name, root
root["version"] = float(version)
return root
def update_1_1( def update_1_1(
self, self,
@ -69,7 +80,7 @@ class RougailUpgrade:
new_root = CommentedMap() new_root = CommentedMap()
for key, value in root.items(): for key, value in root.items():
if not isinstance(value, dict): if not isinstance(value, dict):
if key == 'variable' and "{{ suffix }}" in value: if key == "variable" and "{{ suffix }}" in value:
value = value.replace("{{ suffix }}", "{{ identifier }}") value = value.replace("{{ suffix }}", "{{ identifier }}")
new_root[key] = value new_root[key] = value
continue continue
@ -94,7 +105,7 @@ class RougailUpgrade:
new_root[key] = value new_root[key] = value
for typ, obj in { for typ, obj in {
"boolean": bool, "boolean": bool,
"number": int, "integer": int,
"string": str, "string": str,
"float": float, "float": float,
}.items(): }.items():

View file

@ -0,0 +1,4 @@
%YAML 1.2
---
version: 1.1
...

View file

@ -0,0 +1,3 @@
%YAML 1.2
---
...

View file

@ -0,0 +1,3 @@
%YAML 1.2
---
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
_version: 1.1 _version: 1.1
version: # a variable version: # a variable
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
empty: empty:
...

View file

@ -1,7 +1,8 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: no # a first variable var1: no # a first variable
var2: var2:
description: a second variable description: a second variable
@ -10,3 +11,4 @@ var2:
jinja: |- jinja: |-
{{ _.var1 }} {{ _.var1 }}
description: the value of var1 description: the value of var1
...

View file

@ -1,7 +1,8 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: # a first variable var1: # a first variable
- no - no
- yes - yes
- maybe - maybe
@ -12,6 +13,7 @@ var2:
default: default:
jinja: |- jinja: |-
{% for val in _.var1 %} {% for val in _.var1 %}
{{ val }} {{ val }}
{% endfor %} {% endfor %}
description: the value of _.var1 description: the value of _.var1
...

View file

@ -0,0 +1,22 @@
%YAML 1.2
---
version: 1.1
leadership:
type: leadership
hidden: true
var1: # a first variable
- a_value
var2: a_value # a first variable
var2:
description: a second variable
default:
jinja: >-
{{ var1[0] }}
params:
var1:
variable: _.leadership.var1
...

View file

@ -0,0 +1,16 @@
%YAML 1.2
---
version: 1.1
var1:
description: a first variable
type: domainname
params:
allow_ip: true
multi: true
var2:
description: a second variable
default:
variable: _.var1
...

View file

@ -0,0 +1,12 @@
%YAML 1.2
---
version: 1.1
var1: # a first variable
var2:
description: a second variable
default:
variable: _.var1
description: value of a variable!
...

View file

@ -0,0 +1,18 @@
%YAML 1.2
---
version: 1.1
var1: # a first variable
var2:
description: a second variable
default:
variable: _.var1
description: |-
value
of
a
variable!
var3: # a new variable
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -12,3 +13,4 @@ var2:
description: a second variable description: a second variable
default: default:
variable: _.var1 variable: _.var1
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: # a variable var1: # a variable
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var2: # a variable var2: # a variable
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
without_type: non # a variable without_type: non # a variable
...

View file

@ -1,14 +1,16 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: true # the first variable var1: true # the first variable
var2: true # the second variable var2: true # the second variable
var3: true # the third variable var3: true # the third variable
var4: false # the forth variable var4: false # the forth variable
var5: false # the fifth variable var5: false # the fifth variable
var6: false # the sixth variable var6: false # the sixth variable
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -5,3 +6,4 @@ variable:
description: a variable description: a variable
mandatory: false mandatory: false
default: true default: true
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -26,7 +27,7 @@ var3:
var4: var4:
description: the forth variable description: the forth variable
choices: choices:
- - null
- b - b
- c - c
mandatory: false mandatory: false
@ -46,3 +47,4 @@ var6:
- 2 - 2
- 3 - 3
default: 1 default: 1
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -6,8 +7,9 @@ var:
choices: choices:
jinja: |- jinja: |-
{% for n in trange(0, 10) %} {% for n in trange(0, 10) %}
{{ n }} {{ n }}
{% endfor %} {% endfor %}
return_type: number return_type: integer
description: choices is 0 to 9 description: choices is 0 to 9
default: 9 default: 9
...

View file

@ -0,0 +1,16 @@
%YAML 1.2
---
version: 1.1
var1:
description: the first variable
choices:
- a
- b
- c
var2:
description: the second variable
default:
variable: _.var1
...

View file

@ -1,7 +1,8 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: # a second variable var1: # a second variable
- a - a
- b - b
- c - c
@ -11,3 +12,4 @@ var2:
choices: choices:
variable: _.var1 variable: _.var1
default: a default: a
...

View file

@ -0,0 +1,20 @@
%YAML 1.2
---
version: 1.1
var1: # a second variable
- a
- b
- c
var2:
description: a first variable
choices:
variable: _.var1
default: a
var3:
description: a third variable
default:
variable: _.var2
...

View file

@ -0,0 +1,22 @@
%YAML 1.2
---
version: 1.1
var1: # a second variable
- a
- b
- c
var2:
description: a first variable
choices:
variable: _.var1
default: a
family:
var3:
description: a third variable
default:
variable: __.var2
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -9,3 +10,4 @@ custom2:
description: the seconf variable description: the seconf variable
type: custom type: custom
default: value default: value
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -5,3 +6,4 @@ variable:
description: a domain name variable description: a domain name variable
type: domainname type: domainname
default: my.domain.name default: my.domain.name
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -7,3 +8,4 @@ variable:
params: params:
allow_ip: true allow_ip: true
default: my.domain.name default: my.domain.name
...

View file

@ -1,14 +1,16 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: 0.0 # the first variable var1: 0.0 # the first variable
var2: 0.0 # the second variable var2: 0.0 # the second variable
var3: 0.0 # the third variable var3: 0.0 # the third variable
var4: 10.1 # the forth variable var4: 10.1 # the forth variable
var5: 10.1 # the fifth variable var5: 10.1 # the fifth variable
var6: 10.1 # the sixth variable var6: 10.1 # the sixth variable
...

View file

@ -0,0 +1,16 @@
%YAML 1.2
---
version: 1.1
var1: 0 # the first variable
var2: 0 # the second variable
var3: 0 # the third variable
var4: 10 # this forth variable
var5: 10 # the fifth variable
var6: 10 # the sixth variable
...

View file

@ -0,0 +1,25 @@
%YAML 1.2
---
version: 1.1
var1:
description: an IP
type: ip
default: 1.1.1.1
var2:
description: an IP in CIDR format
examples:
- 192.168.0.128/25
type: ip
params:
cidr: true
default: 1.1.1.1/24
var3:
description: an IP in CIDR format with obsolete CIDR type
type: ip
params:
cidr: true
default: 1.1.1.1/24
...

View file

@ -0,0 +1,23 @@
%YAML 1.2
---
version: 1.1
var1:
description: an network
type: network
default: 1.1.1.0
var2:
description: an network in CIDR format
type: network
params:
cidr: true
default: 1.1.1.0/24
var3:
description: an network in CIDR format with obsolete CIDR type
type: network
params:
cidr: true
default: 1.1.1.0/24
...

View file

@ -1,14 +1,16 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: 0 # the first variable var1: 0 # the first variable
var2: 0 # the second variable var2: 0 # the second variable
var3: 0 # the third variable var3: 0 # the third variable
var4: 10 # this forth variable var4: 10 # this forth variable
var5: 10 # the fifth variable var5: 10 # the fifth variable
var6: 10 # the sixth variable var6: 10 # the sixth variable
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -14,3 +15,4 @@ variable3:
description: a port variable with integer default value description: a port variable with integer default value
type: port type: port
default: 8080 default: 8080
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -8,3 +9,4 @@ var:
- '#b2b2b2' - '#b2b2b2'
regexp: ^#(?:[0-9a-f]{3}){1,2}$ regexp: ^#(?:[0-9a-f]{3}){1,2}$
default: '#a1a1a1' default: '#a1a1a1'
...

View file

@ -0,0 +1,20 @@
%YAML 1.2
---
version: 1.1
var1:
description: a first variable
test:
- '#b1b1b1'
- '#b2b2b2'
regexp: ^#(?:[0-9a-f]{3}){1,2}$
default: '#a1a1a1'
var2:
description: a second variable
test:
- '#b2b1b1'
- '#b3b2b2'
default:
variable: _.var1
...

View file

@ -0,0 +1,13 @@
%YAML 1.2
---
version: 1.1
secret1:
description: the first variable
type: secret
secret2:
description: the second variable
type: secret
default: value
...

View file

@ -0,0 +1,29 @@
%YAML 1.2
---
version: 1.1
secret1:
description: the first variable
type: secret
params:
min_len: 10
secret2:
description: the second variable
type: secret
params:
max_len: 10
forbidden_char:
- $
- ^
default: value
secret3:
description: the third variable
type: secret
params:
max_len: 10
forbidden_char:
- $
default: value
...

View file

@ -1,14 +1,20 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: # the first variable var1: # the first variable
var2: # the second variable var2: # the second variable
var3: # the third variable var3: # the third variable
var4: value # the forth variable var4: value # the forth variable
var5: value # the fifth variable var5: value # the fifth variable
var6: value # the sixth variable var6: value # the sixth variable
var7: '8080' # the seventh variable
var8: 'true' # the height variable
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -9,3 +10,4 @@ var:
- quote" - quote"
- quote"' - quote"'
default: quote' default: quote'
...

View file

@ -0,0 +1,20 @@
%YAML 1.2
---
version: 1.1
var1:
description: the first variable
help: |-
Multi line
Help
With useful information
var2:
description: the second variable
help: |-
Multi line
Help
With useful information
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -8,3 +9,4 @@ var1:
var2: var2:
description: the second variable description: the second variable
help: message with " help: message with "
...

View file

@ -0,0 +1,20 @@
%YAML 1.2
---
version: 1.1
var1:
description: the first <variable>
help: |-
Multi line
<Help>
With useful information
var2:
description: the second <variable>
help: |-
Multi line
<Help>
With useful information
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable: quote" # a variable variable: quote" # a variable
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable: quote'" # a variable variable: quote'" # a variable
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable: quote\"\' # a variable variable: quote\"\' # a variable
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable: quote' # a variable variable: quote' # a variable
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -5,8 +6,9 @@ variable:
description: a variable description: a variable
default: default:
jinja: >- jinja: >-
{{test_information }} {{ test_information }}
description: get information test_information description: get information test_information
params: params:
test_information: test_information:
information: test_information information: test_information
...

View file

@ -0,0 +1,10 @@
%YAML 1.2
---
version: 1.1
variable:
description: a variable
default:
type: namespace
mandatory: false
...

View file

@ -0,0 +1,14 @@
%YAML 1.2
---
version: 1.1
variable:
description: a variable
default:
jinja: >-
{{ namespace }}
params:
namespace:
type: namespace
mandatory: false
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -21,7 +22,7 @@ var3:
var4: var4:
description: the forth variable description: the forth variable
test: test:
- - null
- test1 - test1
- test2 - test2
mandatory: false mandatory: false
@ -38,3 +39,4 @@ var6:
- test1 - test1
- test2 - test2
multi: true multi: true
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -15,3 +16,4 @@ variable2:
- val2 - val2
multi: true multi: true
mandatory: false mandatory: false
...

View file

@ -1,9 +1,10 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
source_variable_1: val1 # the first source variable source_variable_1: val1 # the first source variable
source_variable_2: val2 # the second source variable source_variable_2: val2 # the second source variable
my_variable: my_variable:
description: a variable description: a variable
@ -12,3 +13,4 @@ my_variable:
- variable: _.source_variable_1 - variable: _.source_variable_1
- variable: _.source_variable_2 - variable: _.source_variable_2
default: val1 default: val1
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -11,4 +12,5 @@ variable:
param1: string param1: string
param2: 1 param2: 1
param3: true param3: true
param4: param4: null
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -11,3 +12,4 @@ var:
information: information:
information: test_information information: test_information
variable: _.var variable: _.var
...

View file

@ -1,7 +1,8 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: # a first variable var1: # a first variable
var2: var2:
description: a second variable description: a second variable
@ -12,3 +13,4 @@ var2:
information: information:
information: test_information information: test_information
variable: _.var1 variable: _.var1
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -8,3 +9,4 @@ my_calculated_variable:
optional: true optional: true
- variable: _.my_variable_unexists - variable: _.my_variable_unexists
optional: true optional: true
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -8,3 +9,4 @@ my_calculated_variable:
optional: true optional: true
- variable: _.my_variable - variable: _.my_variable
optional: true optional: true
...

View file

@ -0,0 +1,13 @@
%YAML 1.2
---
version: 1.1
my_variable: val1
my_calculated_variable:
- variable: _.my_variable
optional: true
- variable: _.my_variable_unexists
optional: true
default: value
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -6,3 +7,4 @@ my_calculated_variable:
default: default:
variable: _.my_variable variable: _.my_variable
optional: true optional: true
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -6,7 +7,7 @@ my_variable:
- val2 - val2
my_calculated_variable: my_calculated_variable:
multi: true
default: default:
variable: _.my_variable variable: _.my_variable
optional: true optional: true
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -5,8 +6,15 @@ var1:
description: a first variable description: a first variable
default: default:
jinja: >- jinja: >-
{% if var2 is defined %} {{ var2 }} {% elif var3 is defined %} {{ var3 }} {% {% if var2 is defined %}
elif var4 is defined %} {{ var4 }} {% else %} {{ _.var2 }} {% endif %} {{ var2 }}
{% elif var3 is defined %}
{{ var3 }}
{% elif var4 is defined %}
{{ var4 }}
{% else %}
{{ _.var2 }}
{% endif %}
description: returns a value description: returns a value
params: params:
var2: var2:
@ -21,3 +29,4 @@ var1:
mandatory: false mandatory: false
var2: no # a second variable var2: no # a second variable
...

View file

@ -1,10 +1,12 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: # a first variable var1: # a first variable
var2: var2:
description: a second variable description: a second variable
default: default:
information: test_information information: test_information
variable: _.var1 variable: _.var1
...

View file

@ -1,10 +1,12 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: # a first variable var1: # a first variable
var2: var2:
description: a second variable description: a second variable
default: default:
information: test_information information: test_information
variable: _.var1 variable: _.var1
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -6,8 +7,9 @@ var:
choices: choices:
jinja: |- jinja: |-
{% for item in trange(0, 10) %} {% for item in trange(0, 10) %}
{{ item }} {{ item }}
{%- endfor %} {%- endfor %}
return_type: number return_type: integer
description: choice for 0 to 9 description: choice for 0 to 9
default: 9 default: 9
...

View file

@ -0,0 +1,15 @@
%YAML 1.2
---
version: 1.1
var:
description: a variable
choices:
jinja: |-
{% for item in trange(0, 10) %}
{{ item }}
{%- endfor %}
return_type: integer
description: choice for 0 to 9
default: 9
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -7,3 +8,4 @@ variable:
jinja: >- jinja: >-
no no
description: return no description: return no
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable: rougail # a variable variable: rougail # a variable
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -22,3 +23,4 @@ variable3:
params: params:
variable: variable:
variable: rougail.variable variable: rougail.variable
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable: value # a variable variable: value # a variable
...

View file

@ -1,4 +1,6 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable: value in extra # a variable variable: value in extra # a variable
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -5,3 +6,4 @@ variable:
description: a variable description: a variable
default: default:
variable: extra.variable variable: extra.variable
...

View file

@ -1,26 +1,28 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: # the first variable var1: # the first variable
- true - true
var2: # the second variable var2: # the second variable
- true - true
var3: # the third variable var3: # the third variable
- true - true
var4: # the forth variable var4: # the forth variable
- false - false
var5: # the fifth variable var5: # the fifth variable
- false - false
var6: # the sixth variable var6: # the sixth variable
- false - false
var7: # the seventh variable var7: # the seventh variable
- true - true
var8: # the eighth variable var8: # the eighth variable
- true - true
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -11,3 +12,4 @@ custom2:
type: custom type: custom
default: default:
- value - value
...

View file

@ -1,26 +1,28 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: # the first variable var1: # the first variable
- 0.0 - 0.0
var2: # the second variable var2: # the second variable
- 0.0 - 0.0
var3: # the third variable var3: # the third variable
- 0.0 - 0.0
var4: # the forth variable var4: # the forth variable
- 10.1 - 10.1
var5: # the fifth variable var5: # the fifth variable
- 10.1 - 10.1
var6: # the sixth variable var6: # the sixth variable
- 10.1 - 10.1
var7: # the seventh variable var7: # the seventh variable
- 0.0 - 0.0
var8: # the eighth variable var8: # the eighth variable
- 0.0 - 0.0
...

View file

@ -0,0 +1,28 @@
%YAML 1.2
---
version: 1.1
var1: # the first variable
- 0
var2: # the second variable
- 0
var3: # the third variable
- 0
var4: # the forth variable
- 10
var5: # the fifth variable
- 10
var6: # the sixth variable
- 10
var7: # the seventh variable
- 0
var8: # the eighth variable
- 0
...

View file

@ -1,26 +0,0 @@
---
version: 1.1
var1: # the first variable
- 0
var2: # the second variable
- 0
var3: # the third variable
- 0
var4: # the forth variable
- 10
var5: # the fifth variable
- 10
var6: # the sixth variable
- 10
var7: # the seventh variable
- 0
var8: # the eighth variable
- 0

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -5,5 +6,6 @@ var1:
description: the second variable description: the second variable
default: default:
- value - value
- - null
empty: false empty: false
...

View file

@ -1,23 +1,25 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: [] # the first variable var1: [] # the first variable
var2: [] # the second variable var2: [] # the second variable
var3: [] # the third variable var3: [] # the third variable
var4: # the forth variable var4: # the forth variable
- value - value
var5: # the fifth variable var5: # the fifth variable
- value - value
var6: # the sixth variable var6: # the sixth variable
- value - value
var7: # the seventh variable var7: # the seventh variable
- value - value
var8: # the eighth variable var8: # the eighth variable
- value - value
...

View file

@ -1,5 +1,7 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable: # a variable variable: # a variable
- quote" - quote"
...

View file

@ -1,5 +1,7 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable: # a variable variable: # a variable
- quote'" - quote'"
...

View file

@ -1,5 +1,7 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable: # a variable variable: # a variable
- quote' - quote'
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -7,9 +8,10 @@ variable:
default: default:
jinja: |- jinja: |-
{% for info in test_information %} {% for info in test_information %}
{{ info }} {{ info }}
{% endfor %} {% endfor %}
description: get information test_information description: get information test_information
params: params:
test_information: test_information:
information: test_information_list information: test_information_list
...

View file

@ -1,7 +1,8 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
variable1: # a first variable variable1: # a first variable
- a - a
- b - b
- c - c
@ -10,3 +11,4 @@ variable2:
description: a second variable description: a second variable
choices: choices:
variable: _.variable1 variable: _.variable1
...

View file

@ -0,0 +1,15 @@
%YAML 1.2
---
version: 1.1
variable:
description: a variable
choices:
variable: _.unknown_variable
optional: true
default:
- a
- b
- c
default: c
...

View file

@ -1,9 +1,11 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
int: int:
description: A limited number description: A limited number
params: params:
min_number: 0 min_integer: 0
max_number: 100 max_integer: 100
default: 10 default: 10
...

View file

@ -0,0 +1,11 @@
%YAML 1.2
---
version: 1.1
int:
description: A limited integer
params:
min_integer: 0
max_integer: 100
default: 10
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -5,3 +6,4 @@ variable:
description: an auto save variable description: an auto save variable
default: no default: no
auto_save: true auto_save: true
...

View file

@ -1,10 +1,12 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: no # a first variable var1: no # a first variable
var2: var2:
description: a second variable description: a second variable
default: default:
variable: _.var1 variable: _.var1
auto_save: true auto_save: true
...

View file

@ -1,7 +1,8 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: no # a first variable var1: no # a first variable
var2: var2:
description: a second variable description: a second variable
@ -13,6 +14,7 @@ var2:
hidden: hidden:
jinja: |- jinja: |-
{% if _.var1 == "yes" %} {% if _.var1 == "yes" %}
_.var1 is yes _.var1 is yes
{% endif %} {% endif %}
description: only if the variable var1 has value "yes" description: only if the variable var1 has value "yes"
...

View file

@ -1,3 +1,4 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
@ -7,3 +8,4 @@ var:
auto_save: true auto_save: true
mandatory: false mandatory: false
hidden: true hidden: true
...

View file

@ -1,7 +1,8 @@
%YAML 1.2
--- ---
version: 1.1 version: 1.1
var1: value # a first variable var1: value # a first variable
var2: var2:
description: a second variable description: a second variable
@ -14,5 +15,6 @@ var3:
default: default:
jinja: >- jinja: >-
{% if _.var1 == 'value' or _.var2 == 'blah' %} {% if _.var1 == 'value' or _.var2 == 'blah' %}
value value
{% endif %} {% endif %}
...

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