Add clang-tidy script
authorPaul Bauer <paul.bauer.q@gmail.com>
Thu, 9 Apr 2020 17:21:24 +0000 (17:21 +0000)
committerM. Eric Irrgang <mei2n@virginia.edu>
Thu, 9 Apr 2020 17:21:24 +0000 (17:21 +0000)
Change-Id: I4e3ff318681b562c0941c88360d2381747348517

admin/clang-tidy.sh [new file with mode: 0755]
admin/git-pre-commit
admin/gitlab-ci/lint.gitlab-ci.yml
docs/dev-manual/code-formatting.rst
docs/dev-manual/tools.rst

diff --git a/admin/clang-tidy.sh b/admin/clang-tidy.sh
new file mode 100755 (executable)
index 0000000..677d794
--- /dev/null
@@ -0,0 +1,260 @@
+#!/bin/bash
+#
+# This file is part of the GROMACS molecular simulation package.
+#
+# Copyright (c) 2020, by the GROMACS development team, led by
+# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+# and including many others, as listed in the AUTHORS file in the
+# top-level source directory and at http://www.gromacs.org.
+#
+# GROMACS is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1
+# of the License, or (at your option) any later version.
+#
+# GROMACS is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with GROMACS; if not, see
+# http://www.gnu.org/licenses, or write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+#
+# If you want to redistribute modifications to GROMACS, please
+# consider that scientific software is very special. Version
+# control is crucial - bugs must be traceable. We will be happy to
+# consider code for inclusion in the official distribution, but
+# derived work must not be called official GROMACS. Details are found
+# in the README & COPYING files - if they are missing, get the
+# official version at http://www.gromacs.org.
+#
+# To help us fund GROMACS development, we humbly ask that you cite
+# the research papers on the package. Check out http://www.gromacs.org.
+
+# This script runs clang tidy checks on modified files and
+# reports/applies the necessary changes.
+#
+# See `clang-tidy.sh -h` for a brief usage, and docs/dev-manual/code-formatting.rst
+# for more details.
+
+# Parse command-line arguments
+function usage() {
+    echo "usage: clang-tidy.sh [-f|--force] [--parallel=#Jobs] [--rev=REV]"
+    echo "           [--tidy=(off|check)]"
+    echo "           [--warnings=<file>] [<action>]"
+    echo "           [-B=<builddir>]"
+    echo "<action>: (check*|diff|update)[-(index|workdir*)] (*=default)"
+}
+
+action="check-workdir"
+declare -a diffargs
+baserev="HEAD"
+force=
+tidy_mode=check
+warning_file=
+builddir=
+concurrency=2
+for arg in "$@" ; do
+    if [[ "$arg" == "check-index" || "$arg" == "check-workdir" || \
+          "$arg" == "diff-index" || "$arg" == "diff-workdir" || \
+          "$arg" == "update-index" || "$arg" == "update-workdir" ]]
+    then
+        action=$arg
+    elif [[ "$arg" == "check" || "$arg" == "diff" || "$arg" == "update" ]] ; then
+        action=$arg-workdir
+    elif [[ "$action" == diff-* ]] ; then
+        diffargs+=("$arg")
+    elif [[ "$arg" == --tidy=* ]] ; then
+        tidy_mode=${arg#--tidy=}
+        if [[ "$tidy_mode" != "off" && "$tidy_mode" != "check" ]] ; then
+            echo "Unknown option: $arg"
+            echo
+            usage
+            exit 2
+        fi
+    elif [[ "$arg" == "-f" || "$arg" == "--force" ]] ; then
+        force=1
+    elif [[ "$arg" == --parallel=* ]] ; then
+        concurrency=${arg#--parallel=}
+    elif [[ "$arg" == --rev=* ]] ; then
+        baserev=${arg#--rev=}
+    elif [[ "$arg" == --warnings=* ]] ; then
+        warning_file=${arg#--warnings=}
+    elif [[ "$arg" == -B=* ]] ; then
+        builddir=${arg#-B=}
+    elif [[ "$arg" == "-h" || "$arg" == "--help" ]] ; then
+        usage
+        exit 0
+    else
+        echo "Unknown option: $arg"
+        echo
+        usage
+        exit 2
+    fi
+done
+
+# Check that format is present
+if [[ "$tidy_mode" != "off" ]]
+then
+    if [ -z "$RUN_CLANG_TIDY" ]
+    then
+        RUN_CLANG_TIDY=`git config hooks.runclangtidypath`
+    fi
+    if [ -z "$RUN_CLANG_TIDY" ]
+    then
+        echo "Please set the path to run-clang-tidy using the git hook"
+        echo "git config hooks.runclangtidypath /path/to/run-clang-tidy-7.py"
+        echo "or by setting an environment variable, e.g."
+        echo "RUN_CLANG_TIDY=/path/to/run-clang-tidy-7.py"
+        exit 2
+    fi
+    if ! which "$RUN_CLANG_TIDY" 1>/dev/null
+    then
+        echo "run-clang-tidy-7.py not found: $RUN_CLANG_TIDY"
+        exit 2
+    fi
+fi
+
+# Switch to the root of the source tree and check the config file
+srcdir=`git rev-parse --show-toplevel`
+pushd $srcdir >/dev/null || exit
+
+# Actual processing starts: create a temporary directory
+tmpdir=`mktemp -d -t gmxclangtidy.XXXXXX`
+
+# Produce a list of changed files
+# Only include files that have proper filter set in .gitattributes
+internal_diff_args=
+if [[ $action == *-index ]]
+then
+    internal_diff_args="--cached"
+fi
+git diff-index $internal_diff_args --diff-filter=ACMR $baserev >$tmpdir/difflist
+cut -f2 <$tmpdir/difflist | \
+    git check-attr --stdin filter | \
+    sed -e 's/.*: filter: //' | \
+    paste $tmpdir/difflist - | \
+    grep -E '(complete_formatting|clangformat|copyright|includesort)$' >$tmpdir/filtered
+cut -f2 <$tmpdir/filtered >$tmpdir/filelist_all
+grep -E '(complete_formatting|clangformat)$' <$tmpdir/filtered | \
+    cut -f2 >$tmpdir/filelist_clangtidy
+git diff-files --name-only | grep -Ff $tmpdir/filelist_all >$tmpdir/localmods
+
+# Extract changed files to a temporary directory
+mkdir $tmpdir/org
+if [[ $action == *-index ]] ; then
+    git checkout-index --prefix=$tmpdir/org/
+else
+    rsync -a $srcdir/src/ $tmpdir/org/src/
+fi
+# check for the existence of the compile_commands.json file and abort
+# if it is not present. If we don't have a build directory, try the
+# current source directory.
+if [ -z $builddir ] ; then
+    builddir=$srcdir
+fi
+if [[ ! -f $builddir/compile_commands.json ]] ; then
+    echo "Could not find compile_commands.json in builddir=$builddir"
+    echo "Make sure you gave a correct build tree and that it contains the file!"
+else
+    # Need to have compilation database file available somewhere above where we are using it
+    rsync -a $builddir/compile_commands.json $tmpdir/org
+fi
+# Duplicate the original files to a separate directory, where all changes will
+# be made.
+cp -r $tmpdir/org $tmpdir/new
+
+# Create output file for what was done (in case no messages get written)
+touch $tmpdir/messages
+
+# Run clang-tidy on the temporary directory
+# Can only perform clang-tidy on a non-empty list of files
+cd $tmpdir/new
+if [[ $tidy_mode != "off" &&  -s $tmpdir/filelist_clangtidy ]] ; then
+    $RUN_CLANG_TIDY `cat $tmpdir/filelist_clangtidy` -- -header-filter=.* -j $concurrency -fix -fix-errors --cuda-host-only -nocudainc -quiet >$tmpdir/clang-tidy.out 2>&1
+    grep -v "clang-analyzer" $tmpdir/clang-tidy.out | grep -v "to display errors from all non" | grep -i "error|warning" - > $tmpdir/clang-tidy-errors.out
+    if [ -s $tmpdir/clang-tidy-errors.out ]; then
+        echo "Running code tidying failed. Check output below for errors:"
+        cat $tmpdir/clang-tidy-errors.out
+        rm -rf $tmpdir
+        exit 2
+    fi
+    # Find the changed files if necessary
+    if [[ $action != diff-* ]] ; then
+        msg="found code issues"
+        if [[ $action == update-* ]] ; then
+            msg="clang-tidy performed"
+        fi
+        git diff --no-index --name-only ../org/ . | \
+            awk -v msg="$msg" '{sub(/.\//,""); print $0 ": " msg}' >> $tmpdir/messages
+    fi
+    # TODO: Consider checking whether rerunning clang-tidy causes additional changes
+fi
+
+cd $tmpdir
+
+# If a diff was requested, show it and we are done
+if [[ $action == diff-* ]] ; then
+    git diff --no-index --no-prefix "${diffargs[@]}" org/ new/
+    rm -rf $tmpdir
+    exit 0
+fi
+
+# Find the changed files
+git diff --no-index --name-only --exit-code org/ new/ | \
+    sed -e 's#new/##' > $tmpdir/changed
+changes=
+if [[ -s $tmpdir/changed ]]
+then
+    changes=1
+fi
+
+# Check if changed files have changed outside the index
+if grep -Ff $tmpdir/localmods $tmpdir/changed > $tmpdir/conflicts
+then
+    awk '{print $0 ": has changes in work tree"}' $tmpdir/conflicts \
+        >> $tmpdir/messages
+    if [[ ! $force && $action == update-* ]] ; then
+        echo "Modified files found in work tree, skipping update. Use -f to override."
+        echo "The following would have been done:"
+        sort $tmpdir/messages
+        rm -rf $tmpdir
+        exit 2
+    fi
+fi
+
+# Update the index/work tree if requested
+if [[ $action == update-index ]] ; then
+    grep -Ff $tmpdir/changed $tmpdir/filtered > $tmpdir/tohash
+    cd $tmpdir/new
+    IFS='
+'
+    for change in `cut -f2 $tmpdir/tohash | \
+                   git --git-dir=$srcdir/.git hash-object -w --stdin-paths --no-filters | \
+                   paste - $tmpdir/tohash`
+    do
+        # NOTE: the patterns below contain literal tabs
+        sha1=${change%%        *}
+        rest=${change#*        }
+        mode=${rest:8:6}
+        path=${rest#*  }
+        path=${path%%  *}
+        # Contains a literal tab
+        echo "$mode $sha1      $path" >> $tmpdir/toindex
+    done
+    unset IFS
+    git --git-dir=$srcdir/.git update-index --index-info < $tmpdir/toindex
+elif [[ $action == update-workdir ]] ; then
+    rsync --files-from=$tmpdir/changed $tmpdir/new/ $srcdir/
+fi
+
+# Get back to the original directory
+popd >/dev/null
+
+# Report what was done
+sort $tmpdir/messages | tee $warning_file
+
+rm -rf $tmpdir
+exit $changes
index fc6423fd5eab807802c24bceeb5b44d61adb549d..d5d5bf858ec44abe965e09ab0bae55b54a6216cc 100755 (executable)
@@ -65,12 +65,12 @@ fi
 # Redirect output to stderr.
 exec 1>&2
 
-uncrustify_mode=off
+clangtidy_mode=`git config hooks.clangtidymode`
 clangformat_mode=`git config hooks.clangformatmode`
 copyright_mode=`git config hooks.copyrightmode`
 if [ -z "$uncrustify_mode" ]
 then
-    uncrustify_mode=off
+    clangtidy_mode=off
 fi
 if [ -z "$clangformat_mode" ]
 then
@@ -81,24 +81,24 @@ then
     copyright_mode=off
 fi
 
-if [[ -f admin/uncrustify.sh && \
-      ( "$uncrustify_mode" != "off" ) ]]
+if [[ -f admin/clang-tidy.sh && \
+      ( "$clangtidy_mode" != "off" ) ]]
 then
-    uncrustify_path=`git config hooks.uncrustifypath`
-    if [ -z "$uncrustify_path" ]
+    runclangtidy_path=`git config hooks.runclangtidypath`
+    if [ -z "$runclangtidy_path" ]
     then
-        echo "Please set the path to uncrustify using 'git config hooks.uncrustifypath'."
-        echo "Note that you need a custom version of uncrustify."
+        echo "Please set the path to run-clang-tidy using 'git config hooks.runclangtidypath'."
+        echo "Note that you need at least clang-tidy-8."
         exit 1
     fi
-    export UNCRUSTIFY="$uncrustify_path"
-    admin/uncrustify.sh check-index --rev=$against \
-        --uncrustify="$uncrustify_mode"
+    export RUN_CLANG_TIDY="$runclangtidy_path"
+    admin/clang-tidy.sh check-index --rev=$against \
+        --tidy="$clangtidy_mode"
     stat=$?
     if [ $stat -eq 1 ] ; then
         exit 1
     elif [ $stat -ne 0 ] ; then
-        echo "Source code formatting check with uncrustify failed"
+        echo "Source code checking with clang-tidy failed"
         exit 1
     fi
 fi
index 828b9a3174653ece28fe214333fa7e6f460c02c7..3836cbe5b6010f0d12b1c91c91dfe17b8f1fe112 100644 (file)
@@ -14,6 +14,20 @@ clang-tidy:configure:
   # TODO: Enable GMX_PYTHON_PACKAGE for clang-tidy when dependencies are in Docker image.
 
 clang-tidy:build:
+  extends:
+    - .gromacs:base:build
+    - .use-ccache
+    - .variables:default
+    - .use-clang7
+    - .rules:nightly-not-for-release
+  stage: source-check
+  needs:
+    - job: clang-tidy:configure
+  variables:
+    BUILD_DIR: build-clang-tidy
+    EXTRA_INSTALLS: clang-tidy-$COMPILER_MAJOR_VERSION
+
+clang-tidy:test:
   extends:
     - .gromacs:base:build
     - .use-ccache
@@ -23,10 +37,21 @@ clang-tidy:build:
   stage: source-check
   needs:
     - job: clang-tidy:configure
-      artifacts: true
   variables:
     BUILD_DIR: build-clang-tidy
     EXTRA_INSTALLS: clang-tidy-$COMPILER_MAJOR_VERSION
+    KUBERNETES_CPU_LIMIT: 4
+    KUBERNETES_CPU_REQUEST: 2
+    KUBERNETES_MEMORY_LIMIT: 4Gi
+  script:
+    - RUN_CLANG_TIDY=run-clang-tidy-$COMPILER_MAJOR_VERSION bash admin/clang-tidy.sh check --parallel=$KUBERNETES_CPU_LIMIT --warnings=clang-tidy.log --rev=origin/master -B=$BUILD_DIR
+    - grep -iq "found code issues" clang-tidy.log | tee code-lint.txt || true
+    - if [ -s code-lint.txt ] ; then echo "clang-tidy.sh found issues"; exit 1; fi
+  artifacts:
+    when: on_failure
+    paths:
+      - clang-tidy.log
+      - code-lint.txt
 
 clang-format:
   extends:
index cb9048d859e44bc5c912ba876001d098b0364597..9beeb4529c35113bfddd3c72f45a0400777a5111 100644 (file)
@@ -6,52 +6,17 @@ Automatic source code formatting
 .. highlight:: bash
 
 The source code can be automatically formatted using clang-format
-(GROMACS 2020 and later)
-or uncrustify (GROMACS 2019 and earlier).
+since GROMACS 2020.
 Both are formatting tools that apply the guidelines in :doc:`formatting`.
 Additionally, other Python scripts are used for a few other automatic
 formatting/checking tasks.  The overview tools page contains a list of these
 tools: :ref:`dev-formatting-tools`.
-This page provides more details for clang-format, uncrustify and copyright scripts.
+This page provides more details for clang-format, clang-tidy and copyright scripts.
 
-Jenkins uses these same scripts (in particular, ``clang-format.sh``,
-``copyright.sh`` and the ``check-source`` target) to enforce that
+Our CI uses these same scripts (in particular, ``clang-format.sh``,
+``copyright.sh``, ``clang-tidy.sh`` and the ``check-source`` target) to enforce that
 the code stays invariant under such formatting.
 
-.. _gmx-uncrustify:
-
-Setting up uncrustify
----------------------
-
-A patched version of uncrustify is used for |Gromacs|.  To set this up, you need
-to do these (once):
-
-1. Change to a directory under which you want to build uncrustify and run::
-
-     git clone -b gromacs git://github.com/rolandschulz/uncrustify.git
-     cd uncrustify
-     ./configure
-     make
-
-2. Copy the binary ``src/uncrustify`` into a directory of your choice
-   (``/path/to/uncrustify`` below).
-
-Alternatively, if you are running Linux, you can try whether the binary from
-https://gitlab.com/gromacs/gromacs/-/issues/845 works for you.
-
-In order to use the binary for ``uncrustify.sh`` and for the pre-commit hook, you
-also need to run this in each of your |Gromacs| repositories::
-
-  git config hooks.uncrustifypath /path/to/uncrustify
-
-Alternatively, if you just want to use ``uncrustify.sh``, you can set the
-``UNCRUSTIFY`` environment variable to ``/path/to/uncrustify``.
-
-Using the pre-commit hook or git filters needs additional setup; see the
-respective sections below.
-
-Note that Jenkins now only allows formatting using ``clang-format``.
-
 .. _gmx-clang-format:
 
 Setting up clang-format
@@ -97,7 +62,8 @@ and for the pre-commit hook, you also need to run this in each of your |Gromacs|
 Alternatively, if you just want to use ``clang-format.sh``, you can set the
 ``CLANG_FORMAT`` environment variable to ``/path/to/clang-format``.
 
-As above, see the sections below for using the pre-commit hook or git filters.
+Using the pre-commit hook or git filters needs additional setup; see the
+respective sections below.
 
 clang-format discovers which formatting rules to apply from the
 :file:`.clang-format` configuration file(s) in project directories,
@@ -114,14 +80,62 @@ git filters, specified in ``.gitattributes`` files.  Only files that have the
 attribute ``filter`` set to one of the below values are processed:
 
 - ``filter=complete_formatting``: Performs all formatting. Uses clang-format for code formatting.
-- ``filter=uncrustify``: uncrustify is run. Deprecated and here for historical reasons.
-- ``filter=clangformat``: clang-format is run.
+                                  Files included here are also passed to the clang-tidy code checker.
+- ``filter=clangformat``: clang-format is run. Again also runs clang-tidy.
 - ``filter=includesort``: include order is enforced and copyright headers are checked.
 - ``filter=copyright``: only copyright headers are checked.
 
-Other files are ignored by ``uncrustify.sh``, ``clang-format.sh``,
+Other files are ignored by ``clang-tidy.sh``, ``clang-format.sh``,
 ``copyright.sh`` and ``reformat_all.sh`` scripts (see below).
 
+.. _gmx-clang-tidy:
+
+Setting up clang-tidy
+---------------------
+
+|Gromacs| source code tidiness checking is enforced with clang-tidy 8.0.1.
+:command:`clang-tidy` is one of the core *clang* tools.
+It may be included in a *clang* or *llvm* package from your favorite packaging
+system or you may find a standalone *clang-tidy* package,
+but you should confirm that the provided command is version 8.0.1 or
+7.1.0. Example::
+
+    $ clang-tidy --version
+    clang-tidy version 7.1.0 (tags/RELEASE_710/final)
+
+If you use a different version of clang-tidy,
+you will likely get different checking results than
+the |Gromacs| continuous integration testing system,
+and the commits that you push will fail the automated tests.
+
+.. note::
+
+    Refer to `LLVM <http://releases.llvm.org/download.html#7.1.0>`__ for
+    source and binary downloads.
+    If downloading sources, note that you will need to download both the
+    *LLVM source code* and the *Clang source code*.
+    As per the clang
+    `INSTALL.txt <https://github.com/llvm/llvm-project/blob/release/7.x/clang/INSTALL.txt>`__,
+    place the expanded clang source into a :file:`tools/clang` subdirectory within
+    the expanded llvm archive, then run CMake against the llvm source directory.
+
+In order to use the installed version of clang-tidy for ``clang-tidy.sh``
+and for the pre-commit hook, you also need to run this in each of your |Gromacs| repositories::
+
+  git config hooks.runclangtidypath /path/to/run-clang-tidy.py
+
+Alternatively, if you just want to use ``clang-tidy.sh``, you can set the
+``RUN_CLANG_TIDY`` environment variable to ``/path/to/run-clang-tidy.py``.
+
+As above, see the sections below for using the pre-commit hook or git filters.
+
+clang-tidy discovers which formatting rules to apply from the
+:file:`.clang-tidy` configuration file(s) in project directories,
+which will be automatically updated (if necessary) when you :command:`git pull`
+from the |Gromacs| repository.
+For more about the tool and the :file:`.clang-tidy` configuration file,
+visit https://releases.llvm.org/7.0.1/tools/clang/docs/ClangTidy.html
+
 
 Scripts
 -------
@@ -142,45 +156,11 @@ directly, but instead the bash scripts below use it internally.  You can run
 the script with ``--help`` option if you want to see what all options it provides
 if you need to do some maintenance on the copyright headers themselves.
 
-``uncrustify.sh``
-^^^^^^^^^^^^^^^^^
-
-The information for ``uncrustify`` is mainly provided for historical reasons,
-as the actual code formatting is now done using ``clang-format``.
-
-This script runs ``uncrustify`` on modified files and reports/applies the results.
-By default, the current HEAD commit is compared to the work tree,
-and files that
-
-1. are different between these two trees and
-2. change under uncrustify
-
-are reported.  This behavior can be changed by
-
-1. Specifying an ``--rev=REV`` argument, which uses ``REV`` instead of HEAD as
-   the base of the comparison.  A typical use case is to specify ``--rev=HEAD^``
-   to check the HEAD commit.
-2. Specifying an action:
-
-   - ``check-*``:   reports the files that uncrustify changes
-   - ``diff-*``:    prints the actual diff of what would change
-   - ``update-*``:  applies the changes to the repository
-   - ``*-workdir``: operates on the working directory (files on disk)
-   - ``*-index``:   operates on the index of the repository
-
-   For convenience, if you omit the workdir/index suffix, workdir is assumed
-   (i.e., ``diff`` equals ``diff-workdir``).
-3. Specifying ``--uncrustify=off``, which does not run uncrustify.
-
-By default, ``update-*`` refuses to update dirty files (i.e., that differ
-between the disk and the index) to make it easy to revert the changes.
-This can be overridden by adding a ``-f``/``--force`` option.
-
 ``copyright.sh``
 ^^^^^^^^^^^^^^^^
 
 This script runs ``copyright.py`` on modified files and reports/applies the results.
-By default, the current HEAD commit is compared to the work tree,
+By default, the current HEAD commit on the source branch is compared to the work tree,
 and files that
 
 1. are different between these two trees and
@@ -217,7 +197,7 @@ This can be overridden by adding a ``-f``/``--force`` option.
 ^^^^^^^^^^^^^^^^^^^
 
 This script runs ``clang-format`` on modified files and reports/applies the results.
-By default, the current HEAD commit is compared to the work tree,
+By default, the current HEAD commit on the source branch is compared to the work tree,
 and files that
 
 1. are different between these two trees and
@@ -244,36 +224,70 @@ By default, ``update-*`` refuses to update dirty files (i.e., that differ
 between the disk and the index) to make it easy to revert the changes.
 This can be overridden by adding a ``-f``/``--force`` option.
 
+``clang-tidy.sh``
+^^^^^^^^^^^^^^^^^
+
+This script runs the ``clang-tidy`` source code checker on modified files
+and either reports or applies resulting changes. By default, the current
+HEAD commit on the source branch is compared to the work tree,
+and files that
+
+1. are different between these two trees and
+2. change when applying clang-tidy
+
+are reported. This behavior can be changed by
+
+1. Specifying an ``--rev=REV`` argument, which uses ``REV`` instead of HEAD as
+   the base of the comparison.  A typical use case is to specify ``--rev=HEAD^``
+   to check the HEAD commit.
+2. Specifying an action:
+
+   - ``check-*``:   reports the files that clang-format changes
+   - ``diff-*``:    prints the actual diff of what would change
+   - ``update-*``:  applies the changes to the repository
+   - ``*-workdir``: operates on the working directory (files on disk)
+   - ``*-index``:   operates on the index of the repository
+
+   For convenience, if you omit the workdir/index suffix, workdir is assumed
+   (i.e., ``diff`` equals ``diff-workdir``).
+3. Specifying ``--tidy=off``, which does not run clang-tidy.
+
+By default, ``update-*`` refuses to update dirty files (i.e., that differ
+between the disk and the index) to make it easy to revert the changes.
+This can be overridden by adding a ``-f``/``--force`` option.
+
+
 git pre-commit hook
 ^^^^^^^^^^^^^^^^^^^
 
-If you want to run ``uncrustify.sh``, ``copyright.sh`` and/or
+If you want to run ``copyright.sh``, ``clang-tidy.sh`` and/or
 ``clang-format.sh`` automatically for changes you make, you can
 configure a pre-commit hook using ``admin/git-pre-commit``:
 
 1. Copy the ``git-pre-commit`` script to .git/hooks/pre-commit.
 
-2. Specify the paths to ``uncrustify`` and ``clang-format`` for the hook if you have not already done
+2. Specify the paths to ``run-clang-tidy`` and ``clang-format`` for the hook if you have not already done
    so::
 
-     git config hooks.uncrustifypath /path/to/uncrustify
+     git config hooks.runclangtidypath /path/to/run-clang-tidy.py
      git config hooks.clangformatpath /path/to/clang-format
 
 3. Set the operation modes for the hook::
 
-     git config hooks.uncrustifymode check
+     git config hooks.clangtidymode check
      git config hooks.clangformatmode check
      git config hooks.copyrightmode  update
 
 With this configuration, all source files modified in the commit are run
-through the respective code formatting tool and checked for correct copyright headers.
-If any file would be changed by ``uncrustify.sh``, ``clang-format.sh`` or ``copyright.sh``,
+through the code formatting tool, are checked with clang-tidy
+and also checked for correct copyright headers.
+If any file would be changed by ``clang-tidy.sh``, ``clang-format.sh`` or ``copyright.sh``,
 the names of those files are reported and the commit is prevented.
 The issues can be fixed by running the scripts manually.
 
 To disable the hook without removing the ``pre-commit`` file, you can set ::
 
-  git config hooks.uncrustifymode off
+  git config hooks.clangtidymode off
   git config hooks.copyrightmode off
   git config hooks.clangformatmode off
 
@@ -289,15 +303,15 @@ Note that when you run ``git commit --amend``, the hook is only run for the
 changes that are getting amended, not for the whole commit.  During a rebase,
 the hook is not run.
 
-The actual work is done by the ``admin/uncrustify.sh``, ``admin/clang-format.sh``
+The actual work is done by the ``admin/clang-tidy.sh``, ``admin/clang-format.sh``
 and ``admin/copyright.sh`` scripts, which get run with the ``check-index`` action,
-and with ``--uncrustify``, ``--copyright`` and ``--format`` getting set according
+and with ``--copyright`` and ``--format`` getting set according
 to the ``git config`` settings.
 
 ``reformat_all.sh``
 ^^^^^^^^^^^^^^^^^^^
 
-This script runs uncrustify, clang-format, ``copyright.py``, or the include sorter for all
+This script runs clang-format, ``copyright.py``, or the include sorter for all
 applicable files in the source tree.  See ``reformat_all.sh -h`` for the
 invocation.
 
@@ -323,8 +337,6 @@ An alternative to using a pre-commit hook to automatically apply uncrustify or
 clang-format on changes is to use a git filter (does not require either of the scripts,
 only the ``.gitattributes`` file).  You can run ::
 
-  git config filter.complete_formatting.clean \
-      "/path/to/uncrustify -c admin/uncrustify.cfg -q -l cpp"
   git config filter.clangformat.clean \
       "/path/to/clang-format -i"
 
index d7b96162213f9eec8ed34efbbcfe531365caa1f2..fd90412c285334743a55380d9308631d3bc7deae 100644 (file)
@@ -86,49 +86,46 @@ The tools and scripts listed below are used to automatically check/apply
 formatting that follows |Gromacs| style guidelines described on a separate page:
 :doc:`style`.
 
-uncrustify
-  `uncrustify <http://uncrustify.sourceforge.net>`_ is used for automatic
-  indentation and other formatting of the source code to follow
-  :doc:`formatting`.  All code must remain invariant under uncrustify
-  with the config at ``admin/uncrustify.cfg``.  A patched version of uncrustify is
-  used.  See :ref:`gmx-uncrustify` for details.
-
 clang-format
   We use clang-format to enforce a consistent coding style, with the
   settings recorded in ``.clang-format`` in the main tree.
   See :ref:`gmx-clang-format` for details.
 
+clang-tidy
+  The source code linter clang-tidy is used to enforce common restrictions to the
+  code, with the checks collected under ``.clang-tidy`` at the top of the main tree.
+  See :ref:`gmx-clang-tidy` for details.
+
 ``admin/copyright.py``
   This Python script adds and formats copyright headers in source files.
   ``copyright.sh`` (see below) uses the script to check/update copyright years on
   changed files automatically.
 
-``admin/uncrustify.sh``
-  This ``bash`` script runs uncrustify for all
-  files that have local changes and checks that they conform to the prescribed
-  style.  Optionally, the script can also apply changes to make the files
-  conform. It is included only for historical reasons.
-  See :doc:`formatting` for details.
-
 ``admin/copyright.sh``
   This ``bash`` script runs the ``copyright.py`` python script to enforce
   correct copyright information in all files that have local changes
   and checks that they conform to the prescribed
   style.  Optionally, the script can also apply changes to make the files
   conform.
-  This script is automatically run by Jenkins to ensure that all commits adhere
+  This script is automatically run by the CI to ensure that all commits adhere
   to :doc:`formatting`.  If the copyright job does not succeed, it
   means that this script has something to complain.
   See :doc:`code-formatting` for details.
 
 ``admin/clang-format.sh``
   This script enforces coding style using clang-format.
-  This script is automatically run by Jenkins to ensure that all commits adhere
+  This script is automatically run by our CI to ensure that all commits adhere
   to :doc:`formatting`.
 
+``admin/clang-tidy.sh``
+  The clang-tidy code correctness restrictions are enforced by this script.
+  The script is also used by the CI to verify the code, in addition to nightly
+  compilations using clang-tidy on the whole tree.
+
 ``admin/git-pre-commit``
   This sample git pre-commit hook can be used if one wants to apply
-  ``uncrustify.sh`` and ``clang-format.sh`` automatically before every commit to check for formatting
+  ``clang-tidy.sh``, ``copyright.sh`` and ``clang-format.sh`` automatically
+  before every commit to check for formatting
   issues.  See :doc:`code-formatting` for details.
 
 ``docs/doxygen/includesorter.py``
@@ -142,12 +139,12 @@ include directive checker
   applied in the formatting script.  To check for issues, it is instead integrated into
   a ``check-source`` build target.  When this target is built, it also checks for
   include formatting issues.  Internally, it uses the sorter script.  This check
-  is run in Jenkins as part of the Documentation job.
+  is run in the CI as part of the Documentation job.
   Details for the checking mechanism are on a separate page (common for several
   checkers): :doc:`gmxtree`.
 
 ``admin/reformat_all.sh``
-  This ``bash`` script runs uncrustify/clang-format/``copyright.py``/include sorter
+  This ``bash`` script runs clang-format/``copyright.py``/include sorter
   on all relevant files in the source tree (or in a particular directory).
   The script can also produce the list of files where these scripts are applied,
   for use with other scripts.  See :doc:`code-formatting` for details.
@@ -160,4 +157,3 @@ git attributes
   checking/formatting to apply.  Custom attributes are used for specifying some
   build system dependencies for easier processing in CMake.
 
-include-what-you-use