33
44Set-StrictMode - Off
55
6+ function Get-FileUri {
7+ param ([string ]$path )
8+
9+ $fullPath = [System.IO.Path ]::GetFullPath($path )
10+ $builder = New-Object System.UriBuilder
11+ $builder.Scheme = ' file'
12+ $builder.Host = ' '
13+ $builder.Path = $fullPath
14+ return $builder.Uri
15+ }
16+
17+ function Get-RelativeSolutionPath {
18+ param (
19+ [string ]$pathValue ,
20+ [string ]$sourceDir ,
21+ [string ]$targetDir
22+ )
23+
24+ if ([string ]::IsNullOrWhiteSpace($pathValue )) {
25+ return $pathValue
26+ }
27+
28+ $normalized = $pathValue.Replace (' /' , [System.IO.Path ]::DirectorySeparatorChar)
29+ $absolute = if ([System.IO.Path ]::IsPathRooted($normalized )) {
30+ [System.IO.Path ]::GetFullPath($normalized )
31+ }
32+ else {
33+ [System.IO.Path ]::GetFullPath((Join-Path $sourceDir $normalized ))
34+ }
35+
36+ $targetDirWithSep = if ($targetDir.EndsWith ([System.IO.Path ]::DirectorySeparatorChar)) {
37+ $targetDir
38+ }
39+ else {
40+ $targetDir + [System.IO.Path ]::DirectorySeparatorChar
41+ }
42+
43+ $targetUri = Get-FileUri - path $targetDirWithSep
44+ $absoluteUri = Get-FileUri - path $absolute
45+ $relative = $targetUri.MakeRelativeUri ($absoluteUri ).ToString()
46+ $relative = [System.Uri ]::UnescapeDataString($relative )
47+ return $relative.Replace (' \' , ' /' )
48+ }
49+
50+ function Update-PathAttributes {
51+ param (
52+ [xml ]$xml ,
53+ [string ]$sourceDir ,
54+ [string ]$targetDir
55+ )
56+
57+ $nodes = $xml.SelectNodes (" //Project[@Path] | //File[@Path]" )
58+ foreach ($node in $nodes ) {
59+ $attribute = $node.Attributes [" Path" ]
60+ if ($null -ne $attribute ) {
61+ $attribute.Value = Get-RelativeSolutionPath - pathValue $attribute.Value - sourceDir $sourceDir - targetDir $targetDir
62+ }
63+ }
64+ }
65+
66+ function Ensure-MauiTestsProject {
67+ param ([xml ]$xml )
68+
69+ $testsFolder = $xml.SelectSingleNode (" //Folder[@Name='/tests/Hosting/']" )
70+ if ($null -eq $testsFolder ) {
71+ return
72+ }
73+
74+ $desiredPath = " tests/Aspire.Hosting.Maui.Tests/Aspire.Hosting.Maui.Tests.csproj"
75+ if ($null -ne $testsFolder.SelectSingleNode (" Project[@Path='$desiredPath ']" )) {
76+ return
77+ }
78+
79+ $projectNode = $xml.CreateElement (" Project" )
80+ $pathAttribute = $xml.CreateAttribute (" Path" )
81+ $pathAttribute.Value = $desiredPath
82+ $projectNode.Attributes.Append ($pathAttribute ) | Out-Null
83+
84+ $inserted = $false
85+ $projectNodes = $testsFolder.SelectNodes (" Project" )
86+ foreach ($existing in $projectNodes ) {
87+ if ([string ]::Compare($desiredPath , $existing.Attributes [" Path" ].Value, $true ) -lt 0 ) {
88+ $testsFolder.InsertBefore ($projectNode , $existing ) | Out-Null
89+ $inserted = $true
90+ break
91+ }
92+ }
93+
94+ if (-not $inserted ) {
95+ $testsFolder.AppendChild ($projectNode ) | Out-Null
96+ }
97+ }
98+
99+ function Add-MauiFolder {
100+ param (
101+ [xml ]$xml ,
102+ [System.Xml.XmlElement ]$solutionElement
103+ )
104+
105+ if ($null -ne $solutionElement.SelectSingleNode (" Folder[@Name='/playground/AspireWithMaui/']" )) {
106+ return
107+ }
108+
109+ $mauiFolderXml = @"
110+ <Folder Name="/playground/AspireWithMaui/">
111+ <Project Path="playground/AspireWithMaui/AspireWithMaui.AppHost/AspireWithMaui.AppHost.csproj" />
112+ <Project Path="playground/AspireWithMaui/AspireWithMaui.MauiClient/AspireWithMaui.MauiClient.csproj" />
113+ <Project Path="playground/AspireWithMaui/AspireWithMaui.MauiServiceDefaults/AspireWithMaui.MauiServiceDefaults.csproj" />
114+ <Project Path="playground/AspireWithMaui/AspireWithMaui.ServiceDefaults/AspireWithMaui.ServiceDefaults.csproj" />
115+ <Project Path="playground/AspireWithMaui/AspireWithMaui.WeatherApi/AspireWithMaui.WeatherApi.csproj" />
116+ </Folder>
117+ "@
118+
119+ $tempDoc = [xml ]" <root>$mauiFolderXml </root>"
120+ $mauiNode = $tempDoc.DocumentElement.FirstChild
121+ $importedNode = $xml.ImportNode ($mauiNode , $true )
122+ $solutionElement.AppendChild ($importedNode ) | Out-Null
123+ }
124+
6125if ($restoreMaui ) {
7126 $isWindowsOrMac = ($IsWindows -or $IsMacOS -or (-not (Get-Variable - Name IsWindows - ErrorAction SilentlyContinue)))
8-
127+
9128 if ($isWindowsOrMac ) {
10129 Write-Host " Installing MAUI workload..."
11-
130+
12131 $dotnetCmd = if ($IsWindows -or (-not (Get-Variable - Name IsWindows - ErrorAction SilentlyContinue))) {
13132 Join-Path $RepoRoot " dotnet.cmd"
14- } else {
133+ }
134+ else {
15135 Join-Path $RepoRoot " dotnet.sh"
16136 }
17-
137+
18138 & $dotnetCmd workload install maui 2>&1 | Out-Host
19139 if ($LASTEXITCODE -ne 0 ) {
20140 Write-Host " "
@@ -32,53 +152,47 @@ if ($restoreMaui) {
32152 else {
33153 Write-Host " Skipping MAUI workload installation on Linux (not supported)."
34154 }
35-
155+
36156 # Generate AspireWithMaui.slnx from the base Aspire.slnx
37157 Write-Host " Generating AspireWithMaui.slnx..."
38158 $sourceSlnx = Join-Path $RepoRoot " Aspire.slnx"
39159 $outputPath = Join-Path $RepoRoot " playground/AspireWithMaui"
40160 $outputSlnx = Join-Path $outputPath " AspireWithMaui.slnx"
41-
161+
42162 if (-not (Test-Path $sourceSlnx )) {
43163 Write-Warning " Source solution file not found: $sourceSlnx "
44- } else {
45- # Read and parse the source XML
164+ }
165+ else {
166+ if (-not (Test-Path $outputPath )) {
167+ New-Item - ItemType Directory - Force - Path $outputPath | Out-Null
168+ }
169+
46170 [xml ]$xml = Get-Content $sourceSlnx
47171 $solutionElement = $xml.DocumentElement
48-
49- # Create the Maui folder element
50- $mauiFolderXml = @"
51- <Folder Name="/playground/AspireWithMaui/">
52- <Project Path="playground/AspireWithMaui/AspireWithMaui.AppHost/AspireWithMaui.AppHost.csproj" />
53- <Project Path="playground/AspireWithMaui/AspireWithMaui.MauiClient/AspireWithMaui.MauiClient.csproj" />
54- <Project Path="playground/AspireWithMaui/AspireWithMaui.MauiServiceDefaults/AspireWithMaui.MauiServiceDefaults.csproj" />
55- <Project Path="playground/AspireWithMaui/AspireWithMaui.ServiceDefaults/AspireWithMaui.ServiceDefaults.csproj" />
56- <Project Path="playground/AspireWithMaui/AspireWithMaui.WeatherApi/AspireWithMaui.WeatherApi.csproj" />
57- </Folder>
58- "@
59-
60- # Parse the Maui folder element
61- $tempDoc = [xml ]" <root>$mauiFolderXml </root>"
62- $mauiNode = $tempDoc.DocumentElement.FirstChild
63- $importedNode = $xml.ImportNode ($mauiNode , $true )
64- $solutionElement.AppendChild ($importedNode ) | Out-Null
65-
66- # Write the XML with proper formatting
172+
173+ Add-MauiFolder - xml $xml - solutionElement $solutionElement
174+ Ensure- MauiTestsProject - xml $xml
175+
176+ $sourceDir = Split-Path $sourceSlnx - Parent
177+ $targetDir = Split-Path $outputSlnx - Parent
178+ Update-PathAttributes - xml $xml - sourceDir $sourceDir - targetDir $targetDir
179+
67180 $settings = New-Object System.Xml.XmlWriterSettings
68181 $settings.Indent = $true
69182 $settings.IndentChars = " "
70183 $settings.NewLineChars = [System.Environment ]::NewLine
71184 $settings.NewLineHandling = [System.Xml.NewLineHandling ]::Replace
72185 $settings.OmitXmlDeclaration = $true
73-
186+ $settings.Encoding = New-Object System.Text.UTF8Encoding($true )
187+
74188 $writer = [System.Xml.XmlWriter ]::Create($outputSlnx , $settings )
75189 try {
76190 $xml.WriteTo ($writer )
77191 }
78192 finally {
79193 $writer.Dispose ()
80194 }
81-
195+
82196 Write-Host " Generated AspireWithMaui.slnx at: $outputSlnx "
83197 }
84198}
0 commit comments