from __future__ import absolute_import
from __future__ import print_function
import os, re, sys
from clang_util import clang_format
from file_util import eval_file, get_files, read_file, write_file
from git_util import get_changed_files
from yapf_util import yapf_format
DEFAULT_LINT_WHITELIST_REGEX = r"(.*\.cpp|.*\.cc|.*\.h|.*\.java|.*\.mm|.*\.py)$"
DEFAULT_LINT_BLACKLIST_REGEX = r"$^"
IGNORE_DIRECTORIES = []
script_dir = os.path.dirname(__file__)
root_dir = os.path.join(script_dir, os.pardir)
def msg(filename, status):
if sys.platform == 'win32':
filename = filename.replace("\\", "/")
if len(filename) > 60:
filename = filename[-57:]
pos = filename.find("/")
if pos > 0:
filename = filename[pos:]
filename = "..." + filename
print("%-60s %s" % (filename, status))
updatect = 0
def read_config():
style_cfg = os.path.join(root_dir, ".style.cfg")
if os.path.exists(style_cfg):
config = eval_file(style_cfg)
if 'ignore_directories' in config:
global IGNORE_DIRECTORIES
IGNORE_DIRECTORIES = config['ignore_directories']
def update_file(filename):
oldcontents = read_file(filename)
if len(oldcontents) == 0:
msg(filename, "empty")
return
if os.path.splitext(filename)[1] == ".py":
newcontents = yapf_format(filename, oldcontents)
else:
newcontents = clang_format(filename, oldcontents)
if newcontents is None:
raise Exception("Failed to process %s" % filename)
if newcontents != oldcontents:
msg(filename, "fixed")
global updatect
updatect += 1
write_file(filename, newcontents)
else:
msg(filename, "ok")
return
def fix_style(filenames, white_list=None, black_list=None):
""" Execute clang-format with the specified arguments. """
if not white_list:
white_list = DEFAULT_LINT_WHITELIST_REGEX
white_regex = re.compile(white_list)
if not black_list:
black_list = DEFAULT_LINT_BLACKLIST_REGEX
black_regex = re.compile(black_list)
for filename in filenames:
ignore = False
for dir_part in filename.split(os.sep):
if dir_part in IGNORE_DIRECTORIES:
msg(filename, "ignored")
ignore = True
break
if ignore:
continue
if filename.find('*') > 0:
filenames.extend(get_files(filename))
continue
if os.path.isdir(filename):
filenames.extend(get_files(os.path.join(filename, "*")))
continue
if not os.path.exists(filename):
files = get_changed_files(".", filename)
if len(files) > 0:
filenames.extend(files)
else:
msg(filename, "missing")
continue
if white_regex.match(filename):
if black_regex.match(filename):
msg(filename, "ignored")
else:
update_file(filename)
else:
msg(filename, "skipped")
if __name__ == "__main__":
if len(sys.argv) == 1:
print("Usage: %s [file-path|git-hash|unstaged|staged] ...\n" % sys.argv[0])
print(" Format C, C++ and ObjC files using Chromium's clang-format style.")
print("\nOptions:")
print(" file-path\tProcess the specified file or directory.")
print(" \t\tDirectories will be processed recursively.")
print(" \t\tThe \"*\" wildcard character is supported.")
print(" git-hash\tProcess all files changed in the specified Git commit.")
print(" unstaged\tProcess all unstaged files in the Git repo.")
print(" staged\t\tProcess all staged files in the Git repo.")
sys.exit(1)
read_config()
fix_style(sys.argv[1:])
print('Done - Wrote %d files.' % updatect)