WSL/tools/FormatSource.ps1.in
WSL Team 697572d664 Initial open source commit for WSL.
Many Microsoft employees have contributed to the Windows Subsystem for Linux, this commit is the result of their work since 2016.

The entire history of the Windows Subsystem for Linux can't be shared here, but here's an overview of WSL's history after it moved to it own repository in 2021:

Number of commits on the main branch: 2930
Number of contributors: 31

Head over https://github.com/microsoft/WSL/releases for a more detailed history of the features added to WSL since 2021.
2025-05-15 12:09:45 -07:00

231 lines
7.8 KiB
PowerShell

<#
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root for license information.
this file work is a derivative of https://github.com/microsoft/MixedReality-GraphicsTools-Unreal/blob/main/Tools/scripts/Common.psm1
#>
<#
.SYNOPSIS
Run clang-format on all source files.
.PARAMETER Path
Path to the directory (or file) to be processed recursively. By default scans the entire repo.
.PARAMETER ClangFormat
Path to clang-format executable, e.g. "C:\Tools\clang-format.exe"
.PARAMETER ModifiedOnly
Scan only files modified in current git checkout.
.PARAMETER Staged
Check only files staged for commit
.PARAMETER ChangesFile
Scan only files listed in provided txt file (one path per line). Paths need to be relative to repo root.
.PARAMETER Verify
Whether to fail if files are not formatted (instead of applying changes).
.PARAMETER NoFail
Do not set RC=1 when errors found, i.e. only report errors in output.
#>
[CmdletBinding()]
param (
[string]$Path = $null,
[boolean]$DefaultPackagesConfig = $false,
[string]$ClangFormat = $null,
[boolean]$ModifiedOnly = $True,
[boolean]$Staged = $false,
[string]$ChangesFile = $null,
[boolean]$Verify = $false,
[boolean]$NoFail = $false
)
# Only check source files
$FilePatterns = "\.(h|cpp|hpp|c|hxx)$"
$IgnoreFolders = "(out|.git|.vs|.vscode|bin|CMakeFiles|generated|debug|x64|packages|_deps)$"
$RepoRoot = (Resolve-Path "$PSScriptRoot")
<#
.SYNOPSIS
Given the path to the list of raw git changes, returns an array of
those changes rooted in the git root directory.
.DESCRIPTION
For example, the raw git changes will contain lines like:
Assets/File.cs
This function will return a list of paths that look like (assuming
that RepoRoot is C:\repo):
C:\repo\Assets\File.cs
#>
function GetChangedFiles {
[CmdletBinding()]
param(
[string]$Filename,
[string]$RepoRoot
)
process {
$rawContent = Get-Content -Path $Filename
$processedContent = @()
foreach ($line in $rawContent) {
$joinedPath = Join-Path -Path $RepoRoot -ChildPath $line
$processedContent += $joinedPath
}
$processedContent
}
}
if ([string]::IsNullOrEmpty($Path)) {
$Path = $RepoRoot
}
$ModifiedFiles = $null
if ($ChangesFile) {
if (-not (Test-Path -Path $ChangesFile -PathType Leaf)) {
Write-Host -ForegroundColor Red "ChangesFile not found: $ChangesFile"
Write-Host "Checking all source files"
}
else {
$ModifiedFiles = GetChangedFiles -Filename $ChangesFile -RepoRoot $RepoRoot
if (($null -eq $ModifiedFiles) -or ($ModifiedFiles.Count -eq 0)) {
Write-Host -ForegroundColor Green "No modified files to format."
exit 0
}
}
}
elseif ($ModifiedOnly -or $Staged) {
$ModifiedFiles = @()
Push-Location -Path $RepoRoot
$Success = $False
try {
if ($Staged) {
$Status = (& git diff-index --cached --name-only HEAD)
$Success = ($LASTEXITCODE -eq 0)
$Status | ForEach-Object {
$FullPath = Resolve-Path $_ -ErrorAction SilentlyContinue
$FileName = Split-Path -Leaf -Path $FullPath
if ($FileName -match $FilePatterns) {
$ModifiedFiles += $FullPath
}
}
}
else {
$Status = (& git status --porcelain)
$Success = ($LASTEXITCODE -eq 0)
$Status | ForEach-Object {
$FullPath = (Resolve-Path ($_.Trim() -split " ", 2)[-1] -ErrorAction SilentlyContinue)
$FileName = Split-Path -Leaf -Path $FullPath
if ($FileName -match $FilePatterns) {
$ModifiedFiles += $FullPath
}
}
}
}
catch {
# empty
}
if (-not $Success) {
Write-Host -ForegroundColor Red "Could not get the list of modified files. Check if git is configured correctly."
exit 1
}
Pop-Location
if (($null -eq $ModifiedFiles) -or ($ModifiedFiles.Count -eq 0)) {
Write-Host -ForegroundColor Green "No modified files to format."
exit 0
}
}
$ClangFormat = "${LLVM_INSTALL_DIR}/clang-format.exe"
if (-not (Test-Path -Type Leaf -Path $ClangFormat)) {
# The artifact directory is only known by cmake. Let cmake drop a link/copy where we can find it.
$ClangFormat = "$PSScriptRoot\clang-format.exe"
}
if (-not (Test-Path -Type Leaf -Path $ClangFormat)) {
Write-Host -ForegroundColor Red "clang-format.exe not found, use cmake to grab llvm package or specify directly with -ClangFormat"
exit 1
}
function Format-Directory {
[CmdletBinding()]
param (
[Parameter(Mandatory = $True)]
[string]$Path,
[Parameter(Mandatory = $True)]
[string]$ClangFormat,
[string]$RepoRoot = $null,
[AllowEmptyString()][string]$FilePatterns = $null,
[string[]]$ModifiedFiles = $null,
[boolean]$Verify = $false
)
process {
if (-not (Test-Path -Path $Path)) {
Write-Host -ForegroundColor Red "Item not found: $Path"
return $False
}
if ($null -eq $FilePatterns) {
$FilePatterns = ""
}
$Path = Resolve-Path $Path
$Success = $True
$FilesToFormat = @()
if ((Get-Item -Path $Path) -is [System.IO.DirectoryInfo]) {
Get-ChildItem -Path $Path -File `
| Where-Object { $_ -match $FilePatterns } `
| ForEach-Object {
$FilePath = "$Path\$_"
if (($null -eq $ModifiedFiles) -or ($ModifiedFiles -contains $FilePath)) {
if (!($FilePath -match "Intermediate")) {
$FilesToFormat += $FilePath
}
}
}
Get-ChildItem -Path $Path -Directory `
| Where-Object { $_ -notmatch $IgnoreFolders } `
| ForEach-Object {
$SubResult = (Format-Directory -Path "$Path\$_" `
-ClangFormat $ClangFormat `
-RepoRoot $RepoRoot `
-FilePatterns $FilePatterns `
-ModifiedFiles $ModifiedFiles `
-Verify $Verify)
$Success = $SubResult -and $Success
}
}
else {
$FilesToFormat += $Path
}
$FilesToFormat | ForEach-Object {
if ($Verify) {
Write-Host "[clang-format] Checking formatting: $_"
& $ClangFormat --style=file -Werror --dry-run $_
}
else {
Write-Host "[clang-format] Formatting $_"
& $ClangFormat --style=file -Werror -i $_
}
$Success = (0 -eq $LASTEXITCODE) -and $Success
}
return $Success
}
}
$Success = (Format-Directory -Path $Path `
-ClangFormat $ClangFormat `
-FilePatterns $FilePatterns `
-ModifiedFiles $ModifiedFiles `
-RepoRoot $RepoRoot `
-Verify $Verify)
if ($Success) {
Write-Host "Done."
exit 0
}
else {
Write-Host -ForegroundColor Red "Errors found (see output). Please make sure to resolve all issues before opening a Pull Request."
Write-Host -ForegroundColor Red "Formatting can be applied by running:"
Write-Host -ForegroundColor Red " powershell $PSCommandPath -ModifiedOnly ```$false [-Path <path to file or directory>]"
if ($NoFail) {
exit 0 # do not prevent commit when used in pre-commit hook
}
exit 1
}