Skip to content

Instantly share code, notes, and snippets.

@Fishbowler
Created December 17, 2023 13:44
Show Gist options
  • Save Fishbowler/ed6a05c4e7b7ba539f814df3f54e5772 to your computer and use it in GitHub Desktop.
Save Fishbowler/ed6a05c4e7b7ba539f814df3f54e5772 to your computer and use it in GitHub Desktop.
Check and Update license and copyright headers in Openfire source files
#!/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