- Notifications
You must be signed in to change notification settings - Fork68
C/C++ hooks to integrate with pre-commit
License
pocc/pre-commit-hooks
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This is apre-commit hooks repo thatintegrates 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 when they should not. Some versions of oclint, clang-tidy, and cppcheck have this behavior.
- Honor
--
arguments, which pre-commithas problems with - Optionallyenforce 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
With thiserr.c
#include<stdio.h>intmain(){inti;return;}
and using this.pre-commit-config.yaml
:
fail_fast:falserepos: -repo:https://github.com/pocc/pre-commit-hooksrev:masterhooks: -id:clang-formatargs:[--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 atmedia/all_failed.txt.
clang-format error (indentation)
clang-format.............................................................Failed- hook id: clang-format- exit code: 1err.c====================--- original+++ formatted@@ -1,3 +1,6 @@ #include <stdio.h>-int main(){int i;return;}+int main() {+ int i;+ return;+}
clang-tidy error (non-void main should return a value)
clang-tidy...............................................................Failed- hook id: clang-tidy- exit code: 1/tmp/temp/err.c:2:18: error: non-void function 'main' should return a value [clang-diagnostic-return-type]int main(){int i;return;} ^1 error generated.Error while processing /tmp/temp/err.c.Found compiler error(s).
oclint error (non-void main should return a value)
oclint...................................................................Failed- hook id: oclint- exit code: 6Compiler Errors:(please be aware that these errors will prevent OCLint from analyzing this source code)/tmp/temp/err.c:2:18: non-void function 'main' should return a valueClang Static Analyzer Results:/tmp/temp/err.c:2:18: non-void function 'main' should return a valueOCLint ReportSummary: TotalFiles=0 FilesWithViolations=0 P1=0 P2=0 P3=0[OCLint (https://oclint.org) v21.05]
uncrustify error (indentation)
uncrustify...............................................................Failed- hook id: uncrustify- exit code: 1err.c====================--- original+++ formatted@@ -1,3 +1,5 @@ #include <stdio.h>-int main(){int i;return;}+int main(){+ int i; return;+}
cppcheck error (unused variable i)
cppcheck.................................................................Failed- hook id: cppcheck- exit code: 1err.c:2:16: style: Unused variable: i [unusedVariable]int main(){int i;return;} ^
cpplint error (no copyright message, bad whitespace)
cpplint..................................................................Failed- hook id: cpplint- exit code: 1Done processing err.cTotal errors found: 4err.c:0: No copyright message found. You should have a line: "Copyright [year] <Copyright Owner>" [legal/copyright] [5]err.c:2: More than one command on the same line [whitespace/newline] [0]err.c:2: Missing space after ; [whitespace/semicolon] [3]err.c:2: Missing space before { [whitespace/braces] [5]
include-what-you-use error (remove unused #include )
include-what-you-use.....................................................Failed- hook id: include-what-you-use- exit code: 3err.c:2:18: error: non-void function 'main' should return a value [-Wreturn-type]int main(){int i;return;} ^err.c should add these lines:err.c should remove these lines:- #include <stdio.h> // lines 1-1The full include-list for err.c:---
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-hookscp -r pre-commit-hooks/tests/test_repo.cd test_repogit initgit add.pre-commit run
Note that we are copying the test_repo outside of the pre-commit-hooks reposo that pre-commit doesn't get confused by nested github repositories.
There are 2 flags,--version
and--no-diff
that can be added toargs:
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 version8.0.0, for example, add--version=8.0.0
toargs:
for that linter. Note thatthis is a pre-commit hook arg and will be filtered before args are passed to the linter.
You can add--no-diff
to theargs:
for clang-format and uncrustifyif you would like there to be no diff output for these commands.
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", "-q"]
(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#30) - cpplint:
["--verbose=0"]
If you supply any of these options inargs:
, your options will override the above defaults (use-<flag>=<option>
if possible when overriding).
clang-tidy
andoclint
both expect acompilation database.Both of the hooks for them will ignore the error for not having one.
You can generate with onecmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON <dir>
if youhave 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:
- Linux
brew install llvm uncrustify cppcheck include-what-you-use
[1] [2]oclint
: See note below for installation [3]
- MacOS
brew install llvm uncrustify cppcheck include-what-you-use oclint
- Windows
choco install llvm uncrustify cppcheck inlcude-what-you-use
- Cross-platform
pip install cpplint
pipx install clang-format
[4]
[1]: llvm includes tools likeclang-format
andclang-tidy
.
[2]: While it's possible to use other package managers to install these utilities on Linux, I recommendusing brew to avoid dependency issues between llvm and linters that use it, such as include-what-you-use.
[3]: You can install on MacOS withbrew install oclint
. Oclint's github page also provides compiledbinary 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 from10.0.1
and up are supported.To pin to a specific version like13.0.0
, usepipx install clang-format==13.0.0
.Check out theclang-format-wheel repository for information onhow 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 usetrailing return typebut Fuchsiadisallows 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.Seeoclint error codes for more info on partially catching failed checks.
[4]: By definition, if you are usingpre-commit
, you are using version control.Therefore, it is recommended to avoid needless backup creation by using--no-backup
.
- Official Docs
- clang-formatGuide -a good overview and a great place to get started
- clang-format Configurator - Website tointeractively design your config while
- clang-format Options Explorer - Website to interactivelyunderstand various options
- Source Code
- Official Docs
- clang-tidyguide -Good place to start
- Exampleusage -Explanation of how to use clang-tidy by the creators of Kratos
- Add your ownchecks -Function names must beawesome!
- Source Code
Apache 2.0
About
C/C++ hooks to integrate with pre-commit