feat: library documentation

This commit is contained in:
egarette@silique.fr 2025-10-26 13:29:29 +01:00
parent 96975461d0
commit 1277cce9d9
9 changed files with 692 additions and 262 deletions

View file

@ -70,7 +70,7 @@ Explained differently, Rougail allows you to easily implement an integration of
:titlesonly:
:caption: The library
library
library/index
configuration
.. toctree::

View file

@ -1,261 +0,0 @@
`Rougail`'s library description
=================================
Rougail is a configuration management library that allows you to load variables in a simple and convenient way.
In the following examples, we will use a specific configuration of Rougail.
You will find all the configuraiton options in :doc:`configuration`.
To load the configuration you must import the `RougailConfig` class and set the `main_structural_directories` values:
.. code-block:: python
from rougail import RougailConfig
RougailConfig['main_structural_directories'] = ['dict']
Let's convert a structure file
-------------------------------
As a reminder, a :term:`structure file` is a set of instructions that will allow us to create :term:`families` and :term:`variables`.
Let's start by creating a simple structure file.
Here is a first :file:`dict/00-base.yml` structure file:
.. code-block:: yaml
%YAML 1.2
---
version: 1.1
my_variable:
default: my_value
...
Then, let's create the :term:`Tiramisu` objects via the following script:
.. code-block:: python
:caption: the `script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dict']
rougail = Rougail()
config = rougail.get_config()
print(config.value.get())
.. demo:: Let's execute `script.py`:
.. code-block:: bash
$ python3 script.py
{'rougail.my_variable': 'my_value'}
The operator role
--------------------
The :term:`operator` role corresponds to the :term:`tiramisu` settings:
.. image:: images/tiramisu_get_set.png
.. index:: questionary
But instead of coding in the end user developer way, the opterator will prefer using the Rougail CLI interface:
.. image:: images/QuestionaryChoice.png
The Rougail CLI can output a rather complete view of the dataset:
.. image:: images/UserDataOutput.png
Let's convert an extra structure file
---------------------------------------
.. index:: extras
The default namespace for variables and families is `rougail`. It is possible to define other namespaces. These additional namespaces are called `extras`.
.. FIXME: faire une page pour les extras
Additional namespaces are defined during configuration.
For example, here's how to add an `example` namespace:
.. code-block:: python
RougailConfig['extra_namespaces']['example'] = ['extras/']
Then let's create an extra :term:`structure file` :file:`extras/00-base.yml`:
.. code-block:: yaml
:caption: the :file:`extras/00-base.yml` file content
---
version: '1.1'
my_variable_extra:
default: my_value_extra
Then, let's create the :term:`Tiramisu` objects via the following :file:`script.py` script:
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dict']
RougailConfig['extra_namespaces']['example'] = ['extras/']
rougail = Rougail()
config = rougail.get_config()
print(config.value.dict())
Let's execute `script.py`:
.. code-block:: bash
$ python3 script.py
{'rougail.my_variable': 'my_value', 'example.my_variable_extra': 'my_value_extra'}
Let's create a custom function
----------------------------------
We create the complementary :term:`structure file` named :file:`dict/01-function.yml` so that the `my_variable_jinja` variable is :term:`calculated`:
.. code-block:: yaml
%YAML 1.2
---
version: 1.1
my_variable_jinja:
default:
type: jinja
jinja: "{{ return_no() }}"
...
Then let's define the :func:`return_no` function in :file:`functions.py`:
.. code-block:: python
:caption: the :file:`functions.py` content
def return_no():
return 'no'
Then, let's create the :term:`Tiramisu` objects via the following script:
.. code-block:: python
:caption: the `script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dict']
RougailConfig['extra_namespaces']['example'] = ['extras/']
RougailConfig['functions_file'] = 'functions.py'
rougail = Rougail()
config = rougail.get_config()
print(config.value.dict())
Let's execute `script.py`:
.. code-block:: bash
$ python3 script.py
{'rougail.my_variable': 'my_value', 'rougail.my_variable_jinja': 'no', 'example.my_variable_extra': 'my_value_extra'}
The value of the `my_variable_extra` variable is calculated, and it's value comes from the :func:`return_no` function.
Create your own type
----------------------
A variable has a type. This type enables the variable to define the values that are accepted by this variable.
There is a series of default types, but obviously not all cases are taken.
It's possible to create your own type.
Here an example to a lipogram option (in a string, we cannot use "e" character):
.. code-block:: python
:caption: the `lipogram.py` file content
from tiramisu import StrOption
class LipogramOption(StrOption):
__slots__ = tuple()
_type = 'lipogram'
def validate(self,
value):
super().validate(value)
# verify that there is any 'e' in the sentense
if 'e' in value:
raise ValueError('Perec wrote a book without any "e", you could not do it in a simple sentence?')
To add the new lipogram type in Rougail:
.. code-block:: python
>>> from rougail import Rougail, RougailConfig
>>> RougailConfig['main_structural_directories'] = ['dict']
>>> RougailConfig['custom_types']['lipogram'] = LipogramOption
Now, we can use lipogram type.
Here is a :file:`dict/00-base.yml` structure file:
.. code-block:: yaml
---
version: '1.1'
var:
type: lipogram
.. code-block:: python
>>> rougail = Rougail()
>>> config = rougail.get_config()
>>> config.option('rougail.var').value.set('blah')
>>> config.option('rougail.var').value.set('I just want to add a quality string that has no bad characters')
[...]
tiramisu.error.ValueOptionError: "I just want to add a quality string that has no bad characters" is an invalid lipogram for "var", Perec wrote a book without any "e", you could not do it in a simple sentence?
Upgrade dictionnaries to upper version
----------------------------------------
All dictionnaries has a format version number.
When a new format version is proposed, it is possible to automatically convert the files to the new version.
We create a term:`structure file` named :file:`dict/01-upgrade.yml` with version 1.0:
.. code-block:: yaml
---
version: '1.0'
my_variable:
multi: true
my_dyn_family:
type: "dynamic"
variable: my_variable
a_variable:
.. code-block:: python
>>> from rougail import RougailUpgrade, RougailConfig
>>> RougailConfig['main_structural_directories'] = ['dict']
>>> upgrade = RougailUpgrade()
>>> upgrade.load_dictionaries('dict_converted')
The term:`structure file` named :file:`dict_converted/01-upgrade.yml` is in version 1.1:
.. code-block:: yaml
version: '1.1'
my_variable:
multi: true
my_dyn_family:
type: dynamic
a_variable: null
dynamic:
type: variable
variable: my_variable
propertyerror: false

