blob: 4f49d78025be190cb818c1fd405fb274cfea4d7e [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A python wrapper to check style issues with git-clang-format"""
from __future__ import print_function
import argparse
import fnmatch
import os
import re
import subprocess
import sys
DIFF_FILEPATH_REGEXP = re.compile(r'^\+\+\+ b/(?P<file_path>.*)$',
flags=re.MULTILINE)
# Use git-clang-format from upstream as it supports per-commit checks.
# TODO(jcliang): Remove this once sys-devel/llvm package is upgraded.
CLANG_FORMAT = os.path.join(os.path.abspath(os.path.dirname(__file__)),
'upstream-git-clang-format')
PRESUBMIT_IGNORE_FILE = os.path.join(
os.path.abspath(os.path.dirname(os.path.dirname(__file__))),
'.presubmitignore')
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('--commit', type=str, help='The commit to check.',
default='HEAD')
parser.add_argument('--fix', action='store_true',
help='Fix any formatting errors automatically.')
parser.add_argument('--diff', action='store_true',
help='Show the diff output of clang-format.')
args = parser.parse_args(argv)
cmd = ['git', 'log', '%s^..%s' % (args.commit, args.commit),
'--pretty=oneline']
stdout = subprocess.check_output(cmd, universal_newlines=True)
commit_hash, commit_message = stdout.split(' ', 1)
print('[Commit %s] %s' % (commit_hash[:8], commit_message), file=sys.stderr)
cmd = [CLANG_FORMAT, '--style', 'Chromium', '--diff', '%s^' % args.commit,
args.commit]
stdout = subprocess.check_output(cmd, universal_newlines=True)
if stdout.strip() == 'no modified files to format':
return 0
diff_files = DIFF_FILEPATH_REGEXP.findall(stdout)
ignored_files = []
with open(PRESUBMIT_IGNORE_FILE) as f:
for pattern in f.readlines():
ignored_files += fnmatch.filter(diff_files, pattern.strip())
diff_files = [f for f in diff_files if f not in ignored_files]
if diff_files:
if args.fix:
proc = subprocess.Popen(['git', 'apply'], stdin=subprocess.PIPE,
universal_newlines=True)
proc.communicate(input=stdout)
proc.wait()
else:
print('The following files have formatting errors:')
for f in diff_files:
print('\t%s' % f)
print('You can run `%s --fix %s` to fix this.' %
(__file__, ' '.join(argv)))
if args.diff:
print('\nDiff output from clang-format:\n')
print(stdout)
return 1
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))