Preliminaries
================

.. objectives:: Objectives

   We will learn how to:

   - create a Rougail :term:`structure description file <structure file>`
   - define a Rougail :term:`structure file format version <structure file>`
   - define a Rougail :term:`variable` and set its :term:`value`

.. prerequisites:: Prerequisites

    We assume that Rougail's library is :ref:`installed <installation>` on your computer.

Making a structure file 
-------------------------

.. demo:: The folder structure

    Here is the tree structure we want to have::

        workplace
        ├── firefox
        │   └── struct.yml

- Let's make a :file:`workplace` directory, with a :file:`firefox` subfolder.
- First, we wil make a :term:`structure file <structure file>`, so let's create a :file:`struct.yml` file
  located in the :file:`firefox` subfolder.

.. type-along:: An empty structure file

This is an empty Rougail structure description file.

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_000/firefox/00-proxy.yml
   :language: yaml
   :caption: An empty rougail dictionnary file with the version number only
   :name: RougailStructVersion

.. 
    ---
    version: 1.1


Defining a variable and its default value
----------------------------------------------

.. type-along:: a first variable

    Let's put a variable in the Rougail :term:`structure description file <structure file>`

This is a first Rougail variable in a Rougail dictionnary:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_010/firefox/00-proxy.yml
   :language: yaml
   :caption: A Rougail dictionnary file with only one variable
   :name: RougailDictionaryFirstVariableName

.. 
    ---
    proxy_mode:

- If we run the Rougail CLI utility command 

.. code-block:: text
   :class: terminal
   
    rougail -v 1.1 -m firefox/

we will actually have an error: 

.. raw:: html
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_010/config/01/output_ro.html
   :class: error-box

..
    🛑 ERRORS
    ┣━━ The following variables are mandatory but have no value:
    ┗━━   - proxy_mode

Because this variable is :term:`mandatory` and needs to be set **but** there's no value yet.

We can therefore deduce this result:

.. note:: Once defined, an option configuration :term:`value` is :term:`mandatory`.
   
Rougail waits for the `proxy_mode` configuration option's value to be set.

.. seealso:: To go further, have a look at the :tiramisu:`mandatory option <glossary.html#term-mandatory-option>` according to the definition of Tiramisu.

.. glossary::

    mandatory

        A variable is mandatory when a value is required, that is, `None` is not a possible value.
        It **must** have a defined value.
        
Let's add a variable's description, which is not mandatory but which is a good practice:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_011/firefox/00-proxy.yml
   :language: yaml
   :caption: A Rougail dictionnary file with a variable and a description
   :name: RougailStructFirstVariableDescription

.. 
    ---
    proxy_mode:
      description: Configure Proxy Access to the Internet

.. type-along:: how to set a value -- the default value

We need to set a value to this `proxy_mode` variable. A first way to do it is *to set a value by default*. 

.. glossary::

    default value
        
        A default value is a variable value that is predefined, that is, this value is placed 
        right in the structure file.

So let's define a variable with a description -- **and a default value**

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/a1969abccd5e10872d4eb901a26fa16007c9fb1d/firefox/00-proxy.yml
    :language: yaml
    :caption: A rougail dictionnary file with a default value for the variable
    :name: RougailDictionaryVariableDefault

..
    ---
    proxy_mode:
      description: Configure Proxy Access to the Internet
      default: No proxy


.. type-along:: how to set a value -- the assignment

    A default value has been set, great. Now how do I assign a value to a variable?

How to set a value
----------------------

So far we have only talked about the one that writes the :term:`structure files <structure file>`\ . It's *role* is called the integrator's role.

.. glossary::

    integrator

        An integrator in the Rougail field is the person who writes the :term:`structure files <structure file>`\ .
        He has the responsibilité of the integration process, that is,
        defines the variables and the relationship between them, the variables that are allowed
        (or not) to be set, and so on. His responsabilites are the **structuration** and the **consistency**
        of the variables.

Now we will talk about the one that defines the values. It is called the operator.

.. glossary::

    operator

        An operator in the Rougail field is the person who assigns :term:`value`\ s to the pre-defined variables,
        his responsabilities are to set variable values correctly.

        The user :term:`value`\ s, that is the values that have been set by the operator, are of course type validated. The type validation is driven by the definitions in the :term:`structure file <structure file>`.

Values are mandatory
-------------------------

It is the operator's responsibility to set the user datas variables values.
The operator does not handle the structure files, 
he is responsible of other files called the :term:`user data file`\ s. 

.. glossary::

    user datas

        User datas, as opposed to structured datas, are datas that only concern the assignment of values
        and not the consistency of the variables.

        The variable's values are also called **user values**. 
        
        The consistency field is outside of the user datas scope. 
        The consistency is handled in the :term:`structured datas <structured data>`\ 's scope.