View file

@ -0,0 +1,47 @@
Let's create a custom function
==============================
We create the complementary :term:`structure file` named :file:`dict/01-function.yml` so that the `my_variable_jinja` variable is :term:`calculated`:
.. code-block:: yaml
%YAML 1.2
---
version: 1.1
my_variable_jinja:
default:
type: jinja
jinja: "{{ return_no() }}"
...
Then let's define the :func:`return_no` function in :file:`functions.py`:
.. code-block:: python
:caption: the :file:`functions.py` content
def return_no():
return 'no'
Then, let's create the :term:`Tiramisu` objects via the following script:
.. code-block:: python
:caption: the `script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dict']
RougailConfig['extra_namespaces']['example'] = ['extras/']
RougailConfig['functions_file'] = 'functions.py'
rougail = Rougail()
config = rougail.get_config()
print(config.value.dict())
Let's execute `script.py`:
.. code-block:: bash
$ python3 script.py
{'rougail.my_variable': 'my_value', 'rougail.my_variable_jinja': 'no', 'example.my_variable_extra': 'my_value_extra'}
The value of the `my_variable_extra` variable is calculated, and it's value comes from the :func:`return_no` function.

45
docs/library/extra.rst Normal file
View file

@ -0,0 +1,45 @@
Let's convert an extra namespace structural file
================================================
.. index:: extras
The default namespace for variables and families is `rougail`. It is possible to define other namespaces. These additional namespaces are called `extras`.
.. FIXME: faire une page pour les extras
Additional namespaces are defined during configuration.
For example, here's how to add an `example` namespace:
.. code-block:: python
RougailConfig['extra_namespaces']['example'] = ['extras/']
Then let's create an extra :term:`structure file` :file:`extras/00-base.yml`:
.. code-block:: yaml
:caption: the :file:`extras/00-base.yml` file content
---
version: '1.1'
my_variable_extra:
default: my_value_extra
Then, let's create the :term:`Tiramisu` objects via the following :file:`script.py` script:
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dict']
RougailConfig['extra_namespaces']['example'] = ['extras/']
rougail = Rougail()
config = rougail.get_config()
print(config.value.dict())
Let's execute `script.py`:
.. code-block:: bash
$ python3 script.py
{'rougail.my_variable': 'my_value', 'example.my_variable_extra': 'my_value_extra'}

81
docs/library/index.rst Normal file
View file

@ -0,0 +1,81 @@
`Rougail`'s library description
=================================
Rougail is a configuration management library that allows you to load variables in a simple and convenient way.
In the following examples, we will use a specific configuration of Rougail.
You will find all the configuraiton options in :doc:`configuration`.
To load the configuration you must import the `RougailConfig` class and set the `main_structural_directories` values:
.. code-block:: python
from rougail import RougailConfig
RougailConfig['main_structural_directories'] = ['dict']
Let's convert a our first structural file
-----------------------------------------
As a reminder, a :term:`structure file` is a set of instructions that will allow us to create :term:`families` and :term:`variables`.
Let's start by creating a simple structure file.
Here is a first :file:`dict/00-base.yml` structure file:
.. code-block:: yaml
%YAML 1.2
---
version: 1.1
my_variable: my_value # my variable
...
Then, let's create the :term:`Tiramisu` objects via the following script:
.. code-block:: python
:caption: the `script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dict']
rougail = Rougail()
config = rougail.run()
print(config.value.get())
.. demo:: Let's execute `script.py`:
.. code-block:: bash
$ python3 script.py
{'rougail.my_variable': 'my_value'}
The operator role
--------------------
The :term:`operator` role corresponds to the :term:`tiramisu` settings:
.. image:: images/tiramisu_get_set.png
.. index:: questionary
But instead of coding in the end user developer way, the opterator will prefer using the Rougail CLI interface:
.. image:: images/QuestionaryChoice.png
The Rougail CLI can output a rather complete view of the dataset:
.. image:: images/UserDataOutput.png
.. toctree::
:titlesonly:
:caption: Use library
parse
rougailconfig_load_from_cli
extra
custom_function
own_type
upgrade

