Two supplemental BASH scripts have been written to allow for integration of cppcheck and mercurial into the commit stage of development.
The first script cppcheck-diff.sh allows for comparison of two files, checking both, and then examining the difference between the two cppcheck runs. If there are any new lines (as computed by diff-ing the two files), then the output is displayed.
The second script, cppcheck-diff-hook.sh uses cppcheck-diff.sh to compare two file states - specifically any cpp/h files that have been modified during the mercurial commit. If there are any new cppcheck messages, resulting from the modified files, then a message is displayed at the terminal, allowing the committer to optionally abort the commit. Line number changes are not counted as new messages in the output.
The scripts themselves are relatively simple, and thus can be easily modified.
By running cppcheck on files before they are commmited, errors can be detected prior to them being commited into version control, and pushed later to other repositories. Whilst there may be false negatives, as compared to running cppcheck by hand across the whole repository, this automates the procedure, ensuring that new errors are reviewed prior to committing.
This has the added benefit of reducing the need for manual suppressions, as it is assumed that only new cppcheck errors are problematic, old messages will be silently skipped.
It is however recommeded that even with this script in place, that manual runs of cppcheck are still conducted from time to time. Whilst this integration method will reduce the rate at which errors are accidentally introduced, it is not as thorough as cppcheck, when cppcheck is given the whole repository.
To install the scripts, install cppcheck, tre-agrep and the scripts into your PATH. For example, under debian-like systems (eg mint, ubuntu, debian)
$ sudo apt-get install tre-agrep cppcheck
Now install the scripts, cppcheck-diff.sh and cppcheck-diff-hook.sh, eg by (1) downloading the scripts into your home folder, (2) enabling execution permissions, so you can run the script, (3) installing them into a PATH. At this point you may wish to modify the scripts (eg use file matching patterns other than .cpp/.h, change which rules are filtered from the cppcheck output, location of temporary dir, etc.):
$ chmod a+x ~/cppcheck-diff.sh ~/cppcheck-diff-hook.sh $ sudo cp ~/cppcheck-diff-hook.sh ~/cppcheck-diff.sh /usr/local/bin
Verify that the installation was OK, and the scripts can be found
$ which cppcheck-diff.sh $ which cppcheck-diff-hook.sh
Now navigate to the repository that you wish to modify, eg ~/my-hg-repo/, then edit the .hg/hgrc
$ cd ~/my-hg-repo/
$ vi .hg/hgrc/
Add the following two lines (note there only needs to be one [hooks] section, so don't repeat it)
[hooks] precommit.cppcheckdiff = cppcheck-diff-hook.sh
user@computer:~$ mkdir tmp user@computer:~$ cd tmp/ user@computer:~/tmp$ ls user@computer:~/tmp$ hg init . user@computer:~/tmp$ vi .hg/hgrc user@computer:~/tmp$ cat .hg/hgrc [hooks] precommit.cppcheckdiff = cppcheck-diff-hook.sh user@computer:~/tmp$ user@computer:~/tmp$ cat main.cpp #include <iostream> #include <cstdlib> #include <string> using namespace std; int main() { } user@computer:~/tmp$ hg add main.cpp user@computer:~/tmp$ hg commit -u "user" -m "Initial commit" user@computer:~/tmp$ vi main.cpp user@computer:~/tmp$ cat main.cpp #include <iostream> #include <cstdlib> #include <string> using namespace std; int main() { std::string s; } user@computer:~/tmp$ g++ main.cpp -o main -Wall user@computer:~/tmp$ hg commit -m "commit" -u "user" Checking for errors : main.cpp The following new cppcheck warnings were detected: [main.cpp:9]: (style) Unused variable: s abort? (y/n)
Wiki: Home
Wiki: mercurialhook-cppcheck-diff-hook
Wiki: mercurialhook-cppcheck-diff