Skip to content
Merged
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 @@ -155,21 +155,13 @@ internal static TargetFrameworkInformation ToTargetFrameworkInformation(
internal static NuGetFramework GetTargetFramework(IVsProjectProperties properties, string projectFullPath)
{
var targetFrameworkMoniker = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetFrameworkMoniker);
var targetFrameworkIdentifier = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetFrameworkIdentifier);
var targetFrameworkVersion = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetFrameworkVersion);
var targetFrameworkProfile = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetFrameworkProfile);
var targetPlatformIdentifier = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetPlatformIdentifier);
var targetPlatformVersion = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetPlatformVersion);
var targetPlatformMoniker = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetPlatformIdentifier);
var targetPlatformMinVersion = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetPlatformMinVersion);

return MSBuildProjectFrameworkUtility.GetProjectFramework(
projectFullPath,
targetFrameworkMoniker,
targetFrameworkIdentifier,
targetFrameworkVersion,
targetFrameworkProfile,
targetPlatformIdentifier,
targetPlatformVersion,
targetPlatformMoniker,
targetPlatformMinVersion);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -532,11 +532,7 @@ internal static List<TargetFrameworkInformation> GetTargetFrameworkInfos(IReadOn
NuGetFramework targetFramework = MSBuildProjectFrameworkUtility.GetProjectFramework(
projectFilePath: projectInnerNode.Value.FullPath,
targetFrameworkMoniker: msBuildProjectInstance.GetProperty("TargetFrameworkMoniker"),
targetFrameworkIdentifier: msBuildProjectInstance.GetProperty("TargetFrameworkIdentifier"),
targetFrameworkVersion: msBuildProjectInstance.GetProperty("TargetFrameworkVersion"),
targetFrameworkProfile: msBuildProjectInstance.GetProperty("TargetFrameworkProfile"),
targetPlatformIdentifier: msBuildProjectInstance.GetProperty("TargetPlatformIdentifier"),
targetPlatformVersion: msBuildProjectInstance.GetProperty("TargetPlatformVersion"),
targetPlatformMoniker: msBuildProjectInstance.GetProperty("TargetPlatformMoniker"),
targetPlatformMinVersion: msBuildProjectInstance.GetProperty("TargetPlatformMinVersion"));

var targetFrameworkInformation = new TargetFrameworkInformation()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// 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.Globalization;
using System.Linq;
Expand All @@ -15,6 +16,8 @@ public class GetReferenceNearestTargetFrameworkTask : Task
{
private const string NEAREST_TARGET_FRAMEWORK = "NearestTargetFramework";
private const string TARGET_FRAMEWORKS = "TargetFrameworks";
private const string TARGET_FRAMEWORK_MONIKERS = "TargetFrameworkMonikers";
private const string TARGET_PLATFORM_MONIKERS = "TargetPlatformMonikers";
private const string MSBUILD_SOURCE_PROJECT_FILE = "MSBuildSourceProjectFile";

/// <summary>
Expand All @@ -28,6 +31,11 @@ public class GetReferenceNearestTargetFrameworkTask : Task
[Required]
public string CurrentProjectTargetFramework { get; set; }

/// <summary>
/// Optional TargetPlatformMoniker
/// </summary>
public string CurrentProjectTargetPlatform { get; set; }

/// <summary>
/// Optional list of target frameworks to be used as Fallback target frameworks.
/// </summary>
Expand All @@ -51,6 +59,8 @@ public override bool Execute()

BuildTasksUtility.LogInputParam(logger, nameof(CurrentProjectTargetFramework), CurrentProjectTargetFramework);

BuildTasksUtility.LogInputParam(logger, nameof(CurrentProjectTargetPlatform), CurrentProjectTargetPlatform);

BuildTasksUtility.LogInputParam(logger, nameof(FallbackTargetFrameworks),
FallbackTargetFrameworks == null
? ""
Expand All @@ -69,8 +79,8 @@ public override bool Execute()
var fallbackNuGetFrameworks = new List<NuGetFramework>();

// validate current project framework
var errorMessage = string.Format(Strings.UnsupportedTargetFramework, CurrentProjectTargetFramework);
if (!TryParseFramework(CurrentProjectTargetFramework, errorMessage, logger, out var projectNuGetFramework))
var errorMessage = string.Format(CultureInfo.CurrentCulture, Strings.UnsupportedTargetFramework, $"TargetFrameworkMoniker: {CurrentProjectTargetFramework}, TargetPlatformMoniker:{CurrentProjectTargetPlatform}");
if (!TryParseFramework(CurrentProjectTargetFramework, CurrentProjectTargetPlatform, errorMessage, logger, out var projectNuGetFramework))
{
return false;
}
Expand All @@ -81,7 +91,7 @@ public override bool Execute()
foreach (var fallbackFramework in FallbackTargetFrameworks)
{
// validate ATF project frameworks
errorMessage = string.Format(Strings.UnsupportedFallbackFramework, fallbackFramework);
errorMessage = string.Format(CultureInfo.CurrentCulture, Strings.UnsupportedFallbackFramework, fallbackFramework);
if (!TryParseFramework(fallbackFramework, errorMessage, logger, out var nugetFramework))
{
return false;
Expand Down Expand Up @@ -112,6 +122,9 @@ private ITaskItem AssignNearestFrameworkForSingleReference(
{
var itemWithProperties = new TaskItem(project);
var referencedProjectFrameworkString = project.GetMetadata(TARGET_FRAMEWORKS);
var referenceTargetFrameworkMonikers = project.GetMetadata(TARGET_FRAMEWORK_MONIKERS);
var referencedProjectPlatformString = project.GetMetadata(TARGET_PLATFORM_MONIKERS);

var referencedProjectFile = project.GetMetadata(MSBUILD_SOURCE_PROJECT_FILE);

if (string.IsNullOrEmpty(referencedProjectFrameworkString))
Expand All @@ -121,19 +134,43 @@ private ITaskItem AssignNearestFrameworkForSingleReference(
}

var referencedProjectFrameworks = MSBuildStringUtility.Split(referencedProjectFrameworkString);
var referencedProjectTargetFrameworkMonikers = MSBuildStringUtility.Split(referenceTargetFrameworkMonikers);
var referencedProjectTargetPlatformMonikers = MSBuildStringUtility.Split(referencedProjectPlatformString);

if(referencedProjectTargetFrameworkMonikers.Length > 0 &&
(referencedProjectTargetFrameworkMonikers.Length != referencedProjectTargetPlatformMonikers.Length ||
referencedProjectTargetFrameworkMonikers.Length != referencedProjectFrameworks.Length))
{
logger.LogError($"Internal error for {CurrentProjectName}." +
$" Expected {TARGET_FRAMEWORKS}:{referencedProjectFrameworks}, " +
$"{TARGET_FRAMEWORK_MONIKERS}:{referenceTargetFrameworkMonikers}, " +
$"{TARGET_PLATFORM_MONIKERS}:{referencedProjectPlatformString} to have the same number of elements.");
return itemWithProperties;
}
// TargetFrameworks, TargetFrameworkMoniker, TargetPlatforMoniker
var targetFrameworkInformations = new List<TargetFrameworkInformation>();
var useTargetMonikers = referencedProjectTargetFrameworkMonikers.Length > 0;
for (int i = 0; i < referencedProjectFrameworks.Length; i++)
{

targetFrameworkInformations.Add(new TargetFrameworkInformation(
referencedProjectFrameworks[i],
useTargetMonikers ? referencedProjectTargetFrameworkMonikers[i] : null,
useTargetMonikers ? referencedProjectTargetPlatformMonikers[i] : null));
}

// try project framework
var nearestNuGetFramework = NuGetFrameworkUtility.GetNearest(referencedProjectFrameworks, projectNuGetFramework, NuGetFramework.Parse);
var nearestNuGetFramework = NuGetFrameworkUtility.GetNearest(targetFrameworkInformations, projectNuGetFramework, GetNuGetFramework);
if (nearestNuGetFramework != null)
{
itemWithProperties.SetMetadata(NEAREST_TARGET_FRAMEWORK, nearestNuGetFramework);
itemWithProperties.SetMetadata(NEAREST_TARGET_FRAMEWORK, nearestNuGetFramework._targetFrameworkAlias);
return itemWithProperties;
}

// try project fallback frameworks
foreach (var currentProjectTargetFramework in fallbackNuGetFrameworks)
{
nearestNuGetFramework = NuGetFrameworkUtility.GetNearest(referencedProjectFrameworks, currentProjectTargetFramework, NuGetFramework.Parse);
nearestNuGetFramework = NuGetFrameworkUtility.GetNearest(targetFrameworkInformations, currentProjectTargetFramework, GetNuGetFramework);

if (nearestNuGetFramework != null)
{
Expand All @@ -150,13 +187,13 @@ private ITaskItem AssignNearestFrameworkForSingleReference(
// log NU1702 for ATF on project reference
logger.Log(warning);

itemWithProperties.SetMetadata(NEAREST_TARGET_FRAMEWORK, nearestNuGetFramework);
itemWithProperties.SetMetadata(NEAREST_TARGET_FRAMEWORK, nearestNuGetFramework._targetFrameworkAlias);
return itemWithProperties;
}
}

// no match found
logger.LogError(string.Format(Strings.NoCompatibleTargetFramework, project.ItemSpec, CurrentProjectTargetFramework, referencedProjectFrameworkString));
logger.LogError(string.Format(CultureInfo.CurrentCulture, Strings.NoCompatibleTargetFramework, project.ItemSpec, projectNuGetFramework.DotNetFrameworkName, referencedProjectFrameworkString));
return itemWithProperties;
}

Expand All @@ -173,5 +210,51 @@ private static bool TryParseFramework(string framework, string errorMessage, MSB

return true;
}

private static bool TryParseFramework(string targetFrameworkMoniker, string targetPlatformMoniker, string errorMessage, MSBuildLogger logger, out NuGetFramework nugetFramework)
{
// Check if we have a long name.
nugetFramework = targetFrameworkMoniker.Contains(',')
? NuGetFramework.ParseComponents(targetFrameworkMoniker, targetPlatformMoniker)
: NuGetFramework.Parse(targetFrameworkMoniker);

// validate framework
if (nugetFramework.IsUnsupported)
{
logger.LogError(errorMessage);
return false;
}

return true;
}

private static NuGetFramework GetNuGetFramework(TargetFrameworkInformation targetFrameworkInformation)
{
// Legacy path, process targetFrameworks if empty
if (string.IsNullOrEmpty(targetFrameworkInformation._targetFrameworkMoniker))
{
return NuGetFramework.Parse(targetFrameworkInformation._targetFrameworkAlias);
}

// TargetFrameworkMoniker is always expected to be set. TargetPlatformMoniker will have a `None` value when empty, for frameworks like net5.0.
return NuGetFramework.ParseComponents(targetFrameworkInformation._targetFrameworkMoniker,
targetFrameworkInformation._targetPlatformMoniker.Equals("None", StringComparison.OrdinalIgnoreCase) ?
string.Empty :
targetFrameworkInformation._targetPlatformMoniker);
}
}

internal class TargetFrameworkInformation
{
internal readonly string _targetFrameworkAlias;
internal readonly string _targetFrameworkMoniker;
internal readonly string _targetPlatformMoniker;

public TargetFrameworkInformation(string targetFrameworkAlias, string targetFrameworkMoniker, string targetPlatformMoniker)
{
_targetFrameworkAlias = targetFrameworkAlias;
_targetFrameworkMoniker = targetFrameworkMoniker;
_targetPlatformMoniker = targetPlatformMoniker;
}
}
}
Loading