[Libreoffice-commits] core.git: .clang-format .git-hooks/pre-commit solenv/clang-format

Miklos Vajna vmiklos at collabora.co.uk
Fri Nov 3 08:29:40 UTC 2017


 .clang-format                                   |   44 +++++++++
 .git-hooks/pre-commit                           |  113 ++++++++++++++++++++++++
 solenv/clang-format/generate-style-blacklist.sh |   12 ++
 3 files changed, 169 insertions(+)

New commits:
commit 98f5f4d39c9c1cae7e8b56e2b33ee0be58e79f1d
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Nov 2 17:09:03 2017 +0100

    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 at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

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:


More information about the Libreoffice-commits mailing list