diff --git a/.githooks/hook-chain b/.githooks/hook-chain new file mode 100755 index 0000000000..dacab7579a --- /dev/null +++ b/.githooks/hook-chain @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# +# Git "hook chain", used to execute multiple scripts per hook. +# To use: +# * create a directory called <hookname>.d +# * add scripts to this directory (executable) +# * ln -s hook-chain <hookname> +# +# Now the scripts in that directory should be called in order. +# +# Set $HOOKCHAIN_DEBUG to see the names of invoked scripts. +# +# Based on script by Oliver Reflalo: +# https://stackoverflow.com/questions/8730514/chaining-git-hooks +# + +hookname=`basename $0` + +# Temp file for stdin, cleared at exit +FILE=`mktemp` +trap 'rm -f $FILE' EXIT +cat - > $FILE + +# Git hooks directory (this dir) +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" + +# Execute hooks in the directory one by one +for hook in $DIR/$hookname.d/*; +do + if [ -x "$hook" ]; then + + if [ "$HOOKCHAIN_DEBUG" ]; then + echo "Running hook $hook" + fi + + cat $FILE | $hook "$@" + status=$? + + if [ $status -ne 0 ]; then + echo "Hook $hook failed with error code $status" + echo "To commit anyway, use --no-verify" + exit $status + else + if [ "$HOOKCHAIN_DEBUG" ]; then + echo "Hook passed: $hook" + fi + fi + fi +done diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 120000 index 0000000000..84d936b2f1 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1 @@ +hook-chain \ No newline at end of file diff --git a/.githooks/pre-commit.d/50-check-format b/.githooks/pre-commit.d/50-check-format new file mode 100755 index 0000000000..8de58b51e6 --- /dev/null +++ b/.githooks/pre-commit.d/50-check-format @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# +# Runs clang-format on changed regions before commit. +# +# Remaining installation checks/instructions will be printed when you commit. +# +# Based on clang-format pre-commit hook by Alex Eagle +# https://gist.github.com/alexeagle/c8ed91b14a407342d9a8e112b5ac7dab + +# Set KICAD_CHECK_FORMAT to allow this hook to run +# if not set, the hook always succeeds. +if [ -z "$KICAD_CHECK_FORMAT" ]; then + exit 0 +fi + +check_clang_format() { + if hash git-clang-format 2>/dev/null; then + return + else + echo "SETUP ERROR: no git-clang-format executable found, or it is not executable" + exit 1 + fi +} + +check_git_config() { + if [[ "$(git config --get clangFormat.style)" != "file" ]]; then + echo "SETUP ERROR: git config clangFormat.style is wrong (should be 'file'). Fix this with:" + echo "git config clangFormat.style file" + exit 1 + fi +} + +check_clang_format +check_git_config + +readonly out=$(git clang-format -v --diff) + +# In these cases, there is no formatting issues, so we succeed +if [[ "$out" == *"no modified files to format"* ]]; then exit 0; fi +if [[ "$out" == *"clang-format did not modify any files"* ]]; then exit 0; fi + +# Any other case implies formatting results +echo "ERROR: you need to run git clang-format on your commit" + +# print the errors to show what's the issue +git clang-format -v --diff + +# fail the pre-commit +exit 1 diff --git a/Documentation/development/coding-style-policy.md b/Documentation/development/coding-style-policy.md index 3267defa47..5287d28974 100644 --- a/Documentation/development/coding-style-policy.md +++ b/Documentation/development/coding-style-policy.md @@ -50,6 +50,40 @@ developers. The other KiCad developers will appreciate your effort. **Do not modify this document without the consent of the project leader. All changes to this document require approval.** +## 1.3 Tools + +There are some tools that can help you format your code easily. + +[`clang-format`][clang-format] is a formatting tool that can both be used to +provide code-style automation to your editor of choice, as well as allow git to +check formatting when committing (using a "Git hook"). You should install this +program to be able to use the Git hooks. + +The style config file is `_clang-format`, and should be picked up automatically +by `clang-format` when the `--style=file` option is set. + +To enable the Git hooks (only needs to be done once per Git repo): + + git config core.hooksPath .githooks + +Set the `git clang-format` tool to use the provided `_clang-format` file: + + git config clangFormat.style file + +Then, to enable the format checker, set the `KICAD_CHECK_FORMAT` environment +variable in your shell. Without this variable, the format checker will not +run on commit, but you can still use `git clang-format --diff` to check manually. + +If enabled, when you commit a change, you will be told if you have caused any +style violations (only in your changed code). You can fix them automatically +with: + + git clang-format + +Or you can proceed anyway, if you are sure your style is correct: + + git commit --no-verify + # 2. Naming Conventions # {#naming_conventions} Before delving into anything as esoteric as indentation and formatting, @@ -788,6 +822,7 @@ learn something new. - [C++ Operator Overloading Guidelines][overloading] - [Wikipedia's Programming Style Page][style] +[clang-format]: https://clang.llvm.org/docs/ClangFormat.html [cppstandard]:http://www.possibility.com/Cpp/CppCodingStandard.html [kernel]:http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/CodingStyle [overloading]:http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html