|
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
# Copyright 2018 The Meson development team
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import subprocess
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
from .run_tool import run_tool
|
|
|
|
from ..environment import detect_clangformat
|
on newer versions of clang-format, use builtin --check handling
Due to a deficiency in upstream clang-format, our automatic target for
`ninja clang-format-check` runs clang-format, then compares the bytes of
the file before and after to see if anything changed. If it did change,
we rewrite the file back to its original form and error out.
Since clang-format 10, there is an option to report warnings instead of
writing the reformatted file, and also, to make those warnings fatal.
This is a much better user experience, to see *what* is wrong, not just
that something is wrong, and also gets rid of a pretty gross "modify
your files when you didn't ask for it" behavior that is vulnerable to
getting interrupted.
Let's switch over to the new approach, if we can.
2 years ago
|
|
|
from ..mesonlib import version_compare
|
|
|
|
from ..programs import ExternalProgram
|
|
|
|
import typing as T
|
|
|
|
|
|
|
|
def run_clang_format(fname: Path, exelist: T.List[str], check: bool, cformat_ver: T.Optional[str]) -> subprocess.CompletedProcess:
|
on newer versions of clang-format, use builtin --check handling
Due to a deficiency in upstream clang-format, our automatic target for
`ninja clang-format-check` runs clang-format, then compares the bytes of
the file before and after to see if anything changed. If it did change,
we rewrite the file back to its original form and error out.
Since clang-format 10, there is an option to report warnings instead of
writing the reformatted file, and also, to make those warnings fatal.
This is a much better user experience, to see *what* is wrong, not just
that something is wrong, and also gets rid of a pretty gross "modify
your files when you didn't ask for it" behavior that is vulnerable to
getting interrupted.
Let's switch over to the new approach, if we can.
2 years ago
|
|
|
clangformat_10 = False
|
|
|
|
if check and cformat_ver:
|
on newer versions of clang-format, use builtin --check handling
Due to a deficiency in upstream clang-format, our automatic target for
`ninja clang-format-check` runs clang-format, then compares the bytes of
the file before and after to see if anything changed. If it did change,
we rewrite the file back to its original form and error out.
Since clang-format 10, there is an option to report warnings instead of
writing the reformatted file, and also, to make those warnings fatal.
This is a much better user experience, to see *what* is wrong, not just
that something is wrong, and also gets rid of a pretty gross "modify
your files when you didn't ask for it" behavior that is vulnerable to
getting interrupted.
Let's switch over to the new approach, if we can.
2 years ago
|
|
|
if version_compare(cformat_ver, '>=10'):
|
|
|
|
clangformat_10 = True
|
|
|
|
exelist = exelist + ['--dry-run', '--Werror']
|
|
|
|
else:
|
|
|
|
original = fname.read_bytes()
|
|
|
|
before = fname.stat().st_mtime
|
|
|
|
ret = subprocess.run(exelist + ['-style=file', '-i', str(fname)])
|
|
|
|
after = fname.stat().st_mtime
|
|
|
|
if before != after:
|
|
|
|
print('File reformatted: ', fname)
|
on newer versions of clang-format, use builtin --check handling
Due to a deficiency in upstream clang-format, our automatic target for
`ninja clang-format-check` runs clang-format, then compares the bytes of
the file before and after to see if anything changed. If it did change,
we rewrite the file back to its original form and error out.
Since clang-format 10, there is an option to report warnings instead of
writing the reformatted file, and also, to make those warnings fatal.
This is a much better user experience, to see *what* is wrong, not just
that something is wrong, and also gets rid of a pretty gross "modify
your files when you didn't ask for it" behavior that is vulnerable to
getting interrupted.
Let's switch over to the new approach, if we can.
2 years ago
|
|
|
if check and not clangformat_10:
|
|
|
|
# Restore the original if only checking.
|
|
|
|
fname.write_bytes(original)
|
|
|
|
ret.returncode = 1
|
|
|
|
return ret
|
|
|
|
|
|
|
|
def run(args: T.List[str]) -> int:
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument('--check', action='store_true')
|
|
|
|
parser.add_argument('sourcedir')
|
|
|
|
parser.add_argument('builddir')
|
|
|
|
options = parser.parse_args(args)
|
|
|
|
|
|
|
|
srcdir = Path(options.sourcedir)
|
|
|
|
builddir = Path(options.builddir)
|
|
|
|
|
|
|
|
exelist = detect_clangformat()
|
|
|
|
if not exelist:
|
|
|
|
print('Could not execute clang-format "%s"' % ' '.join(exelist))
|
|
|
|
return 1
|
|
|
|
|
|
|
|
if options.check:
|
|
|
|
cformat_ver = ExternalProgram('clang-format', exelist, silent=True).get_version()
|
|
|
|
else:
|
|
|
|
cformat_ver = None
|
|
|
|
|
|
|
|
return run_tool('clang-format', srcdir, builddir, run_clang_format, exelist, options.check, cformat_ver)
|