.. _tutorial_redefine:

Redefine variable
=================

.. objectives:: Objectives

   When we said that a :ref:`variable is immutable <variable_mutability>` when an :term:`integrator` defined it in structured data, we said that it had to be done explicitly.
   Let's see how that works.

.. prerequisites:: Prerequisites

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

    - It is possible to retrieve the current state of the various Rougail files manipulated in this tutorial step
      by checking out the corresponding tag of the `rougail-tutorials` git repository.
      Each tag corresponds to a stage of progress in the tutorial.
      Of course, you can also decide to copy/paste or download the tutorial files contents while following the tutorial steps.

    If you want to follow this tutorial with the help of the corresponding :tutorial:`rougail-tutorials git repository <src/branch/1.1>`, 
    this workshop page corresponds to the tags :tutorial:`v1.1_240 <src/tag/v1.1_240/README.md>` to :tutorial:`v1.1_241 <src/tag/v1.1_241/README.md>` 

    ::
   
       git clone https://forge.cloud.silique.fr/stove/rougail-tutorials.git
       git switch --detach v1.1_240

Username is mandatory if a password is set
------------------------------------------

We now have two new variables following the same pattern as the :ref:`previous three one <tutorial_var_propertyerror>`:

- A variable with the new type `unix_username` `username`, this variable is accessible in type HTTP, HTTPS/SSL, SOCKS4 or SOCKS5
- A variable with the new type `secret` `password`, this variable is accessible in type HTTP, HTTPS/SSL, SOCKS4 or SOCKS5

Nothing really new from now. But we haven't said everything!
In fact, we have to deal with a new situation. We have three :ref:`coherence <overall_coherence>` :ref:`configuration <configuration>` choices:

- either we fill in the username/password pair
- we fill only the username
- or leave it blank

Defining only a password makes no sense.

There are several ways to solve this case.
Let's assume that if the :term:`operator` sets a password, they must also enter a username. The password can be `null`.

In Rougail format, we would say that the password is :ref:`nullable <tutorial_nullable>` and that the username has a :ref:`variable calculation <tutorial_calc_variable>` to determine if it is :ref:`nullable <tutorial_nullable>`.
If the password is empty, the username is :ref:`nullable <tutorial_nullable>`; otherwise, it is not.

Here's how to do it:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_240/foxyproxy/00-foxyproxy.yml
   :language: yaml 
   :caption: The :file:`foxyproxy/00-foxyproxy.yml`

Now let's test with the following user data file:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_240/config/02/config.yml
   :linenos:
   :language: yaml
   :caption: The :file:`config/02/config.yml` user data

If we launch the Rougail CLI: 

.. raw:: html
   :class: terminal
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_240/config/02/cmd_ro.txt

We have this output: 

.. raw:: html
   :class: output
   :url: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_240/config/02/output_ro.html

.. note::

   The value of a variable of type secret is replaced by asterisks (`*`) when it is displayed.

Redefine it to password is hidden if an username is not set
-----------------------------------------------------------

.. type-along:: For those who follow the tutorial with the help of the git repository

    Now you need to checkout the :tutorial:`v1.1_241 <src/tag/v1.1_241/README.md>` version::
     
          git switch --detach v1.1_241

Another solution is to say to ourselves: the username is never mandatory (just like the password) but the password is hidden if the username is empty.

We could modify the structure file as we have been doing since the beginning of this tutorial.
Perhaps it's time to illustrate how to :term:`redefine` a variable.

Redefine means that the variable is unify (combine) from multiple variables declarations.

So we will create a new file with, inside, the same variable name.

First of all, we will to redefine the mandatory attribute of the `username` variable.

Secondly we will added a new calculation in the :ref:`hidden` parameters.

Here is the final result of this file:

.. extinclude:: https://forge.cloud.silique.fr/stove/rougail-tutorials/raw/commit/v1.1_241/foxyproxy/10-redefine.yml
   :language: yaml 
   :caption: The :file:`foxyproxy/10-redefine.yml`

.. keypoints:: Key points

   Redefine a variable involves changing some of its parameters with new ones.
