|
1 | | -function Get-DependencyOrderedScriptFiles { |
2 | | - [OutputType([System.IO.FileInfo[]])] |
3 | | - [CmdletBinding()] |
4 | | - param( |
5 | | - [Parameter(Mandatory)] |
6 | | - [System.IO.FileInfo[]] $Files |
7 | | - ) |
8 | | - |
9 | | - $sortedFiles = $Files | Sort-Object -Property FullName |
10 | | - if ($sortedFiles.Count -le 1) { |
11 | | - return $sortedFiles |
12 | | - } |
13 | | - |
14 | | - $metadataByPath = @{} |
15 | | - $typeToPath = @{} |
16 | | - $duplicateTypes = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) |
17 | | - |
18 | | - foreach ($file in $sortedFiles) { |
19 | | - $content = Get-Content -Path $file.FullName -Raw |
20 | | - $declaredTypes = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) |
21 | | - [Regex]::Matches($content, '(?im)^\s*(class|enum)\s+([^\s:{]+)') | ForEach-Object { |
22 | | - [void] $declaredTypes.Add($_.Groups[2].Value) |
23 | | - } |
24 | | - |
25 | | - $metadataByPath[$file.FullName] = [pscustomobject]@{ |
26 | | - File = $file |
27 | | - Content = $content |
28 | | - DeclaredTypes = $declaredTypes |
29 | | - } |
30 | | - |
31 | | - foreach ($typeName in $declaredTypes) { |
32 | | - if ($typeToPath.ContainsKey($typeName)) { |
33 | | - [void]$duplicateTypes.Add($typeName) |
34 | | - continue |
35 | | - } |
36 | | - |
37 | | - $typeToPath[$typeName] = $file.FullName |
38 | | - } |
39 | | - } |
40 | | - |
41 | | - $dependenciesByPath = @{} |
42 | | - $dependentsByPath = @{} |
43 | | - foreach ($file in $sortedFiles) { |
44 | | - $dependenciesByPath[$file.FullName] = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) |
45 | | - $dependentsByPath[$file.FullName] = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) |
46 | | - } |
47 | | - |
48 | | - foreach ($metadata in $metadataByPath.Values) { |
49 | | - foreach ($typeName in $typeToPath.Keys) { |
50 | | - if ($duplicateTypes.Contains($typeName)) { |
51 | | - continue |
52 | | - } |
53 | | - |
54 | | - if ($metadata.DeclaredTypes.Contains($typeName)) { |
55 | | - continue |
56 | | - } |
57 | | - |
58 | | - $typePattern = "(?<![\w\.])\[$([Regex]::Escape($typeName))\](?![\w\.])" |
59 | | - if ([Regex]::IsMatch($metadata.Content, $typePattern, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)) { |
60 | | - $dependencyPath = $typeToPath[$typeName] |
61 | | - [void]$dependenciesByPath[$metadata.File.FullName].Add($dependencyPath) |
62 | | - [void]$dependentsByPath[$dependencyPath].Add($metadata.File.FullName) |
63 | | - } |
64 | | - } |
65 | | - } |
66 | | - |
67 | | - $remainingPaths = @($sortedFiles.FullName) |
68 | | - $ready = @( |
69 | | - $remainingPaths | |
70 | | - Where-Object { $dependenciesByPath[$_].Count -eq 0 } | |
71 | | - Sort-Object |
72 | | - ) |
73 | | - $orderedPaths = [System.Collections.Generic.List[string]]::new() |
74 | | - |
75 | | - while ($ready.Count -gt 0) { |
76 | | - $currentPath = $ready[0] |
77 | | - $ready = @($ready | Select-Object -Skip 1) |
78 | | - $orderedPaths.Add($currentPath) |
79 | | - $remainingPaths = @($remainingPaths | Where-Object { $_ -ne $currentPath }) |
80 | | - |
81 | | - $dependents = @($dependentsByPath[$currentPath] | Sort-Object) |
82 | | - foreach ($dependentPath in $dependents) { |
83 | | - $null = $dependenciesByPath[$dependentPath].Remove($currentPath) |
84 | | - if ($dependenciesByPath[$dependentPath].Count -eq 0) { |
85 | | - $ready = @($ready + $dependentPath | Sort-Object -Unique) |
86 | | - } |
87 | | - } |
88 | | - } |
89 | | - |
90 | | - if ($orderedPaths.Count -lt $sortedFiles.Count) { |
91 | | - Write-Warning "Detected cyclical or unresolved class/enum dependencies. Falling back to lexical order for remaining files in [$($sortedFiles[0].DirectoryName)]." |
92 | | - $remainingPaths | Sort-Object | ForEach-Object { |
93 | | - $orderedPaths.Add($_) |
94 | | - } |
95 | | - } |
96 | | - |
97 | | - return @($orderedPaths | ForEach-Object { $metadataByPath[$_].File }) |
98 | | -} |
99 | | - |
100 | 1 | function Add-ContentFromItem { |
101 | 2 | <# |
102 | 3 | .SYNOPSIS |
|
0 commit comments