Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a3817e6
Refactored and consolidated MultiTargeting features. Adding dynamic m…
Arlodotexe Dec 1, 2022
a4d5df7
Fixed invalid prop references
Arlodotexe Dec 1, 2022
be5b05b
WIP fixing MultiTargetAwareProjectReference
Arlodotexe Dec 2, 2022
6f37b8b
Completed dynamic multitargeting implementation
Arlodotexe Dec 2, 2022
b892efe
Fixed an issue where Generated folder was not created
Arlodotexe Dec 2, 2022
45110d5
Fixing bugs, cleaning up logging
Arlodotexe Dec 2, 2022
f45612a
Applying test MultiTarget value
Arlodotexe Dec 2, 2022
a004061
Skip template when generating project references
Arlodotexe Dec 5, 2022
24970ac
Added proper exclude filter to project generation script
Arlodotexe Dec 6, 2022
9019e20
Only MultiTarget functional platforms for Rive
Arlodotexe Dec 6, 2022
74f7b04
Fixed creation of missing projectPropsOutputDir on Linux
Arlodotexe Dec 7, 2022
a4382e7
Removed extraneous import
Arlodotexe Dec 8, 2022
5f6706d
Fixed allowGitChanges flag when run outside script directory
Arlodotexe Dec 8, 2022
4e04577
Fixed sample discovery in VSCode
Arlodotexe Dec 8, 2022
c90aba3
Fixed conditional project references in visual studio
Arlodotexe Dec 9, 2022
54a4afb
Added missing default project identifiers
Arlodotexe Dec 9, 2022
452eb1a
Updated MultiTarget description
Arlodotexe Dec 9, 2022
593c407
Merge branch 'main' into feature/dynamic-multitargeting
Arlodotexe Dec 9, 2022
7edbe3f
Fixed invalid path separator on Linux
Arlodotexe Dec 12, 2022
280d271
Fixed TargetFrameworks not respecting MultiTarget value
Arlodotexe Dec 13, 2022
09c342f
Use relative paths for ProjectReference
Arlodotexe Dec 13, 2022
a87f210
Fixed issue where relative paths prevented MultiTarget.props from loa…
Arlodotexe Dec 14, 2022
43ebc27
Removed unused properties
Arlodotexe Dec 14, 2022
ff79eca
Added basic docs
Arlodotexe Dec 14, 2022
42d80b8
Remove "AllGeneratedProjectReferences.props" in favor of a wildcard …
Arlodotexe Dec 14, 2022
14f5245
Use MultiTarget values defined in Source project when not defined in …
Arlodotexe Dec 16, 2022
63bf5d0
Updated docs
Arlodotexe Dec 16, 2022
6c5a0a3
Fixed project generation in PowerShell 5.1
Arlodotexe Dec 16, 2022
a353aed
Add comment to generated files indicating original MultiTarget value
Arlodotexe Dec 20, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -357,4 +357,4 @@ MigrationBackup/

