From 660c54b600b991e04f00f69a1250353bd5fc0120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag=20H=C3=A5kon?= Date: Thu, 1 Feb 2024 11:10:28 +0100 Subject: [PATCH 1/6] Refactored code --- global.json | 2 +- src/Depends.Core/DependencyAnalyzer.cs | 154 +++++++++--------- .../LockFileTargetLibraryExtensions.cs | 6 +- .../Extensions/LoggerExtensions.cs | 6 +- .../Graph/DependencyGraph.Builder.cs | 4 +- src/Depends.Core/Graph/Edge.cs | 20 +-- src/Depends.Core/Graph/Node.cs | 6 +- src/Depends.Core/Output/DotFileWriter.cs | 5 +- src/Depends/Program.cs | 10 +- 9 files changed, 99 insertions(+), 114 deletions(-) diff --git a/global.json b/global.json index bf3fbf9..6e8e0a5 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.201", + "version": "8.0.101", "rollForward": "latestPatch", "allowPrerelease": false } diff --git a/src/Depends.Core/DependencyAnalyzer.cs b/src/Depends.Core/DependencyAnalyzer.cs index 46fdf87..c2740f0 100644 --- a/src/Depends.Core/DependencyAnalyzer.cs +++ b/src/Depends.Core/DependencyAnalyzer.cs @@ -28,8 +28,8 @@ static DependencyAnalyzer() _ = typeof(NuGet.Common.LogLevel); } - private ILogger _logger; - private ILoggerFactory _loggerFactory; + private readonly ILogger _logger; + private readonly ILoggerFactory _loggerFactory; public DependencyAnalyzer(ILoggerFactory loggerFactory) { @@ -45,77 +45,75 @@ public DependencyGraph Analyze(string packageId, string version, string framewor var nuGetFramework = NuGetFramework.ParseFolder(framework); var nugetLogger = _logger.AsNuGetLogger(); - using (var cacheContext = new SourceCacheContext()) - { - var repositories = sourceRepositoryProvider.GetRepositories(); - var resolvedPackages = new ConcurrentDictionary(PackageIdentityComparer.Default); - ResolvePackage(package, nuGetFramework, cacheContext, nugetLogger, repositories, resolvedPackages).Wait(); - - var availablePackages = new HashSet(resolvedPackages.Values); - - var resolverContext = new PackageResolverContext( - DependencyBehavior.Lowest, - new[] { packageId }, - Enumerable.Empty(), - Enumerable.Empty(), - Enumerable.Empty(), - availablePackages, - sourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), - nugetLogger); - - var resolver = new PackageResolver(); - var prunedPackages = resolver.Resolve(resolverContext, CancellationToken.None) - .Select(x => resolvedPackages[x]); - - var rootNode = new PackageReferenceNode(package.Id, package.Version.ToString()); - var packageNodes = new Dictionary(StringComparer.OrdinalIgnoreCase); - var builder = new DependencyGraph.Builder(rootNode); - - foreach (var target in prunedPackages) - { - var downloadResource = target.Source.GetResource(); - var downloadResult = downloadResource.GetDownloadResourceResultAsync(new PackageIdentity(target.Id, target.Version), - new PackageDownloadContext(cacheContext), - SettingsUtility.GetGlobalPackagesFolder(settings), - nugetLogger, CancellationToken.None).Result; - - var libItems = downloadResult.PackageReader.GetLibItems(); - var reducer = new FrameworkReducer(); - var nearest = reducer.GetNearest(nuGetFramework, libItems.Select(x => x.TargetFramework)); - - var assemblyReferences = libItems - .Where(x => x.TargetFramework.Equals(nearest)) - .SelectMany(x => x.Items) - .Where(x => Path.GetExtension(x).Equals(".dll", StringComparison.OrdinalIgnoreCase)) - .Select(x => new AssemblyReferenceNode(Path.GetFileName(x))); - - var frameworkItems = downloadResult.PackageReader.GetFrameworkItems(); - nearest = reducer.GetNearest(nuGetFramework, frameworkItems.Select(x => x.TargetFramework)); - - assemblyReferences = assemblyReferences.Concat(frameworkItems - .Where(x => x.TargetFramework.Equals(nearest)) - .SelectMany(x => x.Items) - .Select(x => new AssemblyReferenceNode(x))); - - var packageReferenceNode = new PackageReferenceNode(target.Id, target.Version.ToString()); - builder.WithNode(packageReferenceNode); - builder.WithNodes(assemblyReferences); - builder.WithEdges(assemblyReferences.Select(x => new Edge(packageReferenceNode, x))); - packageNodes.Add(target.Id, packageReferenceNode); - } + using var cacheContext = new SourceCacheContext(); + var repositories = sourceRepositoryProvider.GetRepositories(); + var resolvedPackages = new ConcurrentDictionary(PackageIdentityComparer.Default); + DependencyAnalyzer.ResolvePackage(package, nuGetFramework, cacheContext, nugetLogger, repositories, resolvedPackages).Wait(); - foreach (var target in prunedPackages) - { - var packageReferenceNode = packageNodes[target.Id]; - builder.WithEdges(target.Dependencies.Select(x => - new Edge(packageReferenceNode, packageNodes[x.Id], x.VersionRange.ToString()))); - } + var availablePackages = new HashSet(resolvedPackages.Values); - return builder.Build(); + var resolverContext = new PackageResolverContext( + DependencyBehavior.Lowest, + new[] { packageId }, + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty(), + availablePackages, + sourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), + nugetLogger); + + var resolver = new PackageResolver(); + var prunedPackages = resolver.Resolve(resolverContext, CancellationToken.None) + .Select(x => resolvedPackages[x]); + + var rootNode = new PackageReferenceNode(package.Id, package.Version.ToString()); + var packageNodes = new Dictionary(StringComparer.OrdinalIgnoreCase); + var builder = new DependencyGraph.Builder(rootNode); + + foreach (var target in prunedPackages) + { + var downloadResource = target.Source.GetResource(); + var downloadResult = downloadResource.GetDownloadResourceResultAsync(new PackageIdentity(target.Id, target.Version), + new PackageDownloadContext(cacheContext), + SettingsUtility.GetGlobalPackagesFolder(settings), + nugetLogger, CancellationToken.None).Result; + + var libItems = downloadResult.PackageReader.GetLibItems(); + var reducer = new FrameworkReducer(); + var nearest = reducer.GetNearest(nuGetFramework, libItems.Select(x => x.TargetFramework)); + + var assemblyReferences = libItems + .Where(x => x.TargetFramework.Equals(nearest)) + .SelectMany(x => x.Items) + .Where(x => Path.GetExtension(x).Equals(".dll", StringComparison.OrdinalIgnoreCase)) + .Select(x => new AssemblyReferenceNode(Path.GetFileName(x))); + + var frameworkItems = downloadResult.PackageReader.GetFrameworkItems(); + nearest = reducer.GetNearest(nuGetFramework, frameworkItems.Select(x => x.TargetFramework)); + + assemblyReferences = assemblyReferences.Concat(frameworkItems + .Where(x => x.TargetFramework.Equals(nearest)) + .SelectMany(x => x.Items) + .Select(x => new AssemblyReferenceNode(x))); + + var packageReferenceNode = new PackageReferenceNode(target.Id, target.Version.ToString()); + builder.WithNode(packageReferenceNode); + builder.WithNodes(assemblyReferences); + builder.WithEdges(assemblyReferences.Select(x => new Edge(packageReferenceNode, x))); + packageNodes.Add(target.Id, packageReferenceNode); } + + foreach (var target in prunedPackages) + { + var packageReferenceNode = packageNodes[target.Id]; + builder.WithEdges(target.Dependencies.Select(x => + new Edge(packageReferenceNode, packageNodes[x.Id], x.VersionRange.ToString()))); + } + + return builder.Build(); } - private async Task ResolvePackage(PackageIdentity package, + private static async Task ResolvePackage(PackageIdentity package, NuGetFramework framework, SourceCacheContext cacheContext, NuGet.Common.ILogger logger, @@ -152,7 +150,7 @@ private async Task ResolvePackage(PackageIdentity package, { await Task.WhenAll(dependencyInfo.Dependencies.Select(dependency => { - return ResolvePackage(new PackageIdentity(dependency.Id, dependency.VersionRange.MinVersion), + return DependencyAnalyzer.ResolvePackage(new PackageIdentity(dependency.Id, dependency.VersionRange.MinVersion), framework, cacheContext, logger, repositories, availablePackages); })); } @@ -170,7 +168,7 @@ public DependencyGraph AnalyzeSolution(string solution, string framework = null) var builder = new DependencyGraph.Builder(solutionNode); foreach (var project in analyzerManager.Projects.Where(p => p.Value.ProjectInSolution.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat)) { - builder = CreateBuilder(project.Value, project.Key, builder, framework); + builder = DependencyAnalyzer.CreateBuilder(project.Value, project.Key, builder, framework); } return builder.Build(); @@ -185,7 +183,7 @@ public DependencyGraph Analyze(string projectPath, string framework = null) if (string.IsNullOrWhiteSpace(projectPath)) { - throw new ArgumentException(nameof(projectPath)); + throw new ArgumentException("Empty parameter", nameof(projectPath)); } if (!File.Exists(projectPath)) @@ -194,22 +192,16 @@ public DependencyGraph Analyze(string projectPath, string framework = null) } var projectAnalyzer = analyzerManager.GetProject(projectPath); - return CreateBuilder(projectAnalyzer, projectPath, null, framework).Build(); + return DependencyAnalyzer.CreateBuilder(projectAnalyzer, projectPath, null, framework).Build(); } - private DependencyGraph.Builder CreateBuilder(IProjectAnalyzer projectAnalyzer, string projectPath, DependencyGraph.Builder builder = null, string framework = null) + private static DependencyGraph.Builder CreateBuilder(IProjectAnalyzer projectAnalyzer, string projectPath, DependencyGraph.Builder builder = null, string framework = null) { var analyzeResults = string.IsNullOrEmpty(framework) ? projectAnalyzer.Build() : projectAnalyzer.Build(framework); - var analyzerResult = string.IsNullOrEmpty(framework) ? - analyzeResults.FirstOrDefault() : analyzeResults[framework]; - - if (analyzerResult == null) - { - // Todo: Something went wrong, log and return better exception. - throw new InvalidOperationException("Unable to load project."); - } + var analyzerResult = (string.IsNullOrEmpty(framework) ? + analyzeResults.FirstOrDefault() : analyzeResults[framework]) ?? throw new InvalidOperationException("Unable to load project."); var projectNode = new ProjectReferenceNode(projectPath); if (builder == null) { diff --git a/src/Depends.Core/Extensions/LockFileTargetLibraryExtensions.cs b/src/Depends.Core/Extensions/LockFileTargetLibraryExtensions.cs index 71ab4c5..d1c64e8 100644 --- a/src/Depends.Core/Extensions/LockFileTargetLibraryExtensions.cs +++ b/src/Depends.Core/Extensions/LockFileTargetLibraryExtensions.cs @@ -8,17 +8,17 @@ internal static class LockFileTargetLibraryExtensions { public static bool IsPackage(this LockFileTargetLibrary library) { - return library.Type.Equals("package", StringComparison.OrdinalIgnoreCase); + return library.Type != null && library.Type.Equals("package", StringComparison.OrdinalIgnoreCase); } public static PackageReferenceNode ToNode(this LockFileTargetLibrary library) { if (!library.IsPackage()) { - throw new ArgumentException(nameof(library)); + throw new ArgumentException("Empty parameter", nameof(library)); } - return new PackageReferenceNode(library.Name, library.Version.ToNormalizedString()); + return new PackageReferenceNode(library.Name, library.Version?.ToNormalizedString()); } } } diff --git a/src/Depends.Core/Extensions/LoggerExtensions.cs b/src/Depends.Core/Extensions/LoggerExtensions.cs index 55ceb14..a9c6f7d 100644 --- a/src/Depends.Core/Extensions/LoggerExtensions.cs +++ b/src/Depends.Core/Extensions/LoggerExtensions.cs @@ -16,8 +16,8 @@ public static ILogger AsNuGetLogger(this MEL.ILogger logger) private class NuGetLogger : ILogger { - private MEL.ILogger _logger; - private Dictionary _logLevelMap = new Dictionary + private readonly MEL.ILogger _logger; + private readonly Dictionary _logLevelMap = new() { [LogLevel.Debug] = MEL.LogLevel.Debug, [LogLevel.Error] = MEL.LogLevel.Error, @@ -27,7 +27,7 @@ private class NuGetLogger : ILogger [LogLevel.Warning] = MEL.LogLevel.Warning }; - public NuGetLogger(Microsoft.Extensions.Logging.ILogger logger) + public NuGetLogger(MEL.ILogger logger) { _logger = logger; } diff --git a/src/Depends.Core/Graph/DependencyGraph.Builder.cs b/src/Depends.Core/Graph/DependencyGraph.Builder.cs index 1492f3a..91dd233 100644 --- a/src/Depends.Core/Graph/DependencyGraph.Builder.cs +++ b/src/Depends.Core/Graph/DependencyGraph.Builder.cs @@ -7,8 +7,8 @@ public sealed partial class DependencyGraph public sealed class Builder { private readonly Node _root; - private HashSet _nodes = new HashSet(); - private HashSet _edges = new HashSet(); + private readonly HashSet _nodes = new(); + private readonly HashSet _edges = new(); public Node Root => _root; diff --git a/src/Depends.Core/Graph/Edge.cs b/src/Depends.Core/Graph/Edge.cs index 103b682..5ec5fa2 100644 --- a/src/Depends.Core/Graph/Edge.cs +++ b/src/Depends.Core/Graph/Edge.cs @@ -22,29 +22,23 @@ public Edge(Node start, Node end, string label) public bool Equals(Edge other) { - if (ReferenceEquals(null, other)) return false; + if (other is null) return false; if (ReferenceEquals(this, other)) return true; return Equals(Start, other.Start) && Equals(End, other.End) && string.Equals(Label, other.Label); } public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) return false; + if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; return obj is Edge edge && Equals(edge); } - public override int GetHashCode() - { - unchecked - { - var hashCode = (Start != null ? Start.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ (End != null ? End.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ (Label != null ? Label.GetHashCode() : 0); - return hashCode; - } - } - + public override int GetHashCode() + { + return HashCode.Combine(Start, End, Label); + } + public override string ToString() { return string.Format(CultureInfo.InvariantCulture, "{0} -{2}-> {1}", Start, End, diff --git a/src/Depends.Core/Graph/Node.cs b/src/Depends.Core/Graph/Node.cs index d73421d..ce6ed72 100644 --- a/src/Depends.Core/Graph/Node.cs +++ b/src/Depends.Core/Graph/Node.cs @@ -12,7 +12,7 @@ protected Node(string id) { if (string.IsNullOrWhiteSpace(id)) { - throw new ArgumentException(nameof(id)); + throw new ArgumentException("Empty parameter", nameof(id)); } Id = id; @@ -20,14 +20,14 @@ protected Node(string id) public bool Equals(Node other) { - if (ReferenceEquals(null, other)) return false; + if (other is null) return false; if (ReferenceEquals(this, other)) return true; return string.Equals(Id, other.Id, StringComparison.OrdinalIgnoreCase); } public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) return false; + if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; return obj is Node node && Equals(node); } diff --git a/src/Depends.Core/Output/DotFileWriter.cs b/src/Depends.Core/Output/DotFileWriter.cs index 045078b..35e902f 100644 --- a/src/Depends.Core/Output/DotFileWriter.cs +++ b/src/Depends.Core/Output/DotFileWriter.cs @@ -69,10 +69,7 @@ public void Write(DependencyGraph graph, TextWriter writer) private static void Write(Node root, ImmutableHashSet edges, TextWriter writer, IDictionary ranks, ISet visited = null, int depth = 0) { - if (visited == null) - { - visited = new HashSet(); - } + visited ??= new HashSet(); if (ranks.TryGetValue(root, out var currentRank)) { diff --git a/src/Depends/Program.cs b/src/Depends/Program.cs index f54c24b..a51db93 100644 --- a/src/Depends/Program.cs +++ b/src/Depends/Program.cs @@ -56,8 +56,9 @@ internal class Program // SOFTWARE. // // https://github.com/jerriep/dotnet-outdated/blob/b2c9e99c530a64e246ac529bbdc42ddde19b1e1a/src/DotNetOutdated.Core/Services/ProjectDiscoveryService.cs - // ReSharper disable once UnusedMember.Local +#pragma warning disable IDE0051 private ValidationResult OnValidate() +#pragma warning restore IDE0051 { if (!(File.Exists(Project) || Directory.Exists(Project))) { @@ -104,8 +105,9 @@ private ValidationResult OnValidate() return ValidationResult.Success; } - // ReSharper disable once UnusedMember.Local +#pragma warning disable IDE0051 private void OnExecute() +#pragma warning restore IDE0051 { var loggerFactory = LoggerFactory.Create(builder => builder .SetMinimumLevel(Verbosity) @@ -172,7 +174,7 @@ public AppWindow(DependencyGraph graph) : base("Depends", 0) { _graph = graph ?? throw new ArgumentNullException(nameof(graph)); _dependencies = _graph.Nodes.OrderBy(x => x.Id).ToImmutableList(); - _visibleDependencies = _dependencies.Where(d => !(d is AssemblyReferenceNode)).ToImmutableList(); + _visibleDependencies = _dependencies.Where(d => d is not AssemblyReferenceNode).ToImmutableList(); _assembliesVisible = false; _lastSelectedDependencyIndex = -1; @@ -268,7 +270,7 @@ public override bool ProcessKey(KeyEvent keyEvent) _assembliesVisible = !_assembliesVisible; _visibleDependencies = _assembliesVisible ? _dependencies : - _dependencies.Where(d => !(d is AssemblyReferenceNode)).ToImmutableList(); + _dependencies.Where(d => d is not AssemblyReferenceNode).ToImmutableList(); _dependenciesView.SetSource(_visibleDependencies); _lastSelectedDependencyIndex = -1; From 37d3edfedd04d5ef0cc0373764cf791a2a70cb80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag=20H=C3=A5kon?= Date: Thu, 1 Feb 2024 11:11:01 +0100 Subject: [PATCH 2/6] Updated nuget versions --- src/Depends.Core/Depends.Core.csproj | 8 ++++---- src/Depends/Depends.csproj | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Depends.Core/Depends.Core.csproj b/src/Depends.Core/Depends.Core.csproj index 1b77fb1..3d27bd6 100644 --- a/src/Depends.Core/Depends.Core.csproj +++ b/src/Depends.Core/Depends.Core.csproj @@ -6,18 +6,18 @@ - + all runtime; build; native; contentfiles; analyzers - - + + - + NU1701 diff --git a/src/Depends/Depends.csproj b/src/Depends/Depends.csproj index 6723579..389b520 100644 --- a/src/Depends/Depends.csproj +++ b/src/Depends/Depends.csproj @@ -16,9 +16,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers From 01727f38ae3297b1d2ad476756bd0ba047323d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag=20H=C3=A5kon?= Date: Thu, 1 Feb 2024 11:31:27 +0100 Subject: [PATCH 3/6] Updated project files to .NET 8 --- src/Depends.Core/Depends.Core.csproj | 2 +- src/Depends/Depends.csproj | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Depends.Core/Depends.Core.csproj b/src/Depends.Core/Depends.Core.csproj index 3d27bd6..859af1a 100644 --- a/src/Depends.Core/Depends.Core.csproj +++ b/src/Depends.Core/Depends.Core.csproj @@ -1,7 +1,7 @@  - net6.0;net7.0 + net8.0 false diff --git a/src/Depends/Depends.csproj b/src/Depends/Depends.csproj index 389b520..fee0465 100644 --- a/src/Depends/Depends.csproj +++ b/src/Depends/Depends.csproj @@ -1,17 +1,17 @@  - net6.0;net7.0 - dotnet-depends + net8.0 + dotnet-dependency True Exe - dotnet-depends - dotnet-depends - mholo65 + dotnet-dependency + dotnet-dependency + daghsentinel Dependency explorer for .NET - 2018 Martin Björkström + 2024 Dag H. Baardsen MIT - https://github.com/mholo65/depends + https://github.com/daghsentinel/depends icon.png From 64350ef9e4f2348ccc03601dac157b990cc4ad75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Bj=C3=B6rkstr=C3=B6m?= Date: Thu, 8 Feb 2024 20:48:38 +0200 Subject: [PATCH 4/6] Revert changes to NuGet package --- src/Depends/Depends.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Depends/Depends.csproj b/src/Depends/Depends.csproj index fee0465..fc7ebff 100644 --- a/src/Depends/Depends.csproj +++ b/src/Depends/Depends.csproj @@ -2,16 +2,16 @@ net8.0 - dotnet-dependency + dotnet-depends True Exe - dotnet-dependency - dotnet-dependency - daghsentinel + dotnet-depends + dotnet-depends + bjorkstromm and contributors Dependency explorer for .NET - 2024 Dag H. Baardsen + 2018 Martin Björkström MIT - https://github.com/daghsentinel/depends + https://github.com/bjorkstromm/depends icon.png From bf70d30f61960a1b823865b96ba68f9ff376dfc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Bj=C3=B6rkstr=C3=B6m?= Date: Sat, 14 Sep 2024 22:12:26 +0300 Subject: [PATCH 5/6] Updated packages --- global.json | 4 ++-- src/Depends.Core/Depends.Core.csproj | 10 +++++----- src/Depends/Depends.csproj | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/global.json b/global.json index 6e8e0a5..ba6f11a 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,7 @@ { "sdk": { - "version": "8.0.101", - "rollForward": "latestPatch", + "version": "8.0.400", + "rollForward": "latestFeature", "allowPrerelease": false } } \ No newline at end of file diff --git a/src/Depends.Core/Depends.Core.csproj b/src/Depends.Core/Depends.Core.csproj index 859af1a..d47a310 100644 --- a/src/Depends.Core/Depends.Core.csproj +++ b/src/Depends.Core/Depends.Core.csproj @@ -6,18 +6,18 @@ - - + + all runtime; build; native; contentfiles; analyzers - - + + - + NU1701 diff --git a/src/Depends/Depends.csproj b/src/Depends/Depends.csproj index fc7ebff..c402e1c 100644 --- a/src/Depends/Depends.csproj +++ b/src/Depends/Depends.csproj @@ -17,9 +17,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers From 5267a73d7a7bd50606974c80524993c0e9c566d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Bj=C3=B6rkstr=C3=B6m?= Date: Sat, 14 Sep 2024 22:19:34 +0300 Subject: [PATCH 6/6] Try make refactorings less intrusive so it's easier to follow the PR --- src/Depends.Core/DependencyAnalyzer.cs | 128 +++++++++++++------------ 1 file changed, 65 insertions(+), 63 deletions(-) diff --git a/src/Depends.Core/DependencyAnalyzer.cs b/src/Depends.Core/DependencyAnalyzer.cs index c2740f0..8d02b44 100644 --- a/src/Depends.Core/DependencyAnalyzer.cs +++ b/src/Depends.Core/DependencyAnalyzer.cs @@ -45,72 +45,74 @@ public DependencyGraph Analyze(string packageId, string version, string framewor var nuGetFramework = NuGetFramework.ParseFolder(framework); var nugetLogger = _logger.AsNuGetLogger(); - using var cacheContext = new SourceCacheContext(); - var repositories = sourceRepositoryProvider.GetRepositories(); - var resolvedPackages = new ConcurrentDictionary(PackageIdentityComparer.Default); - DependencyAnalyzer.ResolvePackage(package, nuGetFramework, cacheContext, nugetLogger, repositories, resolvedPackages).Wait(); - - var availablePackages = new HashSet(resolvedPackages.Values); - - var resolverContext = new PackageResolverContext( - DependencyBehavior.Lowest, - new[] { packageId }, - Enumerable.Empty(), - Enumerable.Empty(), - Enumerable.Empty(), - availablePackages, - sourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), - nugetLogger); - - var resolver = new PackageResolver(); - var prunedPackages = resolver.Resolve(resolverContext, CancellationToken.None) - .Select(x => resolvedPackages[x]); - - var rootNode = new PackageReferenceNode(package.Id, package.Version.ToString()); - var packageNodes = new Dictionary(StringComparer.OrdinalIgnoreCase); - var builder = new DependencyGraph.Builder(rootNode); - - foreach (var target in prunedPackages) + using (var cacheContext = new SourceCacheContext()) { - var downloadResource = target.Source.GetResource(); - var downloadResult = downloadResource.GetDownloadResourceResultAsync(new PackageIdentity(target.Id, target.Version), - new PackageDownloadContext(cacheContext), - SettingsUtility.GetGlobalPackagesFolder(settings), - nugetLogger, CancellationToken.None).Result; - - var libItems = downloadResult.PackageReader.GetLibItems(); - var reducer = new FrameworkReducer(); - var nearest = reducer.GetNearest(nuGetFramework, libItems.Select(x => x.TargetFramework)); - - var assemblyReferences = libItems - .Where(x => x.TargetFramework.Equals(nearest)) - .SelectMany(x => x.Items) - .Where(x => Path.GetExtension(x).Equals(".dll", StringComparison.OrdinalIgnoreCase)) - .Select(x => new AssemblyReferenceNode(Path.GetFileName(x))); - - var frameworkItems = downloadResult.PackageReader.GetFrameworkItems(); - nearest = reducer.GetNearest(nuGetFramework, frameworkItems.Select(x => x.TargetFramework)); - - assemblyReferences = assemblyReferences.Concat(frameworkItems - .Where(x => x.TargetFramework.Equals(nearest)) - .SelectMany(x => x.Items) - .Select(x => new AssemblyReferenceNode(x))); - - var packageReferenceNode = new PackageReferenceNode(target.Id, target.Version.ToString()); - builder.WithNode(packageReferenceNode); - builder.WithNodes(assemblyReferences); - builder.WithEdges(assemblyReferences.Select(x => new Edge(packageReferenceNode, x))); - packageNodes.Add(target.Id, packageReferenceNode); - } + var repositories = sourceRepositoryProvider.GetRepositories(); + var resolvedPackages = new ConcurrentDictionary(PackageIdentityComparer.Default); + ResolvePackage(package, nuGetFramework, cacheContext, nugetLogger, repositories, resolvedPackages).Wait(); + + var availablePackages = new HashSet(resolvedPackages.Values); + + var resolverContext = new PackageResolverContext( + DependencyBehavior.Lowest, + new[] { packageId }, + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty(), + availablePackages, + sourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource), + nugetLogger); + + var resolver = new PackageResolver(); + var prunedPackages = resolver.Resolve(resolverContext, CancellationToken.None) + .Select(x => resolvedPackages[x]); + + var rootNode = new PackageReferenceNode(package.Id, package.Version.ToString()); + var packageNodes = new Dictionary(StringComparer.OrdinalIgnoreCase); + var builder = new DependencyGraph.Builder(rootNode); + + foreach (var target in prunedPackages) + { + var downloadResource = target.Source.GetResource(); + var downloadResult = downloadResource.GetDownloadResourceResultAsync(new PackageIdentity(target.Id, target.Version), + new PackageDownloadContext(cacheContext), + SettingsUtility.GetGlobalPackagesFolder(settings), + nugetLogger, CancellationToken.None).Result; + + var libItems = downloadResult.PackageReader.GetLibItems(); + var reducer = new FrameworkReducer(); + var nearest = reducer.GetNearest(nuGetFramework, libItems.Select(x => x.TargetFramework)); + + var assemblyReferences = libItems + .Where(x => x.TargetFramework.Equals(nearest)) + .SelectMany(x => x.Items) + .Where(x => Path.GetExtension(x).Equals(".dll", StringComparison.OrdinalIgnoreCase)) + .Select(x => new AssemblyReferenceNode(Path.GetFileName(x))); + + var frameworkItems = downloadResult.PackageReader.GetFrameworkItems(); + nearest = reducer.GetNearest(nuGetFramework, frameworkItems.Select(x => x.TargetFramework)); + + assemblyReferences = assemblyReferences.Concat(frameworkItems + .Where(x => x.TargetFramework.Equals(nearest)) + .SelectMany(x => x.Items) + .Select(x => new AssemblyReferenceNode(x))); + + var packageReferenceNode = new PackageReferenceNode(target.Id, target.Version.ToString()); + builder.WithNode(packageReferenceNode); + builder.WithNodes(assemblyReferences); + builder.WithEdges(assemblyReferences.Select(x => new Edge(packageReferenceNode, x))); + packageNodes.Add(target.Id, packageReferenceNode); + } - foreach (var target in prunedPackages) - { - var packageReferenceNode = packageNodes[target.Id]; - builder.WithEdges(target.Dependencies.Select(x => - new Edge(packageReferenceNode, packageNodes[x.Id], x.VersionRange.ToString()))); - } + foreach (var target in prunedPackages) + { + var packageReferenceNode = packageNodes[target.Id]; + builder.WithEdges(target.Dependencies.Select(x => + new Edge(packageReferenceNode, packageNodes[x.Id], x.VersionRange.ToString()))); + } - return builder.Build(); + return builder.Build(); + } } private static async Task ResolvePackage(PackageIdentity package,