From eeb446134cefdf90aebfbc6174cbdff5ed51fcf4 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Fri, 6 Dec 2024 08:23:44 +0200 Subject: [PATCH] Add a pre-commit config to run with the specific defines of major projects Run with pre-commit run -a -c .pre-commit-config-defines.yaml This is not enabled by default, because the code, which is rather convoluted due to the inability to pass --define to dotnet format, coupled with our files' containing BOMs, doesn't run on Windows. It barely runs on Linux, tbh ;-) --- .pre-commit-config-defines.yaml | 26 +++++++ pre-commit-dotnet-format-multiplayer.sh | 4 ++ pre-commit-dotnet-format-oculus.sh | 4 ++ pre-commit-dotnet-format-windows.sh | 4 ++ pre_commit_dotnet_format.sh | 95 +++++++++++++++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 .pre-commit-config-defines.yaml create mode 100755 pre-commit-dotnet-format-multiplayer.sh create mode 100755 pre-commit-dotnet-format-oculus.sh create mode 100755 pre-commit-dotnet-format-windows.sh create mode 100755 pre_commit_dotnet_format.sh diff --git a/.pre-commit-config-defines.yaml b/.pre-commit-config-defines.yaml new file mode 100644 index 0000000000..5003cc3ab2 --- /dev/null +++ b/.pre-commit-config-defines.yaml @@ -0,0 +1,26 @@ +--- +repos: + - repo: local + hooks: + - id: dotnet-format-windows + name: dotnet-format for Windows + language: system + entry: ./pre-commit-dotnet-format-windows.sh + types_or: [c#, vb] + exclude: ^(Assets/ThirdParty)|(Packages/)|(Assets/Photon/) + - repo: local + hooks: + - id: dotnet-format-multiplayer + name: dotnet-format for multiplayer + language: system + entry: ./pre-commit-dotnet-format-multiplayer.sh + types_or: [c#, vb] + exclude: ^(Assets/ThirdParty)|(Packages/)|(Assets/Photon/) + - repo: local + hooks: + - id: dotnet-format-oculus + name: dotnet-format for oculus + language: system + entry: ./pre-commit-dotnet-format-oculus.sh + types_or: [c#, vb] + exclude: ^(Assets/ThirdParty)|(Packages/)|(Assets/Photon/) diff --git a/pre-commit-dotnet-format-multiplayer.sh b/pre-commit-dotnet-format-multiplayer.sh new file mode 100755 index 0000000000..f32841b10f --- /dev/null +++ b/pre-commit-dotnet-format-multiplayer.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +export DEFINES="UNITY_EDITOR UNITY_EDITOR_WIN UNITY_ANDROID TILT_BRUSH PHOTON_UNITY_NETWORKING,PUN_2_0_OR_NEWER,PUN_2_OR_NEWER,PUN_2_19_OR_NEWER,FUSION_WEAVER,FUSION2,CROSS_PLATFORM_INPUT,MOBILE_INPUT,PHOTON_VOICE_DEFINED" +./pre_commit_dotnet_format.sh "$@" diff --git a/pre-commit-dotnet-format-oculus.sh b/pre-commit-dotnet-format-oculus.sh new file mode 100755 index 0000000000..9c3b6e4037 --- /dev/null +++ b/pre-commit-dotnet-format-oculus.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +export DEFINES="UNITY_EDITOR UNITY_ANDROID TILT_BRUSH OCULUS_SUPPORTED FORCE_HEADTRACKING FORCE_FOCUSAWARE FORCE_QUEST_SUPPORT_DEVICE USE_TILT_BRUSH_CPP UNITY_2017_2_OR_NEWER UNITY_2018_4_OR_NEWER UNITY_2019_3_OR_NEWER UNITY_2020_3_OR_NEWER UNITY_5_4_OR_NEWER UNITY_5_6_OR_NEWER PASSTHROUGH_SUPPORTED" +./pre_commit_dotnet_format.sh "$@" diff --git a/pre-commit-dotnet-format-windows.sh b/pre-commit-dotnet-format-windows.sh new file mode 100755 index 0000000000..41a80a5968 --- /dev/null +++ b/pre-commit-dotnet-format-windows.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +export DEFINES="UNITY_EDITOR UNITY_EDITOR_WIN UNITY_WIN TILT_BRUSH SELECTION_ON AUDIO_REACTIVE USD_SUPPORTED FBX_SUPPORTED UNITY_STANDALONE_WIN USE_TILT_BRUSH_CPP UNITY_2017_2_OR_NEWER UNITY_2018_4_OR_NEWER UNITY_2019_3_OR_NEWER UNITY_2020_3_OR_NEWER UNITY_5_4_OR_NEWER UNITY_5_6_OR_NEWER PASSTHROUGH_SUPPORTED" +./pre_commit_dotnet_format.sh "$@" diff --git a/pre_commit_dotnet_format.sh b/pre_commit_dotnet_format.sh new file mode 100755 index 0000000000..724ee4e03e --- /dev/null +++ b/pre_commit_dotnet_format.sh @@ -0,0 +1,95 @@ +#!/bin/bash +set -e + +# Check if the DEFINES environment variable is set +if [[ -z "$DEFINES" ]]; then + echo "Error: The DEFINES environment variable is not set." + exit 1 +fi + +# Convert the DEFINES environment variable into an array +IFS=', ' read -r -a defines <<< "$DEFINES" + +# Temporary marker to identify added lines +marker="### TEMP DEFINES ###" + +# Read the list of staged files from pre-commit +staged_files=("$@") + +# Check if we are running on macOS or Linux +if [[ "$(uname)" == "Darwin" ]]; then + SED_CMD="gsed" # Use gsed on macOS +else + SED_CMD="sed" # Use sed on Linux +fi + +# Process only staged files +echo "Processing staged files..." +for file in "${staged_files[@]}"; do + # Skip non-C# files + if [[ "$file" != *.cs ]]; then + continue + fi + + # Check if the file has a BOM (EF BB BF at the start of the file) using xxd + bom_present=false + bom_hex=$(xxd -p -l 3 "$file") + if [[ "$bom_hex" == "efbbbf" ]]; then + bom_present=true + fi + + # If BOM is present, remove it temporarily + if $bom_present; then + # Remove BOM bytes (first 3 bytes) using tail and save content to temporary file + tail -c +4 "$file" > "$file.tmp" && mv "$file.tmp" "$file" + fi + + # Add defines only if marker is not already present + if ! grep -q "$marker" "$file"; then + # Add each define line separately using sed to insert at the top + for define in "${defines[@]}"; do + $SED_CMD -i "1i\\#define $define" "$file" + done + # Insert marker to identify where defines were added + $SED_CMD -i "1i\\$marker" "$file" + fi + + # If BOM was present, reinsert it at the beginning of the file + if $bom_present; then + # Reinsert BOM at the start of the file + { echo -n -e '\xEF\xBB\xBF'; cat "$file"; } > "$file.tmp" && mv "$file.tmp" "$file" + fi +done + +# Run dotnet format +echo "Running dotnet format..." +dotnet format whitespace --folder --include "$@" + +# Remove only the added defines +echo "Removing temporary defines..." +for file in "${staged_files[@]}"; do + # Skip non-C# files + if [[ "$file" != *.cs ]]; then + continue + fi + + # Check if the file has a BOM (EF BB BF at the start of the file) using xxd + bom_present=false + bom_hex=$(xxd -p -l 3 "$file") + if [[ "$bom_hex" == "efbbbf" ]]; then + bom_present=true + fi + + # Use a temporary file to preserve BOM while modifying + tmp_file="$file.tmp" + # Remove the marker and added defines, ensuring the BOM stays intact + $SED_CMD "/$marker/,+${#defines[@]}d" "$file" > "$tmp_file" && mv "$tmp_file" "$file" + + # If BOM was present, reinsert it at the beginning of the file + if $bom_present; then + # Reinsert BOM at the start of the file + { echo -n -e '\xEF\xBB\xBF'; cat "$file"; } > "$file.tmp" && mv "$file.tmp" "$file" + fi +done + +echo "Pre-commit hook completed!"