lic_check.sh revision 448:8fb4cd2f05a1
1#! /bin/sh -f
2#
3# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
4# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5#
6# This code is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License version 2 only, as
8# published by the Free Software Foundation.
9#
10# This code is distributed in the hope that it will be useful, but WITHOUT
11# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13# version 2 for more details (a copy is included in the LICENSE file that
14# accompanied this code).
15#
16# You should have received a copy of the GNU General Public License version
17# 2 along with this work; if not, write to the Free Software Foundation,
18# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21# or visit www.oracle.com if you need additional information or have any
22# questions.
23#
24
25#
26# This script checks a copyright notice.
27#
28# The script should be located in the main jdk repository under make/scripts.
29# It works with the templates in the make/templates directory of the jdk source.
30#
31# Usage: "lic_check.sh [-gpl] or [-gplcp] or [-bsd] file(s)"
32
33script_directory=`dirname $0`
34script_name=`basename $0`
35first_option=$1
36
37# parse the first argument
38
39case "$1" in
40	"-gpl")
41		header="gpl-header"
42		;;
43	"-gplcp")
44		header="gpl-cp-header"
45		;;
46	"-bsd")
47		header="bsd-header"
48                ;;
49	*)
50		echo "Usage: $0 [-gpl] or [-gplcp] or [-bsd] file(s)" 1>&2
51		exit 1
52		;;
53esac
54shift
55
56#initialize error status
57error_status=0
58
59# determine and set the absolute path for the script directory
60D=`dirname "${script_directory}"`
61B=`basename "${script_directory}"`
62script_dir="`cd \"${D}\" 2>/dev/null && pwd || echo \"${D}\"`/${B}"
63
64# set up a variable for the templates directory
65template_dir=${script_dir}/../templates
66
67# Check existence of the template directory.
68if [ ! -d ${template_dir} ] ; then
69        echo "ERROR: The templates directory "${template_dir}" doesn't exist." 1>&2
70        exit 1
71fi
72
73# set the temporary file location
74tmpfile=/tmp/source_file.$$
75rm -f ${tmpfile}
76
77# check number of lines in the template file
78lines=`cat ${template_dir}/${header} | wc -l`
79
80# the template file has one empty line at the end, we need to ignore it
81lines=`expr ${lines} - 1`
82
83# A loop through the all script parameters:
84#
85# 1. Given a set of source files and a license template header, read a file name of each source file.
86# 2. Check if a given file exists. When a directory is encountered, dive in and process all sources in those directories.
87# 3. Read each line of the given file and check it for a copyright string.
88# 4. If a copyright string found, check the correctness of the years format in the string and replace years with %YEARS%.
89# 5. Continue reading the file until the number of lines is equal to the length of the license template header ($lines) and remove a comment prefix for each line.
90# 6. Store the result (the license header from a given file) into a temporary file.
91# 7. If a temporary file is not empty, compare it with a template file to verify if the license text is the same as in a template.
92# 8. Produce a error in case a temporary file is empty, it means we didn't find a copyright string, or it's not correct
93#
94while [ "$#" -gt "0" ] ; do
95	touch ${tmpfile}
96
97	# In case of the directory as a parameter check recursively every file inside.
98	if [ -d $1 ] ; then
99		curdir=`pwd`
100		cd $1
101		echo "*** Entering directory: "`pwd`
102		echo "***"
103		files=`ls .`
104		sh ${script_dir}/${script_name} ${first_option} ${files}
105		status=$?
106		if [ ${error_status} -ne 1 ] ; then
107			error_status=${status}
108		fi
109		cd ${curdir}
110		shift
111		continue
112	else
113		echo "### Checking copyright notice in the file: "$1
114		echo "###"
115	fi
116
117	# Check the existence of the source file.
118	if [ ! -f $1 ] ; then
119        	echo "ERROR: The source file "$1" doesn't exist." 1>&2
120		error_status=1
121		shift
122        	continue
123	fi
124
125	# read the source file and determine where the header starts, then get license header without prefix
126	counter=0
127	while read line ; do
128		# remove windows "line feed" character from the line (if any)
129		line=`echo "${line}" | tr -d '\r'`
130		# check if the given line contains copyright
131		check_copyright=`echo "${line}" | grep "Copyright (c) "`
132		if [ "${check_copyright}" != "" ] ; then
133			# determine the comment prefix
134			prefix=`echo "${line}" | cut -d "C" -f 1`
135			# remove prefix (we use "_" as a sed delimiter, since the prefix could be like //)
136			copyright_without_prefix=`echo "${line}" | sed s_"^${prefix}"__g`
137			# copyright years
138			year1=`echo "${copyright_without_prefix}" | cut -d " " -f 3`
139			year2=`echo "${copyright_without_prefix}" | cut -d " " -f 4`
140			# Processing the first year in the copyright string
141			length=`expr "${year1}" : '.*'`
142			if [ ${length} -ne 5 ] ; then
143        			break
144			fi
145			check_year1=`echo ${year1} | egrep "19[0-9][0-9],|2[0-9][0-9][0-9],"`
146			if [ "${check_year1}" = "" ] ; then
147        			break
148			fi
149			# Processing the second year in the copyright string
150			if [ "${year2}" != "Oracle" ] ; then
151        			length=`expr "${year2}" : '.*'`
152        			if [ ${length} -ne 5 ] ; then
153                			break
154        			else
155                			check_year2=`echo ${year2} | egrep "19[0-9][0-9],|2[0-9][0-9][0-9],"`
156                			if [ "${check_year2}" = "" ] ; then
157                        			break
158                			fi
159        			fi
160			fi
161
162			# copyright string without copyright years
163			no_years=`echo "${copyright_without_prefix}" | sed 's/[0-9,]*//g'`
164			# copyright string before years
165			before_years=`echo "${no_years}" | cut -d "O" -f 1`
166			# copyright string after years
167			after_years=`echo "${no_years}" | cut -d ")" -f 2`
168			# form a new copyright string with %YEARS%
169			new_copyright=`echo ${before_years}"%YEARS%"${after_years}`
170			# save the new copyright string to a file
171			echo "${new_copyright}" > ${tmpfile}
172			# start counting the lines
173                       	counter=1
174			# move to the next line
175			continue
176		fi
177		if [ ${counter} -ne 0 ] ; then
178			# this should be a license header line, hence increment counter
179			counter=`expr ${counter} + 1`
180			# record a string without a prefix to a file
181			newline=`echo "${line}" | sed s_"^${prefix}"__`
182
183			# we need to take care of the empty lines in the header, i.e. check the prefix without spaces
184			trimmed_prefix=`echo "${prefix}" | tr -d " "`
185			trimmed_line=`echo "${line}"  | tr -d " "`
186			if [ "${trimmed_line}" = "${trimmed_prefix}" ] ; then
187				echo "" >> ${tmpfile}
188			else
189				echo "${newline}" >> ${tmpfile}
190			fi
191		fi
192		# stop reading lines when a license header ends and add an empty line to the end
193		if [ ${counter} -eq ${lines} ] ; then
194			echo "" >> ${tmpfile}
195			break
196		fi
197	done < $1
198
199	# compare the license header with a template file
200	if [ -s ${tmpfile} ] ; then
201		diff -c ${tmpfile} ${template_dir}/${header} 1>&2
202		if [ "$?" = "0" ] ; then
203			echo "SUCCESS: The license header for "`pwd`"/"$1" has been verified."
204			echo "###"
205		else
206			echo "ERROR: License header is not correct in "`pwd`"/"$1 1>&2
207			echo "See diffs above. " 1>&2
208			echo "###" 1>&2
209			echo "" 1>&2
210			error_status=1
211		fi
212	else
213		# If we don't have a temporary file, there is a problem with a copyright string (or no copyright string)
214		echo "ERROR: Copyright string is not correct or missing in "`pwd`"/"$1 1>&2
215		echo "###" 1>&2
216		echo "" 1>&2
217		error_status=1
218	fi
219	rm -f ${tmpfile}
220	shift
221done
222if [ ${error_status} -ne 0 ] ; then
223	exit 1
224fi
225