display requested versions of packages
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
using NuGet.Packaging.Core;
|
||||||
|
using NuGet.ProjectModel;
|
||||||
|
|
||||||
|
namespace SharpIDE.Application.Features.Evaluation;
|
||||||
|
|
||||||
|
public class Dependent
|
||||||
|
{
|
||||||
|
public required string PackageName { get; set; }
|
||||||
|
public required PackageDependency PackageDependency { get; set; }
|
||||||
|
}
|
||||||
|
public static class NugetDependencyGraph
|
||||||
|
{
|
||||||
|
internal static Dictionary<string, List<Dependent>> GetPackageDependencyMap(LockFile assetsFile)
|
||||||
|
{
|
||||||
|
var parentMap = new Dictionary<string, List<Dependent>>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
var target = assetsFile.Targets.SingleOrDefault();
|
||||||
|
if (target == null) return parentMap;
|
||||||
|
|
||||||
|
var packageLibraries = target.Libraries.Where(l => l.Type == "package").ToList();
|
||||||
|
|
||||||
|
foreach (var library in packageLibraries)
|
||||||
|
{
|
||||||
|
var dependencies = library.Dependencies;
|
||||||
|
foreach (var packageDependency in dependencies)
|
||||||
|
{
|
||||||
|
var mapEntry = parentMap!.GetValueOrDefault(packageDependency.Id, []);
|
||||||
|
var dependent = new Dependent
|
||||||
|
{
|
||||||
|
PackageName = library.Name!,
|
||||||
|
PackageDependency = packageDependency
|
||||||
|
};
|
||||||
|
mapEntry.Add(dependent);
|
||||||
|
parentMap[packageDependency.Id] = mapEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parentMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using Ardalis.GuardClauses;
|
using Ardalis.GuardClauses;
|
||||||
using Microsoft.Build.Evaluation;
|
using Microsoft.Build.Evaluation;
|
||||||
using NuGet.ProjectModel;
|
using NuGet.ProjectModel;
|
||||||
|
using NuGet.Versioning;
|
||||||
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||||
|
|
||||||
namespace SharpIDE.Application.Features.Evaluation;
|
namespace SharpIDE.Application.Features.Evaluation;
|
||||||
@@ -64,6 +65,12 @@ public static class ProjectEvaluation
|
|||||||
public required string TargetFramework { get; set; }
|
public required string TargetFramework { get; set; }
|
||||||
public required bool IsTopLevel { get; set; }
|
public required bool IsTopLevel { get; set; }
|
||||||
public required bool IsAutoReferenced { get; set; }
|
public required bool IsAutoReferenced { get; set; }
|
||||||
|
public List<DependentPackage>? DependentPackages { get; set; }
|
||||||
|
}
|
||||||
|
public class DependentPackage
|
||||||
|
{
|
||||||
|
public required string PackageName { get; set; }
|
||||||
|
public required VersionRange RequestedVersion { get; set; }
|
||||||
}
|
}
|
||||||
public static async Task<List<InstalledPackage>> GetPackageReferencesForProject(SharpIdeProjectModel projectModel, bool includeTransitive = true)
|
public static async Task<List<InstalledPackage>> GetPackageReferencesForProject(SharpIdeProjectModel projectModel, bool includeTransitive = true)
|
||||||
{
|
{
|
||||||
@@ -88,6 +95,7 @@ public static class ProjectEvaluation
|
|||||||
private static List<InstalledPackage> GetPackagesFromAssetsFile(LockFile assetsFile, bool includeTransitive)
|
private static List<InstalledPackage> GetPackagesFromAssetsFile(LockFile assetsFile, bool includeTransitive)
|
||||||
{
|
{
|
||||||
var packages = new List<InstalledPackage>();
|
var packages = new List<InstalledPackage>();
|
||||||
|
var dependencyMap = NugetDependencyGraph.GetPackageDependencyMap(assetsFile);
|
||||||
|
|
||||||
foreach (var target in assetsFile.Targets.Where(t => t.RuntimeIdentifier == null))
|
foreach (var target in assetsFile.Targets.Where(t => t.RuntimeIdentifier == null))
|
||||||
{
|
{
|
||||||
@@ -102,22 +110,30 @@ public static class ProjectEvaluation
|
|||||||
.Select(s => s.Name)
|
.Select(s => s.Name)
|
||||||
.ToHashSet();
|
.ToHashSet();
|
||||||
|
|
||||||
foreach (var library in target.Libraries.Where(l => l.Type == "package"))
|
foreach (var lockFileTargetLibrary in target.Libraries.Where(l => l.Type == "package"))
|
||||||
{
|
{
|
||||||
var isTopLevel = topLevelDependencies.Contains(library.Name);
|
var isTopLevel = topLevelDependencies.Contains(lockFileTargetLibrary.Name);
|
||||||
if (!includeTransitive && !isTopLevel) continue;
|
if (!includeTransitive && !isTopLevel) continue;
|
||||||
|
|
||||||
var dependency = tfmInfo.Dependencies
|
var dependency = tfmInfo.Dependencies
|
||||||
.FirstOrDefault(d => d.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase));
|
.FirstOrDefault(d => d.Name.Equals(lockFileTargetLibrary.Name, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
var dependents = dependencyMap.GetValueOrDefault(lockFileTargetLibrary.Name, []);
|
||||||
|
var mappedDependents = dependents.Select(d => new DependentPackage
|
||||||
|
{
|
||||||
|
PackageName = d.PackageName,
|
||||||
|
RequestedVersion = d.PackageDependency.VersionRange
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
packages.Add(new InstalledPackage
|
packages.Add(new InstalledPackage
|
||||||
{
|
{
|
||||||
Name = library.Name,
|
Name = lockFileTargetLibrary.Name,
|
||||||
RequestedVersion = dependency?.LibraryRange.VersionRange?.ToString() ?? "",
|
RequestedVersion = dependency?.LibraryRange.VersionRange?.ToString() ?? "",
|
||||||
ResolvedVersion = library.Version?.ToString(),
|
ResolvedVersion = lockFileTargetLibrary.Version?.ToString(),
|
||||||
TargetFramework = tfm,
|
TargetFramework = tfm,
|
||||||
IsTopLevel = isTopLevel,
|
IsTopLevel = isTopLevel,
|
||||||
IsAutoReferenced = dependency?.AutoReferenced ?? false
|
IsAutoReferenced = dependency?.AutoReferenced ?? false,
|
||||||
|
DependentPackages = mappedDependents
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
|||||||
|
|
||||||
namespace SharpIDE.Application.Features.Nuget;
|
namespace SharpIDE.Application.Features.Nuget;
|
||||||
|
|
||||||
public record InstalledNugetPackageInfo(bool IsTransitive, NuGetVersion Version);
|
public record InstalledNugetPackageInfo(bool IsTransitive, NuGetVersion Version, List<ProjectEvaluation.DependentPackage>? DependentPackages);
|
||||||
public record IdePackageResult(string PackageId, List<IdePackageFromSourceResult> PackageFromSources, InstalledNugetPackageInfo? InstalledNugetPackageInfo);
|
public record IdePackageResult(string PackageId, List<IdePackageFromSourceResult> PackageFromSources, InstalledNugetPackageInfo? InstalledNugetPackageInfo);
|
||||||
public record struct IdePackageFromSourceResult(IPackageSearchMetadata PackageSearchMetadata, PackageSource Source);
|
public record struct IdePackageFromSourceResult(IPackageSearchMetadata PackageSearchMetadata, PackageSource Source);
|
||||||
public class NugetClientService
|
public class NugetClientService
|
||||||
@@ -122,7 +122,7 @@ public class NugetClientService
|
|||||||
var nugetVersionString = installedPackage.ResolvedVersion ?? installedPackage.RequestedVersion;
|
var nugetVersionString = installedPackage.ResolvedVersion ?? installedPackage.RequestedVersion;
|
||||||
var nugetVersion = NuGetVersion.Parse(nugetVersionString);
|
var nugetVersion = NuGetVersion.Parse(nugetVersionString);
|
||||||
|
|
||||||
var installedNugetPackageInfo = new InstalledNugetPackageInfo(isTransitive, nugetVersion);
|
var installedNugetPackageInfo = new InstalledNugetPackageInfo(isTransitive, nugetVersion, installedPackage.DependentPackages);
|
||||||
var idePackageResult = new IdePackageResult(installedPackage.Name, [], installedNugetPackageInfo);
|
var idePackageResult = new IdePackageResult(installedPackage.Name, [], installedNugetPackageInfo);
|
||||||
|
|
||||||
foreach (var source in packageSources)
|
foreach (var source in packageSources)
|
||||||
|
|||||||
@@ -53,6 +53,21 @@ public partial class PackageEntry : MarginContainer
|
|||||||
if (PackageResult is null) return;
|
if (PackageResult is null) return;
|
||||||
_packageNameLabel.Text = PackageResult.PackageId;
|
_packageNameLabel.Text = PackageResult.PackageId;
|
||||||
var installedPackagedInfo = PackageResult.InstalledNugetPackageInfo;
|
var installedPackagedInfo = PackageResult.InstalledNugetPackageInfo;
|
||||||
|
if (installedPackagedInfo?.DependentPackages is not null)
|
||||||
|
{
|
||||||
|
var transitiveOriginsGroupedByVersion = installedPackagedInfo.DependentPackages
|
||||||
|
.GroupBy(t => t.RequestedVersion)
|
||||||
|
.Select(g => new
|
||||||
|
{
|
||||||
|
RequestedVersion = g.Key,
|
||||||
|
PackageNames = g.Select(t => t.PackageName).ToList()
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
_button.TooltipText = $"""
|
||||||
|
Implicitly Referenced Versions
|
||||||
|
{string.Join("\n", transitiveOriginsGroupedByVersion.Select(t => $"{t.RequestedVersion} by {string.Join(", ", t.PackageNames)}"))}
|
||||||
|
""";
|
||||||
|
}
|
||||||
_installedVersionLabel.Text = installedPackagedInfo?.IsTransitive is true ? $"({installedPackagedInfo?.Version.ToNormalizedString()})" : installedPackagedInfo?.Version.ToNormalizedString();
|
_installedVersionLabel.Text = installedPackagedInfo?.IsTransitive is true ? $"({installedPackagedInfo?.Version.ToNormalizedString()})" : installedPackagedInfo?.Version.ToNormalizedString();
|
||||||
var highestVersionPackageFromSource = PackageResult.PackageFromSources
|
var highestVersionPackageFromSource = PackageResult.PackageFromSources
|
||||||
.MaxBy(p => p.PackageSearchMetadata.Identity.Version);
|
.MaxBy(p => p.PackageSearchMetadata.Identity.Version);
|
||||||
|
|||||||
Reference in New Issue
Block a user