| # Copyright 2012 Citrix Systems, Inc. Licensed under the |
| # Apache License, Version 2.0 (the "License"); you may not use this |
| # file except in compliance with the License. Citrix Systems, Inc. |
| # reserves all rights not expressly granted by the License. |
| # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| # Automatically generated by addcopyright.py at 04/03/2012 |
|
|
| from optparse import OptionParser
|
| import sys
|
| import os, os.path
|
| import fnmatch
|
| import time
|
|
|
| class CopyRightDetecter(object):
|
| def isCopyRightLine(self, txt):
|
| return False
|
|
|
| class KeyWordCopyRightDetecter(CopyRightDetecter):
|
| keywords = ['Cloud.com', 'Copyright', '(C)', '2011', 'Citrix', 'Systems', 'Inc', 'All', 'rights', 'reserved', 'This', 'software', 'is', 'licensed', 'under', 'the',
|
| 'GNU', 'General', 'Public', 'License', 'v3', 'or', 'later', 'It', 'is', 'free', 'software:', 'you', 'can', 'redistribute', 'it', 'and/or', 'modify', 'it',
|
| 'under', 'the', 'terms', 'of', 'the', 'GNU', 'General', 'Public', 'License', 'as', 'published', 'by', 'the', 'Free', 'Software', 'Foundation', 'either',
|
| 'version', '3', 'of', 'the', 'License', 'or', 'any', 'later', 'version', 'This', 'program', 'is', 'distributed', 'in', 'the', 'hope', 'that', 'it', 'will',
|
| 'be', 'useful', 'but', 'WITHOUT', 'ANY', 'WARRANTY;', 'without', 'even', 'the', 'implied', 'warranty', 'of', 'MERCHANTABILITY', 'or', 'FITNESS', 'FOR', 'A',
|
| 'PARTICULAR', 'PURPOSE', 'See', 'the', 'GNU', 'General', 'Public', 'License', 'for', 'more', 'details', 'You', 'should', 'have', 'received', 'a', 'copy', 'of',
|
| 'the', 'GNU', 'General', 'Public', 'License', 'along', 'with', 'this', 'program', 'If', 'not', 'see', '<http://www.gnu.org/licenses/>', 'Version', '2', 'only',
|
| '("GPL")', 'Common', 'Development', 'and', 'Distribution', 'License("CDDL")', '(collectively', 'License").', 'language', 'governing', 'permissions', 'limitations',
|
| 'License.', '-', 'When', 'distributing', 'include', 'Header', 'Notice', 'each', 'file', 'at', 'glassfish/bootstrap/legal/LICENSE.txt.', 'Sun', 'designates',
|
| 'particular', 'subject', 'to', 'Classpath', 'exception', 'provided', 'GPL', 'section', 'accompanied', 'code.', 'applicable', 'add', 'following', 'below',
|
| 'fields', 'enclosed', 'brackets', 'replaced', 'your', 'own', 'identifying', 'information', 'Portions', 'Copyrighted', 'year', 'name', 'copyright', 'owner]',
|
| 'Contributor(s)', 'indicate', 'decision', 'adding', '[Contributor', 'elects', 'distribution', 'CDDL', 'license.', "don't", 'single', 'choice', 'license',
|
| 'recipient', 'has', 'option', 'distribute', 'extend', 'its', 'licensees', 'above.', 'However', 'if', 'code', 'therefore', 'elected', 'then', 'applies', 'new',
|
| 'made', 'such', 'holder.']
|
|
|
| def isCopyRightLine(self, txt):
|
| words = [ c.strip().strip('.').strip('\n').strip(',').strip() for c in txt.split(" ") ]
|
| total = len(words)
|
| if total == 0: return False
|
|
|
| numKeyWord = 0
|
| for w in words:
|
| if w == "": continue
|
| if w in self.keywords: numKeyWord+=1
|
|
|
| if float(numKeyWord)/float(total) >= float(1)/float(2): return True
|
| return False
|
|
|
| copyRightDetectingFactory = {"KeyWord":KeyWordCopyRightDetecter.__name__}
|
|
|
| logfd = open("/tmp/addcopyright.log", 'w')
|
| class Logger(object):
|
| @staticmethod
|
| def info(msg):
|
| sys.stdout.write("INFO: %s"%msg)
|
| sys.stdout.write("\n")
|
| sys.stdout.flush()
|
|
|
| @staticmethod
|
| def debug(msg):
|
| logfd.write("DEBUG: %s"%msg)
|
| logfd.write("\n")
|
|
|
| @staticmethod
|
| def warn(msg):
|
| sys.stdout.write("WARNNING: %s"%msg)
|
| sys.stdout.write("\n")
|
| sys.stdout.flush()
|
|
|
| @staticmethod
|
| def error(msg):
|
| sys.stderr.write("ERROR: %s"%msg)
|
| sys.stderr.write("\n")
|
| sys.stderr.flush()
|
|
|
|
|
| class Adder(object):
|
| defaultTxt = '''Copyright 2012 Citrix Systems, Inc. Licensed under the
|
| Apache License, Version 2.0 (the "License"); you may not use this
|
| file except in compliance with the License. Citrix Systems, Inc.
|
| reserves all rights not expressly granted by the License.
|
| You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
| Unless required by applicable law or agreed to in writing, software
|
| distributed under the License is distributed on an "AS IS" BASIS,
|
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| See the License for the specific language governing permissions and
|
| limitations under the License.
|
| '''
|
|
|
| copyRightTxt = None
|
| targetFile = None
|
| fileBody = None
|
| decter = None
|
| signature = 'Automatically generated by addcopyright.py at %s' % time.strftime("%m/%d/%Y", time.localtime())
|
|
|
| COMMENT_NOTATION = ""
|
|
|
| def __init__(self):
|
| self.decter = eval(copyRightDetectingFactory["KeyWord"])()
|
|
|
| def setTargetFile(self, fpath):
|
| self.targetFile = fpath
|
| if not os.path.exists(self.targetFile):
|
| raise Exception("Cannot find %s"%self.targetFile)
|
|
|
| def setCopyRightTxt(self, txt):
|
| self.copyRightTxt = txt.split("\n")
|
|
|
| def checkParams(self):
|
| assert self.targetFile != None, "Target file not set"
|
| if self.copyRightTxt == None:
|
| self.copyRightTxt = self.defaultTxt.split("\n")
|
|
|
| def pasteCopyRight(self):
|
| self.fileBody = self.copyRightTxt + self.fileBody
|
| file(self.targetFile, 'w').write("".join(self.fileBody))
|
| Logger.info("Added copyright header to %s"%self.targetFile)
|
|
|
| def composeCopyRight(self):
|
| l = self.copyRightTxt
|
| l.append(self.signature)
|
| l = [ self.COMMENT_NOTATION + " " + line + "\n" for line in l ]
|
| self.copyRightTxt = l
|
|
|
| def getFileBody(self):
|
| self.fileBody = file(self.targetFile).readlines()
|
|
|
| def isCommentLine(self, line):
|
| if line.strip().startswith(self.COMMENT_NOTATION):
|
| return True
|
| return False
|
|
|
| def removeOldCopyRight(self):
|
| newBody = []
|
| removed = False
|
| for line in self.fileBody[0:50]:
|
| if self.isCommentLine(line) and self.decter.isCopyRightLine(line):
|
| removed = True
|
| Logger.debug("remove old copyright: %s" % line)
|
| continue
|
| newBody.append(line)
|
|
|
| self.fileBody = newBody + self.fileBody[50:]
|
| if removed:
|
| Logger.info("Removed old copyright header of %s"%self.targetFile)
|
|
|
| def cleanBlankComment(self):
|
| newBody = []
|
| for l in self.fileBody[0:50]:
|
| if self.isCommentLine(l) and l.strip().strip(self.COMMENT_NOTATION).strip().strip('\n') == "":
|
| Logger.debug("Blank Comment: %s" % l)
|
| continue
|
| newBody.append(l)
|
| self.fileBody = newBody + self.fileBody[50:]
|
|
|
| def doWork(self):
|
| self.checkParams()
|
| self.getFileBody()
|
| self.removeOldCopyRight()
|
| self.composeCopyRight()
|
| self.cleanBlankComment()
|
| self.pasteCopyRight()
|
|
|
|
|
| class SqlAdder(Adder):
|
| def __init__(self):
|
| super(SqlAdder, self).__init__()
|
| self.COMMENT_NOTATION = "#"
|
|
|
| class InterpreterAdder(Adder):
|
| def __init__(self):
|
| super(InterpreterAdder, self).__init__()
|
| self.COMMENT_NOTATION = "#"
|
|
|
| def pasteCopyRight(self):
|
| if len(self.fileBody) > 0 and self.isCommentLine(self.fileBody[0]):
|
| # Don't cover the first line of interpreter comment
|
| self.fileBody = [self.fileBody[0]] + self.copyRightTxt + self.fileBody[1:]
|
| else:
|
| self.fileBody = self.copyRightTxt + self.fileBody
|
| file(self.targetFile, 'w').write("".join(self.fileBody))
|
| Logger.info("Added copyright header to %s"%self.targetFile)
|
|
|
| class JavaAdder(Adder):
|
| commentOn = False
|
|
|
| def __init__(self):
|
| super(JavaAdder, self).__init__()
|
| self.COMMENT_NOTATION = '//'
|
|
|
| def isCommentLine(self, line):
|
| if line.strip().startswith('//'):
|
| return True
|
| elif line.strip().startswith('/*'):
|
| self.commentOn = True
|
| return True
|
| elif self.commentOn == True and line.find('*/') != -1:
|
| self.commentOn = False
|
| return True
|
| elif self.commentOn:
|
| return True
|
| else:
|
| return False
|
|
|
| def cleanBlankComment(self):
|
| #TODO
|
| pass
|
|
|
|
|
| copyRightAdderFactory = {".sql":SqlAdder.__name__, ".sh":InterpreterAdder.__name__, ".py":InterpreterAdder.__name__}
|
| class CopyRightAdder(object):
|
| parser = None
|
| options = None
|
| args = None
|
| targetFiles = None
|
| excludeFiles = None
|
| copyRightFileTxt = None
|
| rootDir = None
|
|
|
| def errAndExit(self, msg):
|
| Logger.error(msg)
|
| Logger.info("addcopyright -h for help")
|
| sys.exit(1)
|
|
|
| def __init__(self):
|
| usage = '''Usage: addcopyright [file_name_pattern] [--exculdes=file_name_pattern] [--file=copyright_file] [--root=root_dir_of_files_to_add_header] [--replace]
|
| Examples:
|
| addcopyright
|
| addcopyright *.sql
|
| addcopyright *.sql --excludes="*.sql~"
|
| addcopyright *.sql --file=/root/Citrix.copyright
|
| addcopyright *.sql --file=/root/Citrix.copyright --root=~/cloudstack-oss
|
| '''
|
| self.parser = OptionParser(usage=usage)
|
| self.parser.add_option("", "--excludes", action="store", type="string", dest="excludes", default="",
|
| help="Exclude these files when adding copyright header")
|
| self.parser.add_option("", "--file", action="store", type="string", dest="copyRightFile", default="",
|
| help="Path to copyright header file. Default to Citrix copyright header")
|
| self.parser.add_option("", "--root", action="store", type="string", dest="rootDir", default="",
|
| help="Root folder where files being added copyright header locate. Default to current directory")
|
| (self.options, self.args) = self.parser.parse_args()
|
| if len(self.args) > 1:
|
| self.errAndExit("Invalid arguments:%s" % self.args)
|
|
|
| if len(self.args) == 1:
|
| self.targetFiles = self.args[0]
|
| if self.options.excludes != "":
|
| self.excludeFiles = self.options.excludes
|
| if self.options.copyRightFile != "":
|
| self.copyRightFileTxt = file(self.options.copyRightFile).read()
|
| if self.options.rootDir != "":
|
| self.rootDir = os.path.expanduser(self.options.rootDir)
|
| if not os.path.isdir(self.rootDir): raise Exception("Cannot find directory %s"%self.rootDir)
|
| else:
|
| self.rootDir = os.getcwd()
|
|
|
| def createConcreteAdder(self, filename):
|
| (x, ext) = os.path.splitext(filename)
|
| if not copyRightAdderFactory.has_key(ext): return None
|
| return eval(copyRightAdderFactory[ext])()
|
|
|
| def run(self):
|
| for root, dirs, files in os.walk(self.rootDir):
|
| for f in files:
|
| fpath = os.path.join(root, f)
|
| if self.excludeFiles != None and fnmatch.fnmatch(f, self.excludeFiles):
|
| Logger.info("Skipping excluded file %s" % fpath)
|
| continue
|
| if self.targetFiles != None and not fnmatch.fnmatch(f, self.targetFiles):
|
| Logger.info("Skipping %s not matching our file name pattern" % fpath)
|
| continue
|
|
|
| adder = self.createConcreteAdder(f)
|
| if adder == None:
|
| Logger.warn("Cannot find a proper copyright Adder for %s, skip it" % fpath)
|
| continue
|
|
|
| adder.setTargetFile(fpath)
|
| if self.copyRightFileTxt != None:
|
| adder.setCopyRightTxt(self.copyRightFileTxt)
|
| adder.doWork()
|
|
|
|
|
| if __name__ == '__main__':
|
| task = CopyRightAdder()
|
| task.run()
|