Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,7 @@ private async ValueTask<IList<LockFileTarget>> GetTargetsListAsync(string assets
ct.ThrowIfCancellationRequested();

await TaskScheduler.Default;

LockFile lockFile = LockFileUtilities.GetLockFile(assetsFilePath, NullLogger.Instance, LockFileReadFlags.PackageFolders | LockFileReadFlags.Targets);
LockFile lockFile = LockFileUtilities.GetLockFile(assetsFilePath, NullLogger.Instance, LockFileReadFlags.PackageFolders | LockFileReadFlags.Targets | LockFileReadFlags.PackageSpec);
_packageFolders = lockFile?.PackageFolders ?? Array.Empty<LockFileItem>();

return lockFile?.Targets;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,11 @@
using Microsoft.Build.Utilities;
using NuGet.Common;
using NuGet.Frameworks;

#if NETFRAMEWORK || NETSTANDARD
using System.Linq;
#endif

namespace NuGet.Build.Tasks
{
public class GetReferenceNearestTargetFrameworkTask : Microsoft.Build.Utilities.Task
public class GetReferenceNearestTargetFrameworkTask : Task
{
private const string NEAREST_TARGET_FRAMEWORK = "NearestTargetFramework";
private const string TARGET_FRAMEWORKS = "TargetFrameworks";
Expand All @@ -41,6 +38,12 @@ public class GetReferenceNearestTargetFrameworkTask : Microsoft.Build.Utilities.
/// </summary>
public string CurrentProjectTargetPlatform { get; set; }

/// <summary>
/// The value of the current project's TargetFramework property.
/// </summary>

public string CurrentProjectTargetFrameworkProperty { get; set; }

/// <summary>
/// Optional list of target frameworks to be used as Fallback target frameworks.
/// </summary>
Expand Down Expand Up @@ -147,8 +150,8 @@ private ITaskItem AssignNearestFrameworkForSingleReference(
useTargetMonikers ? referencedProjectTargetPlatformMonikers[i] : null));
}

// try project framework
var nearestNuGetFramework = NuGetFrameworkUtility.GetNearest(targetFrameworkInformations, projectNuGetFramework, GetNuGetFramework);
var nearestNuGetFramework = GetNearestTargetFramework(targetFrameworkInformations, projectNuGetFramework, CurrentProjectTargetFrameworkProperty);

if (nearestNuGetFramework != null)
{
itemWithProperties.SetMetadata(NEAREST_TARGET_FRAMEWORK, nearestNuGetFramework._targetFrameworkAlias);
Expand All @@ -158,7 +161,7 @@ private ITaskItem AssignNearestFrameworkForSingleReference(
// try project fallback frameworks
foreach (var currentProjectTargetFramework in fallbackNuGetFrameworks)
{
nearestNuGetFramework = NuGetFrameworkUtility.GetNearest(targetFrameworkInformations, currentProjectTargetFramework, GetNuGetFramework);
nearestNuGetFramework = GetNearestTargetFramework(targetFrameworkInformations, currentProjectTargetFramework, null);

if (nearestNuGetFramework != null)
{
Expand Down Expand Up @@ -250,6 +253,76 @@ public TargetFrameworkInformation(string targetFrameworkAlias, string targetFram
_targetPlatformMoniker = targetPlatformMoniker;
}
}

private static TargetFrameworkInformation GetNearestTargetFramework(List<TargetFrameworkInformation> tfis, NuGetFramework targetFramework, string targetAlias)
{
TargetFrameworkInformation result = null;
List<TargetFrameworkInformation> frameworks = null;
FindMatchingFrameworks(tfis, targetFramework, ref result, ref frameworks);

// We matched a single framework.
if (result != null && frameworks == null)
{
return result;
}

// No exact match found, find the nearest
if (result == null || frameworks == null)
{
var reducer = new FrameworkReducer(DefaultFrameworkNameProvider.Instance, DefaultCompatibilityProvider.Instance);

NuGetFramework mostCompatibleFramework = reducer.GetNearest(targetFramework, tfis.Select(GetNuGetFramework));
FindMatchingFrameworks(tfis, mostCompatibleFramework, ref result, ref frameworks);
}

// We matched a single framework.
if (result != null && frameworks == null)
{
return result;
}

// Multiple matchingFrameworks matched exactly, use target alias to disambiguate
if (result != null && frameworks != null)
{
foreach (var framework in frameworks)
{
if (string.Equals(framework._targetFrameworkAlias, targetAlias, StringComparison.OrdinalIgnoreCase))
{
return framework;
}
}
}

return null;

static void FindMatchingFrameworks(List<TargetFrameworkInformation> tfis, NuGetFramework targetFramework, ref TargetFrameworkInformation matchedFramework, ref List<TargetFrameworkInformation> matchingFrameworks)
{
if (targetFramework == null)
{
return;
}
foreach (TargetFrameworkInformation framework in tfis)
{
if (NuGetFramework.Comparer.Equals(targetFramework, GetNuGetFramework(framework)))
{
// Result not being null means we have multiple matches.
if (matchedFramework != null)
{
if (matchingFrameworks == null)
{
matchingFrameworks = [matchedFramework, framework];
}
else
{
matchingFrameworks.Add(framework);
}
}
matchedFramework = framework;
}
}
}
}

}

}
2 changes: 2 additions & 0 deletions src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ Copyright (c) .NET Foundation. All rights reserved.
<PackageDownloadSupported>true</PackageDownloadSupported>
<!-- Mark that this targets file GetReferenceNearestTargetFrameworkTask task supports the TargetPlatformMoniker -->
<GetReferenceNearestTargetFrameworkTaskSupportsTargetPlatformParameter>true</GetReferenceNearestTargetFrameworkTaskSupportsTargetPlatformParameter>
<!-- Mark that this targets file GetReferenceNearestTargetFrameworkTask task supports the TargetFramework -->
<GetReferenceNearestTargetFrameworkTaskSupportsTargetFrameworKPropertyParameter>true</GetReferenceNearestTargetFrameworkTaskSupportsTargetFrameworKPropertyParameter>
<!-- Flag if the Central package file is enabled -->
<_CentralPackageVersionsEnabled Condition="'$(ManagePackageVersionsCentrally)' == 'true' AND '$(CentralPackageVersionsFileImported)' == 'true'">true</_CentralPackageVersionsEnabled>
</PropertyGroup>
Expand Down
1 change: 0 additions & 1 deletion src/NuGet.Core/NuGet.Commands/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@
[assembly: SuppressMessage("Build", "CA1303:Method 'void PackCommandRunner.PrintVerbose(string outputPath, PackageBuilder builder)' passes a literal string as parameter 'message' of a call to 'void PackCommandRunner.WriteLine(string message, object arg = null)'. Retrieve the following string(s) from a resource table instead: \"Version: {0}\".", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.Commands.PackCommandRunner.PrintVerbose(System.String,NuGet.Packaging.PackageBuilder)")]
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void PackCommandRunner.SetupCurrentDirectory(PackArgs packArgs)', validate parameter 'packArgs' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.Commands.PackCommandRunner.SetupCurrentDirectory(NuGet.Commands.PackArgs)")]
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void RemoveSourceRunner.Run(RemoveSourceArgs args, Func<ILogger> getLogger)', validate parameter 'getLogger' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.Commands.RemoveSourceRunner.Run(NuGet.Commands.RemoveSourceArgs,System.Func{NuGet.Common.ILogger})")]
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void RestoreArgs.ApplyStandardProperties(RestoreRequest request)', validate parameter 'request' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.Commands.RestoreArgs.ApplyStandardProperties(NuGet.Commands.RestoreRequest)")]
[assembly: SuppressMessage("Build", "CA1822:Member GetEffectiveFallbackPackageFolders does not access instance data and can be marked as static (Shared in VisualBasic)", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.Commands.RestoreArgs.GetEffectiveFallbackPackageFolders(NuGet.Configuration.ISettings)~System.Collections.Generic.IReadOnlyList{System.String}")]
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'void RestoreCollectorLogger.ApplyRestoreInputs(PackageSpec projectSpec)', validate parameter 'projectSpec' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.Commands.RestoreCollectorLogger.ApplyRestoreInputs(NuGet.ProjectModel.PackageSpec)")]
[assembly: SuppressMessage("Build", "CA1062:In externally visible method 'bool RestoreCollectorLogger.DisplayMessage(IRestoreLogMessage message)', validate parameter 'message' is non-null before using it. If appropriate, throw an ArgumentNullException when the argument is null or add a Code Contract precondition asserting non-null argument.", Justification = "<Pending>", Scope = "member", Target = "~M:NuGet.Commands.RestoreCollectorLogger.DisplayMessage(NuGet.Common.IRestoreLogMessage)~System.Boolean")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#nullable enable
~NuGet.Commands.SourceRepositoryDependencyProvider.FindLibraryAsync(NuGet.LibraryModel.LibraryRange! libraryRange, NuGet.Frameworks.NuGetFramework! targetFramework, string! targetAlias, NuGet.Protocol.Core.Types.SourceCacheContext! cacheContext, NuGet.Common.ILogger! logger, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<NuGet.LibraryModel.LibraryIdentity!>!
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ public async Task<ValueTuple<bool, List<RestoreTargetGraph>, RuntimeGraph>> Reso
_rootProjectLibraryDependency.LibraryRange,
frameworkRuntimeDefinition.Framework,
runtimeIdentifier: string.IsNullOrWhiteSpace(frameworkRuntimeDefinition.RuntimeIdentifier) ? null : frameworkRuntimeDefinition.RuntimeIdentifier,
frameworkRuntimeDefinition.TargetAlias,
context,
token),
Parent = LibraryRangeIndex.None
Expand Down Expand Up @@ -1394,6 +1395,7 @@ .. chosenResolvedItem.Suppressions
childDependency.LibraryRange,
pair.Framework,
runtimeIdentifier: string.IsNullOrWhiteSpace(pair.RuntimeIdentifier) ? null : pair.RuntimeIdentifier,
pair.TargetAlias,
context,
token)
};
Expand Down
41 changes: 27 additions & 14 deletions src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,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.TargetGraphName
} :
new LockFileTarget
{
TargetFramework = targetGraph.Framework,
RuntimeIdentifier = targetGraph.RuntimeIdentifier,
TargetAlias = targetGraph.TargetAlias,
};

var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, project, targetGraph);

Expand Down Expand Up @@ -389,20 +397,24 @@ private static string GetFallbackFrameworkString(NuGetFramework framework)
return string.Join(", ", frameworks);
}

private static void AddProjectFileDependenciesForPackageReference(PackageSpec project, LockFile lockFile, IEnumerable<RestoreTargetGraph> targetGraphs)
private static void AddProjectFileDependenciesForPackageReference(PackageSpec project, LockFile lockFile, List<RestoreTargetGraph> targetGraphs)
{
// For NETCore put everything under a TFM section
// Projects are included for NETCore
bool isV4LockFile = lockFile.Version >= 4;

foreach (var frameworkInfo in project.TargetFrameworks
.OrderBy(framework => framework.FrameworkName.ToString(),
.OrderBy(framework => framework.TargetAlias,
StringComparer.Ordinal))
{
var dependencies = new List<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 =>
frameworkInfo.TargetAlias.Equals(graph.TargetAlias)
&& string.IsNullOrEmpty(graph.RuntimeIdentifier)) :
targetGraphs.SingleOrDefault(graph =>
graph.Framework.Equals(frameworkInfo.FrameworkName)
&& string.IsNullOrEmpty(graph.RuntimeIdentifier));

var resolvedEntry = targetGraph?
.Flattened
Expand All @@ -428,8 +440,9 @@ private static void AddProjectFileDependenciesForPackageReference(PackageSpec pr
}

// Add entry
string framework = (isV4LockFile && string.IsNullOrEmpty(frameworkInfo.TargetAlias)) ? frameworkInfo.TargetAlias : frameworkInfo.FrameworkName.ToString();
var dependencyGroup = new ProjectFileDependencyGroup(
frameworkInfo.FrameworkName.ToString(),
framework,
uniqueDependencies.Select(x => x.ToLockFileDependencyGroupString())
.OrderBy(dependency => dependency, StringComparer.Ordinal));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ private List<SourceRepository> GetEffectiveSourcesCore(ISettings settings, IList

public void ApplyStandardProperties(RestoreRequest request)
{
if (request == null) throw new ArgumentNullException(nameof(request));

if (request.ProjectStyle == ProjectStyle.PackageReference)
{
request.LockFilePath = Path.Combine(request.RestoreOutputPath, LockFileFormat.AssetsFileName);
Expand All @@ -203,7 +205,8 @@ public void ApplyStandardProperties(RestoreRequest request)

request.RequestedRuntimes.UnionWith(Runtimes);
request.FallbackRuntimes.UnionWith(FallbackRuntimes);
request.LockFileVersion = LockFileFormat.Version;
// Use v3 for classic csproj.
request.LockFileVersion = request.Project.RestoreMetadata?.UsingMicrosoftNETSdk == true ? LockFileFormat.Version : 3;

// Run runtime asset checks for project.json, and for other types if enabled.
if (ValidateRuntimeAssets == null)
Expand Down
Loading