diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-11-02 17:09:03 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-11-03 09:29:11 +0100 |
commit | 98f5f4d39c9c1cae7e8b56e2b33ee0be58e79f1d (patch) | |
tree | ffcaf204c4c934058abd3824ee6795cdf2e2f125 | |
parent | cd592cca271cdf5eabe2aba3479e4831ef3e14a6 (diff) |
Enforce coding style with clang-format for new code
- The actual blacklist has to be generated with
solenv/clang-format/generate-style-blacklist.sh in a separate commit.
- .clang-format is from
<https://lists.freedesktop.org/archives/libreoffice/2014-August/062802.html>,
except:
- the commented out lines are removed
- Standard is Cpp11 instead of Cpp03
- explicitly avoid sorting includes (requested during ESC meeting
2017-10-11)
- no indentation inside namespaces (lots of existing code in sc wants this)
- The git hooks prints a diff when the style is violated, along with a
command to fix up the violation automatically. It also enforces style
only in new files and ignores all files listed in the blacklist.
- To avoid introducing one more hard-to-setup build dependency for new
developers, help them two ways:
- if clang-format is not installed, provide pre-built binaries for
Linux/Windows/macOS
- download/install of these binaries are printed as cmdline
instructions, similar to how we have our own 'make' on Windows
- As per ESC call 2017-11-02, currently don't do any checks if
clang-format is not installed (as a first step).
Change-Id: Iaa139c396337e8734aa1853305d808438260c41a
Reviewed-on: https://gerrit.libreoffice.org/43736
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
-rw-r--r-- | .clang-format | 44 | ||||
-rwxr-xr-x | .git-hooks/pre-commit | 113 | ||||
-rwxr-xr-x | solenv/clang-format/generate-style-blacklist.sh | 12 |
3 files changed, 169 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000000..4dc707ef6468 --- /dev/null +++ b/.clang-format @@ -0,0 +1,44 @@ +AccessModifierOffset: -4 +ConstructorInitializerIndentWidth: 4 +AlignEscapedNewlinesLeft: false +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakTemplateDeclarations: false +AlwaysBreakBeforeMultilineStrings: false +BreakBeforeBinaryOperators: true +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +BinPackParameters: true +ColumnLimit: 80 +ConstructorInitializerAllOnOneLineOrOnePerLine: false +DerivePointerBinding: false +ExperimentalAutoDetectBinPacking: false +IndentCaseLabels: true +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 60 +PenaltyBreakString: 1000 +PenaltyBreakFirstLessLess: 120 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerBindsToType: true +SpacesBeforeTrailingComments: 1 +Cpp11BracedListStyle: false +Standard: Cpp11 +IndentWidth: 4 +TabWidth: 8 +UseTab: Never +BreakBeforeBraces: Allman +IndentFunctionDeclarationAfterType: false +SpacesInParentheses: false +SpacesInAngles: false +SpaceInEmptyParentheses: false +SpacesInCStyleCastParentheses: false +SpaceAfterControlStatementKeyword: true +SpaceBeforeAssignmentOperators: true +ContinuationIndentWidth: 4 +SortIncludes: false diff --git a/.git-hooks/pre-commit b/.git-hooks/pre-commit index b0779e5aaa1f..b40ad6f004d9 100755 --- a/.git-hooks/pre-commit +++ b/.git-hooks/pre-commit @@ -108,6 +108,116 @@ sub check_whitespaces($) } } +sub check_style($) +{ + my ($h) = @_; + my $src = "c|cpp|cxx|h|hxx|inl"; + my @bad_names = (); + my %blacklist_names = (); + + # Use clang-format from PATH, unless it's available in our dedicated + # directory. + my $opt_lo = "/opt/lo/bin"; + my $clang_format = "$opt_lo/clang-format"; + if (! -x $clang_format) + { + foreach my $dir (split /:/, $ENV{PATH}) + { + $clang_format = "$dir/clang-format"; + if (-x $clang_format) + { + last; + } + } + } + + # Read the blacklist. + if (open(LINES, "solenv/clang-format/blacklist")) + { + while (my $line = <LINES>) + { + chomp $line; + $blacklist_names{$line} = 1; + } + } + + # Check if clang-format is installed. + if (! -x $clang_format) + { + # As a first step, don't do any checks in this case. + return; + + my $version = "r302580"; + my $platform = "linux64"; + my $download = "wget"; + if ($^O eq "cygwin") + { + $platform = "win.exe"; + } + elsif ($^O eq "darwin") + { + $platform = "mac"; + $download = "curl -O"; + } + + print("Error: clang-format is not found in $opt_lo or in your PATH.\n"); + print("To get a clang-format binary for your platform, please do:\n\n"); + print("mkdir -p $opt_lo\n"); + print("cd $opt_lo\n"); + print("$download https://dev-www.libreoffice.org/bin/clang-format-$version-$platform\n"); + print("cp clang-format-$version-$platform clang-format\n"); + print("chmod +x clang-format\n"); + exit(1); + } + + if ($^O eq "cygwin") + { + $clang_format = `cygpath -m $clang_format`; + chomp $clang_format; + } + + # Get a list of non-deleted changed files. + open (FILES, "git diff-index --cached --diff-filter=AM --name-only $h |") || die "Cannot run git diff."; + while (my $filename = <FILES>) + { + chomp $filename; + if ($filename =~ /\.($src)$/ and !exists($blacklist_names{$filename})) + { + if (system("$clang_format $filename | git --no-pager diff --no-index --exit-code $filename -") != 0) + { + push @bad_names, $filename; + } + } + } + + # Enforce style. + if (scalar @bad_names) + { + my $autostyle = `git config libreoffice.autostyle`; + chomp $autostyle; + if ($autostyle ne "true") + { + print("\nThe above differences were found between the code to commit \n"); + print("and the clang-format rules. You can apply these changes with:\n"); + print("\n$clang_format -i " . join(" ", @bad_names) . "\n\n"); + print("Aborting commit. Apply changes and commit again or skip checking\n"); + print("with --no-verify (not recommended).\n"); + exit(1); + } + else + { + # 'git config libreoffice.autostyle true' was invoked to run + # clang-format automatically. + print("\nThe above differences were found between the code to commit \n"); + print("and the clang-format rules. Fixing these now automatically.\n"); + print("Running '$clang_format -i " . join(" ", @bad_names) . "' for you...\n"); + system("$clang_format -i " . join(" ", @bad_names)); + system("git add " . join(" ", @bad_names)); + print("Done.\n"); + } + } +} + # Do the work :-) # Initial commit: diff against an empty tree object @@ -172,6 +282,9 @@ while (<FILES>) # fix whitespace in code check_whitespaces( $against); +# fix style in code +check_style($against); + # all OK exit( 0 ); # vi:set shiftwidth=4 expandtab: diff --git a/solenv/clang-format/generate-style-blacklist.sh b/solenv/clang-format/generate-style-blacklist.sh new file mode 100755 index 000000000000..bd55bff76ea4 --- /dev/null +++ b/solenv/clang-format/generate-style-blacklist.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Generates a blacklist containing all existing cxx/hxx files. + +git ls-files |egrep '\.(c|cpp|cxx|h|hxx|inl)$' > solenv/clang-format/blacklist + +# vi:set shiftwidth=4 expandtab: |