Kaydet (Commit) 98f5f4d3 authored tarafından Miklos Vajna's avatar Miklos Vajna

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/43736Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
üst cd592cca
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
......@@ -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:
#!/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:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment