IAP GITLAB

Skip to content
Snippets Groups Projects
do-clang-format.py 4.35 KiB
Newer Older
Hans Dembinski's avatar
Hans Dembinski committed
#!/usr/bin/env python3
"""
Run clang-format with the style file in the CORSIKA repository.

Hans Dembinski's avatar
Hans Dembinski committed
By default it finds new files and files with modifications with respect to the current master and prints the filenames which need clang-formatting. Returns 1 if there are files which need modifications and 0 otherwise, so it can be used as a test.
Hans Dembinski's avatar
Hans Dembinski committed
"""
import argparse
import subprocess as subp
import os
import sys
import re
Hans Dembinski's avatar
Hans Dembinski committed

ralfulrich's avatar
ralfulrich committed
debug = False
do_progress = False
try:    
    from progress.bar import ChargingBar
    do_progress = True
except ImportError as e:
    do_progress = False
    # no progress bar

Hans Dembinski's avatar
Hans Dembinski committed
parser = argparse.ArgumentParser(description=__doc__)
Hans Dembinski's avatar
Hans Dembinski committed
parser.add_argument('--apply', action="store_true",
    help="Apply clang-format to files which need changes.")
parser.add_argument("--all", action="store_true",
    help="Check all files below current path instead of new/modified.")
ralfulrich's avatar
ralfulrich committed
parser.add_argument("--docker", action="store_true",
    help="Use corsika/devel:clang-8 container to run clang-format. Make sure you are in group \"docker\". ")
Hans Dembinski's avatar
Hans Dembinski committed

args = parser.parse_args()

ralfulrich's avatar
ralfulrich committed
excludeDirs = [r"^(\./)?modules/", r"^(\./)?externals/", r"^(\./)?build", r"^(\./)?install",
               r"(\./)?\.git", r"^(\./)?corsika/framework/units",
               r"^(\./)?Random123/"]
Hans Dembinski's avatar
Hans Dembinski committed
filelist = []
if args.all:
    for dirpath, dirnames, filenames in os.walk("."):
ralfulrich's avatar
ralfulrich committed
        excl = False
ralfulrich's avatar
ralfulrich committed
        for excl_dir in excludeDirs:
            if re.findall(excl_dir, dirpath):
ralfulrich's avatar
ralfulrich committed
                excl = True
ralfulrich's avatar
ralfulrich committed
                break
        if excl:
            continue
Hans Dembinski's avatar
Hans Dembinski committed
        for f in filenames:
            if (f.endswith(".hpp") or f.endswith(".cpp") or f.endswith(".inl")):
Hans Dembinski's avatar
Hans Dembinski committed
                filename = os.path.join(dirpath, f)
                if not os.path.islink(filename):
                    filelist.append(filename)
    if not filelist:
Hans Dembinski's avatar
Hans Dembinski committed
        raise SystemExit("Error: You specified --all, but file list is empty. "
                         "Did you run from the build directory?")
Hans Dembinski's avatar
Hans Dembinski committed
else:
    cmd = "git diff master --name-status"
    for line in subp.check_output(cmd, shell=True).decode("utf8").strip().split("\n"):
        if line.startswith("D"): continue
        if line.startswith("R"):
            filelist.append(line.split()[-1])
        else:
            filelist.append(line[1:].lstrip())
Hans Dembinski's avatar
Hans Dembinski committed

    cmd = "git ls-files --exclude-standard --others"
    filelist2 = subp.check_output(cmd, shell=True).decode("utf8").strip().split("\n")
    filelist += filelist2
    # some cleanup
    filelist_clean = []
    for f in filelist:
        if not (f.endswith(".hpp") or f.endswith(".cpp") or f.endswith(".inl")):
            continue
        if os.path.islink(f):
            continue
        excl = False
        for excl_dir in excludeDirs:
            if re.findall(excl_dir, f):
                excl = True
                break
        if excl:
            continue
        filelist_clean.append(f)
    filelist = filelist_clean
Hans Dembinski's avatar
Hans Dembinski committed

ralfulrich's avatar
ralfulrich committed
if debug:
    print ("filelist: ", filelist)
    
if "CLANG_FORMAT" in os.environ:
  cmd = os.environ["CLANG_FORMAT"]
ralfulrich's avatar
ralfulrich committed
if args.docker: 
  USER=os.environ["USER"]
  UID=os.getuid()
  GID=os.getgid()
  PWD=os.getcwd()
  # note, currently in container it is clang-8 
  cmd = "docker container run --rm -v {}:/corsika -w /corsika -u {}:{} corsika/devel:clang-8 clang-format-8".format(PWD,UID,GID)
cmd += " -style=file"

version = subp.check_output(cmd.split() + ["--version"]).decode("utf-8")
print (version)
print ("Note: the clang-format version has an impact on the result. Make sure you are consistent with current CI. Consider \'--docker\' option.")

bar = None
if do_progress:
    bar = ChargingBar('Processing', max=len(filelist))

Hans Dembinski's avatar
Hans Dembinski committed
if args.apply:
ralfulrich's avatar
ralfulrich committed
    changed = []
    for filename in filelist:        
ralfulrich's avatar
ralfulrich committed
        a = open(filename, "rb").read()
Hans Dembinski's avatar
Hans Dembinski committed
        subp.check_call(cmd.split() + ["-i", filename])
ralfulrich's avatar
ralfulrich committed
        b = open(filename, "rb").read()
        if a != b:
            changed.append(filename)
    if bar: bar.finish()
ralfulrich's avatar
ralfulrich committed
    if debug:
        print ("changed: ", changed)
    
Hans Dembinski's avatar
Hans Dembinski committed
else:
    # only print files which need formatting
    files_need_formatting = 0
    for filename in filelist:
Hans Dembinski's avatar
Hans Dembinski committed
        a = open(filename, "rb").read()
        b = subp.check_output(cmd.split() + [filename])
        if a != b:
            files_need_formatting += 1
            print(filename)
    if bar: bar.finish()            
Hans Dembinski's avatar
Hans Dembinski committed
    sys.exit(1 if files_need_formatting > 0 else 0)