-
Notifications
You must be signed in to change notification settings - Fork 77
New <MultiTarget> system, added multitarget-aware ProjectReference generator #330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
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 a4d5df7
Fixed invalid prop references
Arlodotexe be5b05b
WIP fixing MultiTargetAwareProjectReference
Arlodotexe 6f37b8b
Completed dynamic multitargeting implementation
Arlodotexe b892efe
Fixed an issue where Generated folder was not created
Arlodotexe 45110d5
Fixing bugs, cleaning up logging
Arlodotexe f45612a
Applying test MultiTarget value
Arlodotexe a004061
Skip template when generating project references
Arlodotexe 24970ac
Added proper exclude filter to project generation script
Arlodotexe 9019e20
Only MultiTarget functional platforms for Rive
Arlodotexe 74f7b04
Fixed creation of missing projectPropsOutputDir on Linux
Arlodotexe a4382e7
Removed extraneous import
Arlodotexe 5f6706d
Fixed allowGitChanges flag when run outside script directory
Arlodotexe 4e04577
Fixed sample discovery in VSCode
Arlodotexe c90aba3
Fixed conditional project references in visual studio
Arlodotexe 54a4afb
Added missing default project identifiers
Arlodotexe 452eb1a
Updated MultiTarget description
Arlodotexe 593c407
Merge branch 'main' into feature/dynamic-multitargeting
Arlodotexe 7edbe3f
Fixed invalid path separator on Linux
Arlodotexe 280d271
Fixed TargetFrameworks not respecting MultiTarget value
Arlodotexe 09c342f
Use relative paths for ProjectReference
Arlodotexe a87f210
Fixed issue where relative paths prevented MultiTarget.props from loa…
Arlodotexe 43ebc27
Removed unused properties
Arlodotexe ff79eca
Added basic docs
Arlodotexe 42d80b8
Remove "AllGeneratedProjectReferences.props" in favor of a wildcard …
Arlodotexe 14f5245
Use MultiTarget values defined in Source project when not defined in …
Arlodotexe 63bf5d0
Updated docs
Arlodotexe 6c5a0a3
Fixed project generation in PowerShell 5.1
Arlodotexe a353aed
Add comment to generated files indicating original MultiTarget value
Arlodotexe File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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)"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; |
84 changes: 84 additions & 0 deletions
84
common/MultiTarget/GenerateMultiTargetAwareProjectReferenceProps.ps1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 ', ')" | ||
Arlodotexe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| $templateContents = $templateContents -replace [regex]::escape("[CanTargetWasm]"), "'$($multiTargets.Contains("wasm").ToString().ToLower())'"; | ||
Arlodotexe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| $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; | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.