Skip to content

Commit 1ff1a90

Browse files
Extract dependency ordering helper script
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 73081a2 commit 1ff1a90

2 files changed

Lines changed: 98 additions & 99 deletions

File tree

.github/actions/Build-PSModule/src/helpers/Build/Add-ContentFromItem.ps1

Lines changed: 0 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,3 @@
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-
1001
function Add-ContentFromItem {
1012
<#
1023
.SYNOPSIS
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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+
}

0 commit comments

Comments
 (0)