3 # Copyright 2013 GRNET S.A. All rights reserved.
5 # Redistribution and use in source and binary forms, with or
6 # without modification, are permitted provided that the following
9 # 1. Redistributions of source code must retain the above
10 # copyright notice, this list of conditions and the following
13 # 2. Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following
15 # disclaimer in the documentation and/or other materials
16 # provided with the distribution.
18 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 # POSSIBILITY OF SUCH DAMAGE.
31 # The views and conclusions contained in the software and
32 # documentation are those of the authors and should not be
33 # interpreted as representing official policies, either expressed
34 # or implied, of GRNET S.A.
37 import os, sys, shutil
39 EXCLUDE_FILENAMES = ['.gitignore', 'README', 'version', 'c_bsd.licence',
40 'python_bsd.licence', 'devflow.conf', 'verify',
41 'create', 'detach', 'attach', 'parameters.list', 'grow',
42 'remove', 'python_gpl.licence', 'c_gpl.licence', 'tags',
43 'config.env', 'distribute_setup.py']
44 GPL_FILES = ['vlmc_wrapper.py', 'kernel/xseg_posix.c', 'kernel/xseg_pthread.c',
46 EXCLUDE_DIRECTORIES = ['.git', 'doc']
47 VALID_YEARS = [2011, 2012, 2013]
49 PYTHON_INTERPRETER = "#!/usr/bin/env python\n"
50 BASH_INTERPRETER = "#!/bin/bash\n"
51 THIS_PATH = os.path.dirname(os.path.realpath(__file__))
52 PYTHON_BSD_LICENCE = open(os.path.join(THIS_PATH, "python_bsd.licence")).readlines()
53 PYTHON_GPL_LICENCE = open(os.path.join(THIS_PATH, "python_gpl.licence")).readlines()
54 C_BSD_LICENCE = open(os.path.join(THIS_PATH, "c_bsd.licence")).readlines()
55 C_GPL_LICENCE = open(os.path.join(THIS_PATH, "c_gpl.licence")).readlines()
58 class InvalidTypeException(Exception):
59 """Exception to raise for invalid type"""
62 class LicenceException(Exception):
63 """Exception to raise for licence exception"""
66 class ExcludedFileException(Exception):
67 """Exception to raise for excluded file"""
70 class EmptyFileException(Exception):
71 """Exception to raise for empty file"""
74 class PartialLicenceException(Exception):
75 """exception to raise for partial licence"""
78 class NoLicenceException(Exception):
79 """Exception to raise for no licence"""
82 class NoInterpreterException(Exception):
83 """Esception to raise when no interpreter found"""
87 def get_file_type(filename):
88 """Return a string with the type of the file"""
89 for excl_file in EXCLUDE_FILENAMES:
90 if filename.endswith(excl_file):
91 raise ExcludedFileException(filename)
93 if filename.endswith('.c') or filename.endswith('.h'):
95 elif filename.endswith('.sh'):
97 elif filename.endswith('.py'):
99 elif filename.endswith('Makefile') or filename.endswith('.mk'):
102 firstline = open(filename).readline()
103 if firstline == BASH_INTERPRETER:
105 if firstline == PYTHON_INTERPRETER:
108 raise InvalidTypeException(file)
111 def __check_licence(filename, licence, year_line, interpreter = None):
112 """Generic test licence function"""
114 line = fil.readline()
116 raise EmptyFileException("Empty file")
119 if line == interpreter:
120 line = fil.readline()
122 raise Exception("Blank line is expected after %s",
124 line = fil.readline()
126 # raise NoInterpreterException("No interpreter found")
129 raise EmptyFileException("Empty file")
132 for i in range(0, year_line):
133 if line != licence[i]:
134 raise NoLicenceException("No licence")
135 line = fil.readline()
137 for valid_year in VALID_YEARS:
138 licence_line = licence[year_line].replace("#YEAR#", str(valid_year))
139 if line == licence_line:
143 raise NoLicenceException("No licence")
144 line = fil.readline()
145 for licence_line in licence[year_line + 1:]:
146 if licence_line != line:
147 print " Found: " + line
148 print "Expected: " + licence_line
149 raise PartialLicenceException("Partial licence found")
150 line = fil.readline()
153 def __check_licence2(filename, licence, year_line, interpreter = None,
155 """Generic test or insert licence function"""
157 __check_licence(filename, licence, year_line, interpreter)
158 except NoLicenceException:
161 new_filename = filename + '.tmp'
162 new_fil = open(new_filename, 'w')
163 line = fil.readline()
165 if line == interpreter:
167 line = fil.readline()
168 new_fil.write(line) #mustbe "" otherwise Blankline exception
169 line = fil.readline()
171 for i in range(0, year_line):
172 new_fil.write(licence[i])
173 new_fil.write(licence[year_line].replace("#YEAR#", str(CUR_YEAR)))
174 for licence_line in licence[year_line+1:]:
175 new_fil.write(licence_line)
179 line = fil.readline()
181 shutil.move(new_filename, filename)
184 raise NoLicenceException("No licence")
188 def check_licence_python(filename, insert = False):
189 """Check or insert licence in python files"""
190 licence = PYTHON_BSD_LICENCE
191 for gplfile in GPL_FILES:
192 if filename.endswith(gplfile):
193 licence = PYTHON_GPL_LICENCE
194 __check_licence2(filename, licence, 0, PYTHON_INTERPRETER, insert)
197 def check_licence_bash(filename, insert = False):
198 """Check or insert licence for bash files"""
199 __check_licence2(filename, PYTHON_BSD_LICENCE, 0, BASH_INTERPRETER, insert)
202 def check_licence_makefile(filename, insert = False):
203 """Check or insert licence for makefiles files"""
204 __check_licence2(filename, PYTHON_BSD_LICENCE, 0, insert = insert)
207 def check_licence_c(filename, insert = False):
208 """Check or insert licence for c files"""
209 licence = C_BSD_LICENCE
210 for gplfile in GPL_FILES:
211 if filename.endswith(gplfile):
212 licence = C_GPL_LICENCE
214 __check_licence2(filename, licence, 1, insert = insert)
217 if __name__ == "__main__":
219 root_dir = sys.argv[1]
221 print "Usage: %s path [--insert]" % sys.argv[0]
224 do_insert = sys.argv[2] == '--insert'
228 for directory, subdirectories, files in os.walk(root_dir):
229 for ed in EXCLUDE_DIRECTORIES:
230 if ed in subdirectories:
231 subdirectories.remove(ed)
233 full_path = os.path.join(directory, filen)
235 ft = get_file_type(full_path)
237 'c': check_licence_c,
238 'python': check_licence_python,
239 'bash': check_licence_bash,
240 'makefile': check_licence_makefile
241 }[ft](full_path, do_insert)
242 except ExcludedFileException:
244 except InvalidTypeException:
245 print "Invalid type: ", full_path
246 except Exception as e:
247 print e, " ", full_path