pre-commit hooks for C linters
Project description
pre-commit hooks
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:
- Relay correct pass/fail to pre-commit, even when some commands exit 0 for
- Honor
--
arguments, which pre-commit has problems with - Optionally enforce a command version so your team gets code formatted/analyzed the same way.
- Formatters clang-format and uncrustify will error with diffs of what has changed
- More verbose error messages
Example Usage
With int main() { int i; return 10; }
in a file err.cpp
, all five linters should fail on commit
and produce this output 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
args: [-checks=clang-diagnostic-return-type]
- id: oclint
args: [-enable-clang-static-analyzer, -enable-global-analysis]
- id: uncrustify
- id: cppcheck
args: [--enable=all]
- id: cpplint
- id: iwyu
Note that for your config yaml, you can supply your own args or remove the args line entirely, depending on your use case.
Pre-commit linters image output
You can also clone this repo and then run the test_repo to see all of the linters at work,
git clone https://github.com/pocc/pre-commit-hooks
cd tests/test_repo
git init
pre-commit install
git add .
git commit
Using this repo
Special flags in this repo
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.
Default Options
These options are automatically added to enable all errors or are required.
- oclint:
["-enable-global-analysis", "-enable-clang-static-analyzer", "-max-priority-3", "0"]
- uncrustify:
["-c", "defaults.cfg"]
(options added, and a defaults.cfg generated, if -c is missing) - cppcheck:
["-q" , "--error-exitcode=1", "--enable=all", "--suppress=unmatchedSuppression", "--suppress=missingIncludeSystem", "--suppress=unusedFunction"]
(See https://github.com/pocc/pre-commit-hooks/pull/30) - cpplint:
["--verbose=0"]
If any of these options are supplied in args:
, they will override the above defaults.
Compilation Database
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 ...
if you
have a cmake-based project.
Information about the Commands
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.
Installation
You will need to install these utilities in order to use them. Your package manager may already have them. Below are the package names for each package manager, if available:
apt install clang clang-format clang-tidy uncrustify cppcheck
[1] [2]yum install llvm uncrustify cppcheck
[2]brew install llvm oclint uncrustify cppcheck
[3]choco install llvm uncrustify cppcheck
[4]
cpplint can be installed everywhere with pip install cpplint
.
[1]: clang
is a required install for clang-format
or clang-tidy
to work.
[2]: oclint takes a couple hours to compile. I've compiled and tarred oclint-v0.15 for those using linux who want to skip the wait (built on Ubuntu-18.04). You can also download the older oclint-v0.13.1 for linux from oclint's github page (see releases).
[3]: Depending on your brew installation, you may need to install
oclint with brew cask install oclint
.
[4]: oclint is not available on windows.
If your package manager is not listed here, it will have similar names for these tools. You can build all of these from source.
Hook Info
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 Option Comparison
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
.
Development
See README_dev.md
Additional Resources
clang-format
- Official Docs
- clang-format Guide - a good overview and a great place to get started
- clang-format Configurator - Website to interactively design your config while
- clang-format Options Explorer - Website to interactively understand various options
- Source Code
clang-tidy
- Official Docs
- clang-tidy guide - Good place to start
- Example usage - Explanation of how to use clang-tidy by the creators of Kratos
- Add your own checks - Function names must be awesome!
- Source Code
oclint
uncrustify
cppcheck
License
Apache 2.0
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.