diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..554a06e7c1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,31 @@ + +# Custom attribute to mark source files using KiCad C++ formatting +[attr]kicad-cpp-source whitepace=tab-in-indent format.clang-format-kicad + +# Custom attribute to mark KiCad's own CMake files +[attr]kicad-cmake-source whitespace=tab-in-indent + +# Custom attribute for auto-generated sources: +# * Do not perform whitespace checking +# * Do not format +[attr]generated whitespace=-tab-in-indent,-indent-with-non-tab -format.clang-format-kicad + +# By default, all C and C++ files conform to KiCad formatting, +# unless overridden +*.c kicad-cpp-source +*.cpp kicad-cpp-source +*.h kicad-cpp-source + +*.cmake kicad-cmake-source +*.txt kicad-cmake-source + +# Compiled bitmap sources +bitmaps_png/cpp_*/*.cpp generated + +# wxFormBuilder-generated files +**/dialog*/*_base.cpp generated +**/dialog*/*_base.h generated + +# Lemon grammars +common/libeval/grammar.c generated +common/libeval/grammar.h generated diff --git a/.githooks/pre-commit.d/50-check-format b/.githooks/pre-commit.d/50-check-format index 8de58b51e6..5995aa6ea4 100755 --- a/.githooks/pre-commit.d/50-check-format +++ b/.githooks/pre-commit.d/50-check-format @@ -30,20 +30,48 @@ check_git_config() { fi } +get_filtered_filenames() +{ + format_attr='clang-format-kicad' + + # command to get list of candidate files + git_list_files='git diff --cached --name-only --diff-filter=ACM' + + files=$(${git_list_files} | + + # Filter for format-controlled files + git check-attr --stdin format.${format_attr} | + + # output only the file names + grep ": set$" | + cut -d: -f1) + + echo ${files} +} + check_clang_format check_git_config -readonly out=$(git clang-format -v --diff) +files_to_check=$(get_filtered_filenames) + +if [ -z "${files_to_check}" ]; then + # No controlled files to check + exit 0; +fi + +git_clang_format_cmd="git clang-format -v --diff -- ${files_to_check}" + +readonly out=$(${git_clang_format_cmd}) # 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" +echo "ERROR: you need to run clang-format (e.g. using tools/check_coding.sh) on your commit" # print the errors to show what's the issue -git clang-format -v --diff +${git_clang_format_cmd} # fail the pre-commit exit 1 diff --git a/Documentation/development/coding-style-policy.md b/Documentation/development/coding-style-policy.md index 9f3d852585..6d5c4b434e 100644 --- a/Documentation/development/coding-style-policy.md +++ b/Documentation/development/coding-style-policy.md @@ -72,18 +72,25 @@ Set the `git clang-format` tool to use the provided `_clang-format` 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. +run on commit, but you can still check files staged for commit 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: + tools/check_coding.sh --diff - git clang-format +If the hook is 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 your +staged changes automatically with this tool: + + tools/check_coding.sh Or you can proceed anyway, if you are sure your style is correct: git commit --no-verify +The `check_coding.sh` tool has other modes: + +* Make (or see only) changes to files modified in the previous commit: + * `check_coding.sh --amend [--diff]` + # 2. Naming Conventions # {#naming_conventions} Before delving into anything as esoteric as indentation and formatting, diff --git a/tools/check_coding.sh b/tools/check_coding.sh new file mode 100755 index 0000000000..c5f730dfbc --- /dev/null +++ b/tools/check_coding.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash + +# This program source code file is part of KICAD, a free EDA CAD application. +# +# Copyright (C) 2019 Kicad Developers, see AUTHORS.txt for contributors. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, you may find one here: +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# or you may search the http://www.gnu.org website for the version 2 license, +# or you may write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +# Simple program to check and fix formatting in KiCad source files, +# while ignoring violations in "uncontrolled" files, such as generated files +# or 3rd party sources. + +usage='usage: check_coding.sh [] [--] + --help Print usage plus more detailed help. + + --diff Only show proposed changes, do not format files + + --cached Re-format changes currently staged for commit + --amend Re-format changes made in the previous commit +' + +help="$usage"' +Example to format cached files: + check_coding.sh + +To show what would be done: + check_coding.sh --diff +' + +die() { + echo "$@" 1>&2; exit 1 +} + +# Parse command-line arguments. +diff=false +mode='cached' + +while test "$#" != 0; do + case "$1" in + --diff) diff=true ;; + --amend) mode='amend' ;; + --cached) mode='cached' ;; + --) shift ; break ;; + -*) die "$usage" ;; + *) break ;; + esac + shift +done + +test "$#" = 0 || die "$usage" + +# This is the main KiCad formatting attribute +# used by .gitattributes to mark KiCad source files +format_attribute="format.clang-format-kicad" + +format_commit='HEAD' + +# Select the git file list command and the commit to check +case "${mode}" in + '') echo "$usage"; exit 0 ;; + amend) + # Files changed by the last commit + git_list_files='git diff-tree --diff-filter=ACM --name-only HEAD -r --no-commit-id' + format_commit='HEAD^' + ;; + cached) + # Currently staged files + git_list_files='git diff-index --diff-filter=ACM --name-only HEAD --cached' + ;; + *) die "Invalid mode: $mode" ;; +esac + + +if [ "${diff}" = true ]; then + # Only show the proposed changes + format_command="git clang-format --diff ${format_commit}" +else + # Actually make the changes + format_command="git clang-format ${format_commit}" +fi + +${git_list_files} | + + # Filter sources with the formatting attribute set + git check-attr ${format_attribute} --stdin | + + # output only the file names + grep ": set$" | + cut -d: -f1 | + + # Apply the formatting command + xargs -d '\n' ${format_command}