ORB5  v4.9.4
Contributing to the code

Guidelines for contributing to the code development.

Git configuration

If not already present, install git using your favorite package manager. To check if you already have git, you can type

> git --version
git version X.Y.Z

If you get an error, you need to install git.

Please, consider adding your information using the git config:

git config --global user.name "John Doe"
git config --global user.email "john.doe@email.com"
git config --global core.editor emacs

These information are very useful to acknowledge the work of everyone, e.g. if the ORB5 project becomes open source.

If you already have a configuration in place, you can place yourself inside the ORB5 repository and use the --local option instead of --global.

Development workflow

The development of ORB5 uses a variation of the GitHub flow (pull request). The main idea is that the master branch is a special branch on which only tested versions of the code are present. For this reason, master is protected so that only code revewer can push on it. All the development is done on so-called feature branches and whenever ready to publish, a merge request is made so that a code reviewer can include it into master, provided that the changes follow some guidelines.

Note
Work affecting files in the matlab and tools folders are not affected by the push restriction. Feel free to push yourself directly on master.

Workflow step-by-step

  1. Get the latest version of the master
    > git pull --rebase origin master
    Note
    You must already be on master. This should not result in a conflict because you should not work directly on master.
  2. Checkout to a new feature branch
    > git checkout -b <feature_branch_name>
    where <feature_branch_name> is a meaningful name that describe the work done on this branch, e.g. improve_hybrid_electron_model.
  3. Work on your feature branch as usual, i.e. git add, git commit, etc..
  4. Document your code and add tests.
  5. Use to code formatter to make sure you didn't introduce unwanted characters (tab and trailing whitespaces) and that all Fortran keywords are downcased. The code formatter can be found in tools/code_formatting and is used as follows:
    > ./format_orb5_source_code ../../src/
    You need emacs installed on your machine for the formatter to work.
  6. When you work is ready to be published. Create a "pull request" by clicking on the "Create a pull request" menu item in the ORB5 c4science project. Adapt the title with your branch name and add a description of your work. If you expect your work to modify the results, e.g. a bug fix, a new model, etc., please write it down in the pull request. Once submitted, someone will have a look at your work to check that tests have passed and that it follows the general guidelines. Your work will then be merged into the master to be ready for production.

What to do if your push is rejected

If your push is rejected with the following message:

