Compare commits

..

9 commits

28 changed files with 343 additions and 49 deletions

View file

@ -1,3 +1,21 @@
## 0.1.3 (2026-09-02)
### Fix
- check if structural is loaded
## 0.1.2 (2026-09-02)
### Fix
- rougail-output-json version
## 0.1.1 (2026-09-02)
### Fix
- add rougail-structural-hcl packages
## 0.1.0 (2026-07-06) ## 0.1.0 (2026-07-06)
### Feat ### Feat

View file

@ -6,8 +6,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"POT-Creation-Date: 2026-07-06 16:47+0200\n" "POT-Creation-Date: 2026-09-08 09:55+0200\n"
"PO-Revision-Date: 2026-07-06 16:47+0200\n" "PO-Revision-Date: 2026-09-08 09:56+0200\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: fr\n" "Language: fr\n"
@ -17,15 +17,24 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.9\n" "X-Generator: Poedit 3.9\n"
#: src/rougail/output_hcl/export.py:130 #: src/rougail/output_hcl/export.py:134
msgid "The family \"{0}\" has a hcl_type parameter but is not in a root config" msgid "The family \"{0}\" has a hcl_type parameter but is not in a root config"
msgstr "" msgstr ""
"La famille \"{0}\" has le paramètre hcl_type mais n'est pas dans la config " "La famille \"{0}\" has le paramètre hcl_type mais n'est pas dans la config "
"racine" "racine"
#: src/rougail/output_hcl/export.py:142 #: src/rougail/output_hcl/export.py:146 src/rougail/output_hcl/export.py:158
msgid "" msgid ""
"The family \"{0}\" has a hcl_type parameter to label but is not in a block" "The family \"{0}\" has a hcl_type parameter to label but is not in a block"
msgstr "" msgstr ""
"La famille \"{0}\" has le paramètre hcl_type à label mais n'est pas dans un " "La famille \"{0}\" has le paramètre hcl_type à label mais n'est pas dans un "
"block" "block"
#: src/rougail/structural_hcl/annotator.py:55
#: src/rougail/structural_hcl/annotator.py:63
msgid ""
"the family \"{0}\" is a label but there are others families which are not "
"label in same parent family"
msgstr ""
"la famille \"{0}\" est un label mais il y a d'autres familles qui ne sont "
"pas des labels dans la même famille parente"

View file

@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2026-07-06 16:48+0200\n" "POT-Creation-Date: 2026-09-08 09:56+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -15,11 +15,16 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"
#: src/rougail/output_hcl/export.py:130 #: src/rougail/output_hcl/export.py:134
msgid "The family \"{0}\" has a hcl_type parameter but is not in a root config" msgid "The family \"{0}\" has a hcl_type parameter but is not in a root config"
msgstr "" msgstr ""
#: src/rougail/output_hcl/export.py:142 #: src/rougail/output_hcl/export.py:146 src/rougail/output_hcl/export.py:158
msgid "The family \"{0}\" has a hcl_type parameter to label but is not in a block" msgid "The family \"{0}\" has a hcl_type parameter to label but is not in a block"
msgstr "" msgstr ""
#: src/rougail/structural_hcl/annotator.py:55
#: src/rougail/structural_hcl/annotator.py:63
msgid "the family \"{0}\" is a label but there are others families which are not label in same parent family"
msgstr ""

View file

@ -1,34 +1,6 @@
[build-system]
build-backend = "flit_core.buildapi"
requires = ["flit_core >=3.8.0,<4"]
[project] [project]
name = "rougail.output_hcl" name = "rougail.output_hcl"
version = "0.1.0" version = "0.1.3"
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
readme = "README.md"
description = "Rougail output hcl"
requires-python = ">=3.11"
license = {file = "LICENSE"}
classifiers = [
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
"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-base >= 1.2.0,<2",
"python-hcl2 >= 8.1.2,<9",
]
[project.urls]
Home = "https://forge.cloud.silique.fr/stove/rougail-output-hcl"
[tool.commitizen] [tool.commitizen]
name = "cz_conventional_commits" name = "cz_conventional_commits"
@ -37,7 +9,10 @@ version_scheme = "pep440"
version_provider = "pep621" version_provider = "pep621"
version_files = [ version_files = [
"src/rougail/output_hcl/__version__.py", "src/rougail/output_hcl/__version__.py",
"pyproject.toml:version" "pyproject.toml:version",
"rougail-output-pyproject.toml:version",
"rougail-output-pyproject.toml:rougail-structural-hcl == ",
"rougail-structural-pyproject.toml:version",
] ]
update_changelog_on_bump = true update_changelog_on_bump = true
changelog_merge_prerelease = true changelog_merge_prerelease = true

View file

@ -0,0 +1,30 @@
[build-system]
build-backend = "flit_core.buildapi"
requires = ["flit_core >=3.8.0,<4"]
[project]
name = "rougail.output_hcl"
version = "0.1.3"
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
readme = "README.md"
description = "Rougail output hcl"
requires-python = ">=3.11"
license = {file = "LICENSE"}
classifiers = [
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
"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-structural-hcl == 0.1.3",
]
[project.urls]
Home = "https://forge.cloud.silique.fr/stove/rougail-output-hcl"

