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