diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 000000000..604a3dd70 --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,21 @@ +name: clang-format +on: [pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + clang-format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 2 + - name: Install clang-format + run: | + sudo apt-get update + sudo apt-get install -y clang-format-14 + - name: Run clang-format + run: | + ./run-clang-format.sh + git diff --exit-code diff --git a/.gitignore b/.gitignore index ec5401c38..ac767f114 100644 --- a/.gitignore +++ b/.gitignore @@ -452,3 +452,7 @@ _packages soh/src/boot/build.c soh/properties.h + +# Tools +/clang-format +/clang-format.exe diff --git a/run-clang-format.ps1 b/run-clang-format.ps1 new file mode 100644 index 000000000..6aaf12ea4 --- /dev/null +++ b/run-clang-format.ps1 @@ -0,0 +1,48 @@ +Using Namespace System +$url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.6/LLVM-14.0.6-win64.exe" +$llvmInstallerPath = ".\LLVM-14.0.6-win64.exe" +$clangFormatFilePath = ".\clang-format.exe" +$requiredVersion = "clang-format version 14.0.6" +$currentVersion = "" + +function Test-7ZipInstalled { + $sevenZipPath = "C:\Program Files\7-Zip\7z.exe" + return Test-Path $sevenZipPath -PathType Leaf +} + +if (Test-Path $clangFormatFilePath) { + $currentVersion = & $clangFormatFilePath --version + if (-not ($currentVersion -eq $requiredVersion)) { + # Delete the existing file if the version is incorrect + Remove-Item $clangFormatFilePath -Force + } +} + +if (-not (Test-Path $clangFormatFilePath) -or ($currentVersion -ne $requiredVersion)) { + if (-not (Test-7ZipInstalled)) { + Write-Host "7-Zip is not installed. Please install 7-Zip and run the script again." + exit + } + + $wc = New-Object net.webclient + $wc.Downloadfile($url, $llvmInstallerPath) + + $sevenZipPath = "C:\Program Files\7-Zip\7z.exe" + $specificFileInArchive = "bin\clang-format.exe" + & "$sevenZipPath" e $llvmInstallerPath $specificFileInArchive + + Remove-Item $llvmInstallerPath -Force +} + +$basePath = (Resolve-Path .).Path +$files = Get-ChildItem -Path $basePath\soh -Recurse -File ` + | Where-Object { ($_.Extension -eq '.c' -or $_.Extension -eq '.cpp' -or ` + ($_.Extension -eq '.h' -and ` + (-not ($_.FullName -like "*\soh\src\*" -or $_.FullName -like "*\soh\include\*")))) -and ` + (-not ($_.FullName -like "*\soh\assets\*")) } + +foreach ($file in $files) { + $relativePath = $file.FullName.Substring($basePath.Length + 1) + Write-Host "Formatting $relativePath" + .\clang-format.exe -i $file.FullName +} diff --git a/run-clang-format.sh b/run-clang-format.sh new file mode 100755 index 000000000..6f9fc0c80 --- /dev/null +++ b/run-clang-format.sh @@ -0,0 +1,29 @@ +# this line does quite a bit, so let's break it down +# +# find soh +# use "find" to look in the "soh" directory +# this ensures we don't try to format stuff in the submodules +# +# -type f +# only look for files +# +# -name "*.c" -o -name "*.cpp" +# find all .c and .cpp files +# +# -name "*.h" ! -path "soh/src/**.h" ! -path "soh/include/**.h" +# find all .h files that aren't in soh/src or soh/include +# this is because zret decomp only runs clang-format on c files +# https://github.com/zeldaret/mm/blob/b7e5468ca16315a7e322055eff3d97fe980bbc25/format.py#L182 +# +# ! -path "soh/assets/*" +# asset headers are autogenerated, don't fight them +# +# | sed 's| |\\ |g' +# pipe the result of find into sed to +# ensure all the paths returned by find have spaces escaped +# +# | xargs clang-format-14 -i +# use xargs to take each path we've found +# and pass it as an argument to clang-format + +find soh -type f \( -name "*.c" -o -name "*.cpp" -o \( -name "*.h" ! -path "soh/src/**.h" ! -path "soh/include/**.h" \) \) ! -path "soh/assets/*" | sed 's| |\\ |g' | xargs clang-format-14 -i