.. exercise:: Folder structure update

    Now we add a :file:`config/config.yml` file in our project::

        workplace
        ├── firefox
        │   ├── struct.yml
        └── config
            └── config.yml

.. type-along:: how to set a value in a user datas file

So for example if the integrator has not set any default value in his structure file, 
the operator can do it like this:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_011/config/02/config.yaml
   :language: yaml
   :caption: A Rougail user datas file :file:`config/config.yml`, with a default value set.
   :name: RougailConfigDefaultValue

.. 
    ---
    proxy_mode: No proxy

With the rougail CLI the operator has to add the `-u file -ff config/config.yml` options: 

.. code-block:: text
   :class: terminal
   :caption: A rougail Command Line Utility call with the :file:`config/config.yml` Rougail user datas file

   rougail -v 1.1 -m firefox -u file -ff config/01/config.yaml

Let us clarify this essential point:

- the integrator works on structure files
- the operator works on user data files
    
.. note:: Most of the time, the integrator and the operator are one and the same person, here we are talking about roles and not necessarily about people.    

Variable's type
-----------------

.. type-along:: type inference

If the `type` attribute is not set, Rougail infers a `string` type for the `proxy_mode` configuration option variable type as defined in the structure file.

.. type-along:: type setting

If the operator sets an option value for example with the `number` type, like this:

.. code-block:: yaml

    ---
    example_var:
      description: Configure Proxy Access to the Internet
      type: number

Then Rougail will expect a `int` or a `float` as a value for the `example_var` variable.

.. type-along:: Defining a choice type

In our firefox use case, the real type of the `proxy_mode` variable will be now set as a  `choice` type:


.. glossary::

   choice type

       A choice type variable is a variable where the content is constrained by a list

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_013/firefox/00-proxy.yml
   :linenos:
   :language: yaml
   :caption: The real :file:`firefox/proxy.yml` Rougail dictionnary file with a choice type
   :name: RougailDictionaryChoiceType

..
    ---
    proxy_mode:
      description: Configure Proxy Access to the Internet
      type: choice
      choices:
        - No proxy
        - Auto-detect proxy settings for this network
        - Use system proxy settings
        - Manual proxy configuration
        - Automatic proxy configuration URL
      default: No proxy

- Let's run the Rougail CLI 

.. code-block:: text
   :class: terminal
   
    rougail -v 1.1 -m firefox/

We have an output like this one: 

.. raw:: html
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_013/config/01/output_ro.html
   :class: output
   
..
    <pre>╭────────────────────────── Caption ──────────────────────────╮
    │ Variable                           <span style="color: #ffd700">Default value</span>            │
    │ <span style="color: #5c5cff">Undocumented variable</span>              Modified value           │
    │ <span style="color: #ff0000">Undocumented but modified variable</span> (<span style="color: #00aa00">Original default value</span>) │
    │ <span style="color: #ffaf00">Unmodifiable variable</span>                                       │
    ╰─────────────────────────────────────────────────────────────╯
    Variables:
    <span style="color: #5c5cff">┗━━ </span>📓 proxy_mode: <span style="color: #ffd700">No proxy</span>
    </pre>

The `proxy_mode` variable here, implicitely requires a value. It is a :term:`mandatory` variable.

As we set the `proxy_mode` variable as `No proxy` by default, we actually have specified a value, and the value appears in yellow, which means : "set by default". 

Container type
-----------------

We say that the `proxy_mode` variable is *constrained* (by the `choice` type).

We have the list of the possible (authorized) values:

- `No proxy`
- `Auto-detect proxy settings for this network`
- `Use system proxy settings`
- `Manual proxy configuration`
- `Automatic proxy configuration URL`

.. glossary::

    choice type

        The `proxy_mode` setting is "choice" (`type: choice`) means that
        there is a list of available values that can be selected.

.. keypoints:: Key points progress

    Indeed, in the Firefox configuration, it is possible to define several configuration modes, from no proxy at all (`no proxy`) to a kind of automatic configuration mode from a file (`set up proxy configuration from a file`).


    **Keywords**

    - :term:`structure file <structure file>`: structure description file
    - :term:`variable`: an option's name which has a value
    - a variable's description
    - a variable's type
    - a variable's default value
    - the :term:`integrator` and :term:`operator` roles
    - a mandatory value
    - a choice type

    **Progress**

    To sum up, we have arrived at this point in writing a structure file like this:

    **Structure description file**

    .. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/tag/v1.1_013/firefox/00-proxy.yml
       :linenos:
       :language: yaml
       :caption: A Rougail dictionnary file with a variable named `proxy_mode`, with a default value.

..

   .. raw:: text

    ---
    proxy_mode:
      description: Configure Proxy Access to the Internet
      type: choice
      choices:
        - No proxy
        - Auto-detect proxy settings for this network
        - Use system proxy settings
        - Manual proxy configuration
        - Automatic proxy configuration URL
      default: No proxy

