Skip to content

Tests for PR#1963 - #2029

Open
alerickson wants to merge 2 commits into
runtimePackageResolutionfrom
runtimeResolution
Open

Tests for PR#1963#2029
alerickson wants to merge 2 commits into
runtimePackageResolutionfrom
runtimeResolution

Conversation

@alerickson

Copy link
Copy Markdown
Member

PR Summary

PR Context

PR Checklist

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@alerickson

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are confirmed logic bugs in RID/TFM parsing/filtering paths (including RID compatibility-chain handling and dependency-group selection edge cases) that can cause incorrect behavior or test failures.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR introduces platform-aware installation support in PSResourceGet by adding Runtime Identifier (RID) and Target Framework Moniker (TFM) filtering during package extraction, along with TFM-aware dependency-group selection and a new suite of tests covering these behaviors.

Changes:

  • Add -RuntimeIdentifier and -TargetFramework parameters to Install-PSResource, including argument completers, and implement RID/TFM filtering plus merge behavior for already-installed packages.
  • Implement new helpers for RID detection/compatibility and runtime asset filtering/discovery.
  • Add unit + integration tests for RID/TFM filtering and nuspec dependency parsing behavior.
File summaries
File Description
test/PlatformFilteringTests/RuntimePackageHelper.Tests.ps1 Adds unit tests for runtime entry detection/filtering and RID discovery.
test/PlatformFilteringTests/RuntimeIdentifierHelper.Tests.ps1 Adds unit tests for RID detection and compatibility-chain logic.
test/PlatformFilteringTests/PlatformAwareInstall.Tests.ps1 Adds integration tests covering RID/TFM filtering, overrides, merge installs, and warnings.
src/code/Utils.cs Adds MergeDirContents helper to merge extracted filtered content into existing installs.
src/code/RuntimePackageHelper.cs New helper for filtering runtime assets and scanning archives for available RIDs.
src/code/RuntimeIdentifierHelper.cs New helper for current RID detection and compatibility-chain calculation.
src/code/PSResourceInfo.cs Updates dependency parsing to select the best matching TFM dependency group (JSON + nuspec).
src/code/InternalHooks.cs Adds test hook wrappers to exercise the new helpers from Pester tests.
src/code/InstallPSResource.cs Adds new cmdlet parameters and passes them into the install pipeline.
src/code/InstallHelper.cs Implements RID/TFM filtering during extraction, merge behavior, and user warnings.
src/code/ArgumentCompleter.cs Adds argument completers for -RuntimeIdentifier and -TargetFramework.
Review details

Suppressed comments (2)

src/code/RuntimePackageHelper.cs:126

  • GetRidFromRuntimesEntry only extracts a RID from root-level "{rid}/..." entries. With the current implementation, callers scanning a package using the common "runtimes/{rid}/..." layout will always get null and downstream logic (e.g., available RID discovery) will behave incorrectly.
            string normalizedPath = entryFullName.Replace('\\', ZipPathSeparator);
            string[] parts = normalizedPath.Split(ZipPathSeparator);

            if (parts.Length >= 2 && IsRidFolder(parts[0]))
            {

src/code/PSResourceInfo.cs:766

  • If FrameworkReducer returns a framework that isn’t exactly present in groupMap, FirstOrDefault() yields a default JsonElement (ValueKind.Undefined). Assigning that into selectedGroupElement leaves HasValue=true and can throw later when TryGetProperty is called. Guard against Undefined and let the fallback logic pick an Any/first group instead.
                                NuGetFramework bestMatch = reducer.GetNearest(currentFramework, groupMap.Select(g => g.framework));
                                
                                if (bestMatch != null)
                                {
                                    selectedGroupElement = groupMap.FirstOrDefault(g => g.framework.Equals(bestMatch)).groupElement;
  • Files reviewed: 11/11 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/code/PSResourceInfo.cs Outdated
Comment on lines +741 to +745
string tfmString = tfmElement.GetString();
if (!string.IsNullOrWhiteSpace(tfmString))
{
foreach (
JsonElement dependency in dependenciesElement.EnumerateArray().Where(
x => x.TryGetProperty("id", out JsonElement idProperty) &&
!string.IsNullOrWhiteSpace(idProperty.GetString())
)
)
NuGetFramework parsed = NuGetFramework.Parse(tfmString);
if (parsed != null && !parsed.IsUnsupported)
Comment on lines +343 to +360
else if (primaryRid.StartsWith("linux", StringComparison.OrdinalIgnoreCase))
{
// Linux compatibility chain
// linux-x64 -> linux -> unix -> any
// linux-armel -> linux-arm -> linux -> unix -> any
string arch = ExtractArchitecture(primaryRid);
if (arch != null)
{
// armel (ARM EABI soft-float) is compatible with arm
if (string.Equals(arch, "armel", StringComparison.OrdinalIgnoreCase))
{
compatibleRids.Add("linux-arm");
}
compatibleRids.Add("linux");
compatibleRids.Add("unix");
compatibleRids.Add("any");
}
}
Comment on lines +96 to +108
public static bool IsRuntimesEntry(string entryFullName)
{
if (string.IsNullOrEmpty(entryFullName))
{
return false;
}

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]);
}
Comment thread src/code/InternalHooks.cs
Comment on lines +4 to +8
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.InteropServices;
@alerickson

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@alerickson alerickson closed this Sep 11, 2026
@alerickson alerickson reopened this Sep 11, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@alerickson
alerickson changed the base branch from master to runtimePackageResolution September 11, 2026 04:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants