Correct Shake test tolerances
[gromacs.git] / docs / dev-manual / uncrustify.rst
blob9ee104760877b9ae23c0e69bd7e6d69555368cbe
1 Automatic source code formatting
2 ================================
4 .. highlight:: bash
6 The source code can be automatically formatted using uncrustify, an automatic
7 source code formatting tool, to follow the guidelines in
8 :doc:`formatting`.
9 Additionally, Python scripts are used for a few other automatic
10 formatting/checking tasks.  The overview tools page contains a list of these
11 tools: :ref:`dev-formatting-tools`.
12 This page provides more details for uncrustify and copyright scripts.
14 Jenkins uses these same scripts (in particular, ``uncrustify.sh`` and the
15 ``check-source`` target) to enforce that the code stays invariant under such
16 formatting.
18 Setting up uncrustify
19 ---------------------
21 A patched version of uncrustify is used for |Gromacs|.  To set this up, you need
22 to do these (once):
24 1. Change to a directory under which you want to build uncrustify and run::
26      git clone -b gromacs git://github.com/rolandschulz/uncrustify.git
27      cd uncrustify
28      ./configure
29      make
31 2. Copy the binary ``src/uncrustify`` into a directory of your choice
32    (``/path/to/uncrustify`` below).
34 Alternatively, if you are running Linux, you can try whether the binary from
35 http://redmine.gromacs.org/issues/845 works for you.
37 In order to use the binary for ``uncrustify.sh`` and for the pre-commit hook, you
38 also need to run this in each of your |Gromacs| repositories::
40   git config hooks.uncrustifypath /path/to/uncrustify
42 Alternatively, if you just want to use ``uncrustify.sh``, you can set the
43 ``UNCRUSTIFY`` environment variable to ``/path/to/uncrustify``.
45 Using the pre-commit hook or git filters needs additional setup; see the
46 respective sections below.
48 What is automatically formatted?
49 --------------------------------
51 To identify which files are subject to automatic formatting, the scripts use
52 git filters, specified in ``.gitattributes`` files.  Only files that have the
53 attribute ``filter`` set to one of the below values are processed:
55 - ``filter=uncrustify``: uncrustify is run, copyright headers are checked, and
56   include order is enforced
57 - ``filter=uncrustify_only``: only uncrustify is run
58 - ``filter=includesort``: include order is enforced and copyright headers are
59   checked
60 - ``filter=copyright``: only copyright headers are checked
62 Other files are ignored by ``uncrustify.sh`` and ``reformat_all.sh`` scripts (see
63 below).
66 Scripts
67 -------
69 ``copyright.py``
70 ^^^^^^^^^^^^^^^^
72 This script provides low-level functionality to check and update copyright
73 headers in C/C++ source files, as well as in several other types of files like
74 CMake and Python scripts.
76 This file is also used as a loadable Python module for kernel generators, and
77 provides the functionality to generate conformant copyright headers for such
78 scripts.
80 The script is similar to uncrustify in that there is rarely need to run it
81 directly, but instead the bash scripts below use it internally.  You can run
82 the script with ``--help`` option if you want to see what all options it provides
83 if you need to do some maintenance on the copyright headers themselves.
85 ``uncrustify.sh``
86 ^^^^^^^^^^^^^^^^^
88 This script runs uncrustify and ``copyright.py`` on modified files and
89 reports/applies the results.
90 By default, the current HEAD commit is compared to the work tree,
91 and files that
93 1. are different between these two trees and
94 2. change under uncrustify and/or have outdated copyright header
96 are reported.  This behavior can be changed by
98 1. Specifying an ``--rev=REV`` argument, which uses ``REV`` instead of HEAD as
99    the base of the comparison.  A typical use case is to specify ``--rev=HEAD^``
100    to check the HEAD commit.
101 2. Specifying an action:
103    - ``check-*``:   reports the files that uncrustify changes
104    - ``diff-*``:    prints the actual diff of what would change
105    - ``update-*``:  applies the changes to the repository
106    - ``*-workdir``: operates on the working directory (files on disk)
107    - ``*-index``:   operates on the index of the repository
109    For convenience, if you omit the workdir/index suffix, workdir is assumed
110    (i.e., ``diff`` equals ``diff-workdir``).
111 3. Specifying ``--uncrustify=off``, which does not run uncrustify.
112 4. Specifying ``--copyright=<mode>``, which alters the level of copyright
113    checking is done:
115    ``off``
116      does not check copyright headers at all
117    ``year``
118      only update copyright year in new-format copyright headers
119    ``add``
120      in addition to ``year``, add copyright headers to files that do not
121      have any
122    ``update``
123      in addition to ``year`` and ``add``, also update new-format copyright
124      headers if they are broken or outdated
125    ``replace``
126      replace any copyright header with a new-format copyright header
127    ``full``
128      do all of the above
130 By default, ``update-*`` refuses to update dirty files (i.e., that differ
131 between the disk and the index) to make it easy to revert the changes.
132 This can be overridden by adding a ``-f``/``--force`` option.
134 git pre-commit hook
135 ^^^^^^^^^^^^^^^^^^^
137 If you want to run ``uncrustify.sh`` automatically for changes you make, you can
138 configure a pre-commit hook using ``admin/git-pre-commit``:
140 1. Copy the ``git-pre-commit`` script to .git/hooks/pre-commit.
141 2. Specify the path to uncrustify for the hook if you have not already done
142    so::
144      git config hooks.uncrustifypath /path/to/uncrustify
146 3. Set the operation mode for the hook::
148      git config hooks.uncrustifymode check
149      git config hooks.copyrightmode  update
151 With this configuration, all source files modified in the commit are run
152 through uncrustify and checked for correct copyright headers.
153 If any file would be changed by ``uncrustify.sh``, the names of those files are
154 reported and the commit is prevented.  The issues can be fixed by running
155 ``uncrustify.sh`` manually.
157 To disable the hook without removing the ``pre-commit`` file, you can set ::
159   git config hooks.uncrustifymode off
160   git config hooks.copyrightmode off
162 To disable it temporarily for a commit, set NO_FORMAT_CHECK environment
163 variable.  For example, ::
165     NO_FORMAT_CHECK=1 git commit -a
167 You can also run ``git commit --no-verify``, but that also disables other hooks,
168 such as the Change-Id ``commit-msg`` hook used by Gerrit.
170 Note that when you run ``git commit --amend``, the hook is only run for the
171 changes that are getting amended, not for the whole commit.  During a rebase,
172 the hook is not run.
174 The actual work is done by the ``admin/uncrustify.sh`` script, which gets
175 run with the ``check-index`` action, and with ``--uncrustify`` and ``--copyright``
176 getting set according to the ``git config`` settings.
178 ``reformat_all.sh``
179 ^^^^^^^^^^^^^^^^^^^
181 This script runs uncrustify, ``copyright.py``, or the include sorter for all
182 applicable files in the source tree.  See ``reformat_all.sh -h`` for the
183 invocation.
185 The script can also produce the list of files for which these commands would be
186 run.  To do this, specify ``list-files`` on the command line and use
187 ``--filter=<type>`` to specify which command to get the file list for.  This can
188 be used together with, e.g., ``xargs`` to run other scripts on the same set of
189 files.
191 For all the operations, it is also possible to apply patters (of the same style
192 that various git commands accept, i.e., ``src/*.cpp`` matches all ``.cpp`` files
193 recursively under ``src/``).  The patterns can be specified with
194 ``--pattern=<pattern>``, and multiple ``--pattern`` arguments can be given.
196 As with ``uncrustify.sh``, ``-f``/``--force`` is necessary if the working tree and
197 the git index do not match.
200 Using git filters
201 -----------------
203 An alternative to using a pre-commit hook to automatically apply uncrustify on
204 changes is to use a git filter (does not require ``uncrustify.sh``, only the
205 ``.gitattributes`` file).  You can run ::
207   git config filter.uncrustify.clean \
208       "/path/to/uncrustify -c admin/uncrustify.cfg -q -l cpp"
210 To configure a filter for all files that specify ``filter=uncrustify`` attribute.
212 The pre-commit hook + manually running ``uncrustify.sh`` gives better/more
213 intuitive control (with the filter, it is possible to have a work tree that is
214 different from HEAD and still have an empty ``git diff``) and provides better
215 performance for changes that modify many files.  It is the only way that
216 currently also checks the copyright headers.
218 The filter allows one to transparently merge branches that have not been run
219 through uncrustify, and is applied more consistently (the pre-commit hook is
220 not run for every commit, e.g., during a rebase).