Skip to content

Commit

Permalink
Mark packages from .NETCore 1.x and 2.x as dev dependencies (#1339)
Browse files Browse the repository at this point in the history
* Mark packages from .NETCore 1.x and 2.x as dev dependencies

These packages aren't removed completely like later frameworks packages
are, but the previous detector would drop them.
For framework dependent apps these packages will be removed from the output.
To minimize new alerts in the new detector we'll treat these as dev
dependencies similar to other default package references.

* Refactor handling of legacy platform packages

This refactors the handling of 1.x / 2.x platform packages to a separate method.

I've also audited the platform packages and reduced them.
  • Loading branch information
ericstj authored Jan 10, 2025
1 parent bcf79cd commit fae54ba
Show file tree
Hide file tree
Showing 8 changed files with 28,427 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Microsoft.ComponentDetection.Detectors.NuGet;
using System.IO;
using System.Linq;
using global::NuGet.Frameworks;
using global::NuGet.Packaging.Core;
using global::NuGet.ProjectModel;
using global::NuGet.Versioning;

/// <summary>
Expand Down Expand Up @@ -73,7 +75,7 @@ internal static void Register(params FrameworkPackages[] toRegister)
}
}

public static FrameworkPackages[] GetFrameworkPackages(NuGetFramework framework, string[] frameworkReferences)
public static FrameworkPackages[] GetFrameworkPackages(NuGetFramework framework, string[] frameworkReferences, LockFileTarget lockFileTarget)
{
var frameworkPackages = new List<FrameworkPackages>();

Expand Down Expand Up @@ -102,9 +104,64 @@ public static FrameworkPackages[] GetFrameworkPackages(NuGetFramework framework,
}
}

frameworkPackages.AddRange(GetLegacyFrameworkPackagesFromPlatformPackages(framework, lockFileTarget));

return frameworkPackages.ToArray();
}

private static IEnumerable<FrameworkPackages> GetLegacyFrameworkPackagesFromPlatformPackages(NuGetFramework framework, LockFileTarget lockFileTarget)
{
if (framework.Framework == FrameworkConstants.FrameworkIdentifiers.NetCoreApp && framework.Version.Major < 3)
{
// For .NETCore 1.x (all frameworks) and 2.x (ASP.NET Core) the $(MicrosoftNETPlatformLibrary) property specified the framework package of the project.
// This package and all its dependencies were excluded from copy to the output directory for framework deepndent apps.
// See https://github.com/dotnet/sdk/blob/b3d6acae421815e90c74ddb631e426290348651c/src/Tasks/Microsoft.NET.Build.Tasks/ResolvePackageAssets.cs#L1882-L1898
// We can't know from the assets file what the value of MicrosoftNETPlatformLibrary was, nor if an app was self-contained or not.
// To avoid false positives, and since these frameworks are no longer supported, we'll just assume that all platform packages are framework,
// and that the app is framework-dependent.
// This is consistent with the old behavior of the old NuGet Detector.
var lookup = lockFileTarget.Libraries.ToDictionary(l => l.Name, l => l, StringComparer.OrdinalIgnoreCase);
string[] platformPackageNames = [
FrameworkNames.NetCoreApp, // Default platform package for .NET Core 1.x and 2.x https://github.com/dotnet/sdk/blob/516dcf4a3bcf52ac3dce2452ea15ddd5cf057300/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets#L519
FrameworkNames.AspNetCoreApp, // ASP.NET platform package for .NET Core 2.x https://github.com/dotnet/aspnetcore/blob/ac66280fe9024bdd686354e342fcdfb3409597f7/src/Microsoft.AspNetCore.App/build/netcoreapp2.1/Microsoft.AspNetCore.App.targets#L10
"Microsoft.AspNetCore.All", // Alternate ASP.NET platform package for .NET Core 2.x https://github.com/dotnet/aspnetcore/blob/ac66280fe9024bdd686354e342fcdfb3409597f7/src/Microsoft.AspNetCore.All/build/netcoreapp2.1/Microsoft.AspNetCore.All.targets#L10

// ASP.NET did not have platform package / shared framework for .NET Core 1.x - it was app-local only
];

foreach (var platformPackageName in platformPackageNames)
{
if (lookup.TryGetValue(platformPackageName, out var platformLibrary))
{
var frameworkPackagesFromPlatformPackage = new FrameworkPackages(framework, platformPackageName);

frameworkPackagesFromPlatformPackage.Packages.Add(platformLibrary.Name, platformLibrary.Version);

CollectDependencies(platformLibrary.Dependencies);

yield return frameworkPackagesFromPlatformPackage;

// recursively include dependencies, so long as they were not upgraded by some other reference
void CollectDependencies(IEnumerable<PackageDependency> dependencies)
{
foreach (var dependency in dependencies)
{
if (lookup.TryGetValue(dependency.Id, out var library) &&
library.Version.Equals(dependency.VersionRange.MinVersion))
{
// if this is the first time we add the package, add its dependencies as well
if (frameworkPackagesFromPlatformPackage.Packages.TryAdd(library.Name, library.Version))
{
CollectDependencies(library.Dependencies);
}
}
}
}
}
}
}
}

private static FrameworkPackages LoadFrameworkPackagesFromPack(NuGetFramework framework, string frameworkName)
{
if (framework is null || framework.Framework != FrameworkConstants.FrameworkIdentifiers.NetCoreApp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ protected override Task OnFileFoundAsync(ProcessRequest processRequest, IDiction
foreach (var target in lockFile.Targets)
{
var frameworkReferences = GetFrameworkReferences(lockFile, target);
var frameworkPackages = FrameworkPackages.GetFrameworkPackages(target.TargetFramework, frameworkReferences);
var frameworkPackages = FrameworkPackages.GetFrameworkPackages(target.TargetFramework, frameworkReferences, target);
bool IsFrameworkOrDevelopmentDependency(LockFileTargetLibrary library) =>
frameworkPackages.Any(fp => fp.IsAFrameworkComponent(library.Name, library.Version)) ||
IsADevelopmentDependency(library, lockFile);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@
<data name="pip_report_single_pkg_invalid_pkg_version" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>pip_report_single_pkg_invalid_pkg_version.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="project_assets_1_1_console" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\project.assets_1_1_console.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="project_assets_1_1_web" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\project.assets_1_1_web.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="project_assets_2_1_web" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\project.assets_2_1_web.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="project_assets_2_2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\project_assets_2_2.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
Expand Down
Loading

0 comments on commit fae54ba

Please sign in to comment.