diff options
Diffstat (limited to 'misc/scripts')
-rwxr-xr-x | misc/scripts/black_format.sh | 33 | ||||
-rwxr-xr-x | misc/scripts/check_ci_log.py | 65 | ||||
-rwxr-xr-x | misc/scripts/clang_format.sh | 58 | ||||
-rwxr-xr-x | misc/scripts/compare_extension_api.py | 11 | ||||
-rwxr-xr-x | misc/scripts/copyright_headers.py (renamed from misc/scripts/fix_headers.py) | 109 | ||||
-rwxr-xr-x | misc/scripts/file_format.sh | 65 | ||||
-rwxr-xr-x | misc/scripts/fix_style.sh | 78 | ||||
-rwxr-xr-x | misc/scripts/make_icons.sh | 2 | ||||
-rwxr-xr-x | misc/scripts/make_tarball.sh | 66 |
9 files changed, 350 insertions, 137 deletions
diff --git a/misc/scripts/black_format.sh b/misc/scripts/black_format.sh new file mode 100755 index 0000000000..2ad9a23832 --- /dev/null +++ b/misc/scripts/black_format.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# This script runs black on all Python files in the repo. + +set -uo pipefail + +# Apply black. +echo -e "Formatting Python files..." +PY_FILES=$(find \( -path "./.git" \ + -o -path "./thirdparty" \ + \) -prune \ + -o \( -name "SConstruct" \ + -o -name "SCsub" \ + -o -name "*.py" \ + \) -print) +black -l 120 $PY_FILES + +git diff --color > patch.patch + +# If no patch has been generated all is OK, clean up, and exit. +if [ ! -s patch.patch ] ; then + printf "Files in this commit comply with the black style rules.\n" + rm -f patch.patch + exit 0 +fi + +# A patch has been created, notify the user, clean up, and exit. +printf "\n*** The following differences were found between the code " +printf "and the formatting rules:\n\n" +cat patch.patch +printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n" +rm -f patch.patch +exit 1 diff --git a/misc/scripts/check_ci_log.py b/misc/scripts/check_ci_log.py new file mode 100755 index 0000000000..2c75b83bd7 --- /dev/null +++ b/misc/scripts/check_ci_log.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys + +if len(sys.argv) < 2: + print("ERROR: You must run program with file name as argument.") + sys.exit(50) + +fname = sys.argv[1] + +fileread = open(fname.strip(), "r") +file_contents = fileread.read() + +# If find "ERROR: AddressSanitizer:", then happens invalid read or write +# This is critical bug, so we need to fix this as fast as possible + +if file_contents.find("ERROR: AddressSanitizer:") != -1: + print("FATAL ERROR: An incorrectly used memory was found.") + sys.exit(51) + +# There is also possible, that program crashed with or without backtrace. + +if ( + file_contents.find("Program crashed with signal") != -1 + or file_contents.find("Dumping the backtrace") != -1 + or file_contents.find("Segmentation fault (core dumped)") != -1 +): + print("FATAL ERROR: Godot has been crashed.") + sys.exit(52) + +# Finding memory leaks in Godot is quite difficult, because we need to take into +# account leaks also in external libraries. They are usually provided without +# debugging symbols, so the leak report from it usually has only 2/3 lines, +# so searching for 5 element - "#4 0x" - should correctly detect the vast +# majority of memory leaks + +if file_contents.find("ERROR: LeakSanitizer:") != -1: + if file_contents.find("#4 0x") != -1: + print("ERROR: Memory leak was found") + sys.exit(53) + +# It may happen that Godot detects leaking nodes/resources and removes them, so +# this possibility should also be handled as a potential error, even if +# LeakSanitizer doesn't report anything + +if file_contents.find("ObjectDB instances leaked at exit") != -1: + print("ERROR: Memory leak was found") + sys.exit(54) + +# In test project may be put several assert functions which will control if +# project is executed with right parameters etc. which normally will not stop +# execution of project + +if file_contents.find("Assertion failed") != -1: + print("ERROR: Assertion failed in project, check execution log for more info") + sys.exit(55) + +# For now Godot leaks a lot of rendering stuff so for now we just show info +# about it and this needs to be re-enabled after fixing this memory leaks. + +if file_contents.find("were leaked") != -1 or file_contents.find("were never freed") != -1: + print("WARNING: Memory leak was found") + +sys.exit(0) diff --git a/misc/scripts/clang_format.sh b/misc/scripts/clang_format.sh new file mode 100755 index 0000000000..b0020da597 --- /dev/null +++ b/misc/scripts/clang_format.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# This script runs clang-format and fixes copyright headers on all relevant files in the repo. +# This is the primary script responsible for fixing style violations. + +set -uo pipefail +IFS=$'\n\t' + +CLANG_FORMAT_FILE_EXTS=(".c" ".h" ".cpp" ".hpp" ".cc" ".hh" ".cxx" ".m" ".mm" ".inc" ".java" ".glsl") + +# Loops through all text files tracked by Git. +git grep -zIl '' | +while IFS= read -rd '' f; do + # Exclude some files. + if [[ "$f" == "thirdparty"* ]]; then + continue + elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then + continue + elif [[ "$f" == *"-so_wrap."* ]]; then + continue + fi + + for extension in ${CLANG_FORMAT_FILE_EXTS[@]}; do + if [[ "$f" == *"$extension" ]]; then + # Run clang-format. + clang-format --Wno-error=unknown -i "$f" + # Fix copyright headers, but not all files get them. + if [[ "$f" == *"inc" ]]; then + continue 2 + elif [[ "$f" == *"glsl" ]]; then + continue 2 + elif [[ "$f" == *"theme_data.h" ]]; then + continue 2 + elif [[ "$f" == "platform/android/java/lib/src/org/godotengine/godot/input/InputManager"* ]]; then + continue 2 + fi + python misc/scripts/copyright_headers.py "$f" + continue 2 + fi + done +done + +git diff --color > patch.patch + +# If no patch has been generated all is OK, clean up, and exit. +if [ ! -s patch.patch ] ; then + printf "Files in this commit comply with the clang-format style rules.\n" + rm -f patch.patch + exit 0 +fi + +# A patch has been created, notify the user, clean up, and exit. +printf "\n*** The following differences were found between the code " +printf "and the formatting rules:\n\n" +cat patch.patch +printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n" +rm -f patch.patch +exit 1 diff --git a/misc/scripts/compare_extension_api.py b/misc/scripts/compare_extension_api.py new file mode 100755 index 0000000000..f96db4278c --- /dev/null +++ b/misc/scripts/compare_extension_api.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys + +# TODO: +# Add a process that compares the original godot-cpp/godot-headers/extension_api.json with the new extension_api.json (both passed as arguments) and reports any API calls that have been removed. +# If we only have additions or no changes to the file, we pass +# For now we deem this too early because the API isn't stable enough yet. + +sys.exit(0) diff --git a/misc/scripts/fix_headers.py b/misc/scripts/copyright_headers.py index 7af97eec4b..cf3adbfbfa 100755 --- a/misc/scripts/fix_headers.py +++ b/misc/scripts/copyright_headers.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import sys + header = """\ /*************************************************************************/ /* $filename */ @@ -9,8 +11,8 @@ header = """\ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,70 +35,61 @@ header = """\ /*************************************************************************/ """ -files = open("files", "r") - -fname = files.readline() +fname = sys.argv[1] -while fname != "": +# Handle replacing $filename with actual filename and keep alignment +fsingle = fname.strip() +if fsingle.find("/") != -1: + fsingle = fsingle[fsingle.rfind("/") + 1 :] +rep_fl = "$filename" +rep_fi = fsingle +len_fl = len(rep_fl) +len_fi = len(rep_fi) +# Pad with spaces to keep alignment +if len_fi < len_fl: + for x in range(len_fl - len_fi): + rep_fi += " " +elif len_fl < len_fi: + for x in range(len_fi - len_fl): + rep_fl += " " +if header.find(rep_fl) != -1: + text = header.replace(rep_fl, rep_fi) +else: + text = header.replace("$filename", fsingle) +text += "\n" - # Handle replacing $filename with actual filename and keep alignment - fsingle = fname.strip() - if fsingle.find("/") != -1: - fsingle = fsingle[fsingle.rfind("/") + 1 :] - rep_fl = "$filename" - rep_fi = fsingle - len_fl = len(rep_fl) - len_fi = len(rep_fi) - # Pad with spaces to keep alignment - if len_fi < len_fl: - for x in range(len_fl - len_fi): - rep_fi += " " - elif len_fl < len_fi: - for x in range(len_fi - len_fl): - rep_fl += " " - if header.find(rep_fl) != -1: - text = header.replace(rep_fl, rep_fi) - else: - text = header.replace("$filename", fsingle) - text += "\n" +# We now have the proper header, so we want to ignore the one in the original file +# and potentially empty lines and badly formatted lines, while keeping comments that +# come after the header, and then keep everything non-header unchanged. +# To do so, we skip empty lines that may be at the top in a first pass. +# In a second pass, we skip all consecutive comment lines starting with "/*", +# then we can append the rest (step 2). - # We now have the proper header, so we want to ignore the one in the original file - # and potentially empty lines and badly formatted lines, while keeping comments that - # come after the header, and then keep everything non-header unchanged. - # To do so, we skip empty lines that may be at the top in a first pass. - # In a second pass, we skip all consecutive comment lines starting with "/*", - # then we can append the rest (step 2). +fileread = open(fname.strip(), "r") +line = fileread.readline() +header_done = False - fileread = open(fname.strip(), "r") +while line.strip() == "": # Skip empty lines at the top line = fileread.readline() - header_done = False - while line.strip() == "": # Skip empty lines at the top - line = fileread.readline() +if line.find("/**********") == -1: # Godot header starts this way + # Maybe starting with a non-Godot comment, abort header magic + header_done = True - if line.find("/**********") == -1: # Godot header starts this way - # Maybe starting with a non-Godot comment, abort header magic +while not header_done: # Handle header now + if line.find("/*") != 0: # No more starting with a comment header_done = True + if line.strip() != "": + text += line + line = fileread.readline() - while not header_done: # Handle header now - if line.find("/*") != 0: # No more starting with a comment - header_done = True - if line.strip() != "": - text += line - line = fileread.readline() - - while line != "": # Dump everything until EOF - text += line - line = fileread.readline() - - fileread.close() - - # Write - filewrite = open(fname.strip(), "w") - filewrite.write(text) - filewrite.close() +while line != "": # Dump everything until EOF + text += line + line = fileread.readline() - # Next file - fname = files.readline() +fileread.close() -files.close() +# Write +filewrite = open(fname.strip(), "w") +filewrite.write(text) +filewrite.close() diff --git a/misc/scripts/file_format.sh b/misc/scripts/file_format.sh new file mode 100755 index 0000000000..e66bc88bc0 --- /dev/null +++ b/misc/scripts/file_format.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +# This script ensures proper POSIX text file formatting and a few other things. +# This is supplementary to clang_format.sh and black_format.sh, but should be +# run before them. + +# We need dos2unix and recode. +if [ ! -x "$(command -v dos2unix)" -o ! -x "$(command -v recode)" ]; then + printf "Install 'dos2unix' and 'recode' to use this script.\n" +fi + +set -uo pipefail +IFS=$'\n\t' + +# Loops through all text files tracked by Git. +git grep -zIl '' | +while IFS= read -rd '' f; do + # Exclude some types of files. + if [[ "$f" == *"csproj" ]]; then + continue + elif [[ "$f" == *"sln" ]]; then + continue + elif [[ "$f" == *".bat" ]]; then + continue + elif [[ "$f" == *".out" ]]; then + # GDScript integration testing files. + continue + elif [[ "$f" == *"patch" ]]; then + continue + elif [[ "$f" == *"pot" ]]; then + continue + elif [[ "$f" == *"po" ]]; then + continue + elif [[ "$f" == "thirdparty"* ]]; then + continue + elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then + continue + elif [[ "$f" == *"-so_wrap."* ]]; then + continue + fi + # Ensure that files are UTF-8 formatted. + recode UTF-8 "$f" 2> /dev/null + # Ensure that files have LF line endings and do not contain a BOM. + dos2unix "$f" 2> /dev/null + # Remove trailing space characters and ensures that files end + # with newline characters. -l option handles newlines conveniently. + perl -i -ple 's/\s*$//g' "$f" +done + +git diff --color > patch.patch + +# If no patch has been generated all is OK, clean up, and exit. +if [ ! -s patch.patch ] ; then + printf "Files in this commit comply with the formatting rules.\n" + rm -f patch.patch + exit 0 +fi + +# A patch has been created, notify the user, clean up, and exit. +printf "\n*** The following differences were found between the code " +printf "and the formatting rules:\n\n" +cat patch.patch +printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n" +rm -f patch.patch +exit 1 diff --git a/misc/scripts/fix_style.sh b/misc/scripts/fix_style.sh deleted file mode 100755 index 2eee61a459..0000000000 --- a/misc/scripts/fix_style.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env bash - -# Command line arguments -run_black=false -run_clang_format=false -run_fix_headers=false -usage="Invalid argument. Usage:\n$0 <option>\n\t--black|-b\n\t--clang-format|-c\n\t--headers|-h\n\t--all|-a" - -if [ -z "$1" ]; then - echo -e $usage - exit 0 -fi - -while [ $# -gt 0 ]; do - case "$1" in - --black|-b) - run_black=true - ;; - --clang-format|-c) - run_clang_format=true - ;; - --headers|-h) - run_fix_headers=true - ;; - --all|-a) - run_black=true - run_clang_format=true - run_fix_headers=true - ;; - *) - echo -e $usage - exit 0 - esac - shift -done - -echo "Removing generated files, some have binary data and make clang-format freeze." -find -name "*.gen.*" -delete - -# Apply black -if $run_black; then - echo -e "Formatting Python files..." - PY_FILES=$(find \( -path "./.git" \ - -o -path "./thirdparty" \ - \) -prune \ - -o \( -name "SConstruct" \ - -o -name "SCsub" \ - -o -name "*.py" \ - \) -print) - black -l 120 $PY_FILES -fi - -# Apply clang-format -if $run_clang_format; then - # Sync list with pre-commit hook - FILE_EXTS=".c .h .cpp .hpp .cc .hh .cxx .m .mm .inc .java .glsl" - - for extension in ${FILE_EXTS}; do - echo -e "Formatting ${extension} files..." - find \( -path "./.git" \ - -o -path "./thirdparty" \ - -o -path "./platform/android/java/lib/src/com/google" \ - \) -prune \ - -o -name "*${extension}" \ - -exec clang-format -i {} \; - done -fi - -# Add missing copyright headers -if $run_fix_headers; then - echo "Fixing copyright headers in Godot code files..." - find \( -path "./.git" -o -path "./thirdparty" \) -prune \ - -o -regex '.*\.\(c\|h\|cpp\|hpp\|cc\|hh\|cxx\|m\|mm\|java\)' \ - > tmp-files - cat tmp-files | grep -v ".git\|thirdparty\|theme_data.h\|platform/android/java/lib/src/com/google\|platform/android/java/lib/src/org/godotengine/godot/input/InputManager" > files - python misc/scripts/fix_headers.py - rm -f tmp-files files -fi diff --git a/misc/scripts/make_icons.sh b/misc/scripts/make_icons.sh index b590f03d38..cbb9266055 100755 --- a/misc/scripts/make_icons.sh +++ b/misc/scripts/make_icons.sh @@ -20,7 +20,7 @@ zip godot-icons.zip icon*.png icotool -c -o godot-icon.ico icon{16,24,32,48,64,128,256}.png # icns for macOS -# Only some sizes: http://iconhandbook.co.uk/reference/chart/osx/ +# Only some sizes: https://iconhandbook.co.uk/reference/chart/osx/ png2icns godot-icon.icns icon{16,32,128,256,512,1024}.png rm -f icon*.png diff --git a/misc/scripts/make_tarball.sh b/misc/scripts/make_tarball.sh new file mode 100755 index 0000000000..9e02b80af1 --- /dev/null +++ b/misc/scripts/make_tarball.sh @@ -0,0 +1,66 @@ +#!/bin/sh + +if [ ! -e "version.py" ]; then + echo "This script should be ran from the root folder of the Godot repository." + exit 1 +fi + +while getopts "h?sv:g:" opt; do + case "$opt" in + h|\?) + echo "Usage: $0 [OPTIONS...]" + echo + echo " -s script friendly file name (godot.tar.gz)" + echo " -v godot version for file name (e.g. 4.0-stable)" + echo " -g git treeish to archive (e.g. master)" + echo + exit 1 + ;; + s) + script_friendly_name=1 + ;; + v) + godot_version=$OPTARG + ;; + g) + git_treeish=$OPTARG + ;; + esac +done + +if [ ! -z "$git_treeish" ]; then + HEAD=$(git rev-parse $git_treeish) +else + HEAD=$(git rev-parse HEAD) +fi + +if [ ! -z "$script_friendly_name" ]; then + NAME=godot +else + if [ ! -z "$godot_version" ]; then + NAME=godot-$godot_version + else + NAME=godot-$HEAD + fi +fi + +CURDIR=$(pwd) +TMPDIR=$(mktemp -d -t godot-XXXXXX) + +echo "Generating tarball for revision $HEAD with folder name '$NAME'." +echo +echo "The tarball will be written to the parent folder:" +echo " $(dirname $CURDIR)/$NAME.tar.gz" + +git archive $HEAD --prefix=$NAME/ -o $TMPDIR/$NAME.tar + +# Adding custom .git/HEAD to tarball so that we can generate VERSION_HASH. +cd $TMPDIR +mkdir -p $NAME/.git +echo $HEAD > $NAME/.git/HEAD +tar -uf $NAME.tar $NAME + +cd $CURDIR +gzip -c $TMPDIR/$NAME.tar > ../$NAME.tar.gz + +rm -rf $TMPDIR |