Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace Microsoft.ComponentDetection.Contracts.TypedComponent;

using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using PackageUrl;

Expand Down Expand Up @@ -60,10 +61,20 @@
{
packageType = "rpm";
}
else if (this.IsAlpine())
{
packageType = "apk";
}

if (packageType != null)
{
return new PackageUrl(packageType, this.Distribution, this.Name, this.Version, null, null);
var distroId = this.GetDistroId();
var qualifiers = new SortedDictionary<string, string>
{
{ "distro", $"{distroId}-{this.Release}" },
};

return new PackageUrl(packageType, distroId, this.Name, this.Version, qualifiers, null);
Comment on lines 69 to +77
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

PR title/description says packageurl-dotnet is bumped to 2.0.0-rc.3, but Directory.Packages.props in this change set still pins packageurl-dotnet to 2.0.0-rc.2. Either update the central package version to rc.3 or adjust the PR metadata to match what’s actually changing.

This issue also appears on line 106 of the same file.

Copilot uses AI. Check for mistakes.
}

return null;
Expand Down Expand Up @@ -96,4 +107,19 @@
{
return this.Distribution.Equals("RED HAT ENTERPRISE LINUX", StringComparison.OrdinalIgnoreCase);
}

private bool IsAlpine()
{
return this.Distribution.Equals("ALPINE", StringComparison.OrdinalIgnoreCase);
}

private string GetDistroId()
{
if (this.IsRHEL())
{
return "redhat";
}

return this.Distribution.ToLowerInvariant();

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / verify (windows-latest)

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / verify (ubuntu-latest)

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / verify (macos-latest)

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / CocoaPods

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / Yarn

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / Rust

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / Ruby

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / NPM

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / Poetry

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / Go

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / Gradle

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / Pip

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)

Check failure on line 123 in src/Microsoft.ComponentDetection.Contracts/TypedComponent/LinuxComponent.cs

View workflow job for this annotation

GitHub Actions / Maven

In method 'GetDistroId', replace the call to 'ToLowerInvariant' with 'ToUpperInvariant' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1308)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ public void DebianAndUbuntuAreDebType()

ubuntuComponent.PackageUrl.Type.Should().Be("deb");
debianComponent.PackageUrl.Type.Should().Be("deb");

ubuntuComponent.PackageUrl.Qualifiers["distro"].Should().Be("ubuntu-18.04");
debianComponent.PackageUrl.Qualifiers["distro"].Should().Be("debian-buster");
}

[TestMethod]
Expand All @@ -61,17 +64,29 @@ public void CentOsFedoraAndRHELAreRpmType()
centosComponent.PackageUrl.Type.Should().Be("rpm");
fedoraComponent.PackageUrl.Type.Should().Be("rpm");
rhelComponent.PackageUrl.Type.Should().Be("rpm");

centosComponent.PackageUrl.Qualifiers["distro"].Should().Be("centos-18.04");
fedoraComponent.PackageUrl.Qualifiers["distro"].Should().Be("fedora-18.04");
rhelComponent.PackageUrl.Qualifiers["distro"].Should().Be("redhat-18.04");
}

[TestMethod]
public void AlpineAndUnknownDoNotHavePurls()
public void AlpineIsApkType()
{
// Alpine is not yet defined
// https://github.com/package-url/purl-spec/blame/180c46d266c45aa2bd81a2038af3f78e87bb4a25/README.rst#L711
// Alpine uses "apk" purl type
// https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#apk
var alpineComponent = new LinuxComponent("Alpine", "3.13", "bash", "1");

alpineComponent.PackageUrl.Type.Should().Be("apk");
alpineComponent.PackageUrl.Namespace.Should().Be("alpine");
alpineComponent.PackageUrl.Qualifiers["distro"].Should().Be("alpine-3.13");
}

[TestMethod]
public void UnknownDistroDoesNotHavePurl()
{
var unknownLinuxComponent = new LinuxComponent("Linux", "0", "bash", "1'");

alpineComponent.PackageUrl.Should().BeNull();
unknownLinuxComponent.PackageUrl.Should().BeNull();
}

Expand All @@ -88,6 +103,16 @@ public void DistroNamesAreLowerCased()
fedoraComponent.PackageUrl.Namespace.Should().Be("fedora");
}

[TestMethod]
public void RhelNamespaceIsRedhat()
{
// RHEL should use "redhat" as the namespace and distro id, matching Syft conventions
var rhelComponent = new LinuxComponent("Red Hat Enterprise Linux", "9.0", "bash", "1");

rhelComponent.PackageUrl.Namespace.Should().Be("redhat");
rhelComponent.PackageUrl.Qualifiers["distro"].Should().Be("redhat-9.0");
}
Comment on lines +106 to +114
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

The new RhelNamespaceIsRedhat test uses distribution: "Red Hat Enterprise Linux", but production code creates LinuxComponent from distro.Id (short ids like "ubuntu"/"mariner"). To ensure this behavior is actually covered, add/adjust a test case that uses the distro id value you expect from Syft (e.g., "rhel") and asserts the namespace/distro qualifier mapping.

Copilot generated this review using guidance from repository custom instructions.

[TestMethod]
public void CocoaPodNameShouldSupportPurl()
{
Expand Down
Loading