From cc82241505188f8fa82398099cc7c3d623e75a61 Mon Sep 17 00:00:00 2001 From: Paul Gessinger <hello@paulgessinger.com> Date: Tue, 17 Oct 2017 13:00:39 +0200 Subject: [PATCH] add scripts for format and license check --- .clang-format | 7 ++-- CI/check_format | 31 +++++++++++++++ CI/check_format_local | 11 ++++++ CI/check_license.py | 87 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 3 deletions(-) create mode 100755 CI/check_format create mode 100755 CI/check_format_local create mode 100755 CI/check_license.py diff --git a/.clang-format b/.clang-format index 3db10bb5..d0a782f0 100644 --- a/.clang-format +++ b/.clang-format @@ -19,7 +19,7 @@ AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: true BinPackArguments: false BinPackParameters: false -BraceWrapping: +BraceWrapping: AfterClass: true AfterControlStatement: false AfterEnum: false @@ -45,7 +45,7 @@ DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] -IncludeCategories: +IncludeCategories: - Regex: '^<.*>' Priority: 1 - Regex: '^(<|")boost/' @@ -57,7 +57,7 @@ IncludeCategories: IndentCaseLabels: false IndentWidth: 2 IndentWrappedFunctionNames: false -KeepEmptyLinesAtTheStartOfBlocks: false +KeepEmptyLinesAtTheStartOfBlocks: true MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 @@ -88,3 +88,4 @@ Standard: Cpp11 TabWidth: 2 UseTab: Never ... + diff --git a/CI/check_format b/CI/check_format new file mode 100755 index 00000000..e9d794d9 --- /dev/null +++ b/CI/check_format @@ -0,0 +1,31 @@ +#!/bin/sh +# +# check that all code complies w/ the clang-format specification +# +# if all is well, returns w/o errors and does not print anything. +# otherwise, return an error and print offending changes + +set -e # abort on error + +if [ $# -ne 1 ]; then + echo "wrong number of arguments" + echo "" + echo "usage: check_format <DIR>" + exit 1 +fi + +clang-format --version + +cd $1 +find . -iname '*.cpp' -or -iname '*.hpp' -or -iname '*.ipp' \ + | xargs clang-format -i -style=file + + +if ! [ -z $CI ]; then + mkdir changed + for f in $(git diff --name-only); do + cp --parents $f changed + done +fi + +exec git diff --exit-code --stat diff --git a/CI/check_format_local b/CI/check_format_local new file mode 100755 index 00000000..f8fe8cba --- /dev/null +++ b/CI/check_format_local @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ $# -ne 1 ]; then + echo "wrong number of arguments" + echo "" + echo "usage: check_format <DIR>" + exit 1 +fi + +WD="$(cd "$(dirname "$1")"; pwd)/$(basename "$1")" +docker run --rm -ti -v $WD:$WD:rw -w $WD gitlab-registry.cern.ch/pagessin/machines/check CI/check_format . diff --git a/CI/check_license.py b/CI/check_license.py new file mode 100755 index 00000000..61bf68b0 --- /dev/null +++ b/CI/check_license.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +import argparse +import os +import sys +from subprocess import check_output +import re +import difflib +from datetime import datetime + + +def main(): + p = argparse.ArgumentParser() + p.add_argument("input") + p.add_argument("--fix", action="store_true") + + args = p.parse_args() + + if os.path.isdir(args.input): + srcs = str(check_output(["find", args.input, "-iname", "*.cpp", "-or", "-iname", "*.hpp", "-or", "-iname", "*.ipp"]), "utf-8").strip().split("\n") + else: + srcs = [args.input] + + year = datetime.now().strftime("%Y") + + raw = """// This file is part of the ACTS project. +// +// Copyright (C) {year} ACTS project team +// +// 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/.""" + + rawstr = raw.format(year=year) + raw = rawstr + + + reg = ( + r"\A// This file is part of the ACTS project.\n" + +r"//\n" + +r"// Copyright \(C\) 20[0-9]{2} ACTS project team\n" + +r"//\n" + +r"// This Source Code Form is subject to the terms of the Mozilla Public\n" + +r"// License, v\. 2\.0\. If a copy of the MPL was not distributed with this\n" + +r"// file, You can obtain one at http://mozilla.org/MPL/2.0/.\Z" + ) + + ref = re.compile(reg, re.M) + clean_re = re.compile(r"20[0-9]{2}") + def clean(s): + return clean_re.sub("XXXX", s) + def get_clean_lines(s): + return [clean(l)+"\n" for l in s.split("\n")] + raw = get_clean_lines(raw) + + exit = 0 + for src in srcs: + with open(src, "r+") as f: + license = "" + for x in range(len(raw)): + line = f.readline() + if not line.startswith("//"): + break + license += line + license = ("".join(license)).strip() + m = ref.search(license) + if m == None: + sys.stderr.write("invalid / mising license in "+src+"\n") + diff = difflib.unified_diff(raw, get_clean_lines(license)) + sys.stderr.writelines(diff) + sys.stderr.write("\n") + + if args.fix: + print("-> fixing file") + f.seek(0) + file_content = f.read() + f.seek(0) + f.write(rawstr+"\n\n") + f.write(file_content) + + exit = 1 + + sys.exit(exit) + + + +if "__main__" == __name__: + main() -- GitLab