functions/common/Get-FilteredFiles.ps1
function Get-FilteredFiles { <# .SYNOPSIS Filtert eine Liste von Dateien basierend auf einer Exclude-JSON-Datei. .DESCRIPTION Diese Funktion nimmt eine Liste von Dateien entgegen und entfernt alle Dateien, die entweder explizit in der `exclude-files.json` aufgeführt sind oder sich in dort aufgeführten Unterverzeichnissen befinden. Die Einträge in der JSON-Datei müssen relativ zum Wurzelverzeichnis (`RootPath`) angegeben sein. .PARAMETER Files Ein Array von `System.IO.FileInfo`-Objekten, das die zu überprüfenden Dateien enthält. .PARAMETER ExcludeListFile Pfad zur JSON-Datei, die auszuschließende Dateien und Verzeichnisse enthält. .PARAMETER RootPath Optional: Das Wurzelverzeichnis, relativ zu dem die Ausschlüsse interpretiert werden. Falls nicht angegeben, wird versucht, es aus den angegebenen Dateien automatisch zu ermitteln. .EXAMPLE $files = Get-ChildItem -Recurse -File -Path "src" $filtered = Get-FilteredFiles -Files $files -ExcludeListFile "./exclude-files.json" -RootPath "src" Filtert alle Dateien unterhalb von `src`, die in der JSON-Exclude-Liste stehen. .EXAMPLE # exclude-files.json [ "temp/TestFile.ps1", "generated/", "legacy/utils/OldFunction.ps1" ] Die Datei `temp/TestFile.ps1` und `legacy/utils/OldFunction.ps1` werden ausgeschlossen. Zusätzlich wird der gesamte Ordner `generated/` samt Inhalt ignoriert. .OUTPUTS System.IO.FileInfo[] Eine Liste der übrig gebliebenen Dateien nach Anwendung der Ausschlussregeln. .NOTES Dateieinträge in der Exclude-Datei verwenden Schrägstriche (`/`) und sind relativ zum `RootPath`. Ein Schrägstrich am Ende eines Eintrags (`"pfad/zum/ordner/"`) kennzeichnet ein Verzeichnis. Dateinamen verwenden innerhalb des Skripts intern Backslashes (`\`) für Pfadvergleiche. #> param( [Parameter(Mandatory)][System.IO.FileInfo[]] $Files, [Parameter(Mandatory)][string] $ExcludeListFile, [string] $RootPath = $null ) # Wenn kein RootPath angegeben ist, versuche ihn aus den Files abzuleiten if (-not $RootPath) { # Einfachster Ansatz: gemeinsamer Root der Dateien finden $paths = $Files | ForEach-Object { $_.DirectoryName } $RootPath = Get-CommonRootPath -Paths $paths if (-not $RootPath) { throw "RootPath konnte nicht bestimmt werden. Bitte als Parameter übergeben." } } $RootPath = (Resolve-Path $RootPath).Path.TrimEnd('\','/') # Exclude-Liste laden $excludeEntries = @() if (Test-Path $ExcludeListFile) { try { $excludeEntries = Get-Content $ExcludeListFile | ConvertFrom-Json } catch { Write-Warning "Exclude-Datei konnte nicht gelesen werden: $ExcludeListFile" } } # Dateien und Ordner aus der Exclude-Liste trennen $excludeFilesRelative = @() $excludeDirsRelative = @() foreach ($entry in $excludeEntries) { if ($entry.EndsWith('/')) { $excludeDirsRelative += $entry.TrimEnd('/') } else { $excludeFilesRelative += $entry -Replace '/', '\' } } # Hilfsfunktion um relativen Pfad zu bekommen function Get-RelativePath { param ( [string]$fullPath, [string]$basePath ) # Normiere beide Pfade (Backslashes, kein abschließender Slash) $normFull = [IO.Path]::GetFullPath($fullPath).TrimEnd('\','/') $normBase = [IO.Path]::GetFullPath($basePath).TrimEnd('\','/') + '\' if ($normFull.StartsWith($normBase, [System.StringComparison]::OrdinalIgnoreCase)) { return $normFull.Substring($normBase.Length) } else { throw "Pfad '$fullPath' liegt nicht im Basisverzeichnis '$basePath'." } } $filteredFiles = foreach ($file in $Files) { # relativer Pfad zur Root (mit Backslashes) $relPath = Get-RelativePath -fullPath $file.FullName -basePath $RootPath # Prüfe, ob Datei explizit in excludeFiles ist (relativ) if ($excludeFilesRelative -contains $relPath) { continue } # Prüfe, ob Datei in einem ausgeschlossenen Verzeichnis liegt $inExcludedDir = $false foreach ($exDir in $excludeDirsRelative) { if ($relPath.StartsWith($exDir + '\')) { $inExcludedDir = $true break } } if (-not $inExcludedDir) { $file } } return $filteredFiles } |