# Community Toolkit Labs generated files
Toolkit.Labs.All.sln
Labs.SampleRefs.props
common/MultiTarget/Generated/**
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"type": "PowerShell",
"request": "launch",
"name": "Discover samples",
"script": "${workspaceFolder}/DiscoverSamples.ps1",
"script": "${workspaceFolder}/common/MultiTarget/GenerateAllProjectReferences.ps1; ${workspaceFolder}/common/GenerateVSCodeLaunchConfig.ps1; ",
"presentation": {
"group": "2",
"order": 2
Expand Down
104 changes: 0 additions & 104 deletions DiscoverSamples.ps1

This file was deleted.

7 changes: 4 additions & 3 deletions GenerateAllSolution.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Param (
[string]$UseUnoWinUI = 2
)

# Generate required props for "All" solution.
& ./common/MultiTarget/GenerateAllProjectReferences.ps1
& ./common/GenerateVSCodeLaunchConfig.ps1

# Set WinUI version for Uno projects
$originalWorkingDirectory = Get-Location;

Expand Down Expand Up @@ -243,6 +247,3 @@ $solutionTemplate = $solutionTemplate -replace "(?m)^\s*`r`n", "";
# Save
Set-Content -Path $generatedSolutionFilePath -Value $solutionTemplate;
Write-Output "Solution generated at $generatedSolutionFilePath";

# Run sample discovery
& ./DiscoverSamples.ps1
62 changes: 62 additions & 0 deletions common/GenerateVSCodeLaunchConfig.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
Param (
[Parameter(HelpMessage = "Disables suppressing changes to the ./.vscode/launch.json file in git, allowing changes to be committed.")]
[switch]$allowGitChanges = $false
)

function CreateVsCodeLaunchConfigJson {
param (
[string]$projectName
)

return "{
`"name`": `"$projectName`",
`"type`": `"coreclr`",
`"request`": `"launch`",
`"program`": `"dotnet`",
`"args`": [
`"run`",
`"build`",
`"/r`",
`"/p:UnoSourceGeneratorUseGenerationHost=true`",
`"/p:UnoSourceGeneratorUseGenerationController=false`",
`"/p:UnoRemoteControlPort=443`",
`"--project=`$`{workspaceFolder`}/labs/$projectName/samples/$projectName.Wasm/$projectName.Wasm.csproj`"
],
`"presentation`": {
`"group`": `"2`"
},
`"cwd`": `"`$`{workspaceFolder`}/labs/$projectName/samples/$projectName.Wasm`"
}";
}

$launchConfigJson = Get-Content -Path "$PSScriptRoot/../.vscode/launch.json" -ErrorAction Stop;
$launchConfig = $launchConfigJson | ConvertFrom-Json;

# Remove all non-generated configurations
$originalConfigurations = $launchConfig.configurations;
$launchConfig.configurations = @();
$launchConfig.configurations += $originalConfigurations[0];
$launchConfig.configurations += $originalConfigurations[1];

foreach ($wasmProjectPath in Get-ChildItem -Recurse -Path "$PSScriptRoot/../*/*/samples/*.Wasm/*.Wasm.csproj") {
$projectName = [System.IO.Path]::GetFileNameWithoutExtension($wasmProjectPath) -Replace ".Wasm", "";
Write-Host "Generating VSCode launch config for $projectName";

$configJson = CreateVsCodeLaunchConfigJson $projectName;
$config = $configJson | ConvertFrom-Json;

$launchConfig.configurations += $config;
}

if ($allowGitChanges.IsPresent) {
Write-Warning "Changes to the default launch.json can now be committed. Run this command again without the -allowGitChanges flag to disable committing further changes.";
git update-index --no-assume-unchanged $PSScriptRoot/../.vscode/launch.json
}
else {
Write-Output "Changes to the default launch.json are now suppressed. To switch branches, run git reset --hard with a clean working tree. Include the -allowGitChanges flag to enable committing changes.";
git update-index --assume-unchanged $PSScriptRoot/../.vscode/launch.json
}

# Save
Set-Content -Path "$PSScriptRoot/../.vscode/launch.json" -Value ($launchConfig | ConvertTo-Json -Depth 9);
Write-Output "Saved VSCode launch configs to $(Resolve-Path $PSScriptRoot/../.vscode/launch.json)";
2 changes: 2 additions & 0 deletions common/Labs.Head.props
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
<IsAllExperimentHead Condition="$(MSBuildProjectName.StartsWith('CommunityToolkit.Labs.')) == 'true'">true</IsAllExperimentHead>
<IsProjectTemplateHead Condition="$(MSBuildProjectName.StartsWith('ProjectTemplate')) == 'true'">true</IsProjectTemplateHead>
<IsSingleExperimentHead Condition="'$(IsAllExperimentHead)' != 'true' AND '$(IsProjectTemplateHead)' != 'true'">true</IsSingleExperimentHead>

<DefineConstants Condition="$(IsAllExperimentHead) == 'true'">$(DefineConstants);LABS_ALL_SAMPLES</DefineConstants>
</PropertyGroup>

<!-- See https://github.com/CommunityToolkit/Labs-Windows/issues/142 -->
Expand Down
11 changes: 0 additions & 11 deletions common/Labs.SampleRefs.props.template

This file was deleted.

5 changes: 5 additions & 0 deletions common/MultiTarget/Defaults.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project>
<PropertyGroup>
<MultiTarget>uwp;wasdk;wpf;wasm;linuxgtk;macos;ios;android;</MultiTarget>
</PropertyGroup>
</Project>
46 changes: 46 additions & 0 deletions common/MultiTarget/GenerateAllProjectReferences.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Param (
[Parameter(HelpMessage = "The directory where props files for discovered projects should be saved.")]
[string]$projectPropsOutputDir = "$PSScriptRoot/Generated"
)

$preWorkingDir = $pwd;
Set-Location $PSScriptRoot;

# Delete and recreate output folder.
Remove-Item -Path $projectPropsOutputDir -Recurse -Force -ErrorAction SilentlyContinue | Out-Null;
New-Item -ItemType Directory -Force -Path $projectPropsOutputDir -ErrorAction SilentlyContinue | Out-Null;

# Discover projects in provided paths
foreach ($projectPath in Get-ChildItem -Directory -Depth 0 -Path "$PSScriptRoot/../../labs/") {
# Normalize project path
$projectName = $projectPath.Name;

# Folder layout is expected to match the Community Toolkit.
# Uses the <MultiTarget> values from the source library project as the fallback for the sample project.
# This behavior also implemented in MultiTarget.props for TargetFramework evaluation.
$srcPath = Resolve-Path "$($projectPath.FullName)\src";
$srcProjectPath = Get-ChildItem -File "$srcPath\*.csproj";

$samplePath = Resolve-Path "$($projectPath.FullName)\samples\$projectName.Samples";
$sampleProjectPath = Get-ChildItem -File "$samplePath\*.csproj";

if ($srcProjectPath.Length -eq 0) {
Write-Error "Could not locate source csproj for $projectName";
exit(-1);
}

if ($sampleProjectPath.Length -eq 0) {
Write-Error "Could not locate sample csproj for $projectName";
exit(-1);
}

# Generate <ProjectReference>s for sample project
# Use source project MultiTarget as first fallback.
& $PSScriptRoot\GenerateMultiTargetAwareProjectReferenceProps.ps1 -projectPath $sampleProjectPath -outputPath "$projectPropsOutputDir/$($sampleProjectPath.BaseName).props" -multiTargetFallbackPropsPath @("$srcPath/MultiTarget.props", "$samplePath/MultiTarget.props", "$PSScriptRoot/Defaults.props");

# Generate <ProjectReference>s for src project
& $PSScriptRoot\GenerateMultiTargetAwareProjectReferenceProps.ps1 -projectPath $srcProjectPath -outputPath "$projectPropsOutputDir/$($srcProjectPath.BaseName).props" -multiTargetFallbackPropsPath @("$srcPath/MultiTarget.props", "$PSScriptRoot/Defaults.props");
}


Set-Location $preWorkingDir;
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
Param (
[Parameter(HelpMessage = "The full path of the csproj to generated references to.", Mandatory = $true)]
[string]$projectPath,

[Parameter(HelpMessage = "A path to a .props file where generated content should be saved to.", Mandatory = $true)]
[string]$outputPath,

[Parameter(HelpMessage = "The path to the template used to generate the props file.")]
[string]$templatePath = "$PSScriptRoot/MultiTargetAwareProjectReference.props.template",

[Parameter(HelpMessage = "The path to the props file that contains the default MultiTarget values.")]
[string[]]$multiTargetFallbackPropsPath = @("$PSScriptRoot/Defaults.props"),

[Parameter(HelpMessage = "The placeholder text to replace when inserting the project file name into the template.")]
[string]$projectFileNamePlaceholder = "[ProjectFileName]",

[Parameter(HelpMessage = "The placeholder text to replace when inserting the project path into the template.")]
[string]$projectRootPlaceholder = "[ProjectRoot]"
)

$preWorkingDir = $pwd;
Set-Location $PSScriptRoot;

$relativeProjectPath = Invoke-Expression -C "(Resolve-Path -Relative -Path $projectPath)";
$templateContents = Get-Content -Path $templatePath;

Set-Location $preWorkingDir;

# Insert csproj file name.
$csprojFileName = [System.IO.Path]::GetFileName($relativeProjectPath);
$templateContents = $templateContents -replace [regex]::escape($projectFileNamePlaceholder), $csprojFileName;

# Insert project directory
$relativeProjectDirectory = [System.IO.Path]::GetDirectoryName($relativeProjectPath);
$templateContents = $templateContents -replace [regex]::escape($projectRootPlaceholder), "$relativeProjectDirectory";

function LoadMultiTargetsFrom([string] $path) {
$fileContents = "";

# If file does not exist
if ($false -eq (Test-Path -Path $path -PathType Leaf)) {
# Load first available default
foreach ($fallbackPath in $multiTargetFallbackPropsPath) {
if (Test-Path $fallbackPath) {
$fileContents = Get-Content $fallbackPath -ErrorAction Stop;
break;
}
}
}
else {
# Load requested file
$fileContents = Get-Content $path -ErrorAction Stop;
}

# Parse file contents
$regex = Select-String -Pattern '<MultiTarget>(.+?)<\/MultiTarget>' -InputObject $fileContents;

if ($null -eq $regex -or $null -eq $regex.Matches -or $null -eq $regex.Matches.Groups -or $regex.Matches.Groups.Length -lt 2) {
Write-Error "Couldn't get MultiTarget property from $path";
exit(-1);
}

return $regex.Matches.Groups[1].Value;
}

# Load multitarget preferences for project
$multiTargets = LoadMultiTargetsFrom("$([System.IO.Path]::GetDirectoryName($projectPath))\MultiTarget.props");

$templateContents = $templateContents -replace [regex]::escape("[IntendedTargets]"), $multiTargets;

$multiTargets = $multiTargets.Split(';');
Write-Host "Generating project references for $([System.IO.Path]::GetFileNameWithoutExtension($csprojFileName)): $($multiTargets -Join ', ')"

$templateContents = $templateContents -replace [regex]::escape("[CanTargetWasm]"), "'$($multiTargets.Contains("wasm").ToString().ToLower())'";
$templateContents = $templateContents -replace [regex]::escape("[CanTargetUwp]"), "'$($multiTargets.Contains("uwp").ToString().ToLower())'";
$templateContents = $templateContents -replace [regex]::escape("[CanTargetWasdk]"), "'$($multiTargets.Contains("wasdk").ToString().ToLower())'";
$templateContents = $templateContents -replace [regex]::escape("[CanTargetWpf]"), "'$($multiTargets.Contains("wpf").ToString().ToLower())'";
$templateContents = $templateContents -replace [regex]::escape("[CanTargetLinuxGtk]"), "'$($multiTargets.Contains("linuxgtk").ToString().ToLower())'";
$templateContents = $templateContents -replace [regex]::escape("[CanTargetMacOS]"), "'$($multiTargets.Contains("macos").ToString().ToLower())'";
$templateContents = $templateContents -replace [regex]::escape("[CanTargetiOS]"), "'$($multiTargets.Contains("ios").ToString().ToLower())'";
$templateContents = $templateContents -replace [regex]::escape("[CanTargetDroid]"), "'$($multiTargets.Contains("android").ToString().ToLower())'";

# Save to disk
Set-Content -Path $outputPath -Value $templateContents;
Loading