Skip to content

Commit 2547f8a

Browse files
authored
Merge pull request #288 from CommunityToolkit/refactor/multitarget/scripts/check-component-support
Refactor MultiTarget scripts for checking component support
2 parents 26b8832 + a14c549 commit 2547f8a

File tree

4 files changed

+218
-59
lines changed

4 files changed

+218
-59
lines changed

Build-Toolkit-Components.ps1

Lines changed: 12 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,6 @@ $MultiTargets = $MultiTargets | Where-Object { $_ -notin $ExcludeMultiTargets }
121121

122122
Write-Output "Building components '$Components' for MultiTargets: $MultiTargets"
123123

124-
if ($Components -eq @('all')) {
125-
$Components = @('**')
126-
}
127-
128124
if ($ExcludeComponents) {
129125
$Components = $Components | Where-Object { $_ -notin $ExcludeComponents }
130126
}
@@ -212,14 +208,9 @@ function Invoke-MSBuildWithBinlog {
212208
}
213209
}
214210

215-
# List of WinUI-0 (non-WinUI) compatible multitargets
216-
$WinUI0MultiTargets = @('netstandard')
217-
218-
# List of WinUI-2 compatible multitargets
219-
$WinUI2MultiTargets = @('uwp', 'wasm', 'wpf', 'linuxgtk', 'macos', 'ios', 'android')
220-
221-
# List of WinUI-3 compatible multitargets
222-
$WinUI3MultiTargets = @('wasdk', 'wasm', 'wpf', 'linuxgtk', 'macos', 'ios', 'android')
211+
if ($Components -eq @('all')) {
212+
$Components = @('**')
213+
}
223214

