diff --git a/CMakeLists.txt b/CMakeLists.txt index 267670e6b..f7ada843e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ include(cmake/Deb.cmake) include(cmake/Rpm.cmake) include(cmake/SpotifyVersion.cmake) include(cmake/OptionalSource.cmake) +include(cmake/Format.cmake) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) if (CMAKE_CXX_COMPILER MATCHES ".*clang") diff --git a/cmake/Format.cmake b/cmake/Format.cmake new file mode 100644 index 000000000..8f20ff494 --- /dev/null +++ b/cmake/Format.cmake @@ -0,0 +1,4 @@ +add_custom_target(format-diff + COMMAND python ${CMAKE_SOURCE_DIR}/dist/format.py) +add_custom_target(format + COMMAND python ${CMAKE_SOURCE_DIR}/dist/format.py -i) diff --git a/dist/format.py b/dist/format.py new file mode 100644 index 000000000..c5a89c5f3 --- /dev/null +++ b/dist/format.py @@ -0,0 +1,71 @@ +import argparse +import difflib +import os +import subprocess +import sys +import urllib2 + + +def main(): + parser = argparse.ArgumentParser( + description='Reformats C++ source files that have changed from a given ' + 'git ref.') + parser.add_argument('--url', + default='http://clang.clementine-player.org/format', + help='a URL of a Clang-in-the-cloud service') + parser.add_argument('--ref', default='origin/master', + help='the git-ref to compare against') + parser.add_argument('--extension', action='append', metavar='EXT', + default=['cc', 'cpp', 'h', 'c', 'cxx', 'm', 'mm'], + help='file extensions to reformat') + parser.add_argument('-i', dest='inplace', action='store_true', + help='edit files inplace instead of showing a diff') + args = parser.parse_args() + + try: + root_dir = subprocess.check_output([ + 'git', 'rev-parse', '--show-toplevel']).strip() + except subprocess.CalledProcessError: + # Probably we were not called from a git working directory, just ignore this + # error. + return + + changed_files = subprocess.check_output([ + 'git', 'diff-index', args.ref, '--name-only']).splitlines() + + if not changed_files: + print >> sys.stderr, 'No changes from %s' % args.ref + return + + for filename in changed_files: + if not os.path.splitext(filename)[1][1:] in args.extension: + continue + + path = os.path.join(root_dir, filename) + original = open(path).read() + response = urllib2.urlopen(args.url, original) + formatted = response.read() + + if original == formatted: + print >> sys.stderr, '%s: formatting is correct!' % filename + continue + + diff = difflib.unified_diff( + original.split('\n'), formatted.split('\n'), + os.path.join('a', filename), os.path.join('b', filename), + lineterm='') + + if args.inplace: + with open(path, 'w') as fh: + fh.write(formatted) + + print >> sys.stderr, '%s: %d insertion(s), %d deletion(s)' % ( + filename, + sum(1 for x in diff if x.startswith('+')), + sum(1 for x in diff if x.startswith('-'))) + else: + print '\n'.join(diff) + + +if __name__ == '__main__': + main()