Add clang-tidy-fix target

Add the `clang-tidy-fix` target to apply clang-tidy fixes to the source
code.
This is done by calling `run-clang-tidy` with `-fix` argument.

Add a test case to run `clang-tidy-fix` and verify the file is changed.

Signed-off-by: Lei YU <yulei.sh@bytedance.com>
pull/12283/head
Lei YU 1 year ago committed by Jussi Pakkanen
parent f20f331494
commit 8d6b474bf6
  1. 9
      docs/markdown/snippets/meson_clang_tidy_fix.md
  2. 1
      mesonbuild/backend/ninjabackend.py
  3. 7
      mesonbuild/scripts/clangtidy.py
  4. 22
      unittests/allplatformstests.py
  5. 5
      unittests/helpers.py

@ -0,0 +1,9 @@
## clang-tidy-fix target
If `clang-tidy` is installed and the project's source root contains a
`.clang-tidy` (or `_clang-tidy`) file, Meson will automatically define
a `clang-tidy-fix` target that runs `run-clang-tidy` tool with `-fix`
option to apply the changes found by clang-tidy to the source code.
If you have defined your own `clang-tidy-fix` target, Meson will not
generate its own target.

@ -3659,6 +3659,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
if not shutil.which('clang-tidy'):
return
self.generate_clangtool('tidy')
self.generate_clangtool('tidy', 'fix')
def generate_tags(self, tool: str, target_name: str) -> None:
import shutil

@ -23,8 +23,12 @@ import typing as T
def run_clang_tidy(fname: Path, builddir: Path) -> subprocess.CompletedProcess:
return subprocess.run(['clang-tidy', '-p', str(builddir), str(fname)])
def run_clang_tidy_fix(fname: Path, builddir: Path) -> subprocess.CompletedProcess:
return subprocess.run(['run-clang-tidy', '-fix', '-format', '-quiet', '-p', str(builddir), str(fname)])
def run(args: T.List[str]) -> int:
parser = argparse.ArgumentParser()
parser.add_argument('--fix', action='store_true')
parser.add_argument('sourcedir')
parser.add_argument('builddir')
options = parser.parse_args(args)
@ -32,4 +36,5 @@ def run(args: T.List[str]) -> int:
srcdir = Path(options.sourcedir)
builddir = Path(options.builddir)
return run_tool('clang-tidy', srcdir, builddir, run_clang_tidy, builddir)
run_func = run_clang_tidy_fix if options.fix else run_clang_tidy
return run_tool('clang-tidy', srcdir, builddir, run_func, builddir)

@ -42,7 +42,7 @@ from mesonbuild.mesonlib import (
is_sunos, windows_proof_rmtree, python_command, version_compare, split_args, quote_arg,
relpath, is_linux, git, search_version, do_conf_file, do_conf_str, default_prefix,
MesonException, EnvironmentException, OptionKey,
windows_proof_rm
windows_proof_rm, quiet_git
)
from mesonbuild.programs import ExternalProgram
@ -3029,6 +3029,26 @@ class AllPlatformTests(BasePlatformTests):
self.assertIn('cttest.cpp:4:20', out)
self.assertNotIn(dummydir, out)
@skipIfNoExecutable('clang-tidy')
@unittest.skipIf(not is_git_repo(), 'Skipping because this is not in git repo')
def test_clang_tidy_fix(self):
if self.backend is not Backend.ninja:
raise SkipTest(f'Clang-tidy is for now only supported on Ninja, not {self.backend.name}')
if shutil.which('c++') is None:
raise SkipTest('Clang-tidy breaks when ccache is used and "c++" not in path.')
if is_osx():
raise SkipTest('Apple ships a broken clang-tidy that chokes on -pipe.')
testdir = os.path.join(self.unit_test_dir, '68 clang-tidy')
dummydir = os.path.join(testdir, 'dummydir.h')
self.init(testdir, override_envvars={'CXX': 'c++'})
out = self.run_target('clang-tidy-fix')
self.assertIn('cttest.cpp:4:20', out)
self.assertNotIn(dummydir, out)
ret = quiet_git(['diff', '--exit-code', 'test cases/unit/68 clang-tidy/cttest.cpp'], '.')
self.assertFalse(ret[0])
# Restore the file
quiet_git(['checkout', '--', 'test cases/unit/68 clang-tidy/cttest.cpp'], '.')
def test_identity_cross(self):
testdir = os.path.join(self.unit_test_dir, '69 cross')
# Do a build to generate a cross file where the host is this target

@ -12,7 +12,7 @@ from contextlib import contextmanager
from mesonbuild.compilers import detect_c_compiler, compiler_from_language
from mesonbuild.mesonlib import (
MachineChoice, is_osx, is_cygwin, EnvironmentException, OptionKey, MachineChoice,
OrderedSet
OrderedSet, quiet_git
)
from run_tests import get_fake_env
@ -135,6 +135,9 @@ def is_tarball():
return True
return False
def is_git_repo():
return quiet_git(['branch'], '.')[0]
@contextmanager
def chdir(path: str):
curdir = os.getcwd()

Loading…
Cancel
Save