224215
# Components are built individually
225216
foreach ($ComponentName in $Components) {
@@ -236,59 +227,22 @@ foreach ($ComponentName in $Components) {
236227
# Get supported MultiTarget for this component
237228
$supportedMultiTargets = & $PSScriptRoot\MultiTarget\Get-MultiTargets.ps1 -component $componentName
238229

239-
# If WinUI 0 is requested, the component must not support WinUI 2 or WinUI 3 to be built.
240-
# If WinUI 2 or 3 is requested, the component have a target that supports WinUI 2 or 3 to be built.
241-
$isWinUI0Supported = $false
242-
$isWinUI2Supported = $false
243-
$isWinUI3Supported = $false
244-
245-
# Flag to check if any of the requested targets are supported by the component
246-
$isRequestedTargetSupported = $false
247-
248-
foreach ($requestedTarget in $MultiTargets) {
249-
if ($false -eq $isRequestedTargetSupported) {
250-
$isRequestedTargetSupported = $requestedTarget -in $supportedMultiTargets
251-
}
252-
}
253-
254-
foreach ($supportedMultiTarget in $supportedMultiTargets) {
255-
# Only build components that support WinUI 2
256-
if ($false -eq $isWinUI2Supported) {
257-
$isWinUI2Supported = $supportedMultiTarget -in $WinUI2MultiTargets;
258-
}
259-
260-
# Only build components that support WinUI 3
261-
if ($false -eq $isWinUI3Supported) {
262-
$isWinUI3Supported = $supportedMultiTarget -in $WinUI3MultiTargets;
263-
}
264-
265-
# Build components that support neither WinUI 2 nor WinUI 3 (e.g. netstandard only)
266-
if ($false -eq $isWinUI0Supported) {
267-
$isWinUI0Supported = $supportedMultiTarget -in $WinUI0MultiTargets -and -not ($isWinUI2Supported -or $isWinUI3Supported);
268-
}
269-
}
270-
271-
# If none of the requested targets are supported by the component, we can skip build to save time and avoid errors.
272-
if (-not $isRequestedTargetSupported) {
273-
Write-Warning "Skipping $componentName, none of the requested MultiTargets '$MultiTargets' are enabled for this component."
274-
continue
275-
}
276-
277-
if (-not $isWinUI0Supported -and $WinUIMajorVersion -eq 0) {
278-
Write-Warning "Skipping $componentName. WinUI is disabled and one of the supported MultiTargets '$supportedMultiTargets' supports WinUI."
279-
continue;
280-
}
281-
282-
if ((-not $isWinUI2Supported -and $WinUIMajorVersion -eq 2) -or (-not $isWinUI3Supported -and $WinUIMajorVersion -eq 3)) {
283-
Write-Warning "Skipping $componentName. WinUI $WinUIMajorVersion is enabled and not supported by any of the MultiTargets '$supportedMultiTargets'"
230+
$shouldBuild = & $PSScriptRoot\MultiTarget\Test-Component-Support.ps1 `
231+
-RequestedMultiTargets $MultiTargets `
232+
-SupportedMultiTargets $supportedMultiTargets `
233+
-Component $componentName `
234+
-WinUIMajorVersion $WinUIMajorVersion
235+
236+
if (-not $shouldBuild.IsSupported) {
237+
Write-Warning "Skipping $componentName. $($shouldBuild.Reason)"
284238
continue
285239
}
286240

287241
# Filter ExcludeMultiTargets out of supportedMultiTargets
288242
# For display purposes only. The actual build uses the EnabledMultiTargets.props + EnabledTargetFrameworks.props to calculate supported targets at build time.
289243
$supportedMultiTargets = $supportedMultiTargets | Where-Object { $_ -notin $ExcludeMultiTargets }
290-
291244
Write-Output "Building $componentName for MultiTargets '$supportedMultiTargets'"
245+
292246
Invoke-MSBuildWithBinlog $componentCsproj.FullName $EnableBinLogs $BinlogOutput
293247
}
294248
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<#
2+
.SYNOPSIS
3+
Given a list of components, filters them based on their support for the specified MultiTarget TFM(s) and WinUI major version.
4+
5+
.DESCRIPTION
6+
This script checks each component to determine if it supports the specified MultiTarget TFM(s) and WinUI major version.
7+
It returns a list of components that are supported for the given parameters.
8+
9+
.PARAMETER MultiTargets
10+
Specifies the MultiTarget TFM(s) to include for building the components.
11+
12+
.PARAMETER WinUIMajorVersion
13+
Specifies the WinUI major version to use when building for Uno. Also decides the package id and dependency variant.
14+
15+
.NOTES
16+
Author: Arlo Godfrey
17+
Date: 6/6/2025
18+
#>
19+
Param (
20+
[ValidateSet('all', 'wasm', 'uwp', 'wasdk', 'wpf', 'linuxgtk', 'macos', 'ios', 'android', 'netstandard')]
21+
[Alias("mt")]
22+
[Parameter(Mandatory=$true)]
23+
[string[]]$MultiTargets,
24+
25+
[Alias("c")]
26+
[Parameter(Mandatory=$true)]
27+
[string[]]$Components,
28+
29+
[Alias("winui")]
30+
[Parameter(Mandatory=$true)]
31+
[int]$WinUIMajorVersion
32+
)
33+
34+
if ($MultiTargets -eq 'all') {
35+
$MultiTargets = @('wasm', 'uwp', 'wasdk', 'wpf', 'linuxgtk', 'macos', 'ios', 'android', 'netstandard')
36+
}
37+
38+
$supportedComponents = @();
39+
40+
if ($Components -eq @('all')) {
41+
$Components = @('**')
42+
}
43+
44+
foreach ($ComponentName in $Components) {
45+
# Find all components source csproj (when wildcard), or find specific component csproj by name.
46+
$path = "$PSScriptRoot/../../components/$ComponentName/src/*.csproj"
47+
48+
foreach ($componentCsproj in Get-ChildItem -Path $path) {
49+
# Get component name from csproj path
50+
$componentPath = Get-Item "$componentCsproj/../../"
51+
$componentName = $($componentPath.BaseName);
52+
53+
# Get supported MultiTarget for this component
54+
$supportedMultiTargets = & $PSScriptRoot\Get-MultiTargets.ps1 -component $componentName
55+
56+
$componentSupportResult = & $PSScriptRoot\Test-Component-Support.ps1 `
57+
-RequestedMultiTargets $MultiTargets `
58+
-SupportedMultiTargets $supportedMultiTargets `
59+
-Component $componentName `
60+
-WinUIMajorVersion $WinUIMajorVersion
61+
62+
if ($componentSupportResult.IsSupported -eq $true) {
63+
$supportedComponents += $componentName
64+
}
65+
}
66+
}
67+
68+
69+
return $supportedComponents;

MultiTarget/Get-MultiTargets.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@ if ($null -eq $regex -or $null -eq $regex.Matches -or $null -eq $regex.Matches.G
5050
}
5151

5252
$multiTargets = $regex.Matches.Groups[1].Value;
53-
return $multiTargets.Split(';');
53+
return $multiTargets.Split(';') | Where-Object { $_ -ne '' };
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<#
2+
.SYNOPSIS
3+
Tests WinUI support for a specific component and its requested MultiTargets.
4+
5+
.DESCRIPTION
6+
This script tests WinUI support for a specific component and its requested MultiTargets. It checks if the requested MultiTargets are supported by the component and if the WinUI version is compatible.
7+
8+
.PARAMETER SupportedMultiTargets
9+
Specifies known supported MultiTargets for the given component. Is retrieved if not specified.
10+
11+
.PARAMETER RequestedMultiTargets
12+
Specifies the MultiTarget TFM(s) to include for building the components. The default value is 'all'. If not specified, it will use the supported MultiTargets.
13+
14+
.PARAMETER Component
15+
Specifies the names of the components to build. Defaults to all components.
16+
17+
.PARAMETER WinUIMajorVersion
18+
Specifies the WinUI major version to use when building for Uno. Also decides the package id and dependency variant.
19+
20+
.EXAMPLE
21+
Test-Component-Support -RequestedMultiTargets 'uwp', 'wasm' -Component 'MarkdownTextBlock' -WinUIMajorVersion 2
22+
23+
Tests if the 'MarkdownTextBlock' component supports the 'uwp' and 'wasm' target frameworks with WinUI 2. Returns an object indicating if the component is supported and the reason if not.
24+
25+
.EXAMPLE
26+
Test-Component-Support -SupportedMultiTargets 'uwp', 'wasm', 'wasdk' -RequestedMultiTargets 'all' -Component 'DataTable' -WinUIMajorVersion 3
27+
28+
Tests if the 'DataTable' component supports all target frameworks with WinUI 3, using the explicitly provided supported MultiTargets instead of retrieving them.
29+
30+
.NOTES
31+
Author: Arlo Godfrey
32+
Date: 6/6/2025
33+
#>
34+
Param (
35+
[ValidateSet('wasm', 'uwp', 'wasdk', 'wpf', 'linuxgtk', 'macos', 'ios', 'android', 'netstandard')]
36+
[Alias("smt")]
37+
[string[]]$SupportedMultiTargets,
38+
39+
[ValidateSet('all', 'wasm', 'uwp', 'wasdk', 'wpf', 'linuxgtk', 'macos', 'ios', 'android', 'netstandard')]
40+
[Alias("rmt")]
41+
[Parameter(Mandatory=$true)]
42+
[string[]]$RequestedMultiTargets,
43+
44+
[Alias("c")]
45+
[Parameter(Mandatory=$true)]
46+
[string]$Component,
47+
48+
[Alias("winui")]
49+
[Parameter(Mandatory=$true)]
50+
[int]$WinUIMajorVersion
51+
)
52+
53+
if ($RequestedMultiTargets -eq 'all') {
54+
$RequestedMultiTargets = @('wasm', 'uwp', 'wasdk', 'wpf', 'linuxgtk', 'macos', 'ios', 'android', 'netstandard')
55+
}
56+
57+
# List of WinUI-0 (non-WinUI) compatible multitargets
58+
$WinUI0MultiTargets = @('netstandard')
59+
60+
# List of WinUI-2 compatible multitargets
61+
$WinUI2MultiTargets = @('uwp', 'wasm', 'wpf', 'linuxgtk', 'macos', 'ios', 'android')
62+
63+
# List of WinUI-3 compatible multitargets
64+
$WinUI3MultiTargets = @('wasdk', 'wasm', 'wpf', 'linuxgtk', 'macos', 'ios', 'android')
65+
66+
# If WinUI 0 is requested, the component must not support WinUI 2 or WinUI 3 to be built.
67+
# If WinUI 2 or 3 is requested, the component must have a target that supports WinUI 2 or 3 to be built.
68+
$isWinUI0Supported = $false
69+
$isWinUI2Supported = $false
70+
$isWinUI3Supported = $false
71+
72+
if ($null -ne $SupportedMultiTargets -and $SupportedMultiTargets.Count -gt 0) {
73+
# If supported MultiTargets are provided, use them directly
74+
$supportedMultiTargets = $SupportedMultiTargets
75+
} else {
76+
# If not provided, retrieve the supported MultiTargets for the component
77+
if ($null -eq $Component) {
78+
Write-Error "Component name must be specified to retrieve supported MultiTargets."
79+
exit 1
80+
}
81+
$supportedMultiTargets = & $PSScriptRoot\Get-MultiTargets.ps1 -component $Component
82+
}
83+
84+
85+
# Flag to check if any of the requested targets are supported by the component
86+
$isRequestedTargetSupported = $false
87+
88+
foreach ($requestedTarget in $RequestedMultiTargets) {
89+
if ($false -eq $isRequestedTargetSupported) {
90+
$isRequestedTargetSupported = $requestedTarget -in $supportedMultiTargets
91+
}
92+
}
93+
94+
foreach ($supportedMultiTarget in $supportedMultiTargets) {
95+
# Only build components that support WinUI 2
96+
if ($false -eq $isWinUI2Supported) {
97+
$isWinUI2Supported = $supportedMultiTarget -in $WinUI2MultiTargets;
98+
}
99+
100+
# Only build components that support WinUI 3
101+
if ($false -eq $isWinUI3Supported) {
102+
$isWinUI3Supported = $supportedMultiTarget -in $WinUI3MultiTargets;
103+
}
104+
105+
# Build components that support neither WinUI 2 nor WinUI 3 (e.g. netstandard only)
106+
if ($false -eq $isWinUI0Supported) {
107+
$isWinUI0Supported = $supportedMultiTarget -in $WinUI0MultiTargets -and -not ($isWinUI2Supported -or $isWinUI3Supported);
108+
}
109+
}
110+
111+
# If none of the requested targets are supported by the component, we can skip build to save time and avoid errors.
112+
if (-not $isRequestedTargetSupported) {
113+
$IsSupported = $false
114+
$Reason = "None of the requested MultiTargets '$RequestedMultiTargets' are enabled for this component."
115+
}
116+
117+
if (-not $isWinUI0Supported -and $WinUIMajorVersion -eq 0) {
118+
$IsSupported = $false
119+
$Reason = "WinUI is disabled and one of the supported MultiTargets '$supportedMultiTargets' supports WinUI."
120+
}
121+
122+
if ((-not $isWinUI2Supported -and $WinUIMajorVersion -eq 2) -or (-not $isWinUI3Supported -and $WinUIMajorVersion -eq 3)) {
123+
$IsSupported = $false
124+
$Reason = "WinUI $WinUIMajorVersion is enabled and not supported by any of the MultiTargets '$supportedMultiTargets'"
125+
}
126+
127+
if ($null -eq $IsSupported) {
128+
# Default to true if no conditions were met
129+
$IsSupported = $true
130+
$Reason = $null
131+
}
132+
133+
return [PSCustomObject]@{
134+
IsSupported = $IsSupported
135+
Reason = $Reason
136+
}

0 commit comments

Comments
 (0)