52
docs/library/own_type.rst Normal file
View file

@ -0,0 +1,52 @@
Create your own type
====================
A variable has a type. This type enables the variable to define the values that are accepted by this variable.
There is a series of default types, but obviously not all cases are taken.
It's possible to create your own type.
Here an example to a lipogram option (in a string, we cannot use "e" character):
.. code-block:: python
:caption: the `lipogram.py` file content
from tiramisu import StrOption
class LipogramOption(StrOption):
__slots__ = tuple()
_type = 'lipogram'
def validate(self,
value):
super().validate(value)
# verify that there is any 'e' in the sentense
if 'e' in value:
raise ValueError('Perec wrote a book without any "e", you could not do it in a simple sentence?')
To add the new lipogram type in Rougail:
.. code-block:: python
>>> from rougail import Rougail, RougailConfig
>>> RougailConfig['main_structural_directories'] = ['dict']
>>> RougailConfig['custom_types']['lipogram'] = LipogramOption
Now, we can use lipogram type.
Here is a :file:`dict/00-base.yml` structure file:
.. code-block:: yaml
---
version: '1.1'
var:
type: lipogram
.. code-block:: python
>>> rougail = Rougail()
>>> config = rougail.get_config()
>>> config.option('rougail.var').value.set('blah')
>>> config.option('rougail.var').value.set('I just want to add a quality string that has no bad characters')
[...]
tiramisu.error.ValueOptionError: "I just want to add a quality string that has no bad characters" is an invalid lipogram for "var", Perec wrote a book without any "e", you could not do it in a simple sentence?

259
docs/library/parse.rst Normal file
View file

