Skip to content

Commit 7838443

Browse files
authored
Change RestoreTarget.TargetGraphName to use the alias (#6923)
1 parent ba112de commit 7838443

14 files changed

Lines changed: 252 additions & 16390 deletions

File tree

src/NuGet.Core/NuGet.Commands/RestoreCommand/IRestoreTargetGraph.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ namespace NuGet.Commands
1414
{
1515
public interface IRestoreTargetGraph
1616
{
17+
/// <summary>
18+
/// Gets the target graph name.
19+
/// The target graph name is two parts; the first part, when there is an alias this is the alias name; otherwise, it's the framework name
20+
/// For the second part, when there is a runtime identifier, this is a `/` followed by the runtime identifier; otherwise, it's empty.
21+
/// </summary>
1722
string TargetGraphName { get; }
1823

1924
/// <summary>

src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,7 @@ public LockFile CreateLockFile(LockFile previousLockFile,
5252

5353
if (project.RestoreMetadata?.ProjectStyle == ProjectStyle.PackageReference)
5454
{
55-
AddProjectFileDependenciesForPackageReference(project, lockFile, targetGraphs);
56-
}
57-
else
58-
{
59-
AddProjectFileDependenciesForSpec(project, lockFile);
55+
AddProjectFileDependenciesForPackageReference(project, lockFile, targetGraphs.AsList());
6056
}
6157

6258
// Record all libraries used
@@ -393,20 +389,6 @@ private static string GetFallbackFrameworkString(NuGetFramework framework)
393389
return string.Join(", ", frameworks);
394390
}
395391

396-
private static void AddProjectFileDependenciesForSpec(PackageSpec project, LockFile lockFile)
397-
{
398-
foreach (var frameworkInfo in project.TargetFrameworks
399-
.OrderBy(framework => framework.FrameworkName.ToString(),
400-
StringComparer.Ordinal))
401-
{
402-
lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup(
403-
frameworkInfo.FrameworkName.ToString(),
404-
frameworkInfo.Dependencies
405-
.Select(x => x.LibraryRange.ToLockFileDependencyGroupString())
406-
.OrderBy(dependency => dependency, StringComparer.Ordinal)));
407-
}
408-
}
409-
410392
private static void AddProjectFileDependenciesForPackageReference(PackageSpec project, LockFile lockFile, IEnumerable<RestoreTargetGraph> targetGraphs)
411393
{
412394
// For NETCore put everything under a TFM section

src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs

Lines changed: 18 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public RestoreCommand(RestoreRequest request)
154154
_lockFileBuilderCache = request.LockFileBuilderCache;
155155

156156
// Validate the lock file version requested
157-
if (_request.LockFileVersion < 1 || _request.LockFileVersion > LockFileFormat.Version)
157+
if (_request.LockFileVersion < 3 || _request.LockFileVersion > LockFileFormat.Version)
158158
{
159159
throw new ArgumentOutOfRangeException(
160160
paramName: nameof(request),
@@ -249,7 +249,7 @@ public async Task<RestoreResult> ExecuteAsync(CancellationToken token)
249249

250250
// if success == false, it generates an empty restore graph suitable to create an assets file with errors.
251251
// Since the graph is empty, any code that analyzes the graph (like audit) will have nothing to do.
252-
(successfulResult, var graphs) = await GenerateRestoreGraphsAsync(telemetry, contextForProject, success, token);
252+
(successfulResult, List<RestoreTargetGraph> graphs) = await GenerateRestoreGraphsAsync(telemetry, contextForProject, success, token);
253253
success &= successfulResult;
254254

255255
bool auditRan = false;
@@ -571,9 +571,9 @@ private async Task<EvaluateLockFileResult>
571571
return new EvaluateLockFileResult(success, isLockFileValid, regenerateLockFile, packagesLockFilePath, packagesLockFile);
572572
}
573573

574-
private async Task<(bool, IEnumerable<RestoreTargetGraph>)> GenerateRestoreGraphsAsync(TelemetryActivity telemetry, RemoteWalkContext contextForProject, bool success, CancellationToken token)
574+
private async Task<(bool, List<RestoreTargetGraph>)> GenerateRestoreGraphsAsync(TelemetryActivity telemetry, RemoteWalkContext contextForProject, bool success, CancellationToken token)
575575
{
576-
IEnumerable<RestoreTargetGraph> graphs = null;
576+
List<RestoreTargetGraph> graphs = null;
577577
if (success)
578578
{
579579
using (telemetry.StartIndependentInterval(GenerateRestoreGraphDuration))
@@ -608,23 +608,25 @@ private async Task<EvaluateLockFileResult>
608608
// caller of RestoreCommand to have provided at least one AdditionalMessage in RestoreArgs.
609609
// The other scenario is when the lock file is not up to date and we're running locked mode.
610610
// In that case we want to write a `target` for each target framework to avoid missing target errors from the SDK build tasks.
611-
var frameworkRuntimePair = CreateFrameworkRuntimeDefinitions(_request.Project, RequestRuntimeUtility.GetRestoreRuntimes(_request));
612-
graphs = frameworkRuntimePair.Select(e =>
611+
var frameworkRuntimePairs = CreateFrameworkRuntimeDefinitions(_request.Project, RequestRuntimeUtility.GetRestoreRuntimes(_request));
612+
graphs = new(frameworkRuntimePairs.Count);
613+
for (var i = 0; i < frameworkRuntimePairs.Count; i++)
613614
{
614-
return RestoreTargetGraph.Create(_request.Project.RuntimeGraph, Enumerable.Empty<GraphNode<RemoteResolveResult>>(), contextForProject, _logger, e.TargetAlias, e.Framework, e.RuntimeIdentifier);
615-
});
615+
var restoreTargetGraph = RestoreTargetGraph.Create(_request.Project.RuntimeGraph, Enumerable.Empty<GraphNode<RemoteResolveResult>>(), contextForProject, _logger, frameworkRuntimePairs[i].TargetAlias, frameworkRuntimePairs[i].Framework, frameworkRuntimePairs[i].RuntimeIdentifier);
616+
graphs.Add(restoreTargetGraph);
617+
}
616618
}
617619

618620
return (success, graphs);
619621
}
620622

621-
private async Task<(bool, IEnumerable<MSBuildOutputFile>, string, string, LockFile, IEnumerable<RestoreTargetGraph>, PackagesLockFile, string, CacheFile)> ProcessRestoreResultAsync(TelemetryActivity telemetry,
623+
private async Task<(bool, IEnumerable<MSBuildOutputFile>, string, string, LockFile, List<RestoreTargetGraph>, PackagesLockFile, string, CacheFile)> ProcessRestoreResultAsync(TelemetryActivity telemetry,
622624
List<NuGetv3LocalRepository> localRepositories,
623625
RemoteWalkContext contextForProject,
624626
bool isLockFileValid,
625627
bool regenerateLockFile,
626628
LockFile assetsFile,
627-
IEnumerable<RestoreTargetGraph> graphs,
629+
List<RestoreTargetGraph> graphs,
628630
PackagesLockFile packagesLockFile,
629631
string packagesLockFilePath,
630632
CacheFile cacheFile,
@@ -663,9 +665,6 @@ private async Task<EvaluateLockFileResult>
663665
_logger);
664666
}
665667

666-
// If the request is for a lower lock file version, downgrade it appropriately
667-
DowngradeLockFileIfNeeded(assetsFile);
668-
669668
// Revert to the original case if needed
670669
await FixCaseForLegacyReaders(graphs, assetsFile, token);
671670

@@ -758,7 +757,7 @@ private async Task<EvaluateLockFileResult>
758757
/// <param name="telemetry">The <see cref="TelemetryActivity"/> to log NuGetAudit telemetry to.</param>
759758
/// <param name="token">A <see cref="CancellationToken"/> to cancel obtaining a vulnerability database. Once the database is downloaded, audit is quick to complete.</param>
760759
/// <returns>False if no vulnerability database could be found (so packages were not scanned for vulnerabilities), true otherwise.</returns>
761-
private async Task<bool> PerformAuditAsync(IEnumerable<RestoreTargetGraph> graphs, TelemetryActivity telemetry, CancellationToken token)
760+
private async Task<bool> PerformAuditAsync(List<RestoreTargetGraph> graphs, TelemetryActivity telemetry, CancellationToken token)
762761
{
763762
var audit = new AuditUtility(
764763
_request.Project.RestoreMetadata.RestoreAuditProperties,
@@ -1436,14 +1435,6 @@ private string GetAssetsFilePath(LockFile lockFile)
14361435
return Path.GetFullPath(projectLockFilePath);
14371436
}
14381437

1439-
private void DowngradeLockFileIfNeeded(LockFile lockFile)
1440-
{
1441-
if (_request.LockFileVersion <= 1)
1442-
{
1443-
DowngradeLockFileToV1(lockFile);
1444-
}
1445-
}
1446-
14471438
private async Task FixCaseForLegacyReaders(
14481439
IEnumerable<RestoreTargetGraph> graphs,
14491440
LockFile lockFile,
@@ -1467,7 +1458,7 @@ private async Task FixCaseForLegacyReaders(
14671458
private LockFile BuildAssetsFile(
14681459
LockFile existingLockFile,
14691460
PackageSpec project,
1470-
IEnumerable<RestoreTargetGraph> graphs,
1461+
List<RestoreTargetGraph> graphs,
14711462
IReadOnlyList<NuGetv3LocalRepository> localRepositories,
14721463
RemoteWalkContext contextForProject)
14731464
{
@@ -1661,7 +1652,7 @@ private static async Task<IList<CompatibilityCheckResult>> VerifyCompatibilityAs
16611652
return checkResults;
16621653
}
16631654

1664-
private async Task<(bool, IEnumerable<RestoreTargetGraph>)> ExecuteLegacyRestoreAsync(
1655+
private async Task<(bool, List<RestoreTargetGraph>)> ExecuteLegacyRestoreAsync(
16651656
NuGetv3LocalRepository userPackageFolder,
16661657
IReadOnlyList<NuGetv3LocalRepository> fallbackPackageFolders,
16671658
RemoteWalkContext context,
@@ -1675,7 +1666,7 @@ private static async Task<IList<CompatibilityCheckResult>> VerifyCompatibilityAs
16751666
await _logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1001, message));
16761667

16771668
success = false;
1678-
return (success, Enumerable.Empty<RestoreTargetGraph>());
1669+
return (success, []);
16791670
}
16801671
_logger.LogInformation(string.Format(CultureInfo.CurrentCulture, Strings.Log_RestoringPackages, _request.Project.FilePath));
16811672

@@ -1838,7 +1829,7 @@ private static async Task<IList<CompatibilityCheckResult>> VerifyCompatibilityAs
18381829
return (success, allGraphs);
18391830
}
18401831

1841-
private async Task<(bool, IEnumerable<RestoreTargetGraph>)> ExecuteRestoreAsync(
1832+
private async Task<(bool, List<RestoreTargetGraph>)> ExecuteRestoreAsync(
18421833
NuGetv3LocalRepository userPackageFolder,
18431834
IReadOnlyList<NuGetv3LocalRepository> fallbackPackageFolders,
18441835
RemoteWalkContext context,
@@ -1853,7 +1844,7 @@ private static async Task<IList<CompatibilityCheckResult>> VerifyCompatibilityAs
18531844

18541845
success = false;
18551846

1856-
return (success, Enumerable.Empty<RestoreTargetGraph>());
1847+
return (success, []);
18571848
}
18581849

18591850
var projectRestoreRequest = new ProjectRestoreRequest(_request, _request.Project, _request.ExistingLockFile, _logger)
@@ -2057,37 +2048,6 @@ private static RemoteWalkContext CreateRemoteWalkContext(RestoreRequest request,
20572048
return context;
20582049
}
20592050

2060-
private static void DowngradeLockFileToV1(LockFile lockFile)
2061-
{
2062-
// Remove projects from the library section
2063-
var libraryProjects = lockFile.Libraries.Where(lib => lib.Type == LibraryType.Project).ToArray();
2064-
2065-
foreach (var library in libraryProjects)
2066-
{
2067-
lockFile.Libraries.Remove(library);
2068-
}
2069-
2070-
// Remove projects from the targets section
2071-
foreach (var target in lockFile.Targets)
2072-
{
2073-
var targetProjects = target.Libraries.Where(lib => lib.Type == LibraryType.Project).ToArray();
2074-
2075-
foreach (var library in targetProjects)
2076-
{
2077-
target.Libraries.Remove(library);
2078-
}
2079-
}
2080-
2081-
foreach (var library in lockFile.Targets.SelectMany(target => target.Libraries))
2082-
{
2083-
// Null out all target types, these did not exist in v1
2084-
library.Type = null;
2085-
}
2086-
2087-
// Remove the package spec
2088-
lockFile.PackageSpec = null;
2089-
}
2090-
20912051
private static ExternalProjectReference ToExternalProjectReference(PackageSpec project)
20922052
{
20932053
return new ExternalProjectReference(

src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreTargetGraph.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
#nullable disable
55

6+
using System;
67
using System.Collections.Generic;
78
using System.Diagnostics;
9+
using System.Globalization;
810
using System.Linq;
911
using NuGet.Client;
1012
using NuGet.Common;
@@ -80,7 +82,7 @@ internal RestoreTargetGraph(IEnumerable<ResolverConflict> conflicts,
8082
RuntimeGraph = runtimeGraph;
8183
Framework = framework;
8284
Graphs = graphs;
83-
TargetGraphName = FrameworkRuntimePair.GetTargetGraphName(Framework, RuntimeIdentifier);
85+
TargetGraphName = string.IsNullOrEmpty(TargetAlias) ? FrameworkRuntimePair.GetTargetGraphName(Framework, RuntimeIdentifier) : GetTargetGraphName(TargetAlias, RuntimeIdentifier);
8486
Conventions = new ManagedCodeConventions(runtimeGraph);
8587

8688
Install = install;
@@ -90,6 +92,24 @@ internal RestoreTargetGraph(IEnumerable<ResolverConflict> conflicts,
9092
ResolvedDependencies = resolvedDependencies;
9193
}
9294

95+
internal static string GetTargetGraphName(string targetAlias, string runtimeIdentifier)
96+
{
97+
if (string.IsNullOrEmpty(targetAlias)) throw new ArgumentNullException(nameof(targetAlias));
98+
99+
if (string.IsNullOrEmpty(runtimeIdentifier))
100+
{
101+
return targetAlias;
102+
}
103+
else
104+
{
105+
return string.Format(
106+
CultureInfo.InvariantCulture,
107+
"{0}/{1}",
108+
targetAlias,
109+
runtimeIdentifier);
110+
}
111+
}
112+
93113
internal static RestoreTargetGraph Create(IEnumerable<GraphNode<RemoteResolveResult>> graphs, RemoteWalkContext context, ILogger logger, string targetAlias, NuGetFramework framework)
94114
{
95115
return Create(RuntimeGraph.Empty, graphs, context, logger, targetAlias, framework, runtimeIdentifier: null);

src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/AuditUtility.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ internal class AuditUtility
2323
{
2424
private readonly RestoreAuditProperties? _restoreAuditProperties;
2525
private readonly string _projectFullPath;
26-
private readonly IEnumerable<RestoreTargetGraph> _targetGraphs;
26+
private readonly List<RestoreTargetGraph> _targetGraphs;
2727
private readonly IReadOnlyList<IVulnerabilityInformationProvider> _vulnerabilityInfoProviders;
2828
private readonly ILogger _logger;
2929
private readonly IList<TargetFrameworkInformation> _targetFrameworks;
@@ -62,7 +62,7 @@ internal class AuditUtility
6262
public AuditUtility(
6363
RestoreAuditProperties? restoreAuditProperties,
6464
string projectFullPath,
65-
IEnumerable<RestoreTargetGraph> graphs,
65+
List<RestoreTargetGraph> graphs,
6666
IReadOnlyList<IVulnerabilityInformationProvider> vulnerabilityInformationProviders,
6767
IList<TargetFrameworkInformation> targetFrameworks,
6868
ILogger logger)

src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileExtensions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ public static IEnumerable<LockFileTarget> GetTargetGraphs(this IAssetsLogMessage
3333
{
3434
return assetsFile.Targets;
3535
}
36-
37-
return assetsFile.Targets.Where(target => message.TargetGraphs.Contains(target.Name, StringComparer.OrdinalIgnoreCase));
36+
return assetsFile.Targets.Where(target => message.TargetGraphs.Contains(target.TargetAlias + (string.IsNullOrEmpty(target.RuntimeIdentifier) ? "" : "/" + target.RuntimeIdentifier), StringComparer.OrdinalIgnoreCase));
3837
}
3938

4039
/// <summary>

src/NuGet.Core/NuGet.ProjectModel/TargetFrameworkInformation.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System;
77
using System.Collections.Generic;
88
using System.Collections.Immutable;
9+
using System.Diagnostics.CodeAnalysis;
910
using NuGet.Common;
1011
using NuGet.Frameworks;
1112
using NuGet.LibraryModel;
@@ -25,7 +26,7 @@ public class TargetFrameworkInformation : IEquatable<TargetFrameworkInformation>
2526

2627
public string TargetAlias { get; init; } = string.Empty;
2728

28-
public NuGetFramework FrameworkName { get; init; }
29+
public required NuGetFramework FrameworkName { get; init; }
2930

3031
public ImmutableArray<LibraryDependency> Dependencies
3132
{
@@ -114,6 +115,7 @@ public IReadOnlyDictionary<string, PrunePackageReference> PackagesToPrune
114115
/// </summary>
115116
public string RuntimeIdentifierGraphPath { get; init; }
116117

118+
[SetsRequiredMembers]
117119
public TargetFrameworkInformation()
118120
{
119121
TargetAlias = string.Empty;
@@ -125,6 +127,7 @@ public TargetFrameworkInformation()
125127
PackagesToPrune = ImmutableDictionary<string, PrunePackageReference>.Empty;
126128
}
127129

130+
[SetsRequiredMembers]
128131
public TargetFrameworkInformation(TargetFrameworkInformation cloneFrom)
129132
{
130133
TargetAlias = cloneFrom.TargetAlias;

0 commit comments

Comments
 (0)