summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-11-02 17:09:03 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-11-03 09:29:11 +0100
commit98f5f4d39c9c1cae7e8b56e2b33ee0be58e79f1d (patch)
treeffcaf204c4c934058abd3824ee6795cdf2e2f125
parentsolenv: add list of existing C++ files for clang-format blacklist purposes (diff)
downloadcore-98f5f4d39c9c1cae7e8b56e2b33ee0be58e79f1d.tar.gz
core-98f5f4d39c9c1cae7e8b56e2b33ee0be58e79f1d.zip
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-format44
-rwxr-xr-x.git-hooks/pre-commit113
-rwxr-xr-xsolenv/clang-format/generate-style-blacklist.sh12
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: