Kaydet (Commit) 13de7527 authored tarafından Miklos Vajna's avatar Miklos Vajna

clang-format: enforce coding style via Jenkins

- factor out common code to a shared module, and quote path to the
  clang-format binary, just in case.
- add a new check-last-commit script that is the CI equivalent of the
  exiting git pre-commit hook, but this one handles lack of clang-format
  as an error, not as a warning.
- $LODE_HOME/opt/bin is supposed to be in PATH already, so not
  mentioning LODE_HOME in ClangFormat::find() explicitly.
- if both COMPILER_PLUGINS and LODE_HOME is set, invoke
  solenv/clang-format/check-last-commit as part of 'make check'

To test these changes as part of CI, fix a single style violation in an
already committed, non-blacklisted file.

This depends on the lode.git commit
496123bcae28e06c6d6aeda39a5afd1e1fb1fd98 (utils_Linux: install
clang-format in the Jenkins case, 2017-11-16), otherwise erroring out on
a not installed clang-format as part of the build would be a problem.

Change-Id: Ib3110826194ff78a7f1bed1c3796147e92ccb3ba
Reviewed-on: https://gerrit.libreoffice.org/44939Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
üst cd0dd310
......@@ -6,6 +6,8 @@
# if it wants to stop the commit.
use strict;
use lib "solenv/clang-format";
use ClangFormat;
#use File::Copy;
#use Cwd;
......@@ -108,71 +110,26 @@ sub check_whitespaces($)
}
}
# Is this binary the version we standardize on?
sub is_matching_clang_format_version($$)
{
my ($clang_format, $version) = @_;
if (! -x $clang_format)
{
return 0;
}
return `$clang_format -version` =~ /^clang-format version $version \(tags/;
}
sub check_style($)
{
my ($h) = @_;
my $src = "c|cpp|cxx|h|hxx|inl";
my $src = ClangFormat::get_extension_regex();
my @bad_names = ();
my %blacklist_names = ();
# Use clang-format from CLANG_FORMAT, or from PATH unless it's available in our dedicated
# directory.
my $version = "5.0.0";
my $opt_lo = "/opt/lo/bin";
my $clang_format = $ENV{CLANG_FORMAT};
if (!(defined($clang_format) && is_matching_clang_format_version($clang_format, $version)))
{
$clang_format = "$opt_lo/clang-format";
if (!is_matching_clang_format_version($clang_format, $version))
{
foreach my $dir (split /:/, $ENV{PATH})
{
$clang_format = "$dir/clang-format";
if (is_matching_clang_format_version($clang_format, $version))
{
last;
}
}
}
}
# Read the blacklist.
if (open(LINES, "solenv/clang-format/blacklist"))
{
while (my $line = <LINES>)
{
chomp $line;
$blacklist_names{$line} = 1;
}
}
if ($^O eq "cygwin")
{
$clang_format = `cygpath -m $clang_format`;
chomp $clang_format;
}
my $blacklist_names = ClangFormat::get_blacklist();
my $clang_format = ClangFormat::find();
# 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 ($filename =~ /\.($src)$/ and !exists($blacklist_names->{$filename}))
{
if (! -x $clang_format)
{
my $version = ClangFormat::get_wanted_version();
my $opt_lo = ClangFormat::get_own_directory();
print("\nWARNING: Commit touches new (non-blacklisted) files, but no clang-format"
. " ${version}\n");
print(" found (via CLANG_FORMAT or PATH env vars, or in ${opt_lo}).\n\n");
......@@ -200,7 +157,7 @@ sub check_style($)
print("<https://dev-www.libreoffice.org/bin/README.clang-format.txt>).\n\n");
return;
}
if (system("$clang_format $filename | git --no-pager diff --no-index --exit-code $filename -") != 0)
if (!ClangFormat::check_style($clang_format, $filename))
{
push @bad_names, $filename;
}
......
......@@ -19,6 +19,7 @@ build_goal:=$(if $(filter build check,$(MAKECMDGOALS)),all)\
SRCDIR := @SRC_ROOT@
BUILDDIR := @BUILDDIR@
COMPILER_PLUGINS := @COMPILER_PLUGINS@
GIT_BUILD := $(if $(wildcard $(SRCDIR)/.git),T)
# Run autogen.sh if needed and force make to restart itself.
......@@ -262,6 +263,7 @@ bootstrap: check-if-root compilerplugins
# with some translations like "build"->"all" for historic reasons
#
build: bootstrap fetch $(if $(CROSS_COMPILING),cross-toolset) \
$(if $(filter check,$(MAKECMDGOALS)),$(if $(COMPILER_PLUGINS),$(if $(LODE_HOME),clang-format-check))) \
install-gdb-printers
$(MAKE) $(PARALLELISM_OPTION) $(IWYU_OPTION) $(GMAKE_OPTIONS) -f $(SRCDIR)/Makefile.gbuild $(build_goal)
ifeq ($(OS),IOS)
......@@ -452,6 +454,9 @@ dump-deps-png:
dump-deps-sort:
@$(SRCDIR)/bin/module-deps.pl -t $(MAKE) $(SRCDIR)/Makefile.gbuild
clang-format-check:
@$(SRCDIR)/solenv/clang-format/check-last-commit
define gb_Top_GbuildToIdeIntegration
$(1)-ide-integration: gbuildtojson $(if $(filter MACOSX,$(OS_FOR_BUILD)),python3.all)
cd $(SRCDIR) && \
......
......@@ -24,6 +24,7 @@ public:
{
}
constexpr operator sal_uInt16() const { return mnWhich; }
private:
sal_uInt16 const mnWhich;
};
......
# 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/.
package ClangFormat;
use strict;
use warnings;
our @EXPORT_OK = qw(get_blacklist set_blacklist get_wanted_version get_own_directory get_extension_regex find check_style);
# Reads the blacklist.
sub get_blacklist()
{
my $src = "c|cpp|cxx|h|hxx|inl";
my %blacklist_names = ();
# Read the blacklist.
if (open(LINES, "solenv/clang-format/blacklist"))
{
while (my $line = <LINES>)
{
chomp $line;
$blacklist_names{$line} = 1;
}
}
return \%blacklist_names;
}
# Writes the blacklist.
# The single argument is a reference to an array.
sub set_blacklist
{
my @filenames = @{$_[0]};
open my $fh, ">", "solenv/clang-format/blacklist" or die $!;
print $fh "$_\n" for @filenames;
close $fh;
}
# Returns the clang-format version used of style enforcement.
sub get_wanted_version()
{
return "5.0.0";
}
# Returns the directory that can host a binary which is used automatically, even
# if it's not in PATH.
sub get_own_directory()
{
return "/opt/lo/bin";
}
# Returns a regex matching filenames we clang-format.
sub get_extension_regex()
{
return "c|cpp|cxx|h|hxx|inl";
}
# Use clang-format from CLANG_FORMAT, from our dedicated directory or from
# PATH, in this order.
sub find()
{
my $version = get_wanted_version();
my $opt_lo = get_own_directory();
my $clang_format = $ENV{CLANG_FORMAT};
if (!(defined($clang_format) && is_matching_clang_format_version($clang_format, $version)))
{
$clang_format = "$opt_lo/clang-format";
if (!is_matching_clang_format_version($clang_format, $version))
{
foreach my $dir (split /:/, $ENV{PATH})
{
$clang_format = "$dir/clang-format";
if (is_matching_clang_format_version($clang_format, $version))
{
last;
}
}
}
}
if ($^O eq "cygwin")
{
$clang_format = `cygpath -m '$clang_format'`;
chomp $clang_format;
}
return $clang_format;
}
# Diffs the original and the formatted version of a single file.
sub check_style($$)
{
my ($clang_format, $filename) = @_;
return system("'$clang_format' $filename | git --no-pager diff --no-index --exit-code $filename -") == 0;
}
# Private functions.
# Is this binary the version we standardize on?
sub is_matching_clang_format_version($$)
{
my ($clang_format, $version) = @_;
if (! -x $clang_format)
{
return 0;
}
return `'$clang_format' -version` =~ /^clang-format version $version \(tags/;
}
1;
# vim: set shiftwidth=4 softtabstop=4 expandtab:
......@@ -1259,7 +1259,6 @@ chart2/source/inc/chartview/ExplicitScaleValues.hxx
chart2/source/inc/chartview/ExplicitValueProvider.hxx
chart2/source/inc/chartview/chartviewdllapi.hxx
chart2/source/inc/defines.hxx
chart2/source/inc/macros.hxx
chart2/source/inc/servicenames.hxx
chart2/source/inc/servicenames_charttypes.hxx
chart2/source/inc/servicenames_coosystems.hxx
......@@ -10256,7 +10255,6 @@ sc/qa/extras/sccellcursorobj.cxx
sc/qa/extras/sccellobj.cxx
sc/qa/extras/sccellrangeobj.cxx
sc/qa/extras/sccellrangesobj.cxx
sc/qa/extras/sccondformats.cxx
sc/qa/extras/scdatabaserangeobj.cxx
sc/qa/extras/scdatapilotfieldobj.cxx
sc/qa/extras/scdatapilotitemobj.cxx
......@@ -10864,11 +10862,6 @@ sc/source/filter/rtf/expbase.cxx
sc/source/filter/rtf/rtfexp.cxx
sc/source/filter/rtf/rtfimp.cxx
sc/source/filter/rtf/rtfparse.cxx
sc/source/filter/starcalc/collect.cxx
sc/source/filter/starcalc/collect.hxx
sc/source/filter/starcalc/scflt.cxx
sc/source/filter/starcalc/scflt.hxx
sc/source/filter/starcalc/scfobj.cxx
sc/source/filter/xcl97/XclExpChangeTrack.cxx
sc/source/filter/xcl97/XclImpChangeTrack.cxx
sc/source/filter/xcl97/xcl97esc.cxx
......@@ -12142,8 +12135,6 @@ sd/source/ui/framework/module/SlideSorterModule.cxx
sd/source/ui/framework/module/SlideSorterModule.hxx
sd/source/ui/framework/module/ToolBarModule.cxx
sd/source/ui/framework/module/ToolBarModule.hxx
sd/source/ui/framework/module/ToolPanelModule.cxx
sd/source/ui/framework/module/ToolPanelModule.hxx
sd/source/ui/framework/module/ViewTabBarModule.cxx
sd/source/ui/framework/module/ViewTabBarModule.hxx
sd/source/ui/framework/tools/FrameworkHelper.cxx
......@@ -14371,7 +14362,6 @@ svx/source/dialog/linkwarn.cxx
svx/source/dialog/measctrl.cxx
svx/source/dialog/optgrid.cxx
svx/source/dialog/orienthelper.cxx
svx/source/dialog/page.h
svx/source/dialog/pagectrl.cxx
svx/source/dialog/pagenumberlistbox.cxx
svx/source/dialog/papersizelistbox.cxx
......@@ -18221,14 +18211,6 @@ vcl/source/filter/jpeg/jpegc.cxx
vcl/source/filter/jpeg/jpegcomp.h
vcl/source/filter/jpeg/transupp.c
vcl/source/filter/jpeg/transupp.h
vcl/source/filter/sgfbram.cxx
vcl/source/filter/sgfbram.hxx
vcl/source/filter/sgffilt.hxx
vcl/source/filter/sgvmain.cxx
vcl/source/filter/sgvmain.hxx
vcl/source/filter/sgvspln.cxx
vcl/source/filter/sgvspln.hxx
vcl/source/filter/sgvtext.cxx
vcl/source/filter/wmf/emfwr.cxx
vcl/source/filter/wmf/emfwr.hxx
vcl/source/filter/wmf/wmf.cxx
......
#!/usr/bin/env perl
# 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/.
# Checks the style of the files changed in the last commit, for CI purposes.
use strict;
use warnings;
use lib "solenv/clang-format";
use ClangFormat;
sub check_style()
{
if ( ! -e ".git" )
{
# Can't diff when this is not a git checkout.
return;
}
my $src = ClangFormat::get_extension_regex();
my @good_names = ();
my @bad_names = ();
my $blacklist_names = ClangFormat::get_blacklist();
my $clang_format = ClangFormat::find();
# Get a list of non-deleted changed files.
# Explicitly use the low-level 'git diff-tree' (rathern that plain 'git
# diff') so we get the new, but not the old files for renames and/or
# copies.
open (FILES, "git diff-tree -r --diff-filter=AM --name-only HEAD^ HEAD |") || die "Cannot run git diff.";
while (my $filename = <FILES>)
{
chomp $filename;
if ($filename =~ /\.($src)$/ and !exists($blacklist_names->{$filename}))
{
if (! -x $clang_format)
{
my $version = ClangFormat::get_wanted_version();
print("solenv/clang-format/check-last-commit: ");
print("ERROR: no clang-format ${version} was found.\n\n");
exit(1);
}
if (ClangFormat::check_style($clang_format, $filename))
{
push @good_names, $filename;
}
else
{
push @bad_names, $filename;
}
}
}
# Enforce style.
if (scalar @bad_names)
{
print("\nERROR: The above differences were found between the code to commit \n");
print("and the clang-format rules.\n");
print("\nsolenv/clang-format/check-last-commit: KO\n");
exit(1);
}
else
{
print("solenv/clang-format/check-last-commit: checked the following files:\n");
print(join("\n", @good_names));
print("\nsolenv/clang-format/check-last-commit: OK\n");
}
}
check_style();
exit(0);
# vim: set shiftwidth=4 softtabstop=4 expandtab:
#!/bin/bash
#!/usr/bin/env perl
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
......@@ -7,6 +7,25 @@
# Generates a blacklist containing all existing cxx/hxx files.
git ls-files |egrep '\.(c|cpp|cxx|h|hxx|inl)$' > solenv/clang-format/blacklist
use strict;
use warnings;
use lib "solenv/clang-format";
use ClangFormat;
# vi:set shiftwidth=4 expandtab:
my $src = ClangFormat::get_extension_regex();
my @filenames = ();
# Get a list of files.
open (FILES, "git ls-files |") || die "Cannot run git ls-files.";
while (my $filename = <FILES>)
{
chomp $filename;
if ($filename =~ /\.($src)$/)
{
push @filenames, $filename;
}
}
ClangFormat::set_blacklist(\@filenames);
# vim: set shiftwidth=4 softtabstop=4 expandtab:
#!/usr/bin/env perl
# Lists source files which are not blacklisted. This is interesting if the
# clang-format version or config changes. To trigger a reformat in that case,
# you can do:
#
# clang-format -i $(solenv/clang-format/list-formatted-files)
sub check_style()
{
my $src = "c|cpp|cxx|h|hxx|inl";
my %blacklist_names = ();
# Read the blacklist.
if (open(LINES, "solenv/clang-format/blacklist"))
{
while (my $line = <LINES>)
{
chomp $line;
$blacklist_names{$line} = 1;
}
}
# Get a list of files.
open (FILES, "git ls-files |") || die "Cannot run git ls-files.";
while (my $filename = <FILES>)
{
chomp $filename;
if ($filename =~ /\.($src)$/ and !exists($blacklist_names{$filename}))
{
print($filename . "\n");
}
}
}
check_style();
exit(0);
# vim: set shiftwidth=4 softtabstop=4 expandtab:
#!/usr/bin/env perl
# 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/.
# Reformat files which are not blacklisted. This is interesting if the
# clang-format version or config changes.
use strict;
use warnings;
use lib "solenv/clang-format";
use ClangFormat;
my $clang_format = ClangFormat::find();
my $src = ClangFormat::get_extension_regex();
my $blacklist_names = ClangFormat::get_blacklist();
my @filenames = ();
# Get a list of files.
open (FILES, "git ls-files |") || die "Cannot run git ls-files.";
while (my $filename = <FILES>)
{
chomp $filename;
if ($filename =~ /\.($src)$/ and !exists($blacklist_names->{$filename}))
{
push @filenames, $filename;
}
}
print("$clang_format -i " . join(" ", @filenames) . "\n");
system("$clang_format -i " . join(" ", @filenames) . "\n");
# vim: set shiftwidth=4 softtabstop=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