Replace automatic rdtscp checks with boolean option
[gromacs.git] / docs / dev-manual / code-formatting.rst
blob963389b3ce5c2eae7d1ee170dc772a5b05b26471
1 .. _gmx-codeformatting:
3 Automatic source code formatting
4 ================================
6 .. highlight:: bash
8 The source code can be automatically formatted using clang-format
9 since GROMACS 2020.
10 Both are formatting tools that apply the guidelines in :doc:`formatting`.
11 Additionally, other Python scripts are used for a few other automatic
12 formatting/checking tasks.  The overview tools page contains a list of these
13 tools: :ref:`dev-formatting-tools`.
14 This page provides more details for clang-format, clang-tidy and copyright scripts.
16 Our CI uses these same scripts (in particular, ``clang-format.sh``,
17 ``copyright.sh``, ``clang-tidy.sh`` and the ``check-source`` target) to enforce that
18 the code stays invariant under such formatting.
20 .. _gmx-clang-format:
22 Setting up clang-format
23 -----------------------
25 |Gromacs| formatting is enforced with clang-format 7.0.1.
26 :command:`clang-format` is one of the core *clang* tools.
27 It may be included in a *clang* or *llvm* package from your favorite packaging
28 system or you may find a standalone *clang-format* package,
29 but you should confirm that the provided command is version 7.0.1 or
30 7.1.0. Example::
32     $ clang-format --version
33     clang-format version 7.1.0 (tags/RELEASE_710/final)
35 If you use a different version of clang-format,
36 you will likely get different formatting results than
37 the |Gromacs| continuous integration testing system,
38 and the commits that you push will fail the automated tests.
40 .. note::
42     Refer to `LLVM <http://releases.llvm.org/download.html#7.1.0>`__ for
43     source and binary downloads.
44     If downloading sources, note that you will need to download both the
45     *LLVM source code* and the *Clang source code*.
46     As per the clang
47     `INSTALL.txt <https://github.com/llvm/llvm-project/blob/release/7.x/clang/INSTALL.txt>`__,
48     place the expanded clang source into a :file:`tools/clang` subdirectory within
49     the expanded llvm archive, then run CMake against the llvm source directory.
51 .. todo::
53     Consider referencing or providing binary packages and/or checking/managing
54     the executable from an :file:`admin/` script.
55     Reference: https://github.com/mongodb/mongo/blob/master/buildscripts/clang_format.py
57 In order to use the installed version of clang-format for ``clang-format.sh``
58 and for the pre-commit hook, you also need to run this in each of your |Gromacs| repositories::
60   git config hooks.clangformatpath /path/to/clang-format
62 Alternatively, if you just want to use ``clang-format.sh``, you can set the
63 ``CLANG_FORMAT`` environment variable to ``/path/to/clang-format``.
65 Using the pre-commit hook or git filters needs additional setup; see the
66 respective sections below.
68 clang-format discovers which formatting rules to apply from the
69 :file:`.clang-format` configuration file(s) in project directories,
70 which will be automatically updated (if necessary) when you :command:`git pull`
71 from the |Gromacs| repository.
72 For more about the tool and the :file:`.clang-format` configuration file,
73 visit https://releases.llvm.org/7.0.1/tools/clang/docs/ClangFormat.html
75 What is automatically formatted?
76 --------------------------------
78 To identify which files are subject to automatic formatting, the scripts use
79 git filters, specified in ``.gitattributes`` files.  Only files that have the
80 attribute ``filter`` set to one of the below values are processed:
82 - ``filter=complete_formatting``: Performs all formatting. Uses clang-format for code formatting.
83                                   Files included here are also passed to the clang-tidy code checker.
84 - ``filter=clangformat``: clang-format is run. Again also runs clang-tidy.
85 - ``filter=includesort``: include order is enforced and copyright headers are checked.
86 - ``filter=copyright``: only copyright headers are checked.
88 Other files are ignored by ``clang-tidy.sh``, ``clang-format.sh``,
89 ``copyright.sh`` and ``reformat_all.sh`` scripts (see below).
91 .. _gmx-clang-tidy:
93 Setting up clang-tidy
94 ---------------------
96 |Gromacs| source code tidiness checking is enforced with clang-tidy provided
97 alongside *clang* compiler version 9.
98 :command:`clang-tidy` is one of the core *clang* tools.
99 It may be included in a *clang* or *llvm* package from your favorite packaging
100 system or you may find a standalone *clang-tidy* or *clang-tools* package,
101 but you should confirm that the provided command is version 9.
102 Example::
104     $ clang-tidy --version
105       LLVM (http://llvm.org/):
106         LLVM version 9.0.0
108 If you use a different version of clang-tidy,
109 you will likely get different checking results than
110 the |Gromacs| continuous integration testing system,
111 and the commits that you push will fail the automated tests.
113 .. note::
115     Refer to `LLVM <http://releases.llvm.org/download.html#9.0.1>`__ for
116     source and binary downloads.
117     If downloading sources, note that you will need to download both the
118     *LLVM source code* and the *Clang source code*.
119     As per the clang
120     `INSTALL.txt <https://github.com/llvm/llvm-project/blob/release/9.x/clang/INSTALL.txt>`__,
121     place the expanded clang source into a :file:`tools/clang` subdirectory within
122     the expanded llvm archive, then run CMake against the llvm source directory.
124 In order to use the installed version of clang-tidy for ``clang-tidy.sh``
125 and for the pre-commit hook, you also need to run this in each of your |Gromacs| repositories::
127   git config hooks.runclangtidypath /path/to/run-clang-tidy.py
129 Alternatively, if you just want to use ``clang-tidy.sh``, you can set the
130 ``RUN_CLANG_TIDY`` environment variable to ``/path/to/run-clang-tidy.py``.
132 As above, see the sections below for using the pre-commit hook or git filters.
134 clang-tidy discovers which formatting rules to apply from the
135 :file:`.clang-tidy` configuration file(s) in project directories,
136 which will be automatically updated (if necessary) when you :command:`git pull`
137 from the |Gromacs| repository.
138 For more about the tool and the :file:`.clang-tidy` configuration file,
139 visit http://releases.llvm.org/9.0.0/tools/clang/tools/extra/docs/clang-tidy/index.html
141 Scripts
142 -------
144 ``copyright.py``
145 ^^^^^^^^^^^^^^^^
147 This script provides low-level functionality to check and update copyright
148 headers in C/C++ source files, as well as in several other types of files like
149 CMake and Python scripts.
151 This file is also used as a loadable Python module for kernel generators, and
152 provides the functionality to generate conformant copyright headers for such
153 scripts.
155 You should rarely need to run this
156 directly, but instead the bash scripts below use it internally.  You can run
157 the script with ``--help`` option if you want to see what all options it provides
158 if you need to do some maintenance on the copyright headers themselves.
160 ``copyright.sh``
161 ^^^^^^^^^^^^^^^^
163 This script runs ``copyright.py`` on modified files and reports/applies the results.
164 By default, the current HEAD commit on the source branch is compared to the work tree,
165 and files that
167 1. are different between these two trees and
168 2. change under have outdated copyright header
170 are reported.  This behavior can be changed by
172 1. Specifying an ``--rev=REV`` argument, which uses ``REV`` instead of HEAD as
173    the base of the comparison.  A typical use case is to specify ``--rev=HEAD^``
174    to check the HEAD commit.
175 2. Specifying ``--copyright=<mode>``, which alters the level of copyright
176    checking is done:
178    ``off``
179      does not check copyright headers at all
180    ``year``
181      only update copyright year in new-format copyright headers
182    ``add``
183      in addition to ``year``, add copyright headers to files that do not
184      have any
185    ``update``
186      in addition to ``year`` and ``add``, also update new-format copyright
187      headers if they are broken or outdated
188    ``replace``
189      replace any copyright header with a new-format copyright header
190    ``full``
191      do all of the above
193 By default, ``update-*`` refuses to update dirty files (i.e., that differ
194 between the disk and the index) to make it easy to revert the changes.
195 This can be overridden by adding a ``-f``/``--force`` option.
197 ``clang-format.sh``
198 ^^^^^^^^^^^^^^^^^^^
200 This script runs ``clang-format`` on modified files and reports/applies the results.
201 By default, the current HEAD commit on the source branch is compared to the work tree,
202 and files that
204 1. are different between these two trees and
205 2. change under clang-format
207 are reported.  This behavior can be changed by
209 1. Specifying an ``--rev=REV`` argument, which uses ``REV`` instead of HEAD as
210    the base of the comparison.  A typical use case is to specify ``--rev=HEAD^``
211    to check the HEAD commit.
212 2. Specifying an action:
214    - ``check-*``:   reports the files that clang-format changes
215    - ``diff-*``:    prints the actual diff of what would change
216    - ``update-*``:  applies the changes to the repository
217    - ``*-workdir``: operates on the working directory (files on disk)
218    - ``*-index``:   operates on the index of the repository
220    For convenience, if you omit the workdir/index suffix, workdir is assumed
221    (i.e., ``diff`` equals ``diff-workdir``).
222 3. Specifying ``--format=off``, which does not run clang-format.
224 By default, ``update-*`` refuses to update dirty files (i.e., that differ
225 between the disk and the index) to make it easy to revert the changes.
226 This can be overridden by adding a ``-f``/``--force`` option.
228 ``clang-tidy.sh``
229 ^^^^^^^^^^^^^^^^^
231 This script runs the ``clang-tidy`` source code checker on modified files
232 and either reports or applies resulting changes. By default, the current
233 HEAD commit on the source branch is compared to the work tree,
234 and files that
236 1. are different between these two trees and
237 2. change when applying clang-tidy
239 are reported. This behavior can be changed by
241 1. Specifying an ``--rev=REV`` argument, which uses ``REV`` instead of HEAD as
242    the base of the comparison.  A typical use case is to specify ``--rev=HEAD^``
243    to check the HEAD commit.
244 2. Specifying an action:
246    - ``check-*``:   reports the files that clang-format changes
247    - ``diff-*``:    prints the actual diff of what would change
248    - ``update-*``:  applies the changes to the repository
249    - ``*-workdir``: operates on the working directory (files on disk)
250    - ``*-index``:   operates on the index of the repository
252    For convenience, if you omit the workdir/index suffix, workdir is assumed
253    (i.e., ``diff`` equals ``diff-workdir``).
254 3. Specifying ``--tidy=off``, which does not run clang-tidy.
256 By default, ``update-*`` refuses to update dirty files (i.e., that differ
257 between the disk and the index) to make it easy to revert the changes.
258 This can be overridden by adding a ``-f``/``--force`` option.
261 git pre-commit hook
262 ^^^^^^^^^^^^^^^^^^^
264 If you want to run ``copyright.sh``, ``clang-tidy.sh`` and/or
265 ``clang-format.sh`` automatically for changes you make, you can
266 configure a pre-commit hook using ``admin/git-pre-commit``:
268 1. Copy the ``git-pre-commit`` script to .git/hooks/pre-commit.
270 2. Specify the paths to ``run-clang-tidy`` and ``clang-format`` for the hook if you have not already done
271    so::
273      git config hooks.runclangtidypath /path/to/run-clang-tidy.py
274      git config hooks.clangformatpath /path/to/clang-format
276 3. Set the operation modes for the hook::
278      git config hooks.clangtidymode check
279      git config hooks.clangformatmode check
280      git config hooks.copyrightmode  update
282 With this configuration, all source files modified in the commit are run
283 through the code formatting tool, are checked with clang-tidy
284 and also checked for correct copyright headers.
285 If any file would be changed by ``clang-tidy.sh``, ``clang-format.sh`` or ``copyright.sh``,
286 the names of those files are reported and the commit is prevented.
287 The issues can be fixed by running the scripts manually.
289 To disable the hook without removing the ``pre-commit`` file, you can set ::
291   git config hooks.clangtidymode off
292   git config hooks.copyrightmode off
293   git config hooks.clangformatmode off
295 To disable it temporarily for a commit, set NO_FORMAT_CHECK environment
296 variable.  For example, ::
298     NO_FORMAT_CHECK=1 git commit -a
300 You can also run ``git commit --no-verify``, but that also disables other hooks,
301 such as the Change-Id ``commit-msg`` hook used by Gerrit.
303 Note that when you run ``git commit --amend``, the hook is only run for the
304 changes that are getting amended, not for the whole commit.  During a rebase,
305 the hook is not run.
307 The actual work is done by the ``admin/clang-tidy.sh``, ``admin/clang-format.sh``
308 and ``admin/copyright.sh`` scripts, which get run with the ``check-index`` action,
309 and with ``--copyright`` and ``--format`` getting set according
310 to the ``git config`` settings.
312 ``reformat_all.sh``
313 ^^^^^^^^^^^^^^^^^^^
315 This script runs clang-format, ``copyright.py``, or the include sorter for all
316 applicable files in the source tree.  See ``reformat_all.sh -h`` for the
317 invocation.
319 The script can also produce the list of files for which these commands would be
320 run.  To do this, specify ``list-files`` on the command line and use
321 ``--filter=<type>`` to specify which command to get the file list for.  This can
322 be used together with, e.g., ``xargs`` to run other scripts on the same set of
323 files.
325 For all the operations, it is also possible to apply patters (of the same style
326 that various git commands accept, i.e., ``src/*.cpp`` matches all ``.cpp`` files
327 recursively under ``src/``).  The patterns can be specified with
328 ``--pattern=<pattern>``, and multiple ``--pattern`` arguments can be given.
330 ``-f``/``--force`` is necessary if the working tree and
331 the git index do not match.
334 Using git filters
335 -----------------
337 An alternative to using a pre-commit hook to automatically apply uncrustify or
338 clang-format on changes is to use a git filter (does not require either of the scripts,
339 only the ``.gitattributes`` file).  You can run ::
341   git config filter.clangformat.clean \
342       "/path/to/clang-format -i"
344 To configure a filter for all files that specify ``filter=complete_formatting`` attribute
345 that indicates that all formatting steps should be performed.
347 The pre-commit hook + manually running the scripts gives better/more
348 intuitive control (with the filter, it is possible to have a work tree that is
349 different from HEAD and still have an empty ``git diff``) and provides better
350 performance for changes that modify many files.  It is the only way that
351 currently also checks the copyright headers.
353 The filter allows one to transparently merge branches that have not been run
354 through the source checkers, and is applied more consistently (the pre-commit hook is
355 not run for every commit, e.g., during a rebase).