[license-header] refactor: excludes, updating, better logic (#2780)
All checks were successful
GitHub Actions [CI] Build succeeded
All checks were successful
GitHub Actions [CI] Build succeeded
Rewrite of license-header.sh. Lots of new goodies: - Fully POSIX compliant - supports dash arguments (-u/--update, -c/--commit, -uc for both) - can update year or malformed headers in-place now - accounts for shell scripts - exclusion of external files (e.g. sse2neon, my CMake modules/scripts) - better, more extensible logic all around Reviewed-on: #2780
This commit is contained in:
parent
df653d6ca4
commit
d7cd7c6313
6 changed files with 195 additions and 139 deletions
|
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
license_header = <<~EOF
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
EOF
|
||||
|
||||
print 'Getting branch changes...'
|
||||
branch_name = `git rev-parse --abbrev-ref HEAD`.chomp
|
||||
branch_commits = `git log #{branch_name} --not master --pretty=format:"%h"`.split("\n")
|
||||
branch_commit_range = "#{branch_commits[-1]}^..#{branch_commits[0]}"
|
||||
branch_changed_files = `git diff-tree --no-commit-id --name-only #{branch_commit_range} -r`.split("\n")
|
||||
puts 'done'
|
||||
|
||||
print 'Checking files...'
|
||||
issue_files = []
|
||||
branch_changed_files.each do |file_name|
|
||||
if file_name.end_with?('.cpp', '.h', '.kt', '.kts') and File.file?(file_name)
|
||||
file_content = File.read(file_name)
|
||||
if not file_content.start_with?(license_header)
|
||||
issue_files.push(file_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
puts 'done'
|
||||
|
||||
if issue_files.empty?
|
||||
puts "\nAll changed files have correct headers"
|
||||
exit 0
|
||||
end
|
||||
|
||||
puts <<-EOF
|
||||
|
||||
The following #{issue_files.length} files have incorrect license headers:
|
||||
#{issue_files.join("\n")}
|
||||
|
||||
The following license header should be added to the start of all offending files:
|
||||
=== BEGIN ===
|
||||
#{license_header}
|
||||
=== END ===
|
||||
|
||||
If some of the code in this PR is not being contributed by the original author, the files which have been exclusively changed by that code can be ignored.
|
||||
If this happens, this PR requirement can be bypassed once all other files are addressed.
|
||||
EOF
|
||||
|
||||
exit 1
|
||||
|
|
@ -1,74 +1,152 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
HEADER="$(cat "$PWD/.ci/license/header.txt")"
|
||||
HEADER_HASH="$(cat "$PWD/.ci/license/header-hash.txt")"
|
||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
echo "Getting branch changes"
|
||||
# specify full path if dupes may exist
|
||||
EXCLUDE_FILES="CPM.cmake CPMUtil.cmake GetSCMRev.cmake sse2neon.h renderdoc_app.h tools/cpm externals/stb externals/glad externals/getopt externals/gamemode externals/FidelityFX-FSR externals/demangle externals/bc_decoder"
|
||||
|
||||
# BRANCH=`git rev-parse --abbrev-ref HEAD`
|
||||
# COMMITS=`git log ${BRANCH} --not master --pretty=format:"%h"`
|
||||
# RANGE="${COMMITS[${#COMMITS[@]}-1]}^..${COMMITS[0]}"
|
||||
# FILES=`git diff-tree --no-commit-id --name-only ${RANGE} -r`
|
||||
# license header constants, please change when needed :))))
|
||||
YEAR=2025
|
||||
HOLDER="Eden Emulator Project"
|
||||
LICENSE="GPL-3.0-or-later"
|
||||
|
||||
BASE=`git merge-base master HEAD`
|
||||
FILES=`git diff --name-only $BASE`
|
||||
usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [uc]
|
||||
Compares the current HEAD to the master branch to check for license
|
||||
header discrepancies. Each file changed in a branch MUST have a
|
||||
license header, and this script attempts to enforce that.
|
||||
|
||||
#FILES=$(git diff --name-only master)
|
||||
Options:
|
||||
-u, --update Fix license headers, if applicable;
|
||||
if the license header exists but has the incorrect
|
||||
year or is otherwise malformed, it will be fixed.
|
||||
|
||||
echo "Done"
|
||||
-c, --commit Commit changes to Git (requires --update)
|
||||
|
||||
Copyright $YEAR $HOLDER
|
||||
Licensed under $LICENSE
|
||||
|
||||
The following files/directories are marked as external
|
||||
and thus will not have license headers asserted:
|
||||
EOF
|
||||
|
||||
for file in $EXCLUDE_FILES; do
|
||||
echo "- $file"
|
||||
done
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
(-uc) UPDATE=true; COMMIT=true ;;
|
||||
(-u|--update) UPDATE=true ;;
|
||||
(-c|--commit) COMMIT=true ;;
|
||||
("$0") break ;;
|
||||
("") break ;;
|
||||
(*) usage ;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
# human-readable header string
|
||||
header() {
|
||||
header_line1 "$1"
|
||||
header_line2 "$1"
|
||||
}
|
||||
|
||||
header_line1() {
|
||||
echo "$1 SPDX-FileCopyrightText: Copyright $YEAR $HOLDER"
|
||||
}
|
||||
|
||||
header_line2() {
|
||||
echo "$1 SPDX-License-Identifier: $LICENSE"
|
||||
}
|
||||
|
||||
# PCRE header string
|
||||
pcre_header() {
|
||||
begin="$1"
|
||||
echo "(?s)$(header_line1 "$begin").*$(header_line2 "$begin")"
|
||||
}
|
||||
|
||||
check_header() {
|
||||
CONTENT="`head -n3 < $1`"
|
||||
case "$CONTENT" in
|
||||
"$HEADER"*) ;;
|
||||
*) BAD_FILES="$BAD_FILES $1" ;;
|
||||
begin="$1"
|
||||
file="$2"
|
||||
content="$(head -n5 < "$2")"
|
||||
|
||||
header="$(pcre_header "$begin")"
|
||||
|
||||
if ! echo "$content" | grep -Pzo "$header" > /dev/null; then
|
||||
# SRC_FILES is Kotlin/C++
|
||||
# OTHER_FILES is sh, CMake
|
||||
case "$begin" in
|
||||
"//")
|
||||
SRC_FILES="$SRC_FILES $file"
|
||||
;;
|
||||
"#")
|
||||
OTHER_FILES="$OTHER_FILES $file"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
check_cmake_header() {
|
||||
CONTENT="`head -n3 < $1`"
|
||||
BASE=$(git merge-base master HEAD)
|
||||
FILES=$(git diff --name-only "$BASE")
|
||||
|
||||
case "$CONTENT" in
|
||||
"$HEADER_HASH"*) ;;
|
||||
*)
|
||||
BAD_CMAKE="$BAD_CMAKE $1" ;;
|
||||
esac
|
||||
}
|
||||
for file in $FILES; do
|
||||
[ -f "$file" ] || continue
|
||||
|
||||
if [ `basename -- "$file"` = "CMakeLists.txt" ]; then
|
||||
check_cmake_header "$file"
|
||||
# skip files that are third party (crueter's CMake modules, sse2neon, etc)
|
||||
for pattern in $EXCLUDE_FILES; do
|
||||
case "$file" in
|
||||
*"$pattern"*)
|
||||
excluded=true
|
||||
continue
|
||||
fi
|
||||
|
||||
EXTENSION="${file##*.}"
|
||||
case "$EXTENSION" in
|
||||
kts|kt|cpp|h)
|
||||
check_header "$file"
|
||||
;;
|
||||
cmake)
|
||||
check_cmake_header "$file"
|
||||
*)
|
||||
excluded=false
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$excluded" = "true" ] && continue
|
||||
|
||||
case "$file" in
|
||||
*.cmake|*.sh|CMakeLists.txt)
|
||||
begin="#"
|
||||
;;
|
||||
*.kt*|*.cpp|*.h)
|
||||
begin="//"
|
||||
;;
|
||||
*)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
check_header "$begin" "$file"
|
||||
done
|
||||
|
||||
if [ "$BAD_FILES" = "" ] && [ "$BAD_CMAKE" = "" ]; then
|
||||
echo
|
||||
echo "All good."
|
||||
if [ -z "$SRC_FILES" ] && [ -z "$OTHER_FILES" ]; then
|
||||
echo "-- All good."
|
||||
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "$BAD_FILES" != "" ]; then
|
||||
echo "The following source files have incorrect license headers:"
|
||||
echo
|
||||
echo
|
||||
|
||||
for file in $BAD_FILES; do echo $file; done
|
||||
if [ "$SRC_FILES" != "" ]; then
|
||||
echo "-- The following source files have incorrect license headers:"
|
||||
|
||||
HEADER=$(header "//")
|
||||
|
||||
for file in $SRC_FILES; do echo "-- * $file"; done
|
||||
|
||||
cat << EOF
|
||||
|
||||
The following license header should be added to the start of all offending SOURCE files:
|
||||
-- The following license header should be added to the start of these offending files:
|
||||
|
||||
=== BEGIN ===
|
||||
$HEADER
|
||||
|
|
@ -78,18 +156,19 @@ EOF
|
|||
|
||||
fi
|
||||
|
||||
if [ "$BAD_CMAKE" != "" ]; then
|
||||
echo "The following CMake files have incorrect license headers:"
|
||||
echo
|
||||
if [ "$OTHER_FILES" != "" ]; then
|
||||
echo "-- The following CMake and shell scripts have incorrect license headers:"
|
||||
|
||||
for file in $BAD_CMAKE; do echo $file; done
|
||||
HEADER=$(header "#")
|
||||
|
||||
for file in $OTHER_FILES; do echo "-- * $file"; done
|
||||
|
||||
cat << EOF
|
||||
|
||||
The following license header should be added to the start of all offending CMake files:
|
||||
-- The following license header should be added to the start of these offending files:
|
||||
|
||||
=== BEGIN ===
|
||||
$HEADER_HASH
|
||||
$HEADER
|
||||
=== END ===
|
||||
|
||||
EOF
|
||||
|
|
@ -97,50 +176,76 @@ EOF
|
|||
fi
|
||||
|
||||
cat << EOF
|
||||
If some of the code in this PR is not being contributed by the original author,
|
||||
the files which have been exclusively changed by that code can be ignored.
|
||||
If this happens, this PR requirement can be bypassed once all other files are addressed.
|
||||
If some of the code in this PR is not being contributed by the original author,
|
||||
the files which have been exclusively changed by that code can be ignored.
|
||||
If this happens, this PR requirement can be bypassed once all other files are addressed.
|
||||
|
||||
EOF
|
||||
|
||||
if [ "$FIX" = "true" ]; then
|
||||
echo
|
||||
echo "FIX set to true. Fixing headers."
|
||||
echo
|
||||
if [ "$UPDATE" = "true" ]; then
|
||||
TMP_DIR=$(mktemp -d)
|
||||
echo "-- Fixing headers..."
|
||||
|
||||
for file in $BAD_FILES; do
|
||||
cat $file > $file.bak
|
||||
for file in $SRC_FILES $OTHER_FILES; do
|
||||
case $(basename -- "$file") in
|
||||
*.cmake|CMakeLists.txt)
|
||||
begin="#"
|
||||
shell="false"
|
||||
;;
|
||||
*.sh)
|
||||
begin="#"
|
||||
shell=true
|
||||
;;
|
||||
*.kt*|*.cpp|*.h)
|
||||
begin="//"
|
||||
shell="false"
|
||||
;;
|
||||
esac
|
||||
|
||||
cat .ci/license/header.txt > $file
|
||||
echo >> $file
|
||||
cat $file.bak >> $file
|
||||
# This is fun
|
||||
match="$begin SPDX-FileCopyrightText.*$HOLDER"
|
||||
|
||||
rm $file.bak
|
||||
# basically if the copyright holder is already defined we can just replace the year
|
||||
if head -n5 < "$file" | grep -e "$match" >/dev/null; then
|
||||
replace=$(header_line1 "$begin")
|
||||
sed "s|$match|$replace|" "$file" > "$file".bak
|
||||
mv "$file".bak "$file"
|
||||
else
|
||||
header "$begin" > "$TMP_DIR"/header
|
||||
|
||||
git add $file
|
||||
if [ "$shell" = "true" ]; then
|
||||
# grab shebang
|
||||
head -n1 "$file" > "$TMP_DIR/shebang"
|
||||
echo >> "$TMP_DIR/shebang"
|
||||
|
||||
# remove shebang
|
||||
sed '1d' "$file" > "$file".bak
|
||||
mv "$file".bak "$file"
|
||||
|
||||
# add to header
|
||||
cat "$TMP_DIR"/shebang "$TMP_DIR"/header > "$TMP_DIR"/new-header
|
||||
mv "$TMP_DIR"/new-header "$TMP_DIR"/header
|
||||
else
|
||||
echo >> "$TMP_DIR/header"
|
||||
fi
|
||||
|
||||
cat "$TMP_DIR"/header "$file" > "$file".bak
|
||||
mv "$file".bak "$file"
|
||||
fi
|
||||
|
||||
[ "$shell" = "true" ] && chmod a+x "$file"
|
||||
[ "$COMMIT" = "true" ] && git add "$file"
|
||||
done
|
||||
|
||||
for file in $BAD_CMAKE; do
|
||||
cat $file > $file.bak
|
||||
echo "-- Done"
|
||||
fi
|
||||
|
||||
cat .ci/license/header-hash.txt > $file
|
||||
echo >> $file
|
||||
cat $file.bak >> $file
|
||||
|
||||
rm $file.bak
|
||||
|
||||
git add $file
|
||||
done
|
||||
echo "License headers fixed."
|
||||
|
||||
if [ "$COMMIT" = "true" ]; then
|
||||
echo
|
||||
echo "COMMIT set to true. Committing changes."
|
||||
echo
|
||||
if [ "$COMMIT" = "true" ]; then
|
||||
echo "-- Committing changes"
|
||||
|
||||
git commit -m "Fix license headers"
|
||||
|
||||
echo "Changes committed. You may now push."
|
||||
fi
|
||||
else
|
||||
exit 1
|
||||
echo "-- Changes committed. You may now push."
|
||||
fi
|
||||
|
||||
[ -d "$TMP_DIR" ] && rm -rf "$TMP_DIR"
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
|
@ -6,19 +6,21 @@ All commits must have proper license header accreditation.
|
|||
You can easily add all necessary license headers by running:
|
||||
```sh
|
||||
git fetch origin master:master
|
||||
FIX=true COMMIT=true .ci/license-header.sh
|
||||
.ci/license-header.sh -u -c
|
||||
git push
|
||||
```
|
||||
|
||||
Alternatively, you may omit `COMMIT=true` and do an amend commit:
|
||||
Alternatively, you may omit `-c` and do an amend commit:
|
||||
```sh
|
||||
git fetch origin master:master
|
||||
FIX=true .ci/license-header.sh
|
||||
.ci/license-header.sh
|
||||
git commit --amend -a --no-edit
|
||||
```
|
||||
|
||||
If the work is licensed/vendored from other people or projects, you may omit the license headers. Additionally, if you wish to retain authorship over a piece of code, you may attribute it to yourself; however, the code may be changed at any given point and brought under the attribution of Eden.
|
||||
|
||||
For more information on the license header script, run `.ci/license-header.sh -h`.
|
||||
|
||||
## Pull Requests
|
||||
Pull requests are only to be merged by core developers when properly tested and discussions conclude on Discord or other communication channels. Labels are recommended but not required. However, all PRs MUST be namespaced and optionally typed:
|
||||
```
|
||||
|
|
|
|||
0
tools/cpm-fetch-all.sh
Normal file → Executable file
0
tools/cpm-fetch-all.sh
Normal file → Executable file
Loading…
Add table
Add a link
Reference in a new issue