Created
December 17, 2023 13:44
-
-
Save Fishbowler/ed6a05c4e7b7ba539f814df3f54e5772 to your computer and use it in GitHub Desktop.
Check and Update license and copyright headers in Openfire source files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This script checks for the presence of the current year in the license header of all java files in the repo. | |
# Originally inspired by (and somewhat copied from) https://github.com/palaniraja/whatchanged/blob/master/whatchanged.sh | |
THIS_YEAR=$(date +%Y) | |
IGNITE_FOUNDED="2016-10-21" | |
JIVE_ENDED="2010-01-31" | |
REPO_STARTED="2004-10-17" | |
FIXES_ENABLED=true | |
read -r -d '' JAVA_LICENSE << EOM | |
/* | |
* Copyright (C) ###TOKEN###. All rights reserved. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with 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. | |
*/ | |
EOM | |
read -r -d '' JSP_LICENSE << EOM | |
<%-- | |
- | |
- Copyright (C) ###TOKEN###. All rights reserved. | |
- | |
- Licensed under the Apache License, Version 2.0 (the "License"); | |
- you may not use this file except in compliance with 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. | |
--%> | |
EOM | |
getDateFormattedGitLog() { | |
local FILE=$1 | |
git log --format="%cd" --date="format:%Y-%m-%d" --invert-grep --grep="Update to Apache 2.0" --grep="OF-2716" --follow "$FILE" | |
} | |
getDateFormattedGitLogBetweenTwoDates() { | |
local FILE=$1 | |
local FROM_DATE=$2 | |
local TO_DATE=$3 | |
getDateFormattedGitLog "$FILE" | awk -v fromdate="$FROM_DATE" -v todate="$TO_DATE" '$1 >= fromdate && $1 <= todate' | |
} | |
getCopyrightAttribution() { | |
FROM_DATE=$1 | |
TO_DATE=$2 | |
ATTRIBUTE_TO=$3 | |
FIRST_COMMIT_YEAR=$(getDateFormattedGitLogBetweenTwoDates "$line" "$FROM_DATE" "$TO_DATE" | tail -n 1 | awk -F'-' '{print $1}') | |
LAST_COMMIT_YEAR=$(getDateFormattedGitLogBetweenTwoDates "$line" "$FROM_DATE" "$TO_DATE" | head -n 1 | awk -F'-' '{print $1}') | |
if [ "$FIRST_COMMIT_YEAR" -ne "$LAST_COMMIT_YEAR" ]; then | |
COPYRIGHT_YEARS="$FIRST_COMMIT_YEAR-$LAST_COMMIT_YEAR" | |
else | |
COPYRIGHT_YEARS="$FIRST_COMMIT_YEAR" | |
fi | |
ATTRIBUTION="$COPYRIGHT_YEARS $ATTRIBUTE_TO" | |
echo $ATTRIBUTION | |
} | |
getCopyrightAttributionForIgnite(){ | |
local START=$IGNITE_FOUNDED | |
local END="$THIS_YEAR-12-31" | |
local WHO="Ignite Realtime Foundation" | |
getCopyrightAttribution "$START" "$END" "$WHO" | |
} | |
getCopyrightAttributionForJive(){ | |
local START=$REPO_STARTED | |
local END=$JIVE_ENDED | |
local WHO="Jive Software" | |
getCopyrightAttribution "$START" "$END" "$WHO" | |
} | |
existedInTheJiveSoftwareEra() { | |
# We can't use 'git log --before' because git history will cut off trees and return blank results - we need to follow all the way, then filter | |
LOGCOUNT=$(getDateFormattedGitLog "$line" | awk -v jiveended="$JIVE_ENDED" '$1 < jiveended' | wc -l) | |
if [ $LOGCOUNT -gt 0 ]; then | |
return 1 | |
else | |
return 0 | |
fi | |
} | |
# Adds an attribution to the end of an existing copyright line in an existing license header | |
fixMissingCopyrightAttribution() { | |
local FILE=$1 | |
local INTENDED_MENTION=$2 | |
COPYRIGHT_NEEDLE=". All rights reserved" | |
FIXED=0 | |
head -5 "$FILE" | grep "$COPYRIGHT_NEEDLE" > /dev/null | |
if [ $? -eq 0 ]; then | |
sed -i "1,5 s/$COPYRIGHT_NEEDLE/, $INTENDED_MENTION$COPYRIGHT_NEEDLE/" "$FILE" | |
echo "=> Fixed missing attribution!" | |
FIXED=1 | |
else | |
echo "=> FAILED: $COPYRIGHT_NEEDLE not found in $FILE" | |
fi | |
return $FIXED | |
} | |
# Fixes the years for an existing copyright attribution in an existing license header | |
fixIncorrectCopyrightLine(){ | |
local FILE=$1 | |
local CORRECT_ATTRIBUTION=$2 | |
local ATTRIBUTE_TO=$3 | |
DATE_REGEX="[0-9]{4}(-[0-9]{4})?" | |
COPYRIGHT_NEEDLE="$DATE_REGEX $ATTRIBUTE_TO" | |
FIXED=0 | |
head -5 "$FILE" | grep -E "$COPYRIGHT_NEEDLE" > /dev/null | |
if [ $? -eq 0 ]; then | |
sed -i -E "1,5 s/$COPYRIGHT_NEEDLE/$CORRECT_ATTRIBUTION/" "$FILE" | |
echo "=> Fixed incorrect attribution!" | |
FIXED=1 | |
else | |
echo "=> FAILED: $COPYRIGHT_NEEDLE not found in $FILE" | |
fi | |
return $FIXED | |
} | |
fixMissingLicenseHeader() { | |
local FILE=$1 | |
local INTENDED_ATTRIBUTIONS=$2 | |
local FILE_EXTENSION=$(echo "$FILE" | awk -F'.' '{print $NF}') | |
if [ "$FILE_EXTENSION" == "java" ]; then | |
THIS_LICENSE=$JAVA_LICENSE | |
elif [ "$FILE_EXTENSION" == "jsp" ]; then | |
THIS_LICENSE=$JSP_LICENSE | |
else | |
echo "Unknown file extension: $FILE_EXTENSION" | |
return 0 | |
fi | |
THIS_LICENSE=${THIS_LICENSE//###TOKEN###/$INTENDED_ATTRIBUTIONS} | |
TMPFILE=$(mktemp) | |
echo "$THIS_LICENSE" > "$TMPFILE" | |
cat "$FILE" >> "$TMPFILE" | |
mv "$TMPFILE" "$FILE" | |
echo "=> Fixed missing license header in $FILE" | |
} | |
fixMissingC() { | |
local FILE=$1 | |
sed -i -E "1,5 s/Copyright/Copyright (C)/" "$FILE" | |
echo "=> Fixed missing (C) in $FILE" | |
} | |
fixMissingAllRightsReserved() { | |
local FILE=$1 | |
#/192.168.1.2/s/$/ myalias/ | |
sed -i -E "/Copyright/s/$/. All rights reserved/" "$FILE" | |
echo "=> Fixed missing 'All rights reserved' in $FILE" | |
} | |
processFiles(){ | |
# Only git tracked files | |
git ls-tree -r main --name-only | grep '\.java$\|\.jsp$' | sort -u | while read line | |
do | |
#echo Processing "$line" | |
if ! [ -n "${line}" ] || ! [ -e "${line}" ] || | |
[[ ${line} == *"/package-info.java" ]] || # No functional code | |
[[ ${line} == "xmppserver/src/main/java/org/dom4j/io/XMPPPacketReader.java" ]] || # Special license via DOM4J | |
[[ ${line} == "xmppserver/src/main/java/org/jivesoftware/util/FastDateFormat.java" ]]; # Special license via Disney //TODO: https://igniterealtime.atlassian.net/browse/OF-2754 | |
then | |
continue | |
fi | |
MISSING_LICENSE_HEADER=0 | |
MISSING_IGNITE_MENTION=0 | |
INCORRECT_IGNITE_MENTION=0 | |
MISSING_C=0 | |
MISSING_RIGHTS_RESERVED=0 | |
head -5 "$line" | grep -E "Copyright [0-9]{4}" > /dev/null | |
if [ $? -eq 0 ]; then | |
MISSING_C=1 | |
echo "Missing (C) in Copyright line: $line" | |
fi | |
# Check for license | |
grep "Licensed under the Apache License" "$line" > /dev/null | |
if [ $? -eq 1 ]; then | |
MISSING_LICENSE_HEADER=1 | |
FILE_CREATION_DATE=$(git log --diff-filter=A --follow --format=%ad --date="format:%Y-%m-%d" -1 -- "$line") | |
echo "Missing license header in: $line (created $FILE_CREATION_DATE)" | |
fi | |
grep -E "Copyright.*[0-9]{4}" "$line" > /dev/null | |
if [ $? -eq 0 ]; then | |
grep -E "Copyright.*[0-9]{4}.*All rights reserved" "$line" > /dev/null | |
if [ $? -eq 1 ]; then | |
MISSING_RIGHTS_RESERVED=1 | |
echo "Missing 'All rights reserved' in: $line" | |
fi | |
fi | |
# Calculate what the Jive attribution should be | |
existedInTheJiveSoftwareEra | |
EXISTED_IN_THE_JIVE_SOFTWARE_ERA=$? | |
if [ $EXISTED_IN_THE_JIVE_SOFTWARE_ERA -eq 1 ]; then | |
JIVE_ATTRIBUTION=$(getCopyrightAttributionForJive) | |
# I'm not sure I'm happy fixing copyright headers for other folk. | |
# Jive already did this themselves in https://github.com/igniterealtime/Openfire/commit/ff0fa13dc3f67ca269da7bceef161e4a49663259 | |
# So I'm going to leave this commented out for now. | |
# grep "Copyright .* Jive Software" "$line" > /dev/null | |
# if [ $? -eq 1 ]; then | |
# MISSING_JIVE_MENTION=1 | |
# echo "Copyright header not found in: $line - needs to read: $JIVE_ATTRIBUTION" | |
# fi | |
fi | |
# Calculate what the Ignite attribution should be | |
IGNITE_ATTRIBUTION=$(getCopyrightAttributionForIgnite) | |
grep "Copyright .* Ignite Realtime Foundation" "$line" > /dev/null | |
if [ $? -eq 1 ]; then | |
MISSING_IGNITE_MENTION=1 | |
echo "Copyright header not found in: $line - needs to read: $IGNITE_ATTRIBUTION" | |
else | |
grep "Copyright .* $IGNITE_ATTRIBUTION" "$line" > /dev/null | |
if [ $? -eq 1 ]; then | |
INCORRECT_IGNITE_MENTION=1 | |
echo "Copyright header incorrect in: $line - needs to read: $IGNITE_ATTRIBUTION" | |
fi | |
fi | |
## Fixes | |
if [ "$FIXES_ENABLED" == "false" ]; then | |
continue | |
fi | |
# Fix missing (C) | |
if [ $MISSING_C -eq 1 ]; then | |
fixMissingC "$line" | |
fi | |
# Fix missing 'All rights reserved' | |
if [ $MISSING_RIGHTS_RESERVED -eq 1 ]; then | |
fixMissingAllRightsReserved "$line" | |
fi | |
# Fix missing license header | |
if [ $MISSING_LICENSE_HEADER -eq 1 ]; then | |
SET_OF_ATTRIBUTIONS="" | |
if [ $EXISTED_IN_THE_JIVE_SOFTWARE_ERA -eq 1 ]; then | |
SET_OF_ATTRIBUTIONS="$JIVE_ATTRIBUTION" | |
fi | |
if [ $MISSING_IGNITE_MENTION -eq 1 ]; then | |
if [ -n "$SET_OF_ATTRIBUTIONS" ]; then | |
SET_OF_ATTRIBUTIONS="$SET_OF_ATTRIBUTIONS, $IGNITE_ATTRIBUTION" | |
else | |
SET_OF_ATTRIBUTIONS="$IGNITE_ATTRIBUTION" | |
fi | |
fi | |
fixMissingLicenseHeader "$line" "$SET_OF_ATTRIBUTIONS" | |
else | |
# Fix missing Ignite attribution | |
if [ $MISSING_IGNITE_MENTION -eq 1 ]; then | |
fixMissingCopyrightAttribution "$line" "$IGNITE_ATTRIBUTION" | |
fi | |
# Fix incorrect Ignite attribution | |
if [ $INCORRECT_IGNITE_MENTION -eq 1 ]; then | |
fixIncorrectCopyrightLine "$line" "$IGNITE_ATTRIBUTION" \ | |
"Ignite Realtime Foundation" | |
fi | |
fi | |
done | |
echo "Done." | |
} | |
processFiles |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment