clangformat: Only format files tracked by git by default

pull/9304/head
Xavier Claessens 3 years ago committed by Xavier Claessens
parent 0a3a9fa0c3
commit 32b7cbd4a7
  1. 5
      docs/markdown/Code-formatting.md
  2. 16
      mesonbuild/scripts/clangformat.py
  3. 14
      unittests/allplatformstests.py

@ -56,3 +56,8 @@ Note that `.clang-format-ignore` has the same format as used by
A new target `clang-format-check` has been added. It returns an error code if
any file needs to be reformatted. This is intended to be used by CI.
*Since 0.60.0*
If `.clang-format-include` file is missing and source files are in a git
repository, only files tracked by git will be included.

@ -21,6 +21,7 @@ from concurrent.futures import ThreadPoolExecutor
from ..environment import detect_clangformat
from ..compilers import lang_suffixes
from ..mesonlib import Popen_safe
import typing as T
def parse_pattern_file(fname: Path) -> T.List[str]:
@ -52,9 +53,15 @@ def run_clang_format(exelist: T.List[str], fname: Path, check: bool) -> subproce
def clangformat(exelist: T.List[str], srcdir: Path, builddir: Path, check: bool) -> int:
patterns = parse_pattern_file(srcdir / '.clang-format-include')
if not patterns:
patterns = ['**/*']
globs = [srcdir.glob(p) for p in patterns]
globs: T.Union[T.List[T.List[Path]], T.List[T.Generator[Path, None, None]]]
if patterns:
globs = [srcdir.glob(p) for p in patterns]
else:
p, o, _ = Popen_safe(['git', 'ls-files'], cwd=srcdir)
if p.returncode == 0:
globs = [[Path(srcdir, f) for f in o.splitlines()]]
else:
globs = [srcdir.glob('**/*')]
patterns = parse_pattern_file(srcdir / '.clang-format-ignore')
ignore = [str(builddir / '*')]
ignore.extend([str(srcdir / p) for p in patterns])
@ -70,7 +77,8 @@ def clangformat(exelist: T.List[str], srcdir: Path, builddir: Path, check: bool)
any(fnmatch.fnmatch(strf, i) for i in ignore):
continue
futures.append(e.submit(run_clang_format, exelist, f, check))
returncode = max(x.result().returncode for x in futures)
if futures:
returncode = max(x.result().returncode for x in futures)
return returncode
def run(args: T.List[str]) -> int:

@ -2539,6 +2539,7 @@ class AllPlatformTests(BasePlatformTests):
testheader = os.path.join(testdir, 'header.h')
badheader = os.path.join(testdir, 'header_orig_h')
goodheader = os.path.join(testdir, 'header_expected_h')
includefile = os.path.join(testdir, '.clang-format-include')
try:
shutil.copyfile(badfile, testfile)
shutil.copyfile(badheader, testheader)
@ -2547,6 +2548,17 @@ class AllPlatformTests(BasePlatformTests):
Path(goodfile).read_text(encoding='utf-8'))
self.assertNotEqual(Path(testheader).read_text(encoding='utf-8'),
Path(goodheader).read_text(encoding='utf-8'))
# test files are not in git so this should do nothing
self.run_target('clang-format')
self.assertNotEqual(Path(testfile).read_text(encoding='utf-8'),
Path(goodfile).read_text(encoding='utf-8'))
self.assertNotEqual(Path(testheader).read_text(encoding='utf-8'),
Path(goodheader).read_text(encoding='utf-8'))
# Add an include file to reformat everything
with open(includefile, 'w', encoding='utf-8') as f:
f.write('*')
self.run_target('clang-format')
self.assertEqual(Path(testheader).read_text(encoding='utf-8'),
Path(goodheader).read_text(encoding='utf-8'))
@ -2555,6 +2567,8 @@ class AllPlatformTests(BasePlatformTests):
os.unlink(testfile)
if os.path.exists(testheader):
os.unlink(testheader)
if os.path.exists(includefile):
os.unlink(includefile)
@skipIfNoExecutable('clang-tidy')
def test_clang_tidy(self):

Loading…
Cancel
Save