Skip to content

Commit 1a85f19

Browse files
authored
dotnet nuget why reports requested as well as resolved versions (#7017)
1 parent 5b05c1e commit 1a85f19

28 files changed

Lines changed: 846 additions & 950 deletions

File tree

src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/Why/DependencyGraphFinder.cs

Lines changed: 124 additions & 227 deletions
Large diffs are not rendered by default.

src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/Why/DependencyGraphPrinter.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Collections.Generic;
88
using System.Linq;
99
using NuGet.Shared;
10+
using NuGet.Versioning;
1011
using Spectre.Console;
1112
using Spectre.Console.Rendering;
1213

@@ -96,7 +97,19 @@ private static void PrintDependencyGraphPerFramework(List<string> frameworks, Li
9697

9798
private static IRenderable GetNodeText(DependencyNode node, string targetPackage)
9899
{
99-
string text = $"{node.Id} (v{node.Version})";
100+
string text;
101+
102+
if (node is PackageNode pkgNode)
103+
{
104+
string resolved = pkgNode.ResolvedVersion.OriginalVersion ?? pkgNode.ResolvedVersion.ToString();
105+
string requested = pkgNode.RequestedVersion.ToString("f", VersionRangeFormatter.Instance);
106+
text = $"{node.Id}@{resolved} ({requested})";
107+
}
108+
else
109+
{
110+
text = node.Id;
111+
}
112+
100113
Style? style = node.Id.Equals(targetPackage, StringComparison.OrdinalIgnoreCase)
101114
? new Style(foreground: TargetPackageColor)
102115
: null;

src/NuGet.Core/NuGet.CommandLine.XPlat/Commands/Why/DependencyNode.cs

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,76 @@
55

66
using System;
77
using System.Collections.Generic;
8-
using NuGet.Shared;
8+
using System.Linq;
9+
using NuGet.Versioning;
910

1011
namespace NuGet.CommandLine.XPlat.Commands.Why
1112
{
1213
/// <summary>
1314
/// Represents a node in the package dependency graph.
1415
/// </summary>
15-
internal class DependencyNode
16+
internal abstract record DependencyNode(string Id, HashSet<DependencyNode> Children)
1617
{
17-
public string Id { get; set; }
18-
public string Version { get; set; }
19-
public HashSet<DependencyNode> Children { get; set; }
18+
public abstract bool Equals(DependencyNode? other);
2019

21-
public DependencyNode(string id, string version)
20+
public abstract override int GetHashCode();
21+
}
22+
23+
/// <summary>
24+
/// Represents a project node in the dependency graph.
25+
/// </summary>
26+
internal record ProjectNode(string Id, HashSet<DependencyNode> Children)
27+
: DependencyNode(Id, Children)
28+
{
29+
public virtual bool Equals(ProjectNode? other)
2230
{
23-
Id = id ?? throw new ArgumentNullException(nameof(id));
24-
Version = version ?? throw new ArgumentNullException(nameof(version));
25-
Children = new HashSet<DependencyNode>(new DependencyNodeComparer());
31+
if (other == null)
32+
return false;
33+
34+
return string.Equals(Id, other.Id, StringComparison.OrdinalIgnoreCase)
35+
&& Children.SetEquals(other.Children);
2636
}
2737

2838
public override int GetHashCode()
2939
{
30-
var hashCodeCombiner = new HashCodeCombiner();
31-
hashCodeCombiner.AddObject(Id);
32-
hashCodeCombiner.AddObject(Version);
33-
hashCodeCombiner.AddUnorderedSequence(Children);
34-
return hashCodeCombiner.CombinedHash;
40+
var hash = new HashCode();
41+
hash.Add(Id, StringComparer.OrdinalIgnoreCase);
42+
foreach (var child in Children.OrderBy(c => c.Id, StringComparer.OrdinalIgnoreCase))
43+
{
44+
hash.Add(child);
45+
}
46+
return hash.ToHashCode();
3547
}
3648
}
3749

38-
internal class DependencyNodeComparer : IEqualityComparer<DependencyNode>
50+
/// <summary>
51+
/// Represents a package node in the dependency graph.
52+
/// </summary>
53+
internal record PackageNode(string Id, NuGetVersion ResolvedVersion, VersionRange RequestedVersion, HashSet<DependencyNode> Children)
54+
: DependencyNode(Id, Children)
3955
{
40-
public bool Equals(DependencyNode? x, DependencyNode? y)
56+
public virtual bool Equals(PackageNode? other)
4157
{
42-
if (x == null || y == null)
58+
if (other == null)
4359
return false;
4460

45-
return string.Equals(x.Id, y.Id, StringComparison.CurrentCultureIgnoreCase);
61+
return string.Equals(Id, other.Id, StringComparison.OrdinalIgnoreCase)
62+
&& ResolvedVersion.Equals(other.ResolvedVersion)
63+
&& RequestedVersion.Equals(other.RequestedVersion)
64+
&& Children.SetEquals(other.Children);
4665
}
4766

48-
public int GetHashCode(DependencyNode obj)
67+
public override int GetHashCode()
4968
{
50-
return obj.Id.GetHashCode();
69+
var hash = new HashCode();
70+
hash.Add(Id, StringComparer.OrdinalIgnoreCase);
71+
hash.Add(ResolvedVersion);
72+
hash.Add(RequestedVersion);
73+
foreach (var child in Children.OrderBy(c => c.Id, StringComparer.OrdinalIgnoreCase))
74+
{
75+
hash.Add(child);
76+
}
77+
return hash.ToHashCode();
5178
}
5279
}
5380
}

src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.Designer.cs

Lines changed: 11 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,4 +1167,7 @@ Do not translate "PackageVersion"</comment>
11671167
<comment>{0} = package ID
11681168
{1} = comma-separated list of all configured sources </comment>
11691169
</data>
1170+
<data name="WhyCommand_Error_InconsistentAssetsFile" xml:space="preserve">
1171+
<value>Internal error: Assets file is inconsistent</value>
1172+
</data>
11701173
</root>

src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.cs.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,11 @@ Hledání porovnává řetězce bez rozlišování malých a velkých písmen po
14811481
<target state="translated">Nepovedlo se spustit příkaz dotnet nuget why. {0}</target>
14821482
<note>{0} - Exception mssage</note>
14831483
</trans-unit>
1484+
<trans-unit id="WhyCommand_Error_InconsistentAssetsFile">
1485+
<source>Internal error: Assets file is inconsistent</source>
1486+
<target state="new">Internal error: Assets file is inconsistent</target>
1487+
<note />
1488+
</trans-unit>
14841489
<trans-unit id="WhyCommand_Error_InvalidAssetsFile_WithProject">
14851490
<source>The file '{0}' does not appear to be a NuGet assets file. Please run restore for project '{1}' before running this command.</source>
14861491
<target state="translated">Zdá se, že soubor {0} není souborem prostředků NuGet. Před spuštěním tohoto příkazu prosím spusťte obnovení projektu {1}.</target>

src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.de.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,11 @@ Bei der Suche handelt es sich um einen ungültigen Zeichenfolgenvergleich mit de
14811481
<target state="translated">"dotnet nuget why" kann nicht ausgeführt werden. {0}</target>
14821482
<note>{0} - Exception mssage</note>
14831483
</trans-unit>
1484+
<trans-unit id="WhyCommand_Error_InconsistentAssetsFile">
1485+
<source>Internal error: Assets file is inconsistent</source>
1486+
<target state="new">Internal error: Assets file is inconsistent</target>
1487+
<note />
1488+
</trans-unit>
14841489
<trans-unit id="WhyCommand_Error_InvalidAssetsFile_WithProject">
14851490
<source>The file '{0}' does not appear to be a NuGet assets file. Please run restore for project '{1}' before running this command.</source>
14861491
<target state="translated">Die Datei „{0}“ scheint keine NuGet-Ressourcendatei zu sein. Führen Sie die Wiederherstellung für das Projekt „{1}“ aus, bevor Sie diesen Befehl ausführen.</target>

src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.es.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,11 @@ La búsqueda es una comparación de cadenas que no diferencia mayúsculas de min
14811481
<target state="translated">No se puede ejecutar "dotnet nuget why". {0}</target>
14821482
<note>{0} - Exception mssage</note>
14831483
</trans-unit>
1484+
<trans-unit id="WhyCommand_Error_InconsistentAssetsFile">
1485+
<source>Internal error: Assets file is inconsistent</source>
1486+
<target state="new">Internal error: Assets file is inconsistent</target>
1487+
<note />
1488+
</trans-unit>
14841489
<trans-unit id="WhyCommand_Error_InvalidAssetsFile_WithProject">
14851490
<source>The file '{0}' does not appear to be a NuGet assets file. Please run restore for project '{1}' before running this command.</source>
14861491
<target state="translated">El archivo "{0}" no parece ser un archivo de recursos de NuGet. Ejecute la restauración del proyecto "{1}" antes de ejecutar este comando.</target>

src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.fr.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,11 @@ La recherche est une comparaison de chaînes qui ne respecte pas la casse à l
14811481
<target state="translated">Impossible d’exécuter « dotnet nuget why ». {0}</target>
14821482
<note>{0} - Exception mssage</note>
14831483
</trans-unit>
1484+
<trans-unit id="WhyCommand_Error_InconsistentAssetsFile">
1485+
<source>Internal error: Assets file is inconsistent</source>
1486+
<target state="new">Internal error: Assets file is inconsistent</target>
1487+
<note />
1488+
</trans-unit>
14841489
<trans-unit id="WhyCommand_Error_InvalidAssetsFile_WithProject">
14851490
<source>The file '{0}' does not appear to be a NuGet assets file. Please run restore for project '{1}' before running this command.</source>
14861491
<target state="translated">Le fichier «{0}» ne semble pas être un fichier de ressources NuGet. Veuillez exécuter la restauration pour l projet « {1} » avant d’exécuter cette commande.</target>

src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.it.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,11 @@ La ricerca viene eseguita in un confronto di stringhe senza distinzione tra maiu
14811481
<target state="translated">Non è possibile eseguire 'dotnet nuget why'. {0}</target>
14821482
<note>{0} - Exception mssage</note>
14831483
</trans-unit>
1484+
<trans-unit id="WhyCommand_Error_InconsistentAssetsFile">
1485+
<source>Internal error: Assets file is inconsistent</source>
1486+
<target state="new">Internal error: Assets file is inconsistent</target>
1487+
<note />
1488+
</trans-unit>
14841489
<trans-unit id="WhyCommand_Error_InvalidAssetsFile_WithProject">
14851490
<source>The file '{0}' does not appear to be a NuGet assets file. Please run restore for project '{1}' before running this command.</source>
14861491
<target state="translated">Il file '{0}' non sembra essere un file di asset NuGet. Eseguire il ripristino per il progetto '{1}' prima di eseguire questo comando.</target>

0 commit comments

Comments
 (0)