Please review a new script for JDK8: JDK source code legal headers conformance verification

Misha Bykov misha.bykov at oracle.com
Tue Mar 6 00:20:54 UTC 2012


I need a reviewer for a new attached script for JDK8 infrastructure.

SUMMARY

Most of JDK source files  are required to contain a legal approved 
license header. The content and the format of the header is pre-defined 
by legal and any alteration is not permitted.

At the moment JDK8 contains three templates for source license headers: 
gpl, gpl-cp and bsd.
The templates are located in $ROOT/make/templates directory:

$ ls $ROOT/make/templates
bsd-header  gpl-cp-header  gpl-header
$

It's recommended for a developer, when he introduced or modified source 
code files, to check whether a license header is precisely correct for 
every file he worked on.

The new script allows a JDK developer to check if the specified license 
header for a given file (or a set of files) matches the right header 
template.

NAME

lic_check.sh - JDK source code legal headers conformance verification

SYNOPSIS

lic_check.sh [-gpl] or [-gplcp] or [-bsd] file(s)

DESCRIPTION

The script for OpenJDK distribution to verify legal notices in a 
particular source file or a set of files.

The script must be located in the directory:

$ROOT/make/scripts

It uses templates from:

$ROOT/make/templates

The successful output example:

###
### Checking copyright notice in the file: filename.java
###
No differences encountered
SUCCESS: The license header for filename.java has been verified.

The unsuccessful output example if Oracle copyright string is missing or 
copyright years are not correct :

###
### Checking copyright notice in the file: filename.java
###
ERROR: Copyright string is not correct or missing in filename.java.

If the copyright string is correct, but the license header is not 
correct, the script should produce the
"diff" output between a template in $ROOT/make/templates and the license 
header from the given file.

HOW TO TEST

1. Place the script into $ROOT/make/scripts in JDK8 source repository 
(otherwise it will not find $ROOT/make/templates and produce an error).
2. cd to the directory with the files to check license headers
3. $ROOT/make/scripts/lic_check.sh [-gpl] or [-gplcp] or [-bsd] filename(s)

Any questions or comments about bugs in the script, improvement 
suggestions, script style, etc. would be appreciated.

Thanks,
Misha
-------------- next part --------------
#! /bin/sh -f
#
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code 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
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#

#
# This script checks a copyright notice.
#
# The script should be located in the main jdk repository under make/scripts.
# It works with the templates in the make/templates directory of the jdk source.
#
# Usage: "lic_check.sh [-gpl] or [-gplcp] or [-bsd] file(s)"

script_directory=`dirname $0`

# parse the first argument

case "$1" in
	"-gpl")
		header="gpl-header"
		;;
	"-gplcp")
		header="gpl-cp-header"
		;;
	"-bsd")
		header="bsd-header"
                ;;
	*)
		echo "Usage: $0 [-gpl] or [-gplcp] or [-bsd] file(s)" 1>&2
		exit 1
		;;
esac
shift

# determine and set the absolute path for the script directory
D=`dirname "${script_directory}"`
B=`basename "${script_directory}"`
script_dir="`cd \"${D}\" 2>/dev/null && pwd || echo \"${D}\"`/${B}"

# set up a variable for the templates directory

template_dir=${script_dir}/../templates

# Check existence of the template directory.

if [ ! -d ${template_dir} ] ; then
        echo "ERROR: The templates directory "${template_dir}" doesn't exist." 1>&2
        exit 1
fi

# set the temporary file location

tmpfile=/tmp/source_file.$$
rm -f ${tmpfile}

# check number of lines in the template file

lines=`cat ${template_dir}/${header} | wc -l`

# the template file has one empty line at the end, we need to ignore it

lines=`expr ${lines} - 1`

# A loop throuhgh the all script parameters 
while [ "$#" -gt "0" ] ; do

echo "### Checking copyright notice in the file: "$1
echo "###"
touch ${tmpfile}

# Check existence of the source file.
	if [ -d $1 ] ; then
		echo ERROR: $1" is a directory." 1>&2
		shift
		continue
	fi
	if [ ! -f $1 ] ; then
        	echo "ERROR: The source file "$1" doesn't exist." 1>&2
		shift
        	continue
	fi

# read the source file and determine where the header starts, then get license header without prefix
	counter=0
	while read line ; do
# remove windows "line feed" character from the line (if any)
		line=`echo "${line}" | tr -d '\r'`
# check if the given line contains copyright
		check_copyright=`echo "${line}" | grep "Copyright (c) "`
		if [ "${check_copyright}" != "" ] ; then
# determine the comment prefix
			prefix=`echo "${line}" | cut -d "C" -f 1`
# remove prefix (we use "_" as a sed delimiter, since the prefix could be like //)
			copyright_without_prefix=`echo "${line}" | sed s_"^${prefix}"__`
# copyright years
			year1=`echo "${copyright_without_prefix}" | cut -d " " -f 3`
			year2=`echo "${copyright_without_prefix}" | cut -d " " -f 4`
# Processing the first year in the copyright string
			length=`expr "${year1}" : '.*'`
			if [ ${length} -ne 5 ] ; then
        			break
			fi
			check_year1=`echo ${year1} | egrep "19[0-9][0-9],|2[0-9][0-9][0-9],"`
			if [ "${check_year1}" = "" ] ; then
        			break
			fi
# Processing the second year in the copyright string
			if [ "${year2}" != "Oracle" ] ; then
        			length=`expr "${year2}" : '.*'`
        			if [ ${length} -ne 5 ] ; then
                			break
        			else
                			check_year2=`echo ${year2} | egrep "19[0-9][0-9],|2[0-9][0-9][0-9],"`
                			if [ "${check_year2}" = "" ] ; then
                        			break
                			fi
        			fi
			fi

# copyright string without copyright years
			no_years=`echo "${copyright_without_prefix}" | sed 's/[0-9,]*//g'`
# copyright string before years
			before_years=`echo "${no_years}" | cut -d "O" -f 1`
# copyright string after years
			after_years=`echo "${no_years}" | cut -d ")" -f 2`
# form a new copyright string with %YEARS%
			new_copyright=`echo ${before_years}"%YEARS%"${after_years}`
# save the new copyright string to a file
			echo "${new_copyright}" > ${tmpfile}
# start counting the lines
                       	counter=1
# move to the next line
			continue
		fi
		if [ ${counter} -ne 0 ] ; then
# this should be a license header line, hence increment counter
			counter=`expr ${counter} + 1`
# record a string without a prefix to a file
			newline=`echo "${line}" | sed s_"^${prefix}"__`
# we need to take care of the empty lines in the header, i.e. check the prefix without spaces
			trimmed_prefix=`echo "${prefix}" | tr -d " "`
			if [ "${line}" = "${trimmed_prefix}" ] ; then
				echo "" >> ${tmpfile}
			else
				echo "${newline}" >> ${tmpfile}
			fi
		fi
# stop reading lines when a license header ends and add an empty line to the end
		if [ ${counter} -eq ${lines} ] ; then
			echo "" >> ${tmpfile}
			break
		fi
	done < $1

# compare the license header with a template file
	if [ -s ${tmpfile} ] ; then
		diff -c ${tmpfile} ${template_dir}/${header}
		if [ "$?" = "0" ] ; then
			echo "SUCCESS: The license header for "$1" has been verified."
			echo "###"
		fi
	else
		echo "ERROR: Copyright string is not correct or missing in "$1"." 1>&2
		echo "###"
	fi
	rm -f ${tmpfile}
	shift
done


More information about the build-dev mailing list