fix: better path detection
This commit is contained in:
parent
5251554b50
commit
a1ecc76e25
25 changed files with 328 additions and 36 deletions
|
|
@ -1,6 +1,6 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024-2025
|
||||
Copyright (C) 2024-2026
|
||||
|
||||
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
|
||||
|
|
@ -119,7 +119,6 @@ class RougailOutputFormatter:
|
|||
_('the "step.output" is not set to "{0}"').format(self.output_name)
|
||||
)
|
||||
# yaml.top_level_colon_align = True
|
||||
self.main_namespace = normalize_family(self.rougailconfig["main_namespace"])
|
||||
self.has_default_structural_format_version = (
|
||||
self.rougailconfig["default_structural_format_version"] is not None
|
||||
)
|
||||
|
|
@ -135,7 +134,7 @@ class RougailOutputFormatter:
|
|||
|
||||
def run(self):
|
||||
self.upgrade()
|
||||
self.families = {self.main_namespace: CommentedMap()}
|
||||
self.families = {self.rougail.namespace: CommentedMap()}
|
||||
self.parse()
|
||||
self.yaml.indent(mapping=2, sequence=4, offset=2)
|
||||
self.yaml.version = "1.2"
|
||||
|
|
@ -143,7 +142,7 @@ class RougailOutputFormatter:
|
|||
self.yaml.explicit_end = True
|
||||
self.default_flow_style = False
|
||||
with BytesIO() as ymlfh:
|
||||
families = self.families[self.main_namespace]
|
||||
families = self.families[self.rougail.namespace]
|
||||
if not families:
|
||||
self.yaml.dump("", ymlfh)
|
||||
else:
|
||||
|
|
@ -162,7 +161,14 @@ class RougailOutputFormatter:
|
|||
return self.attributes[type_name]
|
||||
|
||||
def upgrade(self) -> None:
|
||||
namespace = self.rougailconfig["main_namespace"]
|
||||
if namespace and self.rougailconfig["extra_namespaces.names"]:
|
||||
namespace = self.rougailconfig["extra_namespaces.names"][0]
|
||||
filenames = self.rougailconfig["extra_namespaces"]["directories"][0]
|
||||
extra = True
|
||||
else:
|
||||
filenames = self.rougailconfig["main_structural_directories"]
|
||||
extra = False
|
||||
if len(filenames) > 1:
|
||||
raise ExtensionError(_('only one filename is allowed, not "{0}"').format(filenames))
|
||||
filename = Path(filenames[0])
|
||||
|
|
@ -177,11 +183,11 @@ class RougailOutputFormatter:
|
|||
self.rougail.load_config()
|
||||
self.rougail.init()
|
||||
self.filename_str = str(filename)
|
||||
if self.main_namespace is None:
|
||||
if namespace is None:
|
||||
self.rougail.namespace = None
|
||||
else:
|
||||
self.rougail.namespace = normalize_family(self.main_namespace)
|
||||
self.rougail.create_namespace(self.main_namespace)
|
||||
self.rougail.namespace = normalize_family(namespace)
|
||||
self.rougail.create_namespace(namespace)
|
||||
self.rougail.validate_file_version(
|
||||
datas,
|
||||
self.filename_str,
|
||||
|
|
@ -199,26 +205,25 @@ class RougailOutputFormatter:
|
|||
return ret
|
||||
|
||||
def parse(self):
|
||||
self.families[self.main_namespace][self.version_name] = float(
|
||||
self.families[self.rougail.namespace][self.version_name] = float(
|
||||
self.rougail.version
|
||||
)
|
||||
self.remaining = len(self.rougail.paths._data)
|
||||
for path, obj in self.rougail.paths._data.items():
|
||||
self.remaining -= 1
|
||||
if path == self.rougail.namespace:
|
||||
# self.families[path] = self.families[None]
|
||||
continue
|
||||
if isinstance(obj, Family):
|
||||
self.parse_family(path, obj)
|
||||
elif isinstance(obj, Variable):
|
||||
self.parse_variable(path, obj)
|
||||
if list(self.families[self.main_namespace]) != [self.version_name]:
|
||||
if list(self.families[self.rougail.namespace]) != [self.version_name]:
|
||||
# just to add an empty line space after "version"
|
||||
self.families[self.main_namespace].yaml_value_comment_extend(
|
||||
self.families[self.rougail.namespace].yaml_value_comment_extend(
|
||||
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]
|
||||
del self.families[self.rougail.namespace][self.version_name]
|
||||
|
||||
def parse_family(self, path, obj):
|
||||
children = [p.rsplit(".", 1)[-1] for p in self.rougail.parents[path]]
|
||||
|
|
@ -355,6 +360,8 @@ class RougailOutputFormatter:
|
|||
if attr not in force_keys and value == default_value:
|
||||
continue
|
||||
value = self.object_to_yaml(attr, type_, value, multi, path)
|
||||
if isinstance(value, dict) and "identifier" in value:
|
||||
value["identifier"] = self.object_to_yaml("identifier", type_, value["identifier"], True, path)
|
||||
variable[attr] = value
|
||||
if variable.get("mandatory") is True and None not in variable.get(
|
||||
"choices", []
|
||||
|
|
@ -605,7 +612,7 @@ class RougailOutputFormatter:
|
|||
def calc_variable_path(self, object_path, variable_path):
|
||||
if not variable_path.startswith("_"):
|
||||
common_path = get_common_path(object_path, variable_path)
|
||||
if not self.rougail.namespace or common_path:
|
||||
if not self.rougail.namespace:
|
||||
if not common_path:
|
||||
len_common_path = 0
|
||||
else:
|
||||
|
|
@ -617,6 +624,15 @@ class RougailOutputFormatter:
|
|||
+ "."
|
||||
+ variable_path[len_common_path:]
|
||||
)
|
||||
if common_path:
|
||||
len_common_path = len(common_path) + 1
|
||||
relative_object_path = object_path[len_common_path:]
|
||||
final_path = "_" * (relative_object_path.count(".") + 1) + "."
|
||||
return (
|
||||
"_" * (relative_object_path.count(".") + 1)
|
||||
+ "."
|
||||
+ variable_path[len_common_path:]
|
||||
)
|
||||
return variable_path
|
||||
|
||||
def get_parent_name(self, path):
|
||||
|
|
@ -636,7 +652,7 @@ class RougailOutputFormatter:
|
|||
name = search_name
|
||||
return _yaml(y[name])
|
||||
|
||||
if self.main_namespace:
|
||||
if self.rougail.namespace:
|
||||
subpath = path.split(".")[1:]
|
||||
else:
|
||||
subpath = path.split(".")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"""
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2024-2025
|
||||
Copyright (C) 2024-2026
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"""Internationalisation utilities
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2025
|
||||
Copyright (C) 2025-2026
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Cadoles (http://www.cadoles.com)
|
|||
Copyright (C) 2021
|
||||
|
||||
Silique (https://www.silique.fr)
|
||||
Copyright (C) 2022-2025
|
||||
Copyright (C) 2022-2026
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ var1: # a first variable
|
|||
var2:
|
||||
description: a second variable
|
||||
default:
|
||||
variable: _.var1
|
||||
description: value of a variable!
|
||||
variable: _.var1
|
||||
...
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ var1: # a first variable
|
|||
var2:
|
||||
description: a second variable
|
||||
default:
|
||||
variable: _.var1
|
||||
description: |-
|
||||
value
|
||||
of
|
||||
a
|
||||
variable!
|
||||
variable: _.var1
|
||||
|
||||
var3: # a new variable
|
||||
...
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ var1:
|
|||
var2:
|
||||
description: an IP in CIDR format
|
||||
examples:
|
||||
- 192.168.0.128/25
|
||||
- 192.168.0.129/25
|
||||
type: ip
|
||||
params:
|
||||
cidr: true
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ version: 1.1
|
|||
|
||||
secret1:
|
||||
description: the first variable
|
||||
examples:
|
||||
- ALongS4cr4t
|
||||
type: secret
|
||||
params:
|
||||
min_len: 10
|
||||
|
|
|
|||
18
tests/results/04_1jinja_and_hidden/rougail/00-base.yml
Normal file
18
tests/results/04_1jinja_and_hidden/rougail/00-base.yml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var1:
|
||||
description: A first variable
|
||||
type: boolean
|
||||
default:
|
||||
jinja: >-
|
||||
true
|
||||
description: A description
|
||||
hidden: true
|
||||
|
||||
var2:
|
||||
description: A second variable
|
||||
disabled:
|
||||
variable: _.var1
|
||||
...
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
condition:
|
||||
description: a condition
|
||||
default: true
|
||||
disabled: true
|
||||
|
||||
variable:
|
||||
description: a variable
|
||||
disabled:
|
||||
variable: _.condition
|
||||
propertyerror: transitive
|
||||
...
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
condition: true # a condition
|
||||
|
||||
variable1:
|
||||
description: a variable
|
||||
disabled:
|
||||
variable: _.condition
|
||||
|
||||
variable2:
|
||||
description: a second variable
|
||||
disabled:
|
||||
variable: _.variable1
|
||||
propertyerror: transitive
|
||||
...
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
condition:
|
||||
description: a condition
|
||||
default: true
|
||||
disabled: true
|
||||
|
||||
variable:
|
||||
description: a variable
|
||||
disabled:
|
||||
variable: _.condition
|
||||
propertyerror: transitive
|
||||
...
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
condition: false # a condition
|
||||
|
||||
variable1:
|
||||
description: a variable
|
||||
default: disabled
|
||||
disabled:
|
||||
variable: _.condition
|
||||
|
||||
variable2:
|
||||
description: a second variable
|
||||
disabled:
|
||||
variable: _.variable1
|
||||
propertyerror: transitive
|
||||
when: disabled
|
||||
...
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
condition: true # a condition
|
||||
|
||||
variable1:
|
||||
description: a variable
|
||||
default: not_disabled
|
||||
disabled:
|
||||
variable: _.condition
|
||||
|
||||
variable2:
|
||||
description: a second variable
|
||||
disabled:
|
||||
variable: _.variable1
|
||||
propertyerror: transitive
|
||||
when: disabled
|
||||
...
|
||||
|
|
@ -8,7 +8,7 @@ leadership:
|
|||
|
||||
leader:
|
||||
description: a leader
|
||||
test:
|
||||
examples:
|
||||
- val1
|
||||
- val2
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var:
|
||||
description: a suffix variable
|
||||
test:
|
||||
- 1
|
||||
- 2
|
||||
type: integer
|
||||
multi: true
|
||||
mandatory: false
|
||||
|
||||
dyn{{ identifier }}:
|
||||
description: a dynamic family
|
||||
dynamic:
|
||||
variable: _.var
|
||||
|
||||
var: val # a variable inside dynamic family from "{{ identifier }}"
|
||||
|
||||
var2:
|
||||
description: a variable
|
||||
default:
|
||||
jinja: >-
|
||||
{% if rougail.dyn1 is defined %}
|
||||
{{ rougail.dyn1.var }}
|
||||
{% endif %}
|
||||
description: get the value of "rougail.dyn1.var"
|
||||
...
|
||||
|
|
@ -3,21 +3,21 @@
|
|||
version: 1.1
|
||||
|
||||
dyn{{ identifier }}:
|
||||
description: A dynamic famify for {{ identifier }}
|
||||
description: a dynamic famify for {{ identifier }}
|
||||
dynamic:
|
||||
- val1
|
||||
- val2
|
||||
|
||||
var: # A dynamic variable for {{ identifier }}
|
||||
var: # a dynamic variable for {{ identifier }}
|
||||
|
||||
var1:
|
||||
description: A new variable
|
||||
description: a new variable
|
||||
disabled:
|
||||
variable: _.dynval1.var
|
||||
when: val
|
||||
|
||||
var2:
|
||||
description: A new variable
|
||||
description: a new variable
|
||||
default:
|
||||
variable: _.dyn{{ identifier }}.var
|
||||
unique: false
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var1: # A suffix variable
|
||||
- val1
|
||||
- val2
|
||||
|
||||
var2: val1 # A suffix variable2
|
||||
|
||||
dyn{{ identifier }}:
|
||||
dynamic:
|
||||
variable: _.var1
|
||||
|
||||
var:
|
||||
description: A dynamic variable
|
||||
default:
|
||||
type: identifier
|
||||
|
||||
var3:
|
||||
description: A variable calculated
|
||||
default:
|
||||
variable: _.dyn{{ identifier }}.var
|
||||
identifier:
|
||||
variable: _.var2
|
||||
...
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var1: # A suffix variable
|
||||
- val1
|
||||
- val2
|
||||
|
||||
var2: val1 # A suffix variable2
|
||||
|
||||
dyn{{ identifier }}:
|
||||
dynamic:
|
||||
variable: _.var1
|
||||
|
||||
var: # A dynamic variable
|
||||
- type: identifier
|
||||
|
||||
var3:
|
||||
description: A variable calculated
|
||||
default:
|
||||
variable: _.dyn{{ identifier }}.var
|
||||
identifier:
|
||||
variable: _.var2
|
||||
...
|
||||
|
|
@ -7,7 +7,8 @@ var1:
|
|||
test:
|
||||
- val1
|
||||
- val2
|
||||
multi: true
|
||||
default:
|
||||
- val1
|
||||
mandatory: false
|
||||
|
||||
dyn{{ identifier }}:
|
||||
|
|
@ -22,5 +23,5 @@ var2:
|
|||
description: A variable calculated
|
||||
default:
|
||||
variable: _.dynval1.var
|
||||
optional: true
|
||||
propertyerror: false
|
||||
...
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var1:
|
||||
description: A suffix variable
|
||||
test:
|
||||
- val1
|
||||
- val2
|
||||
multi: true
|
||||
mandatory: false
|
||||
|
||||
dyn{{ identifier }}:
|
||||
dynamic:
|
||||
variable: _.var1
|
||||
|
||||
var:
|
||||
description: A dynamic variable
|
||||
disabled: true
|
||||
|
||||
var2:
|
||||
description: A variable calculated
|
||||
default:
|
||||
variable: _.dynval1.var
|
||||
optional: true
|
||||
...
|
||||
|
|
@ -4,7 +4,7 @@ version: 1.1
|
|||
|
||||
var:
|
||||
description: a suffix variable
|
||||
test:
|
||||
examples:
|
||||
- val1
|
||||
- val2
|
||||
- val3
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var: # a suffix variable
|
||||
- val1
|
||||
- val2
|
||||
|
||||
'{{ identifier }}_dyn':
|
||||
description: a dynamic family
|
||||
dynamic:
|
||||
variable: _.var
|
||||
|
||||
var1:
|
||||
description: value is suffix for {{ identifier }}
|
||||
default:
|
||||
type: identifier
|
||||
|
||||
var2:
|
||||
description: value is first variable
|
||||
default:
|
||||
variable: _.var1
|
||||
|
||||
var3:
|
||||
description: value is relative first variable
|
||||
default:
|
||||
variable: _.var1
|
||||
|
||||
var4:
|
||||
description: value is first variable of val1
|
||||
default:
|
||||
variable: __.val1_dyn.var1
|
||||
...
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
version: 1.1
|
||||
|
||||
var: # A suffix variable
|
||||
- val1
|
||||
- val2
|
||||
|
||||
dyn{{ identifier }}:
|
||||
dynamic:
|
||||
variable: _.var
|
||||
|
||||
dyn{{ identifier }}:
|
||||
dynamic:
|
||||
variable: __.var
|
||||
|
||||
var1: # A dynamic variable
|
||||
|
||||
var2:
|
||||
description: A variable calculated
|
||||
default:
|
||||
variable: ___.dynval2.dyn{{ identifier }}.var1
|
||||
unique: false
|
||||
...
|
||||
|
|
@ -68,18 +68,26 @@ def test_structural_files_formatter_namespace(test_dir):
|
|||
rougailconfig = get_rougail_config(test_dir, namespace)
|
||||
if not rougailconfig:
|
||||
return
|
||||
if rougailconfig["extra_namespaces.names"]:
|
||||
for n_idx, namespace in enumerate(rougailconfig['extra_namespaces.names']):
|
||||
for dir_name in rougailconfig["extra_namespaces"]["directories"][n_idx]:
|
||||
for file_name in Path(dir_name).iterdir():
|
||||
if file_name.suffix in [".yml", ".yaml"]:
|
||||
rougailconfig["extra_namespaces"].set_follower("directories", n_idx, [str(file_name)])
|
||||
_test_structural_files(file_name, namespace, rougailconfig)
|
||||
rougailconfig["extra_namespaces"].reset()
|
||||
for dir_name in rougailconfig['main_structural_directories']:
|
||||
for file_name in Path(dir_name).iterdir():
|
||||
if file_name.suffix in [".yml", ".yaml"]:
|
||||
rougailconfig["main_structural_directories"] = [str(file_name)]
|
||||
_test_structural_files(file_name, namespace, rougailconfig)
|
||||
for namespace, dirs_name in rougailconfig['extra_namespaces'].items():
|
||||
rougailconfig["main_namespace"] = namespace
|
||||
for dir_name in dirs_name:
|
||||
for file_name in Path(dir_name).iterdir():
|
||||
if file_name.suffix in [".yml", ".yaml"]:
|
||||
rougailconfig["main_structural_directories"] = [str(file_name)]
|
||||
_test_structural_files(file_name, namespace, rougailconfig)
|
||||
# for namespace, dirs_name in rougailconfig['extra_namespaces'].items():
|
||||
# rougailconfig["main_namespace"] = namespace
|
||||
# for dir_name in dirs_name:
|
||||
# for file_name in Path(dir_name).iterdir():
|
||||
# if file_name.suffix in [".yml", ".yaml"]:
|
||||
# rougailconfig["main_structural_directories"] = [str(file_name)]
|
||||
# _test_structural_files(file_name, namespace, rougailconfig)
|
||||
|
||||
|
||||
def test_structural_files_formatter_load(test_dir):
|
||||
|
|
|
|||
Loading…
Reference in a new issue