From c72557ae05b92deb4640aded3a69ca4d80ec385e Mon Sep 17 00:00:00 2001 From: Nikolche Kolev Date: Thu, 2 Oct 2025 12:42:51 -0700 Subject: [PATCH] Full support for aliasing in restore --- .../Projects/LegacyPackageReferenceProject.cs | 1 + .../Models/AssetsFileDependenciesSnapshot.cs | 32 +------- .../MSBuildStaticGraphRestore.cs | 2 +- .../PublicAPI/net472/PublicAPI.Unshipped.txt | 2 + .../PublicAPI/net8.0/PublicAPI.Unshipped.txt | 2 + .../RestoreCommand/CompatibilityChecker.cs | 2 +- .../UnexpectedDependencyMessages.cs | 6 +- .../Diagnostics/UnresolvedMessages.cs | 2 +- .../RestoreCommand/IRestoreTargetGraph.cs | 2 + .../RestoreCommand/LockFileBuilder.cs | 68 +++++++---------- .../RestoreCommand/ProjectRestoreCommand.cs | 4 +- .../RequestFactory/RestoreArgs.cs | 2 + .../RestoreCommand/RestoreCommand.cs | 76 +++++-------------- .../RestoreCommand/RestoreTargetGraph.cs | 23 ++++++ .../RestoreCommand/Utility/AuditUtility.cs | 4 +- .../Utility/MSBuildRestoreUtility.cs | 2 +- .../Utility/PackageSpecFactory.cs | 2 +- .../Remote/RemoteDependencyWalker.cs | 1 + .../ResolverUtility.cs | 1 + .../NuGet.ProjectModel/LockFile/LockFile.cs | 1 + .../LockFile/LockFileExtensions.cs | 2 +- .../LockFile/LockFileFormat.cs | 19 +++-- .../Utf8JsonStreamLockFileConverter.cs | 32 +++++++- ...Utf8JsonStreamLockFileTargetConverterV4.cs | 39 ++++++++++ .../PublicAPI.Unshipped.txt | 1 + .../TargetFrameworkInformation.cs | 5 +- .../Utf8JsonReaderExtensions.cs | 1 + .../UWPRestoreTests.cs | 2 +- .../RestoreCommandTests.cs | 3 +- .../LockFileExtensionsTests.cs | 6 +- 30 files changed, 192 insertions(+), 153 deletions(-) create mode 100644 src/NuGet.Core/NuGet.ProjectModel/LockFile/Utf8JsonStreamLockFileTargetConverterV4.cs diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs index f694e71a66a..9236ce5a252 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Projects/LegacyPackageReferenceProject.cs @@ -479,6 +479,7 @@ private async Task GetPackageSpecAsync(ISettings settings) FrameworkName = targetFramework, Warn = warn, PackagesToPrune = packagesToPrune, + TargetAlias = targetFramework.ToString(), }; // Build up runtime information. diff --git a/src/NuGet.Clients/NuGet.VisualStudio.Implementation/SolutionExplorer/Models/AssetsFileDependenciesSnapshot.cs b/src/NuGet.Clients/NuGet.VisualStudio.Implementation/SolutionExplorer/Models/AssetsFileDependenciesSnapshot.cs index 4905da672af..2ba952917fc 100644 --- a/src/NuGet.Clients/NuGet.VisualStudio.Implementation/SolutionExplorer/Models/AssetsFileDependenciesSnapshot.cs +++ b/src/NuGet.Clients/NuGet.VisualStudio.Implementation/SolutionExplorer/Models/AssetsFileDependenciesSnapshot.cs @@ -96,11 +96,11 @@ private AssetsFileDependenciesSnapshot(LockFile? lockFile, AssetsFileDependencie continue; } - string targetAlias = GetTargetAlias(lockFileTarget.Name); + string targetAlias = lockFileTarget.TargetAlias; previous.DataByTarget.TryGetValue(targetAlias, out AssetsFileTarget? previousTarget); - ImmutableArray logMessages = ParseLogMessages(lockFile, previousTarget, lockFileTarget.Name); + ImmutableArray logMessages = ParseLogMessages(lockFile, previousTarget, targetAlias); dataByTarget.Add( targetAlias, @@ -114,34 +114,6 @@ private AssetsFileDependenciesSnapshot(LockFile? lockFile, AssetsFileDependencie DataByTarget = dataByTarget.ToImmutable(); return; - string GetTargetAlias(string lockFileTargetName) - { - // In some places, the target alias specified in the project file (e.g. "net472") will not - // match the target name used throughout the lock file (e.g. ".NETFramework,Version=v4.7.2"). - // The dependencies tree only uses the target alias (what's in the project file) so we need - // to map back to that. See https://github.com/dotnet/project-system/issues/6832. - - if (lockFile.PackageSpec.TargetFrameworks.Any(t => t.TargetAlias == lockFileTargetName)) - { - // The target name used in the assets file matches the target alias in the project file. - return lockFileTargetName; - } - - // The target name used in the assets file does NOT match any target alias in the project. - // Attempt to find the name used in the project. - foreach (TargetFrameworkInformation targetInfo in lockFile.PackageSpec.TargetFrameworks) - { - if (targetInfo.FrameworkName.DotNetFrameworkName == lockFileTargetName) - { - // We found a match, so return the alias. - return targetInfo.TargetAlias; - } - } - - // No match was found. Not ideal. Nothing to do but return the original value. - return lockFileTargetName; - } - static ImmutableArray ParseLogMessages(LockFile lockFile, AssetsFileTarget? previousTarget, string target) { if (lockFile.LogMessages.Count == 0) diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Console/MSBuildStaticGraphRestore.cs b/src/NuGet.Core/NuGet.Build.Tasks.Console/MSBuildStaticGraphRestore.cs index fbe893fb463..8036b8b18d1 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Console/MSBuildStaticGraphRestore.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Console/MSBuildStaticGraphRestore.cs @@ -752,7 +752,7 @@ internal static List GetTargetFrameworkInfos(IReadOn FrameworkReferences = GetFrameworkReferences(msBuildProjectInstance), PackagesToPrune = prunedReferences, RuntimeIdentifierGraphPath = msBuildProjectInstance.GetProperty(nameof(TargetFrameworkInformation.RuntimeIdentifierGraphPath)), - TargetAlias = targetAlias, + TargetAlias = string.IsNullOrEmpty(targetAlias) ? targetFramework.ToString() : targetAlias, Warn = warn }; diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt index fff86e267f7..328786e4083 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt @@ -1,3 +1,5 @@ #nullable enable ~NuGet.Commands.IRestoreTargetGraph.TargetAlias.get -> string +~NuGet.Commands.IRestoreTargetGraph.TargetGraphNameWithAlias.get -> string ~NuGet.Commands.RestoreTargetGraph.TargetAlias.get -> string +~NuGet.Commands.RestoreTargetGraph.TargetGraphNameWithAlias.get -> string diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Unshipped.txt index fff86e267f7..328786e4083 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -1,3 +1,5 @@ #nullable enable ~NuGet.Commands.IRestoreTargetGraph.TargetAlias.get -> string +~NuGet.Commands.IRestoreTargetGraph.TargetGraphNameWithAlias.get -> string ~NuGet.Commands.RestoreTargetGraph.TargetAlias.get -> string +~NuGet.Commands.RestoreTargetGraph.TargetGraphNameWithAlias.get -> string diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/CompatibilityChecker.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/CompatibilityChecker.cs index b7465b2e872..fd82ac402c7 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/CompatibilityChecker.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/CompatibilityChecker.cs @@ -230,7 +230,7 @@ internal async Task CheckAsync( /// private static RestoreLogMessage GetErrorMessage(NuGetLogCode logCode, CompatibilityIssue issue, RestoreTargetGraph graph) { - return RestoreLogMessage.CreateError(logCode, issue.Format(), issue.Package.Id, graph.TargetGraphName); + return RestoreLogMessage.CreateError(logCode, issue.Format(), issue.Package.Id, graph.TargetGraphNameWithAlias); } private static IEnumerable GetPackageFrameworks( diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Diagnostics/UnexpectedDependencyMessages.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Diagnostics/UnexpectedDependencyMessages.cs index b3159622010..32173bf0dc2 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Diagnostics/UnexpectedDependencyMessages.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Diagnostics/UnexpectedDependencyMessages.cs @@ -78,7 +78,7 @@ public static IEnumerable GetMissingLowerBounds(IEnumerable e.Child.Name, StringComparer.OrdinalIgnoreCase) .ThenBy(e => e.Child.Version) .ThenBy(e => e.Parent.Name, StringComparer.OrdinalIgnoreCase) - .Select(e => GetMissingLowerBoundMessage(e, graph.TargetGraphName))); + .Select(e => GetMissingLowerBoundMessage(e, graph.TargetGraphNameWithAlias))); } return messages; @@ -159,7 +159,7 @@ public static IEnumerable GetBumpedUpDependencies( match.Key.Name, match.Key.Version); - var graphName = indexedGraph.Graph.TargetGraphName; + var graphName = indexedGraph.Graph.TargetGraphNameWithAlias; messages.Add(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1601, message, match.Key.Name, graphName)); } @@ -290,7 +290,7 @@ public static IEnumerable GetDependenciesAboveUpperBounds(Lis child, actual); - messages.Add(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1608, message, dependencyId, graph.TargetGraphName)); + messages.Add(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1608, message, dependencyId, graph.TargetGraphNameWithAlias)); } } } diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Diagnostics/UnresolvedMessages.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Diagnostics/UnresolvedMessages.cs index 8a49cb978cd..aa3fcd803fc 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Diagnostics/UnresolvedMessages.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Diagnostics/UnresolvedMessages.cs @@ -33,7 +33,7 @@ internal static async Task LogAsync(IEnumerable graphs, Rem { var tasks = graphs.SelectMany(graph => graph.Unresolved.Select(e => GetMessageAsync( - graph.TargetGraphName, + graph.TargetGraphNameWithAlias, e, context.FilterDependencyProvidersForLibrary(e), context.PackageSourceMapping.IsEnabled, diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/IRestoreTargetGraph.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/IRestoreTargetGraph.cs index b6a81dae3f0..e41c83881a5 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/IRestoreTargetGraph.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/IRestoreTargetGraph.cs @@ -12,6 +12,8 @@ namespace NuGet.Commands { public interface IRestoreTargetGraph { + string TargetGraphNameWithAlias { get; } + string TargetGraphName { get; } /// diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs index 5ee088b0058..305aa8ffcbe 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs @@ -50,11 +50,7 @@ public LockFile CreateLockFile(LockFile previousLockFile, if (project.RestoreMetadata?.ProjectStyle == ProjectStyle.PackageReference) { - AddProjectFileDependenciesForPackageReference(project, lockFile, targetGraphs); - } - else - { - AddProjectFileDependenciesForSpec(project, lockFile); + AddProjectFileDependenciesForPackageReference(project, lockFile, targetGraphs.AsList()); } // Record all libraries used @@ -164,12 +160,20 @@ public LockFile CreateLockFile(LockFile previousLockFile, .OrderBy(graph => graph.Framework.ToString(), StringComparer.Ordinal) .ThenBy(graph => graph.RuntimeIdentifier, StringComparer.Ordinal)) { - var target = new LockFileTarget - { - TargetFramework = targetGraph.Framework, - RuntimeIdentifier = targetGraph.RuntimeIdentifier, - TargetAlias = targetGraph.TargetAlias, - }; + var target = lockFile.Version >= 4 ? + new LockFileTarget + { + TargetFramework = targetGraph.Framework, + RuntimeIdentifier = targetGraph.RuntimeIdentifier, + TargetAlias = targetGraph.TargetAlias, + Name = targetGraph.TargetGraphNameWithAlias + } : + new LockFileTarget + { + TargetFramework = targetGraph.Framework, + RuntimeIdentifier = targetGraph.RuntimeIdentifier, + TargetAlias = targetGraph.TargetAlias, + }; var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, project, targetGraph); @@ -266,7 +270,7 @@ public LockFile CreateLockFile(LockFile previousLockFile, NuGetLogCode.NU1701, message, library.Name, - targetGraph.TargetGraphName); + targetGraph.TargetGraphNameWithAlias); _logger.Log(logMessage); @@ -391,42 +395,25 @@ private static string GetFallbackFrameworkString(NuGetFramework framework) return string.Join(", ", frameworks); } - private static void AddProjectFileDependenciesForSpec(PackageSpec project, LockFile lockFile) + private static void AddProjectFileDependenciesForPackageReference(PackageSpec project, LockFile lockFile, List targetGraphs) { - // Use empty string as the key of dependencies shared by all frameworks - lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( - string.Empty, - project.Dependencies - .Select(group => group.LibraryRange.ToLockFileDependencyGroupString()) - .OrderBy(group => group, StringComparer.Ordinal))); + bool isV4LockFile = lockFile.Version >= 4; foreach (var frameworkInfo in project.TargetFrameworks - .OrderBy(framework => framework.FrameworkName.ToString(), - StringComparer.Ordinal)) - { - lockFile.ProjectFileDependencyGroups.Add(new ProjectFileDependencyGroup( - frameworkInfo.FrameworkName.ToString(), - frameworkInfo.Dependencies - .Select(x => x.LibraryRange.ToLockFileDependencyGroupString()) - .OrderBy(dependency => dependency, StringComparer.Ordinal))); - } - } - - private static void AddProjectFileDependenciesForPackageReference(PackageSpec project, LockFile lockFile, IEnumerable targetGraphs) - { - // For NETCore put everything under a TFM section - // Projects are included for NETCore - foreach (var frameworkInfo in project.TargetFrameworks - .OrderBy(framework => framework.FrameworkName.ToString(), + .OrderBy(framework => framework.TargetAlias, StringComparer.Ordinal)) { var dependencies = new List(); dependencies.AddRange(project.Dependencies.Select(e => e.LibraryRange)); dependencies.AddRange(frameworkInfo.Dependencies.Select(e => e.LibraryRange)); - var targetGraph = targetGraphs.SingleOrDefault(graph => - graph.Framework.Equals(frameworkInfo.FrameworkName) - && string.IsNullOrEmpty(graph.RuntimeIdentifier)); + RestoreTargetGraph targetGraph = !string.IsNullOrEmpty(frameworkInfo.TargetAlias) ? + targetGraphs.SingleOrDefault(graph => + graph.TargetAlias.Equals(frameworkInfo.TargetAlias) + && string.IsNullOrEmpty(graph.RuntimeIdentifier)) : + targetGraphs.SingleOrDefault(graph => + graph.Framework.Equals(frameworkInfo.FrameworkName) + && string.IsNullOrEmpty(graph.RuntimeIdentifier)); var resolvedEntry = targetGraph? .Flattened @@ -452,8 +439,9 @@ private static void AddProjectFileDependenciesForPackageReference(PackageSpec pr } // Add entry + string framework = isV4LockFile && string.IsNullOrEmpty(frameworkInfo.TargetAlias) ? frameworkInfo.FrameworkName.ToString() : frameworkInfo.TargetAlias; var dependencyGroup = new ProjectFileDependencyGroup( - frameworkInfo.FrameworkName.ToString(), + framework, uniqueDependencies.Select(x => x.ToLockFileDependencyGroupString()) .OrderBy(dependency => dependency, StringComparer.Ordinal)); diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/ProjectRestoreCommand.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/ProjectRestoreCommand.cs index 4ce4da3356e..de8999f05e0 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/ProjectRestoreCommand.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/ProjectRestoreCommand.cs @@ -52,6 +52,8 @@ public async Task, RuntimeGraph>> TryRestor TelemetryActivity telemetryActivity, string telemetryPrefix) { + // Aliasing should only be supported in new world. + // TODO NK - this is where we do the splitting var allRuntimes = RuntimeGraph.Empty; var frameworkTasks = new List>(); var graphs = new List(); @@ -315,7 +317,7 @@ internal async Task ResolutionSucceeded(IEnumerable gr string.Join(", ", conflict.Requests), graphName); - _logger.Log(RestoreLogMessage.CreateError(NuGetLogCode.NU1106, message, conflict.Name, graph.TargetGraphName)); + _logger.Log(RestoreLogMessage.CreateError(NuGetLogCode.NU1106, message, conflict.Name, graph.TargetGraphNameWithAlias)); } } diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/RequestFactory/RestoreArgs.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/RequestFactory/RestoreArgs.cs index 891cede13b2..a6ba61860b3 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/RequestFactory/RestoreArgs.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/RequestFactory/RestoreArgs.cs @@ -201,6 +201,8 @@ public void ApplyStandardProperties(RestoreRequest request) request.RequestedRuntimes.UnionWith(Runtimes); request.FallbackRuntimes.UnionWith(FallbackRuntimes); + + // TODO NK - set-up the lock file version here. request.LockFileVersion = LockFileFormat.Version; // Run runtime asset checks for project.json, and for other types if enabled. diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs index d53dd665f1c..66e9c02e927 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs @@ -152,7 +152,7 @@ public RestoreCommand(RestoreRequest request) _lockFileBuilderCache = request.LockFileBuilderCache; // Validate the lock file version requested - if (_request.LockFileVersion < 1 || _request.LockFileVersion > LockFileFormat.Version) + if (_request.LockFileVersion < 1 || _request.LockFileVersion > LockFileFormat.LatestVersion) { throw new ArgumentOutOfRangeException( paramName: nameof(request), @@ -247,7 +247,7 @@ public async Task ExecuteAsync(CancellationToken token) // if success == false, it generates an empty restore graph suitable to create an assets file with errors. // Since the graph is empty, any code that analyzes the graph (like audit) will have nothing to do. - (successfulResult, var graphs) = await GenerateRestoreGraphsAsync(telemetry, contextForProject, success, token); + (successfulResult, List graphs) = await GenerateRestoreGraphsAsync(telemetry, contextForProject, success, token); success &= successfulResult; bool auditRan = false; @@ -572,9 +572,9 @@ private async Task return new EvaluateLockFileResult(success, isLockFileValid, regenerateLockFile, packagesLockFilePath, packagesLockFile); } - private async Task<(bool, IEnumerable)> GenerateRestoreGraphsAsync(TelemetryActivity telemetry, RemoteWalkContext contextForProject, bool success, CancellationToken token) + private async Task<(bool, List)> GenerateRestoreGraphsAsync(TelemetryActivity telemetry, RemoteWalkContext contextForProject, bool success, CancellationToken token) { - IEnumerable graphs = null; + List graphs = null; if (success) { using (telemetry.StartIndependentInterval(GenerateRestoreGraphDuration)) @@ -613,19 +613,19 @@ private async Task graphs = frameworkRuntimePair.Select(e => { return RestoreTargetGraph.Create(_request.Project.RuntimeGraph, Enumerable.Empty>(), contextForProject, _logger, e.TargetAlias, e.Framework, e.RuntimeIdentifier); - }); + }).ToList(); } return (success, graphs); } - private async Task<(bool, IEnumerable, string, string, LockFile, IEnumerable, PackagesLockFile, string, CacheFile)> ProcessRestoreResultAsync(TelemetryActivity telemetry, + private async Task<(bool, IEnumerable, string, string, LockFile, List, PackagesLockFile, string, CacheFile)> ProcessRestoreResultAsync(TelemetryActivity telemetry, List localRepositories, RemoteWalkContext contextForProject, bool isLockFileValid, bool regenerateLockFile, LockFile assetsFile, - IEnumerable graphs, + List graphs, PackagesLockFile packagesLockFile, string packagesLockFilePath, CacheFile cacheFile, @@ -664,9 +664,6 @@ private async Task _logger); } - // If the request is for a lower lock file version, downgrade it appropriately - DowngradeLockFileIfNeeded(assetsFile); - // Revert to the original case if needed await FixCaseForLegacyReaders(graphs, assetsFile, token); @@ -1437,14 +1434,6 @@ private string GetAssetsFilePath(LockFile lockFile) return Path.GetFullPath(projectLockFilePath); } - private void DowngradeLockFileIfNeeded(LockFile lockFile) - { - if (_request.LockFileVersion <= 1) - { - DowngradeLockFileToV1(lockFile); - } - } - private async Task FixCaseForLegacyReaders( IEnumerable graphs, LockFile lockFile, @@ -1468,7 +1457,7 @@ private async Task FixCaseForLegacyReaders( private LockFile BuildAssetsFile( LockFile existingLockFile, PackageSpec project, - IEnumerable graphs, + List graphs, IReadOnlyList localRepositories, RemoteWalkContext contextForProject) { @@ -1521,7 +1510,7 @@ private static async Task ValidateCyclesAsync(IEnumerable ValidateConflictsAsync(IEnumerable _request.Project.Name) + $" {Environment.NewLine} {versionConflict.Selected.GetPathWithLastRange()} {Environment.NewLine} {versionConflict.Conflicting.GetPathWithLastRange()}."; - await logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1107, message, versionConflict.Selected.Key.Name, graph.TargetGraphName)); + await logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1107, message, versionConflict.Selected.Key.Name, graph.TargetGraphNameWithAlias)); return false; } } @@ -1598,11 +1587,11 @@ internal static Task LogDowngradeWarningsOrErrorsAsync(IEnumerable> VerifyCompatibilityAs checkResults.Add(res); if (res.Success) { - await logger.LogAsync(LogLevel.Verbose, string.Format(CultureInfo.CurrentCulture, Strings.Log_PackagesAndProjectsAreCompatible, graph.TargetGraphName)); + await logger.LogAsync(LogLevel.Verbose, string.Format(CultureInfo.CurrentCulture, Strings.Log_PackagesAndProjectsAreCompatible, graph.TargetGraphNameWithAlias)); } else { @@ -1662,7 +1651,7 @@ private static async Task> VerifyCompatibilityAs return checkResults; } - private async Task<(bool, IEnumerable)> ExecuteLegacyRestoreAsync( + private async Task<(bool, List)> ExecuteLegacyRestoreAsync( NuGetv3LocalRepository userPackageFolder, IReadOnlyList fallbackPackageFolders, RemoteWalkContext context, @@ -1676,7 +1665,7 @@ private static async Task> VerifyCompatibilityAs await _logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1001, message)); success = false; - return (success, Enumerable.Empty()); + return (success, []); } _logger.LogInformation(string.Format(CultureInfo.CurrentCulture, Strings.Log_RestoringPackages, _request.Project.FilePath)); @@ -1839,7 +1828,7 @@ private static async Task> VerifyCompatibilityAs return (success, allGraphs); } - private async Task<(bool, IEnumerable)> ExecuteRestoreAsync( + private async Task<(bool, List)> ExecuteRestoreAsync( NuGetv3LocalRepository userPackageFolder, IReadOnlyList fallbackPackageFolders, RemoteWalkContext context, @@ -1854,7 +1843,7 @@ private static async Task> VerifyCompatibilityAs success = false; - return (success, Enumerable.Empty()); + return (success, []); } var projectRestoreRequest = new ProjectRestoreRequest(_request, _request.Project, _request.ExistingLockFile, _logger) @@ -2058,37 +2047,6 @@ private static RemoteWalkContext CreateRemoteWalkContext(RestoreRequest request, return context; } - private static void DowngradeLockFileToV1(LockFile lockFile) - { - // Remove projects from the library section - var libraryProjects = lockFile.Libraries.Where(lib => lib.Type == LibraryType.Project).ToArray(); - - foreach (var library in libraryProjects) - { - lockFile.Libraries.Remove(library); - } - - // Remove projects from the targets section - foreach (var target in lockFile.Targets) - { - var targetProjects = target.Libraries.Where(lib => lib.Type == LibraryType.Project).ToArray(); - - foreach (var library in targetProjects) - { - target.Libraries.Remove(library); - } - } - - foreach (var library in lockFile.Targets.SelectMany(target => target.Libraries)) - { - // Null out all target types, these did not exist in v1 - library.Type = null; - } - - // Remove the package spec - lockFile.PackageSpec = null; - } - private static ExternalProjectReference ToExternalProjectReference(PackageSpec project) { return new ExternalProjectReference( diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreTargetGraph.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreTargetGraph.cs index 794edd91e8d..07f074ae05a 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreTargetGraph.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreTargetGraph.cs @@ -1,8 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Linq; using NuGet.Client; using NuGet.Common; @@ -53,6 +55,8 @@ public class RestoreTargetGraph : IRestoreTargetGraph public string TargetGraphName { get; } + public string TargetGraphNameWithAlias { get; } + // TODO: Move conflicts to AnalyzeResult public IEnumerable Conflicts { get; } @@ -79,6 +83,7 @@ internal RestoreTargetGraph(IEnumerable conflicts, Framework = framework; Graphs = graphs; TargetGraphName = FrameworkRuntimePair.GetTargetGraphName(Framework, RuntimeIdentifier); + TargetGraphNameWithAlias = GetTargetGraphName(TargetAlias, RuntimeIdentifier); Conventions = new ManagedCodeConventions(runtimeGraph); Install = install; @@ -88,6 +93,24 @@ internal RestoreTargetGraph(IEnumerable conflicts, ResolvedDependencies = resolvedDependencies; } + internal static string GetTargetGraphName(string targetAlias, string runtimeIdentifier) + { + if (targetAlias is null) throw new ArgumentNullException(nameof(targetAlias)); + + if (string.IsNullOrEmpty(runtimeIdentifier)) + { + return targetAlias; + } + else + { + return string.Format( + CultureInfo.InvariantCulture, + "{0}/{1}", + targetAlias, + runtimeIdentifier); + } + } + internal static RestoreTargetGraph Create(IEnumerable> graphs, RemoteWalkContext context, ILogger logger, string targetAlias, NuGetFramework framework) { return Create(RuntimeGraph.Empty, graphs, context, logger, targetAlias, framework, runtimeIdentifier: null); diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/AuditUtility.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/AuditUtility.cs index 16555041361..fe930e71f21 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/AuditUtility.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/AuditUtility.cs @@ -425,9 +425,9 @@ private static (string severityLabel, NuGetLogCode code) GetSeverityLabelAndCode } // Multiple package sources might list the same known vulnerability, so de-dupe those too. - if (!affectedGraphs.Contains(graph.TargetGraphName)) + if (!affectedGraphs.Contains(graph.TargetGraphNameWithAlias)) { - affectedGraphs.Add(graph.TargetGraphName); + affectedGraphs.Add(graph.TargetGraphNameWithAlias); } if (!auditInfo.IsDirect && diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/MSBuildRestoreUtility.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/MSBuildRestoreUtility.cs index 5560cd209cd..591f7e253be 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/MSBuildRestoreUtility.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/MSBuildRestoreUtility.cs @@ -500,7 +500,7 @@ private static IEnumerable GetTargetFrameworkInforma FrameworkName = targetFramework, Imports = imports, RuntimeIdentifierGraphPath = runtimeIdentifierGraphPath, - TargetAlias = targetAlias, + TargetAlias = string.IsNullOrEmpty(targetAlias) ? targetFramework.ToString() : targetAlias, Warn = warn }; diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/PackageSpecFactory.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/PackageSpecFactory.cs index eb1831faee7..39187d32331 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/PackageSpecFactory.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/PackageSpecFactory.cs @@ -237,7 +237,7 @@ internal static List GetTargetFrameworkInfos(IProjec FrameworkReferences = GetFrameworkReferences(msBuildProjectInstance), PackagesToPrune = prunedReferences, RuntimeIdentifierGraphPath = msBuildProjectInstance.GetProperty(nameof(TargetFrameworkInformation.RuntimeIdentifierGraphPath)), - TargetAlias = targetAlias, + TargetAlias = string.IsNullOrEmpty(targetAlias) ? targetFramework.ToString() : targetAlias, Warn = warn }; diff --git a/src/NuGet.Core/NuGet.DependencyResolver.Core/Remote/RemoteDependencyWalker.cs b/src/NuGet.Core/NuGet.DependencyResolver.Core/Remote/RemoteDependencyWalker.cs index 21994191e6a..7e9052ff677 100644 --- a/src/NuGet.Core/NuGet.DependencyResolver.Core/Remote/RemoteDependencyWalker.cs +++ b/src/NuGet.Core/NuGet.DependencyResolver.Core/Remote/RemoteDependencyWalker.cs @@ -20,6 +20,7 @@ public class RemoteDependencyWalker { private readonly RemoteWalkContext _context; + // Play around with changing the inside types. public RemoteDependencyWalker(RemoteWalkContext context) { _context = context; diff --git a/src/NuGet.Core/NuGet.DependencyResolver.Core/ResolverUtility.cs b/src/NuGet.Core/NuGet.DependencyResolver.Core/ResolverUtility.cs index 379edc38466..2491033f213 100644 --- a/src/NuGet.Core/NuGet.DependencyResolver.Core/ResolverUtility.cs +++ b/src/NuGet.Core/NuGet.DependencyResolver.Core/ResolverUtility.cs @@ -173,6 +173,7 @@ private static async Task> CreateGraphItemAsync( if (cacheContext == null) throw new ArgumentNullException(nameof(cacheContext)); if (logger == null) throw new ArgumentNullException(nameof(logger)); + // TODO NK - This is where we might want to do things based on the alias, but this can be a second phase too. var projectMatch = await FindProjectMatchAsync(libraryRange, framework, projectProviders, cancellationToken); if (projectMatch != null) diff --git a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFile.cs b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFile.cs index 0186fba332b..e2968ce9481 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFile.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFile.cs @@ -36,6 +36,7 @@ public LockFileTarget GetTarget(NuGetFramework framework, string runtimeIdentifi string.Equals(runtimeIdentifier, t.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase)))); } + // todo nk - project file dependency group. public LockFileTarget GetTarget(string frameworkAlias, string runtimeIdentifier) { var framework = PackageSpec.TargetFrameworks.FirstOrDefault(tfi => tfi.TargetAlias.Equals(frameworkAlias, StringComparison.OrdinalIgnoreCase))?.FrameworkName; diff --git a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileExtensions.cs b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileExtensions.cs index cf3e3a11516..3b93d71f929 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileExtensions.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileExtensions.cs @@ -32,7 +32,7 @@ public static IEnumerable GetTargetGraphs(this IAssetsLogMessage return assetsFile.Targets; } - return assetsFile.Targets.Where(target => message.TargetGraphs.Contains(target.Name, StringComparer.OrdinalIgnoreCase)); + return assetsFile.Targets.Where(target => message.TargetGraphs.Contains(target.TargetAlias + (string.IsNullOrEmpty(target.RuntimeIdentifier) ? "" : "/" + target.RuntimeIdentifier), StringComparer.OrdinalIgnoreCase)); } /// diff --git a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs index e97d9e18fce..8ce9f11d6a9 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs @@ -16,6 +16,7 @@ namespace NuGet.ProjectModel public class LockFileFormat { public static readonly int Version = 3; + public static readonly int LatestVersion = 4; // If this is ever renamed, you should also rename NoOpRestoreUtilities.NoOpCacheFileName to keep them in sync. public static readonly string AssetsFileName = "project.assets.json"; @@ -174,7 +175,10 @@ private static void WriteLockFile(JsonWriter writer, IObjectWriter jsonObjectWri JsonUtility.WriteObject(writer, lockFile.Libraries, WriteLibrary); writer.WritePropertyName(ProjectFileDependencyGroupsProperty); - JsonUtility.WriteObject(writer, lockFile.ProjectFileDependencyGroups, WriteProjectFileDependencyGroup); + if (lockFile.Version <= 3) + { + JsonUtility.WriteObject(writer, lockFile.ProjectFileDependencyGroups, WriteProjectFileDependencyGroup); + } if (lockFile.PackageFolders?.Any() == true) { @@ -187,11 +191,16 @@ private static void WriteLockFile(JsonWriter writer, IObjectWriter jsonObjectWri if (lockFile.PackageSpec != null) { writer.WritePropertyName(PackageSpecProperty); - jsonObjectWriter.WriteObjectStart(); - - PackageSpecWriter.Write(lockFile.PackageSpec, jsonObjectWriter); - + if (lockFile.Version >= 4) + { + // TODO NK + PackageSpecWriter.Write(lockFile.PackageSpec, jsonObjectWriter); + } + else + { + PackageSpecWriter.Write(lockFile.PackageSpec, jsonObjectWriter); + } jsonObjectWriter.WriteObjectEnd(); } } diff --git a/src/NuGet.Core/NuGet.ProjectModel/LockFile/Utf8JsonStreamLockFileConverter.cs b/src/NuGet.Core/NuGet.ProjectModel/LockFile/Utf8JsonStreamLockFileConverter.cs index 1b2518b9e9e..a41c203cd65 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/LockFile/Utf8JsonStreamLockFileConverter.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/LockFile/Utf8JsonStreamLockFileConverter.cs @@ -84,7 +84,14 @@ public LockFile Read(ref Utf8JsonStreamReader reader, LockFileReadFlags flags) if ((flags & LockFileReadFlags.Targets) == LockFileReadFlags.Targets) { - lockFile.Targets = reader.ReadObjectAsList(Utf8JsonReaderExtensions.LockFileTargetConverter); + if (lockFile.Version >= 4) + { + lockFile.Targets = reader.ReadObjectAsList(Utf8JsonReaderExtensions.LockFileTargetConverterV4); + } + else + { + lockFile.Targets = reader.ReadObjectAsList(Utf8JsonReaderExtensions.LockFileTargetConverter); + } } else { @@ -126,12 +133,25 @@ public LockFile Read(ref Utf8JsonStreamReader reader, LockFileReadFlags flags) if ((flags & LockFileReadFlags.PackageSpec) == LockFileReadFlags.PackageSpec) { - lockFile.PackageSpec = JsonPackageSpecReader.GetPackageSpec( + if (lockFile.Version >= 4) + { + // TODO NK + lockFile.PackageSpec = JsonPackageSpecReader.GetPackageSpec( ref reader, name: null, packageSpecPath: null, EnvironmentVariableWrapper.Instance, snapshotValue: null); + } + else + { + lockFile.PackageSpec = JsonPackageSpecReader.GetPackageSpec( + ref reader, + name: null, + packageSpecPath: null, + EnvironmentVariableWrapper.Instance, + snapshotValue: null); + } } else { @@ -195,6 +215,14 @@ public LockFile Read(ref Utf8JsonStreamReader reader, LockFileReadFlags flags) } } + if (lockFile.Version >= 4) + { + foreach (var target in lockFile.Targets) + { + target.TargetFramework = lockFile.PackageSpec.GetRestoreMetadataFramework(target.TargetAlias).FrameworkName; + } + } + var projectPath = lockFile.PackageSpec?.RestoreMetadata?.ProjectPath; if (!string.IsNullOrEmpty(projectPath) && lockFile.LogMessages.Count > 0) { diff --git a/src/NuGet.Core/NuGet.ProjectModel/LockFile/Utf8JsonStreamLockFileTargetConverterV4.cs b/src/NuGet.Core/NuGet.ProjectModel/LockFile/Utf8JsonStreamLockFileTargetConverterV4.cs new file mode 100644 index 00000000000..dd5827c1298 --- /dev/null +++ b/src/NuGet.Core/NuGet.ProjectModel/LockFile/Utf8JsonStreamLockFileTargetConverterV4.cs @@ -0,0 +1,39 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Text.Json; + +namespace NuGet.ProjectModel +{ + /// + /// A to allow read JSON into + /// + /// + /// "net45/win8": { + /// , + /// } + /// + internal class Utf8JsonStreamLockFileTargetConverterV4 : IUtf8JsonStreamReaderConverter + { + public LockFileTarget Read(ref Utf8JsonStreamReader reader) + { + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException("Expected PropertyName, found " + reader.TokenType); + } + + var lockFileTarget = new LockFileTarget(); + //We want to read the property name right away + var propertyName = reader.GetString(); + var (targetFramework, runTimeFramework) = propertyName.SplitInTwo(LockFile.DirectorySeparatorChar); + + lockFileTarget.TargetAlias = targetFramework; + lockFileTarget.RuntimeIdentifier = runTimeFramework; + + reader.Read(); + lockFileTarget.Libraries = reader.ReadObjectAsList(Utf8JsonReaderExtensions.LockFileTargetLibraryConverter); + + return lockFileTarget; + } + } +} diff --git a/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Unshipped.txt index 3e0f078be37..c7def0cc5b6 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Unshipped.txt @@ -1,4 +1,5 @@ #nullable enable +static readonly NuGet.ProjectModel.LockFileFormat.LatestVersion -> int ~NuGet.ProjectModel.LockFileTarget.Name.init -> void ~NuGet.ProjectModel.LockFileTarget.TargetAlias.get -> string ~NuGet.ProjectModel.LockFileTarget.TargetAlias.set -> void diff --git a/src/NuGet.Core/NuGet.ProjectModel/TargetFrameworkInformation.cs b/src/NuGet.Core/NuGet.ProjectModel/TargetFrameworkInformation.cs index 5e540212cab..6a1b5bfe844 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/TargetFrameworkInformation.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/TargetFrameworkInformation.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using NuGet.Common; using NuGet.Frameworks; using NuGet.LibraryModel; @@ -23,7 +24,7 @@ public class TargetFrameworkInformation : IEquatable public string TargetAlias { get; init; } = string.Empty; - public NuGetFramework FrameworkName { get; init; } + public required NuGetFramework FrameworkName { get; init; } public ImmutableArray Dependencies { @@ -112,6 +113,7 @@ public IReadOnlyDictionary PackagesToPrune /// public string RuntimeIdentifierGraphPath { get; init; } + [SetsRequiredMembers] public TargetFrameworkInformation() { TargetAlias = string.Empty; @@ -123,6 +125,7 @@ public TargetFrameworkInformation() PackagesToPrune = ImmutableDictionary.Empty; } + [SetsRequiredMembers] public TargetFrameworkInformation(TargetFrameworkInformation cloneFrom) { TargetAlias = cloneFrom.TargetAlias; diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonReaderExtensions.cs b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonReaderExtensions.cs index bf53c40bba2..2a2e584fc2a 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonReaderExtensions.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonReaderExtensions.cs @@ -15,6 +15,7 @@ internal static class Utf8JsonReaderExtensions internal static readonly Utf8JsonStreamLockFileTargetLibraryConverter LockFileTargetLibraryConverter = new Utf8JsonStreamLockFileTargetLibraryConverter(); internal static readonly Utf8JsonStreamLockFileLibraryConverter LockFileLibraryConverter = new Utf8JsonStreamLockFileLibraryConverter(); internal static readonly Utf8JsonStreamLockFileTargetConverter LockFileTargetConverter = new Utf8JsonStreamLockFileTargetConverter(); + internal static readonly Utf8JsonStreamLockFileTargetConverterV4 LockFileTargetConverterV4 = new Utf8JsonStreamLockFileTargetConverterV4(); internal static readonly Utf8JsonStreamProjectFileDependencyGroupConverter ProjectFileDepencencyGroupConverter = new Utf8JsonStreamProjectFileDependencyGroupConverter(); internal static readonly Utf8JsonStreamIAssetsLogMessageConverter IAssetsLogMessageConverter = new Utf8JsonStreamIAssetsLogMessageConverter(); diff --git a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/UWPRestoreTests.cs b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/UWPRestoreTests.cs index 56d39883256..e71f09f0ce8 100644 --- a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/UWPRestoreTests.cs +++ b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/UWPRestoreTests.cs @@ -372,7 +372,7 @@ static Task RunRestoreAsync(SimpleTestPathContext pathContext, pa } // Verify that File > New Project > Class Library (Portable) can restore without errors or warnings. - [Fact] + [Fact(Skip = "https://github.com/NuGet/Client.Engineering/issues/3008")] public async Task UWPRestore_ModernPCL() { // Arrange diff --git a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs index c89db8981ee..e50daab4052 100644 --- a/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Commands.Test/RestoreCommandTests/RestoreCommandTests.cs @@ -1811,7 +1811,8 @@ public async Task RestoreCommand_LogDowngradeWarningsOrErrorsAsync_ErrorWhenCpvm var centralPackageName = "D"; var centralPackageVersion = "2.0.0"; var otherVersion = "3.0.0"; - NuGetFramework framework = NuGetFramework.Parse("net45"); + string targetAlias = "net45"; + NuGetFramework framework = NuGetFramework.Parse(targetAlias); var logger = new TestLogger(); var context = new TestRemoteWalkContext(); diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileExtensionsTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileExtensionsTests.cs index abe2b6f4b30..d14f67f19b9 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileExtensionsTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileExtensionsTests.cs @@ -16,8 +16,10 @@ public class LockFileExtensionsTests public void GivenALogMessageVerifyTargetGraphIsReturned() { var assetsFile = new LockFile(); + var expected = "net45"; assetsFile.Targets.Add(new LockFileTarget() { + TargetAlias = expected, TargetFramework = NuGetFramework.Parse("net45"), }); @@ -27,12 +29,11 @@ public void GivenALogMessageVerifyTargetGraphIsReturned() Version = NuGetVersion.Parse("1.0.0") }); - var expected = NuGetFramework.Parse("net45").DotNetFrameworkName; var message = new AssetsLogMessage(LogLevel.Warning, NuGetLogCode.NU1103, "test", expected); var graphs = message.GetTargetGraphs(assetsFile); - graphs.Select(e => e.Name).Should().BeEquivalentTo(new[] { expected }); + graphs.Select(e => e.Name).Should().BeEquivalentTo(new[] { expected }); // TODO NK - This makes an argument for tying all the changes together. } [Fact] @@ -68,6 +69,7 @@ public void GivenALogMessageWithNoTargetGraphsVerifyAllGraphsAreReturned() var assetsFile = new LockFile(); assetsFile.Targets.Add(new LockFileTarget() { + TargetAlias = "net45", TargetFramework = NuGetFramework.Parse("net45"), });