@ -0,0 +1,259 @@
Retrieve all variables and families
===================================
Rougail returns a :term:`Tiramisu` config.
Let's retrieve our variables and families to manager this.
First of all, create our structural file:
.. code-block:: yaml
:caption: the :file:`dist/00-base.yml` file content
%YAML 1.2
---
version: 1.1
my_variable: # a simple variable
- value1
- value2
a_family: # a simple family
my_variable: my_value # a simple variable inside the family
a_dyn_family_{{ identifier }}:
description: a dynamic family for "{{ identifier }}"
dynamic:
variable: _.my_variable
a_leadership:
description: a leader family
a_leader: # a leader variable
a_follower: # a follower variable
...
Walk through our config
----------------------
Create our first script to walk through our config:
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dist']
rougail = Rougail()
config = rougail.run()
def walk(config):
for option in config:
print(option.description())
if option.isoptiondescription():
walk(option)
if __name__ == '__main__':
walk(config)
Let's execute `script.py`:
.. code-block:: bash
$ python3 script.py
rougail
rougail.my_variable (a simple variable)
rougail.a_family (a simple family)
rougail.a_family.my_variable (a simple variable inside the family)
rougail.a_dyn_family_value1 (a dynamic family for "value1")
rougail.a_dyn_family_value1.a_leadership (a leader family)
rougail.a_dyn_family_value1.a_leadership.a_leader (a leader variable)
rougail.a_dyn_family_value1.a_leadership.a_follower (a follower variable)
rougail.a_dyn_family_value2 (a dynamic family for "value2")
rougail.a_dyn_family_value2.a_leadership (a leader family)
rougail.a_dyn_family_value2.a_leadership.a_leader (a leader variable)
rougail.a_dyn_family_value2.a_leadership.a_follower (a follower variable)
We retrieve alls description of variables and families.
Let us distinguish the variables of the families
------------------------------------------------
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dist']
rougail = Rougail()
config = rougail.run()
def walk(config, level=0):
for option in config:
if option.isoptiondescription():
typ = "family"
else:
typ = "variable"
prefix = " " * level
print(f"{prefix}{typ}: {option.description()}")
if option.isoptiondescription():
walk(option, level + 1)
if __name__ == '__main__':
walk(config)
Let's execute `script.py`:
.. code-block:: bash
family: rougail
variable: rougail.my_variable (a simple variable)
family: rougail.a_family (a simple family)
variable: rougail.a_family.my_variable (a simple variable inside the family)
family: rougail.a_dyn_family_value1 (a dynamic family for "value1")
family: rougail.a_dyn_family_value1.a_leadership (a leader family)
variable: rougail.a_dyn_family_value1.a_leadership.a_leader (a leader variable)
variable: rougail.a_dyn_family_value1.a_leadership.a_follower (a follower variable)
family: rougail.a_dyn_family_value2 (a dynamic family for "value2")
family: rougail.a_dyn_family_value2.a_leadership (a leader family)
variable: rougail.a_dyn_family_value2.a_leadership.a_leader (a leader variable)
variable: rougail.a_dyn_family_value2.a_leadership.a_follower (a follower variable)
Or if we want more precision:
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dist']
rougail = Rougail()
config = rougail.run()
def walk(config, level=0):
for option in config:
if option.isoptiondescription():
if option.isleadership():
typ = "leadership"
elif option.isdynamic():
typ = "dynamic family"
else:
typ = "family"
else:
if option.isleader():
typ = "leader"
elif option.isfollower():
typ = "follower"
else:
typ = "option"
if option.isdynamic():
typ = f"dynamic {typ}"
prefix = " " * level
print(f"{prefix}{typ}: {option.description()}")
if option.isoptiondescription():
walk(option, level + 1)
if __name__ == '__main__':
walk(config)
Let's execute `script.py`:
.. code-block:: bash
family: rougail
option: rougail.my_variable (a simple variable)
family: rougail.a_family (a simple family)
option: rougail.a_family.my_variable (a simple variable inside the family)
dynamic family: rougail.a_dyn_family_value1 (a dynamic family for "value1")
dynamic family: rougail.a_dyn_family_value1.a_leadership (a leader family)
dynamic option: rougail.a_dyn_family_value1.a_leadership.a_leader (a leader variable)
dynamic option: rougail.a_dyn_family_value1.a_leadership.a_follower (a follower variable)
dynamic family: rougail.a_dyn_family_value2 (a dynamic family for "value2")
dynamic family: rougail.a_dyn_family_value2.a_leadership (a leader family)
dynamic option: rougail.a_dyn_family_value2.a_leadership.a_leader (a leader variable)
dynamic option: rougail.a_dyn_family_value2.a_leadership.a_follower (a follower variable)
Get variable values
-------------------
If we want to walk to get variables and their values:
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dist']
rougail = Rougail()
config = rougail.run()
def walk(config):
for option in config:
if option.isoptiondescription():
walk(option)
else:
print(f"{option.description()}: {option.value.get()}")
if __name__ == '__main__':
walk(config)
Let's execute `script.py`:
.. code-block:: bash
rougail.my_variable (a simple variable): ['value1', 'value2']
rougail.a_family.my_variable (a simple variable inside the family): my_value
rougail.a_dyn_family_value1.a_leadership.a_leader (a leader variable): None
rougail.a_dyn_family_value1.a_leadership.a_follower (a follower variable): None
rougail.a_dyn_family_value2.a_leadership.a_leader (a leader variable): None
rougail.a_dyn_family_value2.a_leadership.a_follower (a follower variable): None
Modify variable values
----------------------
Some variables are mandatories but hasn't value. Here we set alls values:
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail, RougailConfig
RougailConfig['main_structural_directories'] = ['dist']
rougail = Rougail()
config = rougail.run()
def walk(config):
for option in config:
if option.isoptiondescription():
walk(option)
else:
print(f"{option.description()}: {option.value.get()}")
if __name__ == '__main__':
print("Mandatories variables without value:")
print(config.value.mandatory())
config.value.set("rougail.my_variable", ["value 5", "value 6"])
config.value.set("rougail.a_dyn_family_value_5.a_leadership.a_leader", "value 1")
config.value.set("rougail.a_dyn_family_value_5.a_leadership.a_follower", "value 2")
config.value.set("rougail.a_dyn_family_value_6.a_leadership.a_leader", "value 3")
config.value.set("rougail.a_dyn_family_value_6.a_leadership.a_follower", "value 4")
print("Mandatories variables without value:")
print(config.value.mandatory())
walk(config)
Let's execute `script.py`:
.. code-block:: bash
Mandatories variables without value:
[<TiramisuOption path="rougail.a_dyn_family_value1.a_leadership.a_leader">, <TiramisuOption path="rougail.a_dyn_family_value1.a_leadership.a_follower">, <TiramisuOption path="rougail.a_dyn_family_value2.a_leadership.a_leader">, <TiramisuOption path="rougail.a_dyn_family_value2.a_leadership.a_follower">]
Mandatories variables without value:
[]
rougail.my_variable (a simple variable): ['value 5', 'value 6']
rougail.a_family.my_variable (a simple variable inside the family): my_value
rougail.a_dyn_family_value_5.a_leadership.a_leader (a leader variable): value 1
rougail.a_dyn_family_value_5.a_leadership.a_follower (a follower variable): value 2
rougail.a_dyn_family_value_6.a_leadership.a_leader (a leader variable): value 3
rougail.a_dyn_family_value_6.a_leadership.a_follower (a follower variable): value 4