View file

@ -0,0 +1,32 @@
[build-system]
build-backend = "flit_core.buildapi"
requires = ["flit_core >=3.8.0,<4"]
[project]
name = "rougail.structural_hcl"
version = "0.1.3"
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
readme = "README.md"
description = "Rougail structural hcl"
requires-python = ">=3.11"
license = {file = "LICENSE"}
classifiers = [
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
"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-base >= 1.2.0,<2",
"rougail-output-json >=1.0.1,<2",
"python-hcl2 >= 8.1.2,<9",
]
[project.urls]
Home = "https://forge.cloud.silique.fr/stove/rougail-structural-hcl"

View file

@ -1 +1 @@
__version__ = "0.1.0" __version__ = "0.1.3"

View file

@ -115,8 +115,12 @@ class RougailOutputHcl(RougailOutputJson):
parent_obj[name] = [] parent_obj[name] = []
block_to_insert = parent_obj[name] block_to_insert = parent_obj[name]
block_to_insert.extend(child_obj) block_to_insert.extend(child_obj)
elif parent_is_block: elif parent_is_block and child_obj.get("__is_block__", False):
parent_obj.append({name: child_obj}) parent_obj.append({name: child_obj})
elif parent_is_block:
if not parent_obj:
parent_obj.append({})
parent_obj[-1][name] = child_obj
else: else:
parent_obj[name] = child_obj parent_obj[name] = child_obj
@ -148,6 +152,15 @@ class RougailOutputHcl(RougailOutputJson):
child_obj["__is_block__"] = True child_obj["__is_block__"] = True
quote_name = True quote_name = True
elif hcl_type == "label_with_label": elif hcl_type == "label_with_label":
if self.config == parent or not parent.information.get(
"hcl_type", None
):
msg = _(
'The family "{0}" has a hcl_type parameter to label but is not in a block'
).format(child.path())
raise DictConsistencyError(
msg, 502, child.information.get("ymlfiles", None)
)
quote_name = True quote_name = True
return quote_name return quote_name

View file

@ -19,6 +19,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
""" """
from .i18n import _
from rougail.annotator.variable import Walk from rougail.annotator.variable import Walk
from rougail.error import DictConsistencyError from rougail.error import DictConsistencyError
@ -49,14 +50,20 @@ class Annotator(Walk):
hasattr(child, "hcl_type") and child.hcl_type == "block" hasattr(child, "hcl_type") and child.hcl_type == "block"
) )
information_value = None information_value = None
if child.hcl_type == "label": if hasattr(child, "hcl_type") and child.hcl_type == "label":
if is_label == False: if is_label == False:
raise Exception() msg = _('the family "{0}" is a label but there are others families which are not label in same parent family').format(child.path)
raise DictConsistencyError(
msg, 504, child.xmlfiles
)
information_value = "label" information_value = "label"
is_label = True is_label = True
sub_is_block = True sub_is_block = True
elif is_label: elif is_label:
raise Exception() msg = _('the family "{0}" is a label but there are others families which are not label in same parent family').format(child.path)
raise DictConsistencyError(
msg, 503, child.xmlfiles
)
else: else:
is_label = False is_label = False
if self.parse_family(child_path, sub_is_block): if self.parse_family(child_path, sub_is_block):
@ -70,9 +77,8 @@ class Annotator(Walk):
self.objectspace.informations.add( self.objectspace.informations.add(
child.path, "hcl_type", information_value child.path, "hcl_type", information_value
) )
hcl_name = getattr(child, "hcl_name") if hasattr(child, "hcl_name") and child.hcl_name:
if hcl_name: self.objectspace.informations.add(child.path, "hcl_name", child.hcl_name)
self.objectspace.informations.add(child.path, "hcl_name", hcl_name)
return is_label return is_label
def parse_variable(self): def parse_variable(self):

View file

@ -0,0 +1,12 @@
%YAML 1.2
---
version: 1.1
a_block:
hcl_type: label
a_label:
hcl_type: label
a_variable: a value
...

View file

@ -0,0 +1 @@
502

View file

@ -0,0 +1,17 @@
%YAML 1.2
---
version: 1.1
a_block:
hcl_type: block
a_block:
hcl_type: block
a_variable: a value
a_label:
hcl_type: label
a_variable: a value
...

View file

@ -0,0 +1 @@
504

View file

@ -0,0 +1,17 @@
%YAML 1.2
---
version: 1.1
a_block:
hcl_type: block
a_label:
hcl_type: label
a_variable: a value
a_block:
hcl_type: block
a_variable: a value
...

View file

@ -0,0 +1 @@
503

View file

@ -0,0 +1,8 @@
stack {
a_family_1 = {
a_variable = "a value"
}
a_family_2 = {
a_variable = "a value"
}
}

View file

