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