clangformat: Only format files tracked by git by default

pull/9304/head
Xavier Claessens 4 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 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. 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 ..environment import detect_clangformat
from ..compilers import lang_suffixes from ..compilers import lang_suffixes
from ..mesonlib import Popen_safe
import typing as T import typing as T
def parse_pattern_file(fname: Path) -> T.List[str]: 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: def clangformat(exelist: T.List[str], srcdir: Path, builddir: Path, check: bool) -> int:
patterns = parse_pattern_file(srcdir / '.clang-format-include') patterns = parse_pattern_file(srcdir / '.clang-format-include')
if not patterns: globs: T.Union[T.List[T.List[Path]], T.List[T.Generator[Path, None, None]]]
patterns = ['**/*'] if patterns:
globs = [srcdir.glob(p) for p in 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') patterns = parse_pattern_file(srcdir / '.clang-format-ignore')
ignore = [str(builddir / '*')] ignore = [str(builddir / '*')]
ignore.extend([str(srcdir / p) for p in patterns]) 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): any(fnmatch.fnmatch(strf, i) for i in ignore):
continue continue
futures.append(e.submit(run_clang_format, exelist, f, check)) 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 return returncode
def run(args: T.List[str]) -> int: def run(args: T.List[str]) -> int:

@ -2539,6 +2539,7 @@ class AllPlatformTests(BasePlatformTests):
testheader = os.path.join(testdir, 'header.h') testheader = os.path.join(testdir, 'header.h')
badheader = os.path.join(testdir, 'header_orig_h') badheader = os.path.join(testdir, 'header_orig_h')
goodheader = os.path.join(testdir, 'header_expected_h') goodheader = os.path.join(testdir, 'header_expected_h')
includefile = os.path.join(testdir, '.clang-format-include')
try: try:
shutil.copyfile(badfile, testfile) shutil.copyfile(badfile, testfile)
shutil.copyfile(badheader, testheader) shutil.copyfile(badheader, testheader)
@ -2547,6 +2548,17 @@ class AllPlatformTests(BasePlatformTests):
Path(goodfile).read_text(encoding='utf-8')) Path(goodfile).read_text(encoding='utf-8'))
self.assertNotEqual(Path(testheader).read_text(encoding='utf-8'), self.assertNotEqual(Path(testheader).read_text(encoding='utf-8'),
Path(goodheader).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.run_target('clang-format')
self.assertEqual(Path(testheader).read_text(encoding='utf-8'), self.assertEqual(Path(testheader).read_text(encoding='utf-8'),
Path(goodheader).read_text(encoding='utf-8')) Path(goodheader).read_text(encoding='utf-8'))
@ -2555,6 +2567,8 @@ class AllPlatformTests(BasePlatformTests):
os.unlink(testfile) os.unlink(testfile)
if os.path.exists(testheader): if os.path.exists(testheader):
os.unlink(testheader) os.unlink(testheader)
if os.path.exists(includefile):
os.unlink(includefile)
@skipIfNoExecutable('clang-tidy') @skipIfNoExecutable('clang-tidy')
def test_clang_tidy(self): def test_clang_tidy(self):

Loading…
Cancel
Save