@ -0,0 +1,15 @@
%YAML 1.2
---
version: 1.1
stack:
hcl_type: block
a_family_1: # a family 1
a_variable: a value
a_family_2: # a family 2
a_variable: a value
...

View file

@ -29,12 +29,12 @@ def _test_structural_files(test_file, ext):
rougailconfig["main_structural_directories"] = [str(test_file.absolute())] rougailconfig["main_structural_directories"] = [str(test_file.absolute())]
################################## ##################################
rougail = Rougail(rougailconfig) rougail = Rougail(rougailconfig)
config = rougail.run()
config.information.set("description_type", "path_and_description")
config.property.read_only()
with Path(str(test_file.absolute()) + ".errno").open() as fh: with Path(str(test_file.absolute()) + ".errno").open() as fh:
error_no = int(fh.read().strip()) error_no = int(fh.read().strip())
with raises(DictConsistencyError) as err: with raises(DictConsistencyError) as err:
config = rougail.run()
config.information.set("description_type", "path_and_description")
config.property.read_only()
generated_output = RougailOutput(config, rougailconfig=rougailconfig).run()[1] generated_output = RougailOutput(config, rougailconfig=rougailconfig).run()[1]
assert err.value.errno == error_no, f'expected errno: {error_no}, errno: {err.value.errno}, msg: {err}' assert err.value.errno == error_no, f'expected errno: {error_no}, errno: {err.value.errno}, msg: {err}'

View file

@ -5,7 +5,6 @@ from rougail.output_hcl import RougailOutputHcl as RougailOutput
from rougail.error import DictConsistencyError from rougail.error import DictConsistencyError
def _test_subconfig(error): def _test_subconfig(error):
rougailconfig = RougailConfig.copy() rougailconfig = RougailConfig.copy()
################################## ##################################

37
tests/test_types.py Normal file
View file

@ -0,0 +1,37 @@
from pytest import raises
from pathlib import Path
from rougail import Rougail, RougailConfig
from rougail.output_hcl import RougailOutputHcl as RougailOutput
from rougail.error import DictConsistencyError
def _test_types(name):
rougailconfig = RougailConfig.copy()
##################################
rougailconfig['step.output'] = 'hcl'
rougailconfig["main_namespace"] = None
rougailconfig["types"] = [str((Path(__file__).parent / 'types' / name / 'types').absolute())]
rougailconfig["main_structural_directories"] = [str((Path(__file__).parent / 'types' / name / 'structures').absolute())]
##################################
rougail = Rougail(rougailconfig)
config = rougail.run()
config.information.set("description_type", "path_and_description")
config.property.read_only()
generated_output = RougailOutput(config, rougailconfig=rougailconfig).run()[1]
output_file = Path(__file__).parent / 'types' / name / 'rougail.hcl'
if not output_file.is_file():
if not output_file.parent.is_dir():
output_file.parent.mkdir()
with output_file.open('w') as outfh:
outfh.write(generated_output)
with output_file.open() as outfh:
attented_output = outfh.read()
assert generated_output == attented_output, f'filename {output_file}'
def test_types_01():
_test_types('01-types')
def test_types_02():
_test_types('02-double')

View file

@ -0,0 +1,8 @@
a_new_block_1 "a_label" {
an_attribute = "a value"
}
a_new_block_2 "a_label" {
an_attribute = "a value"
}

View file

@ -0,0 +1,13 @@
%YAML 1.2
---
version: 1.1
a_new_block_1:
type: a_block
a_new_block_2:
hcl_type: block
a_label:
type: a_label
...

View file

@ -0,0 +1,20 @@
%YAML 1.2
---
version: 1.1
a_block:
description: A block is a family with hcl_type attribute
hcl_type: block
a_label:
description: A label is also a family with hcl_type attribute
hcl_type: label
an_attribute: a value # An attribute in a block
a_label:
description: A label is also a family with hcl_type attribute
hcl_type: label
an_attribute: a value # An attribute in a block
...

View file

@ -0,0 +1,8 @@
a_new_block_1 "a_label" {
an_attribute = "a value new"
}
a_new_block_2 "a_label" {
an_attribute = "a value new"
}

View file

@ -0,0 +1,13 @@
%YAML 1.2
---
version: 1.1
a_new_block_1:
type: a_block
a_new_block_2:
hcl_type: block
a_label:
type: a_label
...

View file

@ -0,0 +1,20 @@
%YAML 1.2
---
version: 1.1
a_block_ori:
description: A block is a family with hcl_type attribute
hcl_type: block
a_label:
description: A label is also a family with hcl_type attribute
hcl_type: label
an_attribute: a value # An attribute in a block
a_label_ori:
description: A label is also a family with hcl_type attribute
hcl_type: label
an_attribute: a value # An attribute in a block
...

View file

@ -0,0 +1,16 @@
%YAML 1.2
---
version: 1.1
a_block:
type: a_block_ori
a_label:
an_attribute: a value new
a_label:
type: a_label_ori
an_attribute: a value new
...