‍Pushes on master are restricted. Please create a pull request (http://orb5.epfl.ch/contributing.html#workflow)

it means you were trying to push directly on the master branch with changes that affect the src folder. To solve this problem, begin by getting the latest version of the repository

> git fetch origin

Then, create a new feature branch from your local master

> git branch <feature branch name>

Reset your local master branch to match the one on origin:

> git reset origin/master

At this point, your local master is on origin/master and you can see a bunch of modified files with your git status. Those are the files you modified and already included in your feature branch. Verify that is indeed the case and restore them to the master version by typing

> git checkout <list fo modified files>

You should now be able to push your feature branch and create a merge request.

Tips and tricks

  • Try to merge the master branch into your feature branch as often as possible. It will avoid long and tricky merges at the end
  • Each feature branch should address a single feature. Do not hesitate to create many feature branches
  • Make small commits, each with a single intent in the code. This is much easier to review than large commits changing half the code.

Coding guidelines

Coding style

The following rules are mostly there to increase the uniformity of the code as well as its robustness. Remember than a code is generally written once, but read many times. It is therefore important for the general quality of the code to enforce a few cosmetic rules that will increase readabilty.

Files and general comments

  • All the Fortran files use the .F90 (capital F) extension
  • File name is the same as the program unit it contains. For example, module my_mod should be in file my_mod.F90.
  • Only one module per file.
  • Line length is limited to 132 characters.
  • Use lower case Fortran intrinsics.
  • Indentation is done using 2 spaces. Do not use the tab character.
  • Do not put commented blank lines, just an empty line.

Fortran style

  • All the modules should have the following structure
    module my_mod
    ! First the Fortran intrinsic modules (in alphabetical order)
    use intrinsic_mod_a
    use intrinsic_mod_b
    ! Then third-party and local modules (in alphabetical order)
    use mod_a
    use mod_b
    ! Always use a single implicit none at the beginning
    implicit none
    ! Everything should be private by default
    private
    public :: ! Add your list of public entities
    contains
    end module my_mod
  • Always use the double colon after a type declaration, e.g. integer :: a
  • Use modern comparison operators, i.e. ==, /=, >, <, <=, and >= instead of .eq., .neq., .gt., .lt., .geq., and .leq..
  • Use spaced ends, e.g. end if instead of endif.
  • Try to avoid non-standard Fortran
  • Fortran keywords, e.g. data, should not be used as variable names
  • Put a space before and after an operator (=, .and., <=, etc.), a punctuation sign ('.', ',', etc.)
  • Add spaces between mathematical operators to lighten the code. Note that you can group some terms. For example, use a = 2*b + c instead of a = 2*b+c
  • Avoid trailing whitespaces

Note that various editors allow you to automatize those coding conventions.

Editor configuration

Emacs

Adding the following lines to your Emacs configuration file, init.el, will allow you to enforce a few coding rules.

;; Set most of the indentations to 2 spaces
(setq f90-do-indent 2)
(setq f90-if-indent 2)
(setq f90-type-indent 2)
(setq f90-program-indent 2)
;; Set indentation for line continuation to 4 spaces
(setq f90-continuation-indent 4)
;; Draw a line at column number 132 to have a visual limit for line length
;; Note that this requires you to install the Emacs package `fill-column-indicator`
(add-hook 'f90-mode-hook 'fci-mode)
(add-hook 'f90-mode-hook (lambda () (setq fci-rule-column 132)))
;; Remove trailing whitespaces
;; Note that this will remove trailing whitspaces for all the files you save,
;; not only .F90 files!
(add-hook 'before-save-hook 'delete-trailing-whitespace)

Tools for code formatting and linting

Linting the code with flint

flint is a source-code static analyzer and quality checker coded in Python. It parses the source files and checks that a certain number of rules are enforced. It generates a report and can compute a quality "score".

Install it is as easy as:

> pip install flinter

Note the use of flinter instead of flint because the latter name was already taken.

The following command is used to lint a source file:

> flint lint -r flint_config.yaml my_file.F90

and the following to compute the "score":

> flint score -r flint_config.yaml my_file.F90

The option -r flint_config.yaml is to use the config file containing the rules for ORB5. If this configuration is not used, many more rules, not relevant for ORB5, will be applied. You can find the configuration file in tools/lint/flint_config.yaml.

Illustrated example

Let us consider the following file, lint_example.F90:

program lint_example
INTEGER:: var
!Add 2 to var
var=var + 2
endprogram lint_example

The linting process returns

> flint lint -r tools/lint/flint_config.yaml DOC/Doxygen/examples/lint_example.F90
nospace-end
+---------+--------+------+-------------------------+
| line_no | column | span | line |
+---------+--------+------+-------------------------+
| 0 | 0 | 10 | endprogram lint_example |
+---------+--------+------+-------------------------+
types-should-be-lowercased
+---------+--------+------+-----------------+
| line_no | column | span | line |
+---------+--------+------+-----------------+
| 2 | 2 | 7 | INTEGER:: var |
+---------+--------+------+-----------------+
missing-space-before-separator
+---------+--------+------+-----------------+
| line_no | column | span | line |
+---------+--------+------+-----------------+
| 2 | 8 | 3 | INTEGER:: var |
+---------+--------+------+-----------------+
one-space-after-comment
+---------+--------+------+-----------------+
| line_no | column | span | line |
+---------+--------+------+-----------------+
| 4 | 2 | 2 | !Add 2 to var |
+---------+--------+------+-----------------+
missing-space-around-operator
+---------+--------+------+---------------+
| line_no | column | span | line |
+---------+--------+------+---------------+
| 5 | 4 | 3 | var=var + 2 |
+---------+--------+------+---------------+
Definition: examples.F90:1

Indicating the problems and their location in the file.

The similar command for scoring the file returns

> flint score -r tools/lint/flint_config.yaml DOC/Doxygen/examples/lint_example.F90
Flinter global rating -->|2.86|<-- (7 statements)

Note that the scores can have a maximum value of 10.0. The farther from 10.0 (negative values are authorized), the less conforming to the rules.

Once all the rules applied, the example file looks like the following

program lint_example
integer :: var
! Add 2 to var
var = var + 2
end program lint_example
Note
flint is based on regular expressions to lint the Fortran source code. As such, it is not a perfect tool and false positive/negative may occur.