View file

@ -0,0 +1,165 @@
Load Rougail configuration from Rougail command line informations
==================================================================
There is a lot you can do with the Rougail command line (rougail-cli), but sometimes you need to do a more advanced script.
Rather than duplicating the configuration, why not load the information from the configuration file, environment variables, or command line options?
We can loading a combination of source information but always in this order:
- configuration file
- environment variables
- commandline options
.. warning:: specific options reserve for command line (in namespace "cli") are not available in script
Then let's create an structual file:term:`structure file` :file:`dist/00-base.yml`:
.. code-block:: yaml
:caption: the :file:`dist/00-base.yml` file content
%YAML 1.2
---
version: 1.1
my_variable: my_value_extra # a simple variable
...
Command line configuration file
-------------------------------
Create a command line configuration file :file:`.rougailcli.yml`:
.. code-block:: yaml
:caption: the :file:`.rougailcli.yml` file content
---
main_structural_directories: # directories where are place structural file
- dist
step.output: json # output is not console but json
Let's execute Rougail command line:
.. code-block:: bash
$ rougail
{
"my_variable": "my_value_extra"
}
Then, let's create the :term:`Tiramisu` objects via the following :file:`script.py` script:
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail
rougail = Rougail()
try:
config = rougail.run()
print(config.value.get())
except Exception as err:
print(f"ERROR: {err}")
exit(1)
Let's execute `script.py`:
.. code-block:: bash
$ python3 script.py
ERROR: option "Directories where structural files are placed" is mandatory but hasn't value
As expected, the .rougailcli.yml file is not loaded because it is specific to the command line.
Let's modifying the script to do this:
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail, RougailConfig
from rougail.cli.rougailconfig import load
load(RougailConfig, yaml_file=".rougailcli.yml")
rougail = Rougail()
try:
config = rougail.run()
print(config.value.get())
except Exception as err:
print(f"ERROR: {err}")
exit(1)
Let's execute `script.py`:
.. code-block:: bash
$ python3 script.py
{<TiramisuOption path="rougail">: {<TiramisuOption path="rougail.my_variable">: 'my_value_extra'}}
Environment variables
---------------------
If we don't have .rougailcli.yml, it's possible to set option with environment variables, like this:
.. code-block:: bash
$ env ROUGAILCLI_MAIN_STRUCTURAL_DIRECTORIES=dist/ ROUGAILCLI_STEP.OUTPUT=json ROUGAILCLI_MAIN_NAMESPACE=test bin/rougail
{
"test": {
"my_variable": "my_value_extra"
}
}
Do the same with a script:
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail, RougailConfig
from rougail.cli.rougailconfig import load
load(RougailConfig, env_prefix="ROUGAILCLI")
rougail = Rougail()
try:
config = rougail.run()
print(config.value.get())
except Exception as err:
print(f"ERROR: {err}")
exit(1)
Let's execute `script.py`:
.. code-block:: bash
$ env ROUGAILCLI_MAIN_STRUCTURAL_DIRECTORIES=dist/ ROUGAILCLI_STEP.OUTPUT=json ROUGAILCLI_MAIN_NAMESPACE=test python3 script.py
{<TiramisuOption path="test">: {<TiramisuOption path="test.my_variable">: 'my_value_extra'}}
Command line option
-------------------
To reproduce this:
.. code-block:: bash
./bin/rougail --main_structural_directories dist/ --step.output json --main_namespace=new_test
{
"new_test": {
"my_variable": "my_value_extra"
}
}
Do this script:
.. code-block:: python
:caption: the :file:`script.py` file content
from rougail import Rougail, RougailConfig
from rougail.cli.rougailconfig import load
load(RougailConfig, commandline=True)
rougail = Rougail()
try:
config = rougail.run()
print(config.value.get())
except Exception as err:
print(f"ERROR: {err}")
exit(1)
.. code-block:: bash
$ python3 script.py --main_structural_directories dist/ --step.output json --main_namespace=new_test
{<TiramisuOption path="new_test">: {<TiramisuOption path="new_test.my_variable">: 'my_value_extra'}

42
docs/library/upgrade.rst Normal file
View file

@ -0,0 +1,42 @@
Upgrade dictionnaries to upper version
======================================
All dictionnaries has a format version number.
When a new format version is proposed, it is possible to automatically convert the files to the new version.
We create a term:`structure file` named :file:`dict/01-upgrade.yml` with version 1.0:
.. code-block:: yaml
---
version: '1.0'
my_variable:
multi: true
my_dyn_family:
type: "dynamic"
variable: my_variable
a_variable:
.. code-block:: python
>>> from rougail import RougailUpgrade, RougailConfig
>>> RougailConfig['main_structural_directories'] = ['dict']
>>> upgrade = RougailUpgrade()
>>> upgrade.load_dictionaries('dict_converted')
The term:`structure file` named :file:`dict_converted/01-upgrade.yml` is in version 1.1:
.. code-block:: yaml
version: '1.1'
my_variable:
multi: true
my_dyn_family:
type: dynamic
a_variable: null
dynamic:
type: variable
variable: my_variable
propertyerror: false