Platform-aware Install-PSResource: filter runtimes by RID, libs by TFM - #1963
Platform-aware Install-PSResource: filter runtimes by RID, libs by TFM#1963Justin Chung (jshigetomi) wants to merge 9 commits into
Conversation
…wershell dep resolution, add warning when filtering libs
…FM or RID is specified
|
Justin Chung (@jshigetomi) is this PR still needed? were you able to add tests? |
…into runtimeResolution
There was a problem hiding this comment.
🟡 Changes recommended
There are correctness and state-leak risks (RID parsing not handling runtimes/{rid}/... as tested, and a global merge flag that can affect unrelated installs) that should be fixed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds platform-aware filtering to Install-PSResource so package extraction can select runtime assets by RID and assemblies by TFM, with opt-in overrides for cross-platform/cross-framework deployments.
Changes:
- Adds
-RuntimeIdentifierand-TargetFrameworkparameters toInstall-PSResource, plus argument completers. - Implements RID filtering (package assets) and TFM filtering (
lib/selection) during extraction, including cross-lineage warnings. - Updates dependency parsing to select a best-matching dependency group by TFM (JSON and nuspec paths), and introduces merge semantics when re-installing with explicit overrides.
File summaries
| File | Description |
|---|---|
| test/PlatformFilteringTests/RuntimePackageHelper.Tests.ps1 | Adds unit tests for runtime package entry filtering behavior. |
| test/PlatformFilteringTests/RuntimeIdentifierHelper.Tests.ps1 | Adds unit tests for RID detection and compatibility chains. |
| test/PlatformFilteringTests/PlatformAwareInstall.Tests.ps1 | Adds integration tests covering RID/TFM filtering, overrides, merge behavior, and nuspec deps parsing. |
| src/code/Utils.cs | Adds a directory-merge helper used for override “merge” installs. |
| src/code/RuntimePackageHelper.cs | Introduces helper functions to detect RID-rooted entries and filter extraction accordingly. |
| src/code/RuntimeIdentifierHelper.cs | Adds RID detection + compatibility logic for platform-aware filtering. |
| src/code/PSResourceInfo.cs | Makes dependency parsing TFM-aware and adds nuspec dependency-group selection. |
| src/code/InternalHooks.cs | Exposes new internal helpers for test access. |
| src/code/InstallPSResource.cs | Adds new public parameters and passes them into install flow. |
| src/code/InstallHelper.cs | Implements extraction-time RID/TFM filtering and override merge behavior. |
| src/code/ArgumentCompleter.cs | Adds completers for RID and TFM parameters. |
Review details
Suppressed comments (1)
src/code/RuntimePackageHelper.cs:126
GetRidFromRuntimesEntry()currently only extracts the RID from root-level{rid}/...entries. If the entry is in the NuGet formruntimes/{rid}/..., this returns null, which breaks RID discovery/filtering for that layout.
string normalizedPath = entryFullName.Replace('\\', ZipPathSeparator);
string[] parts = normalizedPath.Split(ZipPathSeparator);
if (parts.Length >= 2 && IsRidFolder(parts[0]))
{
- Files reviewed: 11/11 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if (hasExplicitOverride) | ||
| { | ||
| _cmdletPassedIn.WriteVerbose($"Resource '{pkgToInstall.Name}' with version '{pkgVersion}' is already installed. " + | ||
| $"Proceeding to merge additional platform content (TargetFramework='{_targetFramework}', RuntimeIdentifier='{_runtimeIdentifier}')."); | ||
| _mergeFilteredContent = true; |
| string normalizedPath = entryFullName.Replace('\\', ZipPathSeparator); | ||
| string[] segments = normalizedPath.Split(ZipPathSeparator); | ||
|
|
||
| // Pattern: {rid}/... (root-level RID folders like win-x64/native.dll) | ||
| return segments.Length >= 2 && IsRidFolder(segments[0]); |
| using System.Collections.Generic; | ||
| using System.IO; | ||
| using System.IO.Compression; | ||
| using System.Reflection; | ||
| using System.Runtime.InteropServices; |
PR Summary
Adds automatic RID (Runtime Identifier) and TFM (Target Framework Moniker) filtering during package extraction, plus two new parameters (
-RuntimeIdentifier,-TargetFramework) for explicit cross-platform/cross-framework deployment.Design Decisions for Review
1. Root-level RID folders, not NuGet
runtimes/conventionPowerShell modules use
win-x64/,linux-x64/at the package root for native assets, not the standard NuGetruntimes/{rid}/native/layout. Filtering targets this PS-ecosystem convention.2. Merge semantics on re-install with explicit overrides
-TargetFrameworkor-RuntimeIdentifier+ already installed → merge new content into existing version directory without overwriting files-Reinstall+ override → full replace (clean filtered install)This enables incremental multi-target builds:
3. Singular TFM selection — no fallback extraction
NuGet.Frameworks.FrameworkReducerpicks the single best-match TFM fromlib/. Only that TFM's assemblies are extracted — no fallback that extracts multiple TFMs. This prevents accidental cross-lineage mixing but means users must explicitly merge if they need both.4. Cross-lineage warning
When the selected TFM is .NETCoreApp but the package also has
net472(or vice versa), a non-fatal warning tells the user how to add the other lineage:PR Context
Platform aware installation was brought up in issue: MicrosoftDocs/PowerShell-Docs#794.
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.Install-PSResourceMicrosoftDocs/PowerShell-Docs-PSGet#347