1Developer and Contributor Guide
2===============================
3
4This page is designed to give new developers general guidelines for
5implementing code consistent with the VOTCA and cpp style and standard.
6
7-  `Reporting Bugs <#reporting-bugs>`__
8-  `Making a release <#making-a-release>`__
9-  `CPP Resources <#cpp-resources>`__
10-  `CPP Coding Rules <#CPP-Coding-Rules>`__
11-  `Testing <#testing>`__
12-  `CPP Coding Style Guide <#cpp-coding-style-guide>`__
13-  `CPP Comment Guide <#cpp-comment-guide>`__
14-  `Updating Git Submodules <#updating-git-submodules>`__
15-  `Updates from stable <#updates-from-stable>`__
16-  `Failed Release Builds <#failed-release-builds>`__
17-  `
18
19Reporting Bugs
20--------------
21
22To report a bug, please create an issue on the appropriate GitHub repo.
23Please be sure to provide as much information as possible such as:
24
25-  The error messages
26-  The operating system
27-  What compiler was used
28-  What dependencies were installed
29-  The calculation that was being run
30
31Issues can be directly created on the appropriate GitHub repo:
32
33-  `tools <https://github.com/votca/tools/issues>`__
34-  `csg <https://github.com/votca/csg/issues>`__
35-  `csg-tutorials <https://github.com/votca/csg-tutorials/issues>`__
36-  `xtp <https://github.com/votca/xtp/issues>`__
37-  `votca <https://github.com/votca/votca/issues>`__
38
39Formatting code
40---------------
41
42VOTCA uses ``clang-format`` to format the code, code that is not
43properly formatted is automatically rejected. The style files can be
44found in each repo. CMake provides a format target which you can run to format your code.
45The easiest way to format your code is just a ``@votca-bot format`` comment in the PR, which then will automatically format your code.
46
47Doxygen documentation
48---------------
49A complete overview of all C++ classes and code can be found `here <https://doc.votca.org/>`_ .
50
51VOTCA dev-tools
52---------------
53
54Running clang-format on every commit can be a drag, as can changing the
55copyright in every header. Fortunately, you will find small scripts in the
56`dev-tools repo <https://github.com/votca/dev-tools>`__, which can
57automate this.
58
59VOTCA Continuous Integration (GitHub Actions)
60---------------------------------------------
61
62Each pull request to master in the tools, csg, csg-tutorials, xtp, xtp-tutorials or votca repository
63is built on a machine in the cloud using `GitHub actions <https://docs.github.com/en/actions>`__
64
65VOTCA can be built on various linux distributions, which are not all natively supported by GitHub actions. For non natively supported distributions,
66instead of using the default virtual machines, VOTCA first builds and then runs a `docker container <https://www.docker.com/resources/what-container>`__ for each Pull Request. The container contains all the necessary dependencies of VOTCA (see :code:`buildenv` below)
67
68The docker images can be found at `Docker Hub <https://hub.docker.com/u/votca>`__. The **votca/buildenv** containers are the basic containers, which contain all the dependencies VOTCA requires; VOTCA code itself is not included. The **votca/buildenv** can be found on `VOTCA's GitHub Container registry <https://github.com/orgs/votca/packages>`__.
69The actual containers used for running the test builds are built on top of the **votca/buildenv** containers, the resulting **votca/votca** container can be found on `Docker Hub <https://hub.docker.com/u/votca>`__ as well as `VOTCA's GitHub Container registry <https://github.com/orgs/votca/packages>`__.
70
71More information can be found in the `GitHub workflow files <https://github.com/votca/votca/tree/master/.github/workflows>`__.
72
73Making a Release
74----------------
75
76Similar to the VOTCA containers, releases are also handled by GitHub actions. :code:`votca/votca` has a :code:`release` workflow that can only be triggered manually.
77To trigger it go `here <https://github.com/votca/votca/actions?query=workflow%3Arelease>`_. The release can only be made from the
78:code:`stable` branch, but testing the creation of a release can be triggered on any branch. To make a release, trigger the action from the
79:code:`stable` branch, pick a new release tag in the :code:`release tag` box (all CHANGELOG files should already contain a section with the tag, but the date will be updated) and type :code:`yesyesyes` into the deploy box. A new release will trigger the creation of the release tag in all involved submodules (plus pull requests for the :code:`stable` to :code:`master` branch, see `below <#updates-from-stable>`__).
80
81Major releases
82~~~~~~~~~~~~~~
83
84In preparation for a major (not minor!) release the following additional steps need to be done:
85-  Create a new branch from the master branch of the :code:`votca/votca` repository and also in each of the submodules, e.g. :code:`stable_bump`.
86
87   ::
88
89       git checkout master
90       git submodules foreach git checkout master
91       git checkout -b stable_bump
92       git submodules foreach git checkout -b stable_bump
93
94-  Bump the version in each of the CMakeLists files in the :code:`votca/votca` repository and each of the submodules. This can be done by
95   replacing the string :code:`<major>-dev` by :code:`<major>-rc.1` in the main :code:`CMakeLists.txt` of :code:`votca/votca` and all submodules.
96-  Update the :code:`CHANGELOG.rst` files accordingly, by changing the top most section from :code:`<major>-dev` to :code:`<major>-rc.1`
97-  Commit changes in all submodules and update the submodules in :code:`votca/votca`
98   ::
99
100       git submodules foreach git commit -m "Version bumped to <major>-rc.1"
101       git add -u
102       git commit -m " Version bumped to <major>-rc.1"
103
104-  Push everything, but do NOT make the pull requests yet
105   ::
106
107       git submodules foreach git push origin stable_bump
108       git push origin stable_bump
109
110-  Create a branch, e.g. :code:`master_bump`, in :code:`votca/votca` and all submodules from the current master
111   ::
112
113       git checkout master
114       git submodules foreach git checkout master
115       git checkout -b master_bump
116       git submodules foreach git checkout -b master_bump
117
118-  Bump the version in each of the CMakeLists files in the :code:`votca/votca` repository and each of the submodules. This can be done by
119   replacing the string :code:`<major>-dev` by :code:`<major+1>-dev` in the main :code:`CMakeLists.txt` of :code:`votca/votca` and all submodules.
120-  Create a new secion in the :code:`CHANGELOG.rst` files for :code:`<major+1>-dev`
121-  Commit changes in all submodules and update the submodules in :code:`votca/votca`
122   ::
123
124       git submodules foreach git commit -m "Version bumped to <major+1>-dev"
125       git add -u
126       git commit -m " Version bumped to <major+1>-dev"
127
128-  Push everything, but do NOT make the pull requests yet
129   ::
130
131       git submodules foreach git push origin master_bump
132       git push origin master_bump
133
134-  Now, create a PR in :code:`votca/votca` from :code:`master_bump` into :code:`master`
135-  Once merged, create PRs in all submodules from :code:`master_bump` into :code:`master`
136-  Once all of these are merged and the automatically "Update master submodules" PR is merged, start with :code:`stable_bump` PRs
137-  Create a PR in :code:`votca/votca` from the :code:`stable_bump` branch into the :code:`stable` branch
138-  Once merged, create PRs in all submodules from each of the :code:`stable_bump` branches into each of their :code:`stable` branches
139-  Once all of them are merged and merge the automatically "Update stable submodules" PR
140-  Now everything is ready for the automatic release creation by Github Actions
141
142Release names
143~~~~~~~~~~~~~
144
145Some releases have names, so far we have:
146
147-  1.1: SuperAnn - named after the spouse of a core developer
148-  1.2: SuperDoris - named after the administrator at MPI-P (VOTCA's birthplace)
149-  1.3: SuperUzma - named after the spouse of a core developer
150-  1.4: SuperKurt - in occasion of Kurt Kremer's 60th birthday
151-  1.5: SuperVictor - named after Victor Rühle, one of the original core developers
152-  1.6: SuperPelagia - named after the spouse of a core developer
153-  1.6.2: SuperGitta - in memory of the grandmother of a core developer
154
155
156CPP Resources
157-------------
158
159A good starting point, is to take a look at the cpp standard. Though the
160code has not always consistently followed the cpp standard we now make
161an effort to really enforce it and follow best practices.
162
163-  `Best
164   Practices1 <https://www.gitbook.com/book/lefticus/cpp-best-practices/details>`__
165-  `Best
166   Practices2 <https://google.github.io/styleguide/cppguide.html>`__
167
168CPP Coding Rules
169----------------
170
171
172Here are a few general rules that should be followed:
173
174Files
175~~~~~
176
177-  Each class goes into a separate file.
178-  Each filename should be the the name of the class it contains written in lowercase.
179
180Includes
181~~~~~~~~
182
183-  When including a header file from within the same repo that you are
184   working use the relative includes. This consists of using quotation
185   marks i.e.
186
187   #include "molecule.h"
188
189-  When including from another repository, for instance you are working
190   in the csg repostory and want to include a file from the tools repo
191   use the anglular brackets i.e.
192
193   #include <votca/tools/molecule.h>
194
195Header Files
196~~~~~~~~~~~~
197
198-  One class, one header.
199-  When creating header guards use the template: VOTCA\_VOTCA-REPO-NAME\_CLASS-NAME\_H. Where
200   "VOTCA-REPO-NAME" is replaced by whichever repo the header file is in, this could be
201   tools, csg or xtp. The "CLASS-NAME" component should also be replaced, but by the name of the
202   class described in the header file:
203
204   #ifndef VOTCA\_VOTCA-REPO-NAME\_CLASS-NAME\_H #define
205   VOTCA\_VOTCA-REPO-NAME\_CLASS-NAME\_H : Code : #endif //
206   VOTCA\_VOTCA-REPO-NAME\_CLASS-NAME\_H
207
208-  Never use the "using namespace" in a header file.
209-  Avoid using includes in header files. If possible forward declare a
210   class instead.
211
212Auto
213~~~~
214
215-  Avoid using auto unless the type is very long, the reason being auto
216   obscures the underlying type and can make it difficult to discern
217   what a variable is meant to be used for.
218
219Classes
220~~~~~~~
221
222-  Normally class names in upper case.
223-  Order of access modifiers in class definitions should be as follows:
224   -  first ``public`` all functions
225   -  then ``private``/``protected`` all member variables
226   -  then ``private``/``protected`` member functions
227-  There is no rule as to where to define a ``public typedef`` in the class.
228-  All member variables are ``private``/``public``.
229-  The body of class methods should be placed in a source file or inlined at the end of the header if it exceeds a single line.
230
231Naming in Classes
232~~~~~~~~~~~~~~~~~
233
234-  All member variables should be in lower case and end with ``_``.
235-  All functions should start with upper case, no ``_`` should exist in their names.
236-  Only ``get``/``set`` methods can begin with lower case letters.
237-  For consistency all Ids should start at 0 not 1.
238
239get/set Functions
240~~~~~~~~~~~~~~~~~
241
242-  ``get``/``set`` functions should start with a lowercase ``get``/``set`` (these are the only
243   functions which should directly ``set``/``get`` a private member variable)
244-  ``get`` must return a constant reference and keep the ``class const``:
245   ``const int &getId() const;``
246-  ``set`` only sets the member, e.g.
247   ``void setId(const int &id) { _id = id; }``
248
249Functions
250~~~~~~~~~
251
252-  Functions should remain short.
253-  Functions should not have more than one use, so use boolean arguments
254   sparingly.
255
256Pointers
257~~~~~~~~
258
259-  In general, use pointers sparringly. Most objects are small and a
260   copy does not change performance. Use references if you want to avoid copies.
261-  If your pointer owns an object (i.e. it has to delete it later) use a
262   ``unique_ptr`` to it, so you do not have to call ``delete`` on it
263   yourself.
264-  If multiple objects own an object and the last object alive should
265   delete it, use a ``shared_ptr``.
266-  If your object does not have ownership but just wants to visit, you
267   can use a raw pointer, but if you can a reference is better.
268-  If you ever have to explicitly call ``delete``, you did something
269   very wrong.
270
271General
272~~~~~~~
273
274-  Do not comment out code, if you do not use it delete it.
275-  Variables should have clear and explicit names.
276-  Do not duplicate code.
277-  Functions should have no more than 3 arguments. Otherwise create a
278   class.
279-  XYZ positions should be ``Eigen::Vector3d`` from the eigen library.
280-  Readability is more important than elegant design.
281-  Leave the code better than you found it.
282-  Use pointers sparingly and especially try not to pass them around
283   objects. Prefer references.
284-  Do not write code, which you may use in the future. Only write code
285   you will use now. Write code, you need later, later. This avoids
286   cluttering the codebase with unused "at some point we will need this
287   functions".
288
289VOTCA specifics (indexing, ids, units)
290~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
291
292This can all be found here `VOTCA\_LANGUAGE\_GUIDE <VOTCA_LANGUAGE_GUIDE.rst>`__
293
294Testing
295-------
296
297Unit Testing
298~~~~~~~~~~~~
299
300Each repository contains a src folder. Within the src folder exists a
301library folder: libtools, libcsg etc... and a tools folder. A tests
302folder should also exist in the src folder. If it does not you should
303create one.
304
305For every new object and algorithm created there should exist a test. We
306use the Boost libraries testing framework. Good documentation can be
307found here:
308
309-  `Boost
310   link <https://www.ibm.com/developerworks/aix/library/au-ctools1_boost/>`__
311
312We will outline the general workflow here using the vec object in
313votca::tools. This object only has a header file it is in:
314tools/include/votca/tools/vec.h.
315
316Determine if a tests folder has already been created or not in /src. If
317it has not, take a look at what was done in the votca-tools repo.
318
3191. Create a test file in
320   `tools/src/tests/ <https://github.com/votca/tools/tree/master/src/tests>`__\ test\_vec.cc
321   must have the same name as what appears in the foreach in the
322   CMakeLists.txt file. And place the following contents:
323
324   ::
325
326       #define BOOST_TEST_MAIN
327
328       #define BOOST_TEST_MODULE vec_test
329       #include <boost/test/unit_test.hpp>
330       #include <exception>
331
332       #include <votca/tools/vec.h>
333
334       using namespace std;
335       using namespace votca::tools;
336
337       BOOST_AUTO_TEST_SUITE(vec_test)
338
339
340       BOOST_AUTO_TEST_CASE(test1){
341         vecv;
342         BOOST_CHECK_EQUAL(...);
343         BOOST_CHECK_EQUAL(...);
344         :
345       }
346       BOOST_AUTO_TEST_CASE(test2){
347         vecv;
348         BOOST_CHECK_EQUAL(...);
349         BOOST_CHECK_EQUAL(...);
350         :
351       }
352       :
353       BOOST_AUTO_TEST_SUITE_END()
354
355Replace the '...' and ':' with the appropriate syntax. For more info on
356which boost test macros to use refer to the boost documentation
357
3582. To compile and test the code create a folder tools/build and run the
359   following commands:
360
361   ::
362
363       cmake -DENABLE_TESTING=ON ../
364       make
365       make test
366
367Ensure you have an up to date version of cmake or use cmake3.
368
369Testing Across Repos
370~~~~~~~~~~~~~~~~~~~~
371
372There may come a time where changes have to be committed across more
373than one repo at the same time. Attempting to merge one repo at a time
374will cause the continuous integration to fail as changes in the other
375repos will not be pulled in. To do this correctly the following steps
376should be taken.
377
378Assuming you are in the votca/votca repository:
379
380::
381
382    git checkout <base_branch>
383    git submodule update
384    git checkout -b <some_descriptive_branch_name>
385    git submodule foreach git remote update
386    git -C <module1> checkout <sha_or_branch_of_module1_to_test>
387    git -C <module2> checkout <sha_or_branch_of_module2_to_test>
388    git add <module1> <module2>
389    git commit -m "test <module1> with <module2>"
390    git push origin <some_descriptive_branch_name>
391
3921. Here ``base_branch`` will typically be the :code:`master` or :code:`stable` branch.
393
394   ::
395
396       git checkout <base_branch>
397
3982. The submodules are updated to be sure they have incorporated the
399   latest changes in your local repository.
400
401   ::
402
403       git submodule update
404
4053. Create a branch with a descriptive name.
406
407   ::
408
409       git checkout -b <some_descriptive_name>
410
4114. Update each of the submodules, by pulling in any remote changes to
412   the submodules.
413
414   ::
415
416       git submodule foreach git remote update
417
4185. '-C' changes directory to the submodule directory and then checks out
419   the appropriate commit.
420
421   ::
422
423       git -C <module1> checkout <sha_or_branch_of_module1_to_test>
424       git -C <module2> checkout <sha_or_branch_of_module2_to_test>
425
4266. The changes are then added and commited.
427
428   ::
429
430       git add <module1> <module2>
431       git commit -m "test <module1> with <module2>"
432
4337. Finally, they are pushed to the remote branch.
434
435   ::
436
437       git push origin <some_descriptive_branch_name>
438
439A pull request is then made for the votca/votca repo using the branch
440name. Once the branch passes all tests, it can be merged. Pull requests
441for each of the repos changed can then be made. They will now compile
442against the updated votca/votca repo. Once they pass their tests, they
443can be merged. If a pull request was already made, the travis tests may
444simply need to be restarted.
445
446CPP Coding Style Guide
447-----------------------
448
449VOTCA uses a few auto formatting tools to help enforce the rules.
450
451`clang-format <https://clang.llvm.org/docs/ClangFormat.html>`__
452~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
453
454Automatically ensures consistent formatting for .cc and .h files. The
455style follows the google style fomatting rules. Have a look at the
456``.clang-format file`` in the `main votca
457repository <https://github.com/votca/votca/blob/master/.clang-format>`__
458for details.
459
460To run the clang-format function on file.cc.
461
462::
463
464    clang-format -i -style=file file.cc
465
466'-i' ensures it will make changes to file.cc, omitting the '-i' will
467display the changes without implementing them. '-style=file' ensures the
468format is read from the .clang-format file otherwise it will use a
469default style guide.
470
471By default tabs should not be used to indent, avoid inserting '\\t', it
472is preferable that spaces be used instead.
473
474`autopep8 <https://pypi.org/project/autopep8/0.8/>`__
475~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
476
477Automatically formats python .py files. We are useing the default format
478rules of autopep8. To run on file.py and update the file run:
479
480::
481
482    autopep8 -i file.py
483
484Automating Formatting
485~~~~~~~~~~~~~~~~~~~~~
486
487The above formatters can be automated at every commit using the script
488found in the `dev-tools <https://github.com/votca/dev-tools>`__
489repository. To use it copy the file ``pre-commit`` to your local .git
490subfolder to the hooks folder. E.g.
491
492::
493
494    chmod 777 dev-tools/pre-commit
495    cp dev-tools/pre-commit tools/.git/hooks/
496
497The above will make the script executable and then copy it to the local
498.git/hooks directory in the tools repository. The script not only
499updates the file format of every file staged during a commit it will
500also update the license date.
501
502CPP Comment Guide
503-----------------
504
505It is preferential that the following guidelines be followed when adding
506comments to code:
507
5081. The ``/* */`` comment blocks should be avoided and the ``//`` used in
509   their place. This is so that the ``/* */`` comment blocks can be
510   easily used for debugging.
5112. It would be preferential that the following doxygen commenting
512   stencil be used in the header files above each class and function
513   description.
514
515   ::
516
517       /**
518       * \brief function/class summary
519       *
520       * Detailed function/class description if needed
521       *
522       * @param[in] - description of parameter 1
523       * @param[out] - description of parameter 2
524       * @param[in,out] - description of parameter 3
525       * :
526       * @return - description of return type
527       */
528
529Doxygen commenting will help future developers maintain the code, in
530its fully compiled state. It may be found at: http://doc.votca.org.
531
532NOTE: Compilation of the doxygen documentation is automated when code is
533merged into the :code:`master` votca branch!
534
535Updating Git Submodules
536-----------------------
537
538VOTCA with all of its repos can be build by using the parent `votca
539repo <https://github.com/votca/votca>`__. All the other necessary repos
540appear as submodules in the parent repo. It is worth noting, the
541submodules are automatically updated through a pull request whenever changes are made to
542their respective :code:`master` branches. In essence, a submodule refers to a
543specific commit of the repo it represents.
544
545Normally, it is not necessary, but occassionally a new commit must be manually
546merged into the :code:`master` branch of a child repository. If this occurs, the
547submodule state in the parent repo also has to be updated to reflect the latest
548commit of the child repo.
549
550To update the state of a submodule the following commands can be used:
551
552::
553
554    git submodule foreach git checkout master
555    git submodule foreach git pull
556    git add -u
557    git commit -m "update all submodules"
558
559
560Updates from :code:`stable`
561
562The :code:`stable` branch contains the latest release with the most uptodate bug fixes since the release.
563Only in very limited circumstances should new features be merged into the :code:`stable` branch.
564Developers can add bug fixes by making a pull request with the :code:`stable` branch as target.
565
566As the :code:`master` branch of each repo is a child of each repo's :code:`stable` branch,
567any bugfix added to a repos :code:`stable` branch will also need to be pulled into its :code:`master` branch. If the bugfix
568is added in one of the child repositories (not :code:`votca/votca`) then :code:`votca/votca` will also need to
569reflect these changes.
570
571Keeping the repositories synchronised can be difficult. In order to help keep the :code:`master` branches and :code:`votca/votca`
572synchronised with changes in the :code:`stable` branch of a child repository the generation of four pull requests are
573automatically generated anytime a bugfix is made to the :code:`stable` branch of a child repository.
574
575E.g. if :code:`hot-bug-fix` is merged into the :code:`stable` branch of :code:`tools`:
576
5771. A pull request is created to merge :code:`stable` from :code:`tools` (child repo) into :code:`master` of :code:`tools` (child repo).
5782. A pull request is created to merge :code:`stable` from :code:`tools` (child repo) into :code:`stable` of :code:`votca/votca` (parent repo). This shoud consiste of updating the submodules in the :code:`stable` branch of votca/votca.
5793. A pull request is created to merge :code:`master` from :code:`tools` (child repo) into :code:`master` of :code:`votca/votca` (parent repo). Again this should consist of updating the submodules but in the :code:`master` branch of votca/votca.
5804. Finally, a pull request is made from :code:`stable` from :code:`votca/votca` (parent repo) to :code:`master` of :code:`votca/votca` (parent repo).
581
582To minimize manual work, it is usually best to merge the pull requests in the order that hey have been shown in the example.
583
584Failed Release Builds
585---------------------
586
587To prepare votca for distribution on different linux flavors there are
588different requirements from the package managers. Some of the
589architectures that the package managers support can be quite varied. In
590the case that a failure occurs on an architecture, that is not available
591to you, there are different approaches for debugging the problem. As an
592example, fedora dnf has extended support to the **pcc64le** architecture.
593Assuming you have access to fedora you can run the following commands to
594simulate the build process on the **pcc64le** architecture:
595
596::
597
598    dnf update
599    dnf install qemu-user-static dnf-utils
600    usermod -a -G mock <username>
601    mock -r epel-7-ppc64le --forcearch ppc64le --dnf --init
602    wget https://raw.githubusercontent.com/votca/fedora-copr/master/votca.spec
603    spectool -g votca.spec
604    rpmbuild -D"_sourcedir ${PWD}" -D"_srcrpmdir ${PWD}" -bs votca.spec
605    mock -r epel-7-ppc64le --forcearch ppc64le --dnf --no-clean votca-1.5-1.*.src.rpm
606
607Here, votca-1.5-1 should be replaced with the correct version. The above
608commands would setup and run the dnf installation process on the
609**pcc64le** enviroment. If a bug was found and the build crashes one can
610interactively intervene by issuing the following command:
611
612::
613
614    mock -r epel-7-ppc64le --forcearch ppc64le --shell
615
616You will also need to install a text editor if you want to change the
617source files before running the interactive instance.
618
619::
620
621    mock -r epel-7-ppc64le --forcearch ppc64le --install vim
622
623Note: we have used this process with the **ppc64le** architecture as an
624example, but the same procedure can be extended with different
625architectures and diferent operating systems. For example, you could use
626the **aarch64** or **armv7hl** architecture in place of **pcc64le**. You
627could also replace the **epel-7-ppc64le** os-architecure to
628**fedora-28-ppc64le**, **fedora-27-aarch64** or some other combination.
629A final point, if you simply want to build natively, for instance if you
630are running fedora on an **x86\_64** machine, the ``frocearch pcc64le``
631in the above case could just be dropped.
632