#!/usr/bin/env python # ----------------------------------------------------------------------------- # add_version_headers # # Add version header # # Copyright (c) 2017 Yann Herklotz Grave -- MIT License # See file LICENSE for more details # ----------------------------------------------------------------------------- """ @file Adds the version headers to every file. ## Add Version Headers This file adds the version headers to every file in the directory ### Improvements Add the ability to input command line arguments. """ import os import re import sys from subprocess import call header = """/** ---------------------------------------------------------------\ ------------ * -*- c++ -*- * @file: {0} * * Copyright (c) 2017 Yann Herklotz Grave * MIT License, see LICENSE file for more details. * ---------------------------------------------------------------------------- */ """ lic_regex = re.compile( "\/(?:\*|\*\*) -+\n \* ((?:@file: )?[a-z0-9]+\.(?:cpp|h)|\{0\})\n(?: \*[ a-zA-Z0-9_.,\-()<>@]*\n)+ \* -+\n \*/\n\n", re.MULTILINE) class HeaderUpdate(object): """Updates the header in all the source and header files in the code""" def __init__(self, **kwargs): self.match_re = ".*[.]cpp$|.*[.]h$" self.exclude_re = "^$" self.exclude_build = True self.exclude_dir = ".*build.*" self.match_dir = "" self.starting_dir = os.getcwd() for key, value in kwargs.items(): setattr(self, key, value) def writeHeader(self): def writeFileOperation(filePath): with open(filePath, "r+") as f: src = f.read() f.seek(0) if not lic_regex.match(src): print("Adding {}: ".format( os.path.basename(filePath)), end="") src = header.format(os.path.basename(filePath)) + src print("done") f.write(src) f.truncate() self._traverseDir(self.starting_dir, writeFileOperation) def updateHeader(self): def updateFileOperation(filePath): with open(filePath, "r+") as f: src = f.read() f.seek(0) if lic_regex.match(src): other_src = lic_regex.sub(header.format( os.path.basename(filePath)), src) if other_src != src: print("Updating {}: ".format( os.path.basename(filePath)), end="") src = other_src print("done") else: print("Adding {}: ".format( os.path.basename(filePath)), end="") src = header.format(os.path.basename(filePath)) + src print("done") f.write(src) f.truncate() self._traverseDir(self.starting_dir, updateFileOperation) def removeHeader(self): ... def _traverseDir(self, path, fileOperation): for subdir, dirs, files in os.walk(os.getcwd()): if (re.match(self.match_dir, subdir)) and ( not re.match(self.exclude_dir, subdir)): for fileName in files: if (re.match(self.match_re, fileName)) and ( not re.match(self.exclude_re, fileName)): fileOperation(os.path.join(subdir, fileName)) def runClangFormat(self): def clangFormatFileOpration(filePath): call(["clang-format", "-i", filePath]) self._traverseDir(self.starting_dir, clangFormatFileOpration) def main(argv): update = HeaderUpdate(exclude_re="^picopng\.cpp", match_dir=".*yage|.*tests", exclude_dir=".*lib.*|.*build.*|.*googletest.*") update.updateHeader() update.runClangFormat() if __name__ == "__main__": main(sys.argv)