This is a pre-commit hooks repo that integrates two C/C++ code formatters:
and five C/C++ static code analyzers:
This repo's hooks do more than passthrough arguments to provide these features:
--
arguments, which pre-commit has problems withWith this err.c
#include <stdio.h>
int main(){int i;return;}
and using this .pre-commit-config.yaml
:
fail_fast: false
repos:
- repo: https://github.com/pocc/pre-commit-hooks
rev: master
hooks:
- id: clang-format
args: [--style=Google]
- id: clang-tidy
- id: oclint
- id: uncrustify
- id: cppcheck
- id: cpplint
- id: include-what-you-use
All seven linters should fail on commit with these messages. Full text is at media/all_failed.txt.
Note that for your config yaml, you can supply your own args or remove the args line entirely, depending on your use case.
You can also clone this repo and then run the test_repo to see all of the linters at work to produce this output:
git clone https://github.com/pocc/pre-commit-hooks
cp -r pre-commit-hooks/tests/test_repo .
cd test_repo
git init
git add .
pre-commit run
Note that we are copying the test_repo outside of the pre-commit-hooks repo so that pre-commit doesn't get confused by nested github repositories.
There are 2 flags, --version
and --no-diff
that can be added to args:
for a pre-commit hook.
They will be removed and not be passed on to the command.
Some linters change behavior between versions. To enforce a linter version
8.0.0, for example, add --version=8.0.0
to args:
for that linter. Note that
this is a pre-commit hook arg and will be filtered before args are passed to the linter.
You can add --no-diff
to the args:
for clang-format and uncrustify
if you would like there to be no diff output for these commands.
These options are automatically added to enable all errors or are required.
["-enable-global-analysis", "-enable-clang-static-analyzer", "-max-priority-3", "0"]
["-c", "defaults.cfg", "-q"]
(options added, and a defaults.cfg generated, if -c is missing)["-q" , "--error-exitcode=1", "--enable=all", "--suppress=unmatchedSuppression", "--suppress=missingIncludeSystem", "--suppress=unusedFunction"]
(See https://github.com/pocc/pre-commit-hooks/pull/30)["--verbose=0"]
If you supply any of these options in args:
, your options will override the above defaults (use -<flag>=<option>
if possible when overriding).
clang-tidy
and oclint
both expect a
compilation database.
Both of the hooks for them will ignore the error for not having one.
You can generate with one cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON <dir>
if you
have a cmake-based project.
Python3.6+ is required to use these hooks as all 5 invoking scripts are written in it. As this is also the minimum version of pre-commit, this should not be an issue.
Use these commands to install some or all of the linters used in this project:
brew install llvm uncrustify cppcheck include-what-you-use
[1] [2]oclint
: See note below for installation [3]brew install llvm uncrustify cppcheck include-what-you-use oclint
choco install llvm uncrustify cppcheck inlcude-what-you-use
pip install cpplint
pipx install clang-format
[4][1]: llvm includes tools like clang-format
and clang-tidy
.
[2]: While it's possible to use other package managers to install these utilities on Linux, I recommend using brew to avoid dependency issues between llvm and linters that use it, such as include-what-you-use.
[3]: You can install on MacOS with brew install oclint
. Oclint's github page also provides compiled
binary packages (and zip of source code to compile) for Macos/Linux:
releases. oclint is not available on windows.
[4]: This will download the latest version. Versions from 10.0.1
and up are supported.
To pin to a specific version like 13.0.0
, use pipx install clang-format==13.0.0
.
Check out the clang-format-wheel repository for information on
how to download the clang-format binary as part of a CI pre-commit build.
Hook Info | Type | Languages |
---|---|---|
clang-format | Formatter | C, C++, ObjC, ObjC++, Java |
clang-tidy | Static code analyzer | C, C++, ObjC |
oclint | Static code analyzer | C, C++, ObjC |
uncrustify | Formatter | C, C++, C#, ObjC, D, Java, Pawn, Vala |
cppcheck | Static code analyzer | C, C++ |
cpplint | Style checker | C, C++ |
include-what-you-use | Static code analyzer | C, C++ |
Hook Options | Fix In Place | Enable all Checks | Set key/value |
---|---|---|---|
clang-format | -i |
||
clang-tidy | --fix-errors [1] |
-checks=* -warnings-as-errors=* [2] |
|
oclint | -enable-global-analysis -enable-clang-static-analyzer -max-priority-3 0 [3] |
-rc=<key>=<value> |
|
uncrustify | --replace --no-backup [4] |
--set key=value |
|
cppcheck | -enable=all |
||
cpplint | --verbose=0 |
||
include-what-you-use | --verbose=3 |
[1]: -fix
will fail if there are compiler errors. -fix-errors
will -fix
and fix compiler errors if it can, like missing semicolons.
[2]: Be careful with -checks=*
. can have self-contradictory rules in newer versions of llvm (9+):
modernize wants to use trailing return type
but Fuchsia disallows it.
Thanks to @rambo.
[3]: The oclint pre-commit hook does the equivalent of -max-priority-3 0
by default, which returns an error code when any check fails.
See oclint error codes for more info on partially catching failed checks.
[4]: By definition, if you are using pre-commit
, you are using version control.
Therefore, it is recommended to avoid needless backup creation by using --no-backup
.
See README_dev.md
Apache 2.0