Good practices regarding Git and Gitlab
#######################################
CIF uses the version control system ``git`` has its code hosted on a Gitlab instance.
These tools put very few restriction on your contributions but some good practices
can be followed in order to produce better quality and easily maintanable code.
.. admonition:: Official documentations
Gitlab has a `very complete documentation `__
which also contain a `git documentation `__
Some basics
===========
Work on an up-to-date version of the code
-----------------------------------------
Before modifying CIF's code, make sure you are on the latest version of the code.
This will help to avoid conflicts with other people modifications.
Use the ``git pull`` command to update your local repository.
Write descriptive commit messages
---------------------------------
When submitting your changes, write a commit message that describes what have been
change. Commit messages like "updated file", "fix bug" are in most cases unhelpful.
Pull before pushing
-------------------
To avoid conflicts with other people modifications, you should always "pull"
incoming changes before pushing yours.
Here is the typical order of operations for a simple change:
.. code-block:: shell
git pull # Work on an up-to-date version of the code
# Modify "foo.py" and "sources/toto.py"
git add foo.py sources/toto.py # Add the modified files to the staged changes
git commit -m "Describe your changes here"
git pull # Make sure you are still on the la test version of the code
git push # Submit your changes
Dividing your contribution in multiple small commits
----------------------------------------------------
Rather than a big single commit containing changes for dozens of files, it is often
better to divide your contribution in multiple smaller commits.
Here is the typical order of operations for changes with multiple commits:
.. code-block:: shell
git pull
# Modify "foo.py" and "sources/toto.py"
git add foo.py sources/toto.py
git commit -m "Describe your changes here"
# Modify "sources/mod.f90"
git add sources/mod.f90
git commit -m "Describe your others changes here"
git pull
git push
.. _tests-pipeline:
Pay attention to the automatic tests
------------------------------------
When you push some commits, the Gitlab instance runs some automated tests.
These tests **may** fail if you broke something, in that case you should receive an
email notification from Gitlab.
.. warning::
The tests do not cover all of the CIF use cases.
Thus, passing tests **do not** mean that your changes are free of bugs
.. |running| image:: images/favicon_status_running.png
.. |success| image:: images/favicon_status_success.png
.. |failed| image:: images/favicon_status_failed.png
You can see the state of the tests related to your commit by clicking the *pipeline
button* ( |running| |failed| |success| ) one the side of your commit or following this link:
``https://gitlab.in2p3.fr/satinv/cif/-/commit/[your-commit-id]/pipelines``
.. image:: images/commit.png
:align: left
:width: 700
|
|
Working on a separate branch
============================
Should I work on the main developpment branch ``devel`` or on my own branch?
----------------------------------------------------------------------------
You want to:
* Fix a small bug
* Add a new option in a plugin
* Add a new by :doc:`datastream plugin `
Or more generally do a modification that **should not affect other users configuration
or conflict with other users contributions**.
Then you should be able to publish your changes directly on the main developpment branch ``devel`` safely.
.. warning::
Always pay attention to the results of the :ref:`automated tests ` when
pusshing changes on the developpment branch ``devel``.
In other cases, especially if you plan to modify some part of the code used by others
or to submit big changes, you should create a new branch and push to push your contribution on.
Creating a new branch
---------------------
You can create a new branch from the Gitlab repository homepage or with the command:
.. code-block:: shell
git branch [your-new-branch]
.. image:: images/create_branch.png
:width: 400
Switching your CIF directory to your new branch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can switch your CIF directory to your new branch with the command:
.. code-block:: shell
git checkout [your-new-branch]
After that, every commit you make will be pushed to your new branch.
.. note::
If you installed ``pycif`` in editable mode (``-e`` or ``--editable`` option
when installing with ``pip install``), running your pycif will now use the
code of your new branch.
Create a new CIF directory for your new branch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Maybe you will want to be able to run some simulations with an unmodified version
of CIF while working on your new branch.
If you want to keep your current CIF directory unchanged you can create a new CIF
directory on your new branch with the command:
.. code-block:: shell
git worktree add [/path/to/new/directory] [your-new-branch]
Then you may want to create a Python virtual environment in order to be able to
run your new copy of ``pycif`` while preserving the current one:
.. code-block:: shell
cd /path/to/new/directory
python -m venv .venv-cif-branch # Create a new virtual environment in .venv-cif-branch
source .venv-cif-branch/bin/activate # Activate the virtual environment
pip install -e . # Install the new copy of pycif in the virtual environment
You can activate the virtual environment and run the new copy of ``pycif`` with:
.. code-block:: shell
cd /path/to/new/directory
source .venv-cif-branch/bin/activate # Activate the virtual environment
python -m pycif some-config-file.yaml # Run the new copy of pycif
deactivate # Deactivate the virtual environment, switch back to the main python installation
Merging your branch to the developpment branch
----------------------------------------------
Creating a merge request
~~~~~~~~~~~~~~~~~~~~~~~~
Once you have finished your contribution, you can open a merge request on Gitlab
from your branch to the ``devel`` branch.
In the merge request, you should describe your changes, explain why they are needed,
and add any other relevant information. You can also tag people that might be impacted
by your contribution, and mention eventual issues that would be fixed by your contribution.
.. note::
Before creating the merge request, you can limit the risk of conflicts and
clean the Git history with a `rebase `__:
.. code-block:: shell
git fetch origin devel
git rebase origin/devel [your-new-branch]
git push
If there is some merge conflicts and you have difficulties resolving them,
you can fall back to a simple merge:
.. code-block:: shell
git rebase --abort # Abort the current rebase operation
git merge origin/devel
git push
Merging your branch
~~~~~~~~~~~~~~~~~~~
Before merging you should make sure that:
- There is no conflict with the ``devel`` branch
- All the tests have passed successfully for your branch
- The "squash commits" checkbox is checked
- The "delete source branch" checkbox is checked
When all these conditions are met, you can merge your branch to the ``devel`` branch
Code quality
============
Follow Python coding conventions and guidelines
-----------------------------------------------
When coding in Python, the language itsef does not enforce any particular coding style
(variable naming conventions, indentation, etc.).
Considering that code is read much more often than it is written, and that in a community
project as CIF, other people will read your code, it is important to make sure that
your code is readable and easy to understand.
Ideally Python code in CIF should should follow Python official `PEP8 style guidelines `__.
Within PEP8 guidelines, naming conventions are especially important:
* Functions and variables names should be lowercase, with words separated by underscores as necessary to improve readability:
- Good: ``my_function``, ``my_variable``
- Bad: ``nameWithAnyCaps``, ``toolongnamewithnounderscore``
* Names with a single leading underscore as ``_private_var_or_func`` are private to their module/class of origin and should **never** be used outside of it.
* Names with a double leading and trailing underscores ("dunder") as ``__name__`` are "magic" objects or attributes. You should **never** invent such names in your code.
Document your code
------------------
Other people will read and use your code, so it is important that you are not the
only person able to understand easily.
Use comments to describe your code and `docstrings `__
to document your functions (what dor they do, what parameters they take, what they return).
Use a linter
------------
Using a linter like `pylint `__ can highlight problems or
unconventional usages of Python in your code and provide hints on how to fix them.
Most Python code editors have a built-in linter, or linter extensions.
Use a formatter
---------------
Formatting your code accordingly to PEP8 conventions helps a lot with readability.
It can be done automatically with tools like `black `__
or `autopep8 `__.
Most Python code editors have a built-in formatter, or formatter extensions.