***************
Developer guide
***************

Here a few guidelines for ChemShell developers.


Git repositories
================

The Py-ChemShell and DL-FIND repositories are kept on `STFC's Gitlab instance <https://gitlab.stfc.ac.uk>`_.
Please contact the developers if you wish to gain access.

Development follows the `Gitlab workflow <https://about.gitlab.com/2016/10/25/gitlab-workflow-an-overview/>`_ 
with a `Gitlab flow <https://docs.gitlab.com/ee/workflow/gitlab_flow.html>`_ release branch model.

In practice this means that for any new feature, bug fix or other development task, 
the following process should be followed:

1. Create a **New Issue** on GitLab. This is the place to describe your idea 
   or problem and for potential solutions to be discussed. 
2. Once the issue has been created and any discussions have been resolved, the
   **Create Merge Request** button on the issue page should be used to create
   a working branch for the issue and draft merge request. Please keep branch 
   names short but informative, and retain GitLab's provided numbering.
3. Commit and push your changes to the branch until the issue is resolved.
4. When the branch is ready to be merged, go to the merge request page on 
   GitLab and click **Ready** to remove the draft status. The branch will then
   be reviewed by the maintainers and merged if all is well.

Note that pushing directly to the master branch is not permitted, as this 
breaks the branch and merge model.

Best practices for branches and commits
---------------------------------------

* Ideally, changes in a branch should resolve the issue that it has been 
  created for, and should contain no unrelated developments. A new issue and 
  branch should be created for these wherever possible.
* Branches should be short lived. The longer a branch exists, the harder it 
  will be to integrate into the main codebase. If you find that a task requires
  a long lived branch, consider whether it can be broken down into smaller 
  issues that can be tackled in turn.
* Commits should be small and serve a single purpose. Large, unfocused commits
  are hard for other developers to follow.
* On the other hand, don't commit a change one file at a time if they are all 
  for the same purpose; commit them as a single logical unit.
* Avoid trivial test commits and committing temporary files that don't belong
  in the repository. 
* Always write helpful commit messages that allow others to quickly understand
  the change.

By convention commit messages should be writen as a short, single sentence 
summary of the change, ideally of 50 characters or less, and then if necessary
followed by a blank line then a more detailed description of the commit.
More importantly than the formatting, the message should always explain
**what** was done and **why** you did it.

For a more detailed guide to writing good commit messages, see 
`How to Write a Git Commit Messsage <https://cbea.ms/git-commit/>`_.


Languages
=========

The code should as standard support the GNU compilers and libraries
that are available on the latest LTS (long term support) version of
Ubuntu Linux. Ideally, any changes should also be tested with Intel's compilers. 


Python
------

The code should support Python v3.7 and above. Python 2 is NOT supported.

The official `Python Style Guide <http://legacy.python.org/dev/peps/pep-0008/>`_
should be followed as far as possible when writing python code.

In particular use **4 spaces** for indentation, and never tabs!

Fortran
-------

Fortran 2003 is now generally well supported by all major compilers and can
be used if it provides clear advantages over using only Fortran 90/95 constructs.
We make extensive use of Fortran 2003 for coupling together Python and Fortran,
e.g. through the ``ISO_C_BINDING`` module.

Features from more recent versions of Fortran can be used providing they are 
supported by the following compilers: GNU (gfortran), Intel (ifort), IBM (xlf),
Nvidia/PGI, and Cray. If you do not have direct access to these compilers, 
please make sure at least to check online documentation that the constructs 
are supported.

Regardless of the version used, all Fortran files should use the 
suffix ``.f90``, which indicates free format. The only exception is 
legacy fixed-format code (e.g. where required to interface to external codes),
where the suffix ``.f`` should be used.

C
-

In general C should only be used where absolutely necessary, to minimise
the complexity of the code.
One example where C must be used is calling the Python-C API 
to embed the python interpreter in the ChemShell executable.

C is implicitly used for coupling python and Fortran via ctypes, but this
does not require writing any actual C code.

C extensions may be used providing they are supported by the GNU, Intel, 
IBM, Nvidia/PGI and Cray C compilers.

C++ should not be used, except when required to compile external software
linked in to ChemShell.


Build system
============

CMake is the preferred solution for building the code.


Testing platforms
=================

Py-ChemShell is tested using the `ANVIL <https://anvil.softeng-support.ac.uk/>`_ 
research software testing platform maintained by STFC. ANVIL in turn makes 
use of the Jenkins CI system. The test suite in
``tests/`` is run automatically whenever a commit is pushed to the
central repository. Both Intel and GNU compilers are tested in
serial and parallel with a range of external QM and MM codes.

Please ensure that all code is tested locally on the test suite before
being pushed to the central repository in order to minimise the chance of
complaints from Jenkins. 

The test suite is run using the script ``test`` in ``tests/``.



Licencing
=========

Both Py-ChemShell and DL-FIND are released under the open source GNU LGPL v3 licence.
Authors should ensure they have permission for any code committed to the repository
to be released under this licence.

