diff --git a/src/NuGet.Clients/NuGet.CommandLine/Commands/ProjectFactory.cs b/src/NuGet.Clients/NuGet.CommandLine/Commands/ProjectFactory.cs index cff42a24767..8eb76d5d328 100644 --- a/src/NuGet.Clients/NuGet.CommandLine/Commands/ProjectFactory.cs +++ b/src/NuGet.Clients/NuGet.CommandLine/Commands/ProjectFactory.cs @@ -131,7 +131,7 @@ private void Initialize(dynamic project) string targetFrameworkMoniker = _project.GetPropertyValue("TargetFrameworkMoniker"); if (!String.IsNullOrEmpty(targetFrameworkMoniker)) { - TargetFramework = new FrameworkName(targetFrameworkMoniker); + TargetFramework = NuGetFramework.Parse(targetFrameworkMoniker); } // This happens before we obtain warning properties, so this Logger is still IConsole. @@ -170,7 +170,7 @@ private string TargetPath set; } - private FrameworkName TargetFramework + private NuGetFramework TargetFramework { get; set; @@ -804,7 +804,7 @@ private void AddOutputFiles(Packaging.PackageBuilder builder) } else { - nugetFramework = TargetFramework != null ? NuGetFramework.Parse(TargetFramework.FullName) : null; + nugetFramework = TargetFramework; } var projectOutputDirectory = Path.GetDirectoryName(TargetPath); @@ -1001,7 +1001,7 @@ private void AddDependencies(Dictionary>(() => ReverseTransform(file, transforms), isThreadSafe: false); - TargetFramework = FrameworkNameUtility.ParseFrameworkNameFromFilePath(Path, out _effectivePath); + NuGetFramework = NuGet.Packaging.FrameworkNameUtility.ParseNuGetFrameworkFromFilePath(Path, out _effectivePath); + if (NuGetFramework != null && NuGetFramework.Version.Major < 5) + { + TargetFramework = new FrameworkName(NuGetFramework.DotNetFrameworkName); + } } public string Path @@ -1484,6 +1488,12 @@ public FrameworkName TargetFramework get; private set; } + + public NuGetFramework NuGetFramework + { + get; + private set; + } } } } diff --git a/src/NuGet.Core/NuGet.Frameworks/CompatibilityProvider.cs b/src/NuGet.Core/NuGet.Frameworks/CompatibilityProvider.cs index 6a9ff3c09a7..7b7f638a408 100644 --- a/src/NuGet.Core/NuGet.Frameworks/CompatibilityProvider.cs +++ b/src/NuGet.Core/NuGet.Frameworks/CompatibilityProvider.cs @@ -181,18 +181,18 @@ private bool IsCompatibleWithTarget(NuGetFramework target, NuGetFramework candid private static bool IsCompatibleWithTargetCore(NuGetFramework target, NuGetFramework candidate) { - if (target.IsNet5Era) - { - return NuGetFramework.FrameworkNameComparer.Equals(target, candidate) - && IsVersionCompatible(target.Version, candidate.Version) - && (!candidate.HasProfile || StringComparer.OrdinalIgnoreCase.Equals(target.Profile, candidate.Profile)); - } - else - { - return NuGetFramework.FrameworkNameComparer.Equals(target, candidate) + bool result = NuGetFramework.FrameworkNameComparer.Equals(target, candidate) && IsVersionCompatible(target.Version, candidate.Version) && StringComparer.OrdinalIgnoreCase.Equals(target.Profile, candidate.Profile); + + if (target.IsNet5Era && candidate.HasPlatform) + { + result = result + && StringComparer.OrdinalIgnoreCase.Equals(target.Platform, candidate.Platform) + && IsVersionCompatible(target.PlatformVersion, candidate.PlatformVersion); } + + return result; } private static bool IsVersionCompatible(Version target, Version candidate) diff --git a/src/NuGet.Core/NuGet.Frameworks/FrameworkConstants.cs b/src/NuGet.Core/NuGet.Frameworks/FrameworkConstants.cs index 4375a402675..14a8f374ccc 100644 --- a/src/NuGet.Core/NuGet.Frameworks/FrameworkConstants.cs +++ b/src/NuGet.Core/NuGet.Frameworks/FrameworkConstants.cs @@ -34,13 +34,6 @@ public static class PlatformIdentifiers public const string Windows = "Windows"; } - /// - /// Allowed list of profiles in Net5.0ERA - /// - internal static HashSet FrameworkProfiles - = new HashSet(StringComparer.OrdinalIgnoreCase) - { }; - public static class FrameworkIdentifiers { public const string NetCoreApp = ".NETCoreApp"; diff --git a/src/NuGet.Core/NuGet.Frameworks/NuGetFramework.cs b/src/NuGet.Core/NuGet.Frameworks/NuGetFramework.cs index 2354726b1cc..d16e829c109 100644 --- a/src/NuGet.Core/NuGet.Frameworks/NuGetFramework.cs +++ b/src/NuGet.Core/NuGet.Frameworks/NuGetFramework.cs @@ -37,13 +37,16 @@ public NuGetFramework(string framework) } public NuGetFramework(string framework, Version version) - : this(framework, version, null) + : this(framework, version, string.Empty, FrameworkConstants.EmptyVersion) { } private const int Version5 = 5; - public NuGetFramework(string frameworkIdentifier, Version frameworkVersion, string frameworkProfile) + /// + /// Creates a new NuGetFramework instance, with an optional profile (only available for netframework) + /// + public NuGetFramework(string frameworkIdentifier, Version frameworkVersion, string profile) { if (frameworkIdentifier == null) { @@ -57,8 +60,47 @@ public NuGetFramework(string frameworkIdentifier, Version frameworkVersion, stri _frameworkIdentifier = frameworkIdentifier; _frameworkVersion = NormalizeVersion(frameworkVersion); - _frameworkProfile = frameworkProfile ?? string.Empty; + IsNet5Era = (_frameworkVersion.Major >= Version5 && StringComparer.OrdinalIgnoreCase.Equals(FrameworkConstants.FrameworkIdentifiers.NetCoreApp, _frameworkIdentifier)); + + _frameworkProfile = profile ?? string.Empty; + Platform = string.Empty; + PlatformVersion = FrameworkConstants.EmptyVersion; + } + + /// + /// Creates a new NuGetFramework instance, with an optional platform and platformVersion (only available for net5.0+) + /// + public NuGetFramework(string frameworkIdentifier, Version frameworkVersion, string platform, Version platformVersion) + { + if (frameworkIdentifier == null) + { + throw new ArgumentNullException("frameworkIdentifier"); + } + + if (frameworkVersion == null) + { + throw new ArgumentNullException("frameworkVersion"); + } + + if (platform == null) + { + throw new ArgumentNullException("platform"); + } + + if (platformVersion == null) + { + throw new ArgumentNullException("platformVersion"); + } + + _frameworkIdentifier = frameworkIdentifier; + _frameworkVersion = NormalizeVersion(frameworkVersion); + _frameworkProfile = string.Empty; + + IsNet5Era = (_frameworkVersion.Major >= Version5 && StringComparer.OrdinalIgnoreCase.Equals(FrameworkConstants.FrameworkIdentifiers.NetCoreApp, _frameworkIdentifier)); + + Platform = IsNet5Era ? platform : string.Empty; + PlatformVersion = IsNet5Era ? NormalizeVersion(platformVersion) : FrameworkConstants.EmptyVersion; } /// @@ -77,6 +119,32 @@ public Version Version get { return _frameworkVersion; } } + /// + /// Framework Platform (net5.0+) + /// + public string Platform + { + get; + private set; + } + + /// + /// Framework Platform Version (net5.0+) + /// + public Version PlatformVersion + { + get; + private set; + } + + /// + /// True if the platform is non-empty + /// + public bool HasPlatform + { + get { return !string.IsNullOrEmpty(Platform); } + } + /// /// True if the profile is non-empty /// @@ -112,9 +180,11 @@ public string GetDotNetFrameworkName(IFrameworkNameProvider mappings) // Check for rewrites var framework = mappings.GetFullNameReplacement(this); - var result = string.Empty; - - if (framework.IsSpecificFramework) + if (framework.IsNet5Era) + { + return GetShortFolderName(); + } + else if (framework.IsSpecificFramework) { var parts = new List(3) { Framework }; @@ -125,14 +195,12 @@ public string GetDotNetFrameworkName(IFrameworkNameProvider mappings) parts.Add(string.Format(CultureInfo.InvariantCulture, "Profile={0}", framework.Profile)); } - result = string.Join(",", parts); + return string.Join(",", parts); } else { - result = string.Format(CultureInfo.InvariantCulture, "{0},Version=v0.0", framework.Framework); + return string.Format(CultureInfo.InvariantCulture, "{0},Version=v0.0", framework.Framework); } - - return result; } /// @@ -218,6 +286,19 @@ public virtual string GetShortFolderName(IFrameworkNameProvider mappings) framework.DotNetFrameworkName)); } } + else if (IsNet5Era) + { + if (!string.IsNullOrEmpty(framework.Platform)) + { + sb.Append("-"); + sb.Append(framework.Platform.ToLowerInvariant()); + + if (framework.PlatformVersion != FrameworkConstants.EmptyVersion) + { + sb.Append(mappings.GetVersionString(framework.Framework, framework.PlatformVersion)); + } + } + } else { // add the profile @@ -350,7 +431,7 @@ public bool IsSpecificFramework /// /// True if this framework is Net5 or later, until we invent something new. /// - internal bool IsNet5Era { get; set; } + internal bool IsNet5Era { get; private set; } /// /// Full framework comparison of the identifier, version, profile, platform, and platform version diff --git a/src/NuGet.Core/NuGet.Frameworks/NuGetFrameworkFactory.cs b/src/NuGet.Core/NuGet.Frameworks/NuGetFrameworkFactory.cs index 6f1bf93696a..d2d160bdc1d 100644 --- a/src/NuGet.Core/NuGet.Frameworks/NuGetFrameworkFactory.cs +++ b/src/NuGet.Core/NuGet.Frameworks/NuGetFrameworkFactory.cs @@ -92,18 +92,19 @@ public static NuGetFramework ParseFrameworkName(string frameworkName, IFramework // if the first part is a special framework, ignore the rest if (!TryParseSpecialFramework(parts[0], out result)) { - string platform = null; - if (!mappings.TryGetIdentifier(parts[0], out platform)) + string framework = null; + if (!mappings.TryGetIdentifier(parts[0], out framework)) { - platform = parts[0]; + framework = parts[0]; } var version = new Version(0, 0); string profile = null; + string platform = null; + var platformVersion = new Version(0, 0); var versionPart = SingleOrDefaultSafe(parts.Where(s => s.IndexOf("Version=", StringComparison.OrdinalIgnoreCase) == 0)); var profilePart = SingleOrDefaultSafe(parts.Where(s => s.IndexOf("Profile=", StringComparison.OrdinalIgnoreCase) == 0)); - if (!string.IsNullOrEmpty(versionPart)) { var versionString = versionPart.Split('=')[1].TrimStart('v'); @@ -127,7 +128,7 @@ public static NuGetFramework ParseFrameworkName(string frameworkName, IFramework profile = profilePart.Split('=')[1]; } - if (StringComparer.OrdinalIgnoreCase.Equals(FrameworkConstants.FrameworkIdentifiers.Portable, platform) + if (StringComparer.OrdinalIgnoreCase.Equals(FrameworkConstants.FrameworkIdentifiers.Portable, framework) && !string.IsNullOrEmpty(profile) && profile.Contains("-")) { @@ -139,7 +140,15 @@ public static NuGetFramework ParseFrameworkName(string frameworkName, IFramework profile)); } - result = new NuGetFramework(platform, version, profile); + if (version.Major >= 5 + && StringComparer.OrdinalIgnoreCase.Equals(FrameworkConstants.FrameworkIdentifiers.NetCoreApp, framework)) + { + result = new NuGetFramework(framework, version, platform ?? string.Empty, platformVersion ?? FrameworkConstants.EmptyVersion); + } + else + { + result = new NuGetFramework(framework, version, profile); + } } return result; @@ -204,10 +213,22 @@ public static NuGetFramework ParseFolder(string folderName, IFrameworkNameProvid framework = FrameworkConstants.FrameworkIdentifiers.NetCoreApp; if (!string.IsNullOrEmpty(profileShort)) { - bool validProfile = FrameworkConstants.FrameworkProfiles.Contains(profileShort); - if (validProfile) + // Find a platform version if it exists and yank it out + var platformChars = profileShort; + var versionStart = 0; + while (versionStart < platformChars.Length + && IsLetterOrDot(platformChars[versionStart])) + { + versionStart++; + } + string platform = versionStart > 0 ? profileShort.Substring(0, versionStart) : profileShort; + string platformVersionString = versionStart > 0 ? profileShort.Substring(versionStart, profileShort.Length - versionStart) : null; + + // Parse the version if it's there. + Version platformVersion = FrameworkConstants.EmptyVersion; + if ((string.IsNullOrEmpty(platformVersionString) || mappings.TryGetVersion(platformVersionString, out platformVersion))) { - result = new NuGetFramework(framework, version, profileShort.ToLower()); + result = new NuGetFramework(framework, version, platform ?? string.Empty, platformVersion ?? FrameworkConstants.EmptyVersion); } else { @@ -216,7 +237,7 @@ public static NuGetFramework ParseFolder(string folderName, IFrameworkNameProvid } else { - result = new NuGetFramework(framework, version, string.Empty); + result = new NuGetFramework(framework, version, string.Empty, FrameworkConstants.EmptyVersion); } } else diff --git a/src/NuGet.Core/NuGet.Frameworks/comparers/NuGetFrameworkFullComparer.cs b/src/NuGet.Core/NuGet.Frameworks/comparers/NuGetFrameworkFullComparer.cs index 29204626880..c57b943a26f 100644 --- a/src/NuGet.Core/NuGet.Frameworks/comparers/NuGetFrameworkFullComparer.cs +++ b/src/NuGet.Core/NuGet.Frameworks/comparers/NuGetFrameworkFullComparer.cs @@ -33,6 +33,8 @@ public bool Equals(NuGetFramework x, NuGetFramework y) return x.Version == y.Version && StringComparer.OrdinalIgnoreCase.Equals(x.Framework, y.Framework) && StringComparer.OrdinalIgnoreCase.Equals(x.Profile, y.Profile) + && StringComparer.OrdinalIgnoreCase.Equals(x.Platform, y.Platform) + && x.PlatformVersion == y.PlatformVersion && !x.IsUnsupported; } diff --git a/src/NuGet.Core/NuGet.Localization/NuGet.Localization.nuspec b/src/NuGet.Core/NuGet.Localization/NuGet.Localization.nuspec index 93d562a50b6..2614ea84eba 100644 --- a/src/NuGet.Core/NuGet.Localization/NuGet.Localization.nuspec +++ b/src/NuGet.Core/NuGet.Localization/NuGet.Localization.nuspec @@ -11,9 +11,12 @@ © Microsoft Corporation. All rights reserved. NuGet localization package. nuget + + + - \ No newline at end of file + diff --git a/src/NuGet.Core/NuGet.Packaging/Core/FrameworkNameValidatorUtility.cs b/src/NuGet.Core/NuGet.Packaging/Core/FrameworkNameValidatorUtility.cs index a2c4291dead..a177563d9fd 100644 --- a/src/NuGet.Core/NuGet.Packaging/Core/FrameworkNameValidatorUtility.cs +++ b/src/NuGet.Core/NuGet.Packaging/Core/FrameworkNameValidatorUtility.cs @@ -19,11 +19,11 @@ internal static bool IsValidFrameworkName(NuGetFramework framework) internal static bool IsValidFrameworkName(string path) { - FrameworkName fx; + NuGetFramework fx; try { string effectivePath; - fx = FrameworkNameUtility.ParseFrameworkNameFromFilePath(path, out effectivePath); + fx = FrameworkNameUtility.ParseNuGetFrameworkFromFilePath(path, out effectivePath); } catch (ArgumentException) { @@ -31,7 +31,7 @@ internal static bool IsValidFrameworkName(string path) } // return false if the framework is Null or Unsupported - return fx != null && fx.Identifier != NuGetFramework.UnsupportedFramework.Framework; + return fx != null && fx.Framework != NuGetFramework.UnsupportedFramework.Framework; } internal static bool IsValidCultureName(PackageArchiveReader builder, string name) diff --git a/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/IPackageFile.cs b/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/IPackageFile.cs index 7cd339d57b7..6fbf21936ed 100644 --- a/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/IPackageFile.cs +++ b/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/IPackageFile.cs @@ -5,6 +5,7 @@ using System; using System.IO; using System.Runtime.Versioning; +using NuGet.Frameworks; namespace NuGet.Packaging { @@ -32,11 +33,23 @@ string EffectivePath get; } + /// + /// FrameworkName object representing this package file's target framework. Deprecated. Must be null on net5.0 and greater. + /// + [Obsolete("Use NuGetFramework instead. This property will be null for any frameworks net5.0 or above.")] FrameworkName TargetFramework { get; } + /// + /// NuGetFramework object representing this package file's target framework. Use this instead of TargetFramework. + /// + NuGetFramework NuGetFramework + { + get; + } + DateTimeOffset LastWriteTime { get; diff --git a/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/PackageBuilder.cs b/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/PackageBuilder.cs index e433838a3ec..8c324c1a6ac 100644 --- a/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/PackageBuilder.cs +++ b/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/PackageBuilder.cs @@ -498,8 +498,8 @@ private static bool RequiresV4TargetFrameworkSchema(ICollection fi { // check if any file under Content or Tools has TargetFramework defined bool hasContentOrTool = files.Any( - f => f.TargetFramework != null && - f.TargetFramework.Identifier != FrameworkConstants.SpecialIdentifiers.Unsupported && + f => f.NuGetFramework != null && + !f.NuGetFramework.IsUnsupported && (f.Path.StartsWith(PackagingConstants.Folders.Content + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) || f.Path.StartsWith(PackagingConstants.Folders.Tools + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))); @@ -510,7 +510,7 @@ private static bool RequiresV4TargetFrameworkSchema(ICollection fi // now check if the Lib folder has any empty framework folder bool hasEmptyLibFolder = files.Any( - f => f.TargetFramework != null && + f => f.NuGetFramework != null && f.Path.StartsWith(PackagingConstants.Folders.Lib + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) && f.EffectivePath == PackagingConstants.PackageEmptyFileName); diff --git a/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/PhysicalPackageFile.cs b/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/PhysicalPackageFile.cs index ca3574c4e0d..4629cb7516a 100644 --- a/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/PhysicalPackageFile.cs +++ b/src/NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/PhysicalPackageFile.cs @@ -4,6 +4,7 @@ using System; using System.IO; using System.Runtime.Versioning; +using NuGet.Frameworks; namespace NuGet.Packaging { @@ -12,6 +13,7 @@ public class PhysicalPackageFile : IPackageFile private readonly Func _streamFactory; private string _targetPath; private FrameworkName _targetFramework; + private NuGetFramework _nugetFramework; private DateTimeOffset _lastWriteTime; public PhysicalPackageFile() @@ -46,11 +48,15 @@ public string TargetPath } set { - if (String.Compare(_targetPath, value, StringComparison.OrdinalIgnoreCase) != 0) + if (string.Compare(_targetPath, value, StringComparison.OrdinalIgnoreCase) != 0) { _targetPath = value; string effectivePath; - _targetFramework = FrameworkNameUtility.ParseFrameworkNameFromFilePath(_targetPath, out effectivePath); + _nugetFramework = FrameworkNameUtility.ParseNuGetFrameworkFromFilePath(_targetPath, out effectivePath); + if (_nugetFramework != null && _nugetFramework.Version.Major < 5) + { + _targetFramework = new FrameworkName(_nugetFramework.DotNetFrameworkName); + } EffectivePath = effectivePath; } } @@ -75,6 +81,11 @@ public FrameworkName TargetFramework get { return _targetFramework; } } + public NuGetFramework NuGetFramework + { + get { return _nugetFramework; } + } + public Stream GetStream() { if (_streamFactory != null) diff --git a/src/NuGet.Core/NuGet.Packaging/PackageCreation/Extensions/FrameworksExtensions.cs b/src/NuGet.Core/NuGet.Packaging/PackageCreation/Extensions/FrameworksExtensions.cs index 457a40bf756..bc2f57b4824 100644 --- a/src/NuGet.Core/NuGet.Packaging/PackageCreation/Extensions/FrameworksExtensions.cs +++ b/src/NuGet.Core/NuGet.Packaging/PackageCreation/Extensions/FrameworksExtensions.cs @@ -1,8 +1,8 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.Runtime.Versioning; - using NuGet.Frameworks; namespace NuGet.Packaging @@ -10,9 +10,15 @@ namespace NuGet.Packaging public static class FrameworksExtensions { // NuGet.Frameworks doesn't have the equivalent of the old VersionUtility.GetFrameworkString - // which is relevant for building packages + // which is relevant for building packages. This isn't needed for net5.0+ frameworks. public static string GetFrameworkString(this NuGetFramework self) { + bool isNet5Era = (self.Version.Major >= 5 && StringComparer.OrdinalIgnoreCase.Equals(FrameworkConstants.FrameworkIdentifiers.NetCoreApp, self.Framework)); + if (isNet5Era) + { + return self.DotNetFrameworkName; + } + var frameworkName = new FrameworkName(self.DotNetFrameworkName); string name = frameworkName.Identifier + frameworkName.Version; if (string.IsNullOrEmpty(frameworkName.Profile)) diff --git a/src/NuGet.Core/NuGet.Packaging/PackageCreation/Utility/FrameworkNameUtility.cs b/src/NuGet.Core/NuGet.Packaging/PackageCreation/Utility/FrameworkNameUtility.cs index 519847f8cf2..647b1de1d5d 100644 --- a/src/NuGet.Core/NuGet.Packaging/PackageCreation/Utility/FrameworkNameUtility.cs +++ b/src/NuGet.Core/NuGet.Packaging/PackageCreation/Utility/FrameworkNameUtility.cs @@ -12,7 +12,6 @@ namespace NuGet.Packaging { public static class FrameworkNameUtility { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#")] public static FrameworkName ParseFrameworkNameFromFilePath(string filePath, out string effectivePath) { foreach (string knownFolder in PackagingConstants.Folders.Known) @@ -52,10 +51,9 @@ public static FrameworkName ParseFrameworkNameFromFilePath(string filePath, out /// if set to true, parse the first folder of path even if it is unrecognized framework. /// returns the path after the parsed target framework /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#")] public static FrameworkName ParseFrameworkFolderName(string path, bool strictParsing, out string effectivePath) { - // The path for a reference might look like this for assembly foo.dll: + // The path for a reference might look like this for assembly foo.dll: // foo.dll // sub\foo.dll // {FrameworkName}{Version}\foo.dll @@ -67,7 +65,7 @@ public static FrameworkName ParseFrameworkFolderName(string path, bool strictPar effectivePath = path; - if (String.IsNullOrEmpty(targetFrameworkString)) + if (string.IsNullOrEmpty(targetFrameworkString)) { return null; } @@ -83,5 +81,75 @@ public static FrameworkName ParseFrameworkFolderName(string path, bool strictPar return null; } + + public static NuGetFramework ParseNuGetFrameworkFromFilePath(string filePath, out string effectivePath) + { + foreach (string knownFolder in PackagingConstants.Folders.Known) + { + string folderPrefix = knownFolder + System.IO.Path.DirectorySeparatorChar; + if (filePath.Length > folderPrefix.Length && + filePath.StartsWith(folderPrefix, StringComparison.OrdinalIgnoreCase)) + { + string frameworkPart = filePath.Substring(folderPrefix.Length); + + try + { + return FrameworkNameUtility.ParseNuGetFrameworkFolderName( + frameworkPart, + strictParsing: knownFolder == PackagingConstants.Folders.Lib, + effectivePath: out effectivePath); + } + catch (ArgumentException) + { + // if the parsing fails, we treat it as if this file + // doesn't have target framework. + effectivePath = frameworkPart; + return null; + } + } + + } + + effectivePath = filePath; + return null; + } + + /// + /// Parses the specified string into FrameworkName object. + /// + /// The string to be parse. + /// if set to true, parse the first folder of path even if it is unrecognized framework. + /// returns the path after the parsed target framework + /// + public static NuGetFramework ParseNuGetFrameworkFolderName(string path, bool strictParsing, out string effectivePath) + { + // The path for a reference might look like this for assembly foo.dll: + // foo.dll + // sub\foo.dll + // {FrameworkName}{Version}\foo.dll + // {FrameworkName}{Version}\sub1\foo.dll + // {FrameworkName}{Version}\sub1\sub2\foo.dll + + // Get the target framework string if specified + string targetFrameworkString = Path.GetDirectoryName(path).Split(Path.DirectorySeparatorChar).First(); + + effectivePath = path; + + if (string.IsNullOrEmpty(targetFrameworkString)) + { + return null; + } + + var nugetFramework = NuGetFramework.ParseFolder(targetFrameworkString); + + if (strictParsing || nugetFramework.IsSpecificFramework) + { + // skip past the framework folder and the character \ + effectivePath = path.Substring(targetFrameworkString.Length + 1); + return nugetFramework; + } + + return null; + } } } diff --git a/test/NuGet.Clients.Tests/NuGet.VisualStudio.Implementation.Test/Extensibility/VsFrameworkCompatibilityTests.cs b/test/NuGet.Clients.Tests/NuGet.VisualStudio.Implementation.Test/Extensibility/VsFrameworkCompatibilityTests.cs index 3e0da0c3246..7bbe1263498 100644 --- a/test/NuGet.Clients.Tests/NuGet.VisualStudio.Implementation.Test/Extensibility/VsFrameworkCompatibilityTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.VisualStudio.Implementation.Test/Extensibility/VsFrameworkCompatibilityTests.cs @@ -52,6 +52,23 @@ public void VsFrameworkCompatibility_GetNearestRejectsNullFallbackFrameworks() Assert.Throws(() => target.GetNearest(targetFramework, fallbackTargetFrameworks, frameworks)); } + [Fact] + public void VsFrameworkCompatibility_GetNearestNet5EraFails() + { + // Arrange + var target = new VsFrameworkCompatibility(); + var targetFramework = new FrameworkName(".NETCoreApp,Version=v5.0"); + var frameworks = new[] { + new FrameworkName(".NETCoreApp,Version=v4.0"), + new FrameworkName(".NETCoreApp,Version=v5.0.0"), + new FrameworkName(".NETCoreApp,Version=v5.1.0"), + new FrameworkName(".NETCoreApp,Version=v6.0"), + }; + + // Act + Assert.Throws(() => target.GetNearest(targetFramework, frameworks)); + } + [Fact] public void VsFrameworkCompatibility_GetNearestWithNoneCompatible() { diff --git a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/PackCommandTests.cs b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/PackCommandTests.cs index 8b5a9e2ad6f..7e91c38d28b 100644 --- a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/PackCommandTests.cs +++ b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/PackCommandTests.cs @@ -639,6 +639,10 @@ public void PackCommand_PackProject_AddsProjectRefsAsPackageRefs() [PlatformTheory(Platform.Windows)] [InlineData("TargetFramework", "netstandard1.4")] [InlineData("TargetFrameworks", "netstandard1.4;net46")] +#if NETCOREAPP5_0 + [InlineData("TargetFramework", "net5.0")] + [InlineData("TargetFrameworks", "netstandard1.4;net5.0")] +#endif public void PackCommand_PackProject_ExactVersionOverrideProjectRefVersionInMsbuild(string tfmProperty, string tfmValue) { // Arrange @@ -727,6 +731,10 @@ public void PackCommand_PackProject_ExactVersionOverrideProjectRefVersionInMsbui [PlatformTheory(Platform.Windows)] [InlineData("TargetFramework", "netstandard1.4")] [InlineData("TargetFrameworks", "netstandard1.4;net46")] +#if NETCOREAPP5_0 + [InlineData("TargetFramework", "net5.0")] + [InlineData("TargetFrameworks", "netstandard1.4;net5.0")] +#endif public void PackCommand_PackProject_GetsProjectRefVersionFromMsbuild(string tfmProperty, string tfmValue) { // Arrange @@ -802,6 +810,10 @@ public void PackCommand_PackProject_GetsProjectRefVersionFromMsbuild(string tfmP [PlatformTheory(Platform.Windows)] [InlineData("TargetFramework", "netstandard1.4")] [InlineData("TargetFrameworks", "netstandard1.4;net46")] +#if NETCOREAPP5_0 + [InlineData("TargetFramework", "net5.0")] + [InlineData("TargetFrameworks", "netstandard1.4;net5.0")] +#endif public void PackCommand_PackProject_GetPackageVersionDependsOnWorks(string tfmProperty, string tfmValue) { // Arrange @@ -1658,6 +1670,80 @@ public void PackCommand_PackProject_OutputsContentFilesInNuspecForMultipleFramew } } +#if NETCOREAPP5_0 + [PlatformFact(Platform.Windows)] + public void PackCommand_SingleFramework_GeneratesPackageOnBuildUsingNet5() + { + using (var testDirectory = msbuildFixture.CreateTestDirectory()) + { + var projectName = "ClassLibrary1"; + var workingDirectory = Path.Combine(testDirectory, projectName); + var projectFile = Path.Combine(workingDirectory, $"{projectName}.csproj"); + + msbuildFixture.CreateDotnetNewProject(testDirectory.Path, projectName, " classlib"); + + using (var stream = new FileStream(projectFile, FileMode.Open, FileAccess.ReadWrite)) + { + var xml = XDocument.Load(stream); + ProjectFileUtils.SetTargetFrameworkForProject(xml, "TargetFramework", "net5.0"); + ProjectFileUtils.AddProperty(xml, "GeneratePackageOnBuild", "true"); + ProjectFileUtils.AddProperty(xml, "NuspecOutputPath", "obj\\Debug"); + + var attributes = new Dictionary(); + + attributes["Version"] = "9.0.1"; + ProjectFileUtils.AddItem( + xml, + "PackageReference", + "Newtonsoft.json", + "", + new Dictionary(), + attributes); + ProjectFileUtils.WriteXmlToFile(xml, stream); + } + + msbuildFixture.RestoreProject(workingDirectory, projectName, string.Empty); + msbuildFixture.BuildProject(workingDirectory, projectName, $"/p:PackageOutputPath={workingDirectory}"); + + var nupkgPath = Path.Combine(workingDirectory, $"{projectName}.1.0.0.nupkg"); + var nuspecPath = Path.Combine(workingDirectory, "obj", "Debug", $"{projectName}.1.0.0.nuspec"); + + Assert.True(File.Exists(nupkgPath), "The output .nupkg is not in the expected place"); + Assert.True(File.Exists(nuspecPath), "The intermediate nuspec file is not in the expected place"); + + using (var nupkgReader = new PackageArchiveReader(nupkgPath)) + { + var nuspecReader = nupkgReader.NuspecReader; + + // Validate the output .nuspec. + Assert.Equal("ClassLibrary1", nuspecReader.GetId()); + Assert.Equal("1.0.0", nuspecReader.GetVersion().ToFullString()); + Assert.Equal("ClassLibrary1", nuspecReader.GetAuthors()); + Assert.Equal("", nuspecReader.GetOwners()); + Assert.Equal("Package Description", nuspecReader.GetDescription()); + Assert.False(nuspecReader.GetRequireLicenseAcceptance()); + + var dependencyGroups = nuspecReader.GetDependencyGroups().ToList(); + Assert.Equal(1, dependencyGroups.Count); + Assert.Equal(FrameworkConstants.CommonFrameworks.Net50, dependencyGroups[0].TargetFramework); + var packages = dependencyGroups[0].Packages.ToList(); + Assert.Equal(1, packages.Count); + Assert.Equal("Newtonsoft.json", packages[0].Id); + Assert.Equal(new VersionRange(new NuGetVersion("9.0.1")), packages[0].VersionRange); + Assert.Equal(new List { "Analyzers", "Build" }, packages[0].Exclude); + Assert.Empty(packages[0].Include); + + // Validate the assets. + var libItems = nupkgReader.GetLibItems().ToList(); + Assert.Equal(1, libItems.Count); + Assert.Equal(FrameworkConstants.CommonFrameworks.Net50, libItems[0].TargetFramework); + Assert.Equal(new[] { "lib/net5.0/ClassLibrary1.dll" }, libItems[0].Items); + } + + } + } +#endif + [PlatformFact(Platform.Windows)] public void PackCommand_SingleFramework_GeneratesPackageOnBuild() { @@ -2701,6 +2787,10 @@ public void PackCommand_PackSolution_AddsProjectRefsAsPackageRefs() [PlatformTheory(Platform.Windows)] [InlineData("TargetFramework", "netstandard1.4")] [InlineData("TargetFrameworks", "netstandard1.4;net46")] +#if NETCOREAPP5_0 + [InlineData("TargetFramework", "net5.0")] + [InlineData("TargetFrameworks", "netstandard1.4;net5.0")] +#endif public void PackCommand_PackTargetHook_ExecutesBeforePack(string tfmProperty, string tfmValue) { @@ -2735,13 +2825,17 @@ public void PackCommand_PackTargetHook_ExecutesBeforePack(string tfmProperty, Assert.True(File.Exists(nupkgPath), "The output .nupkg is not in the expected place"); Assert.True(File.Exists(nuspecPath), "The intermediate nuspec file is not in the expected place"); Assert.True(indexOfHelloWorld < indexOfPackSuccessful, "The custom target RunBeforePack did not run before pack target."); - + } } - + [PlatformTheory(Platform.Windows)] [InlineData("TargetFramework", "netstandard1.4")] [InlineData("TargetFrameworks", "netstandard1.4;net46")] +#if NETCOREAPP5_0 + [InlineData("TargetFramework", "net5.0")] + [InlineData("TargetFrameworks", "netstandard1.4;net5.0")] +#endif public void PackCommand_PackTarget_IsIncremental(string tfmProperty, string tfmValue) { using (var testDirectory = msbuildFixture.CreateTestDirectory()) diff --git a/test/NuGet.Core.Tests/NuGet.Frameworks.Test/CompatibilityTests.cs b/test/NuGet.Core.Tests/NuGet.Frameworks.Test/CompatibilityTests.cs index 8d8b400c684..18752fcfa46 100644 --- a/test/NuGet.Core.Tests/NuGet.Frameworks.Test/CompatibilityTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Frameworks.Test/CompatibilityTests.cs @@ -42,18 +42,56 @@ public class CompatibilityTests [InlineData("net5.1", "netcoreapp3.1", true)] [InlineData("net6.0", "netcoreapp3.1", true)] - // net5.0- is not supported yet - [InlineData("net5.0-android", "net5.0", false)] - [InlineData("net5.0-android", "netcoreapp3.1", false)] - [InlineData("net5.0-ios", "net5.0", false)] - [InlineData("net5.0-macos", "net5.0", false)] - [InlineData("net5.0-tvos", "net5.0", false)] - [InlineData("net5.0-watchos", "net5.0", false)] - [InlineData("net5.0-windows", "net5.0", false)] + // net5.0- is compatible with net5.0 but not the inverse + [InlineData("net5.0-android", "net5.0", true)] + [InlineData("net5.0-android", "netcoreapp3.1", true)] + [InlineData("net5.0-ios", "net5.0", true)] + [InlineData("net5.0-macos", "net5.0", true)] + [InlineData("net5.0-tvos", "net5.0", true)] + [InlineData("net5.0-watchos", "net5.0", true)] + [InlineData("net5.0-windows", "net5.0", true)] + [InlineData("net5.0", "net5.0-android", false)] + [InlineData("net5.0", "net5.0-ios", false)] + [InlineData("net5.0", "net5.0-macos", false)] + [InlineData("net5.0", "net5.0-tvos", false)] + [InlineData("net5.0", "net5.0-watchos", false)] [InlineData("net5.0", "net5.0-windows", false)] - - // net5.0 profile names cannot be made up. they will not be compat with anything. profile name will be changed to "Unsupported". - [InlineData("net5.0-madeupname", "net5.0", false)] + [InlineData("net5.0-android1.0", "net5.0", true)] + [InlineData("net5.0-android1.0", "netcoreapp3.1", true)] + [InlineData("net5.0-ios10", "net5.0", true)] + [InlineData("net5.0-macos15", "net5.0", true)] + [InlineData("net5.0-tvos1.0", "net5.0", true)] + [InlineData("net5.0-watchos1.0", "net5.0", true)] + [InlineData("net5.0-windows10.5", "net5.0", true)] + [InlineData("net5.0", "net5.0-android10", false)] + [InlineData("net5.0", "net5.0-ios10", false)] + [InlineData("net5.0", "net5.0-macos10", false)] + [InlineData("net5.0", "net5.0-tvos10", false)] + [InlineData("net5.0", "net5.0-watchos10", false)] + [InlineData("net5.0", "net5.0-windows10", false)] + + // These parse to Unsupported, and are thus not compatible + [InlineData("net5.0-mac os", "net5.0", false)] + [InlineData("net5.0-macos-14", "net5.0", false)] + [InlineData("net5.0-macos-14..0", "net5.0", false)] + + // net5.0- is compatible with net5.0- + [InlineData("net5.0-android9.0", "net5.0-android8.0", true)] + [InlineData("net5.0-macos10.15.2.3", "net5.0-macos10.15.2.2", true)] + [InlineData("net5.0-ios14.0", "net5.0-ios15.0", false)] + + // net5.0- is not compatible with net5.0- + [InlineData("net5.0-windows", "net5.0-android", false)] + [InlineData("net5.0-android", "net5.0-ios", false)] + [InlineData("net5.0-ios", "net5.0-macos", false)] + [InlineData("net5.0-macos", "net5.0-tvos", false)] + [InlineData("net5.0-tvos", "net5.0-watchos", false)] + [InlineData("net5.0-watchos", "net5.0-windows", false)] + + // Unknown net5.0 platform names will be treated as valid so long as their version is valid + [InlineData("net5.0-madeupname", "net5.0", true)] + [InlineData("net5.0-madeupname12.0", "net5.0", true)] + [InlineData("net5.0-madeupname1.1.3.4.5.6", "net5.0", false)] [InlineData("net5.0", "net5.0-madeupname", false)] // dotnet diff --git a/test/NuGet.Core.Tests/NuGet.Frameworks.Test/NuGetFrameworkParseTests.cs b/test/NuGet.Core.Tests/NuGet.Frameworks.Test/NuGetFrameworkParseTests.cs index 52dd684d95c..e2e48b2e2ce 100644 --- a/test/NuGet.Core.Tests/NuGet.Frameworks.Test/NuGetFrameworkParseTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Frameworks.Test/NuGetFrameworkParseTests.cs @@ -203,6 +203,8 @@ public void NuGetFramework_ProfileName(string folder, string expected) [InlineData("net40", ".NETFramework,Version=v4.0")] [InlineData("net35", ".NETFramework,Version=v3.5")] [InlineData("net40-client", ".NETFramework,Version=v4.0,Profile=Client")] + [InlineData("net5.0", ".NetCoreApp,Version=v5.0")] + [InlineData("net5.0", "net5.0")] [InlineData("net", ".NETFramework,Version=v0.0")] [InlineData("net10.1.2.3", ".NETFramework,Version=v10.1.2.3")] [InlineData("net10.0", ".NETFramework,Version=v10.0")] @@ -224,6 +226,14 @@ public void NuGetFramework_ProfileName(string folder, string expected) [InlineData("netcoreapp1.5", ".NETCoreApp,Version=v1.5")] [InlineData("netcoreapp2.0", ".NetCoreApp,Version=v2.0")] [InlineData("netcoreapp3.0", ".NetCoreApp,Version=v3.0")] + [InlineData("net5.0-android", "net5.0-android")] + [InlineData("net5.0-android", "net5.0-android0.0")] + [InlineData("net5.0-ios14.0", "net5.0-ios14.0")] + [InlineData("net5.0-macos10.0", "net5.0-macos10.0")] + [InlineData("net5.0-watchos1.0", "net5.0-watchos1.0")] + [InlineData("net5.0-tvos1.0", "net5.0-tvos1.0")] + [InlineData("net5.0-windows10.0", "net5.0-windows10.0")] + [InlineData("net5.0-macos10.15.2.3", "net5.0-macos10.15.2.3")] public void NuGetFramework_ParseToShortName(string expected, string fullName) { // Arrange @@ -238,9 +248,11 @@ public void NuGetFramework_ParseToShortName(string expected, string fullName) [Theory] // Net5.0 ERA - [InlineData("net5.0", ".NETCoreApp,Version=v5.0")] - [InlineData("net10.1.2.3", ".NETCoreApp,Version=v10.1.2.3")] - [InlineData("netcoreapp5.0", ".NETCoreApp,Version=v5.0")] + [InlineData("net5.0", "net5.0")] + [InlineData("net10.1.2.3", "net10.1.2.3")] + [InlineData("netcoreapp5.0", "net5.0")] + [InlineData("net5.0-android", "net5.0-android")] + [InlineData("net5.0-ios14.0", "net5.0-ios14.0")] // Pre-Net5.0 ERA [InlineData("net45", ".NETFramework,Version=v4.5")] @@ -397,6 +409,8 @@ public void NuGetFramework_PortableWithInnerPortableProfileFails(string framewor [InlineData("netcoreapp3.1", "netcoreapp31")] [InlineData("netcoreapp31", "netcoreapp3.1")] [InlineData("netcoreapp31", "netcoreapp31")] + [InlineData("net5.0", "net5.0")] + [InlineData("net50", "net5.0")] public void NuGetFramework_TryParseCommonFramework_ParsesCommonFrameworks(string frameworkString1, string frameworkString2) { var framework1 = NuGetFramework.Parse(frameworkString1); diff --git a/test/NuGet.Core.Tests/NuGet.Frameworks.Test/NuGetFrameworkTests.cs b/test/NuGet.Core.Tests/NuGet.Frameworks.Test/NuGetFrameworkTests.cs index 30f58c31664..96eb250466e 100644 --- a/test/NuGet.Core.Tests/NuGet.Frameworks.Test/NuGetFrameworkTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Frameworks.Test/NuGetFrameworkTests.cs @@ -43,13 +43,13 @@ public void NuGetFramework_ShortName(string input, string expected) } [Theory] - [InlineData("net5.0", ".NETCoreApp,Version=v5.0")] + [InlineData("net5.0", "net5.0")] [InlineData("net452", ".NETFramework,Version=v4.5.2")] [InlineData("netcoreapp3.1", ".NETCoreApp,Version=v3.1")] public void NuGetFramework_GetDotNetFrameworkName(string input, string expected) { var fw = NuGetFramework.Parse(input); - + string result = fw.GetDotNetFrameworkName(DefaultFrameworkNameProvider.Instance); Assert.Equal(expected, result); diff --git a/test/NuGet.Core.Tests/NuGet.Packaging.Test/PackageBuilderTest.cs b/test/NuGet.Core.Tests/NuGet.Packaging.Test/PackageBuilderTest.cs index 78579ed0d0b..9e76b973821 100644 --- a/test/NuGet.Core.Tests/NuGet.Packaging.Test/PackageBuilderTest.cs +++ b/test/NuGet.Core.Tests/NuGet.Packaging.Test/PackageBuilderTest.cs @@ -135,6 +135,60 @@ public void CreatePackageWithNuspecIncludeExcludeAnyGroup() } } + [Theory] + [InlineData(".NETFramework,Version=v4.7.2", ".NETFramework4.7.2")] + [InlineData(".NETFramework,Version=v4.7.2,Profile=foo", ".NETFramework4.7.2-foo")] + [InlineData("net5.0", "net5.0")] + [InlineData("net5.0-windows", "net5.0-windows")] + [InlineData("net5.0-macos10.8", "net5.0-macos10.8")] + [InlineData("net6.0", "net6.0")] + public void CreatePackageTFMFormatting(string from, string to) + { + // Arrange + PackageBuilder builder = new PackageBuilder() + { + Id = "A", + Version = NuGetVersion.Parse("1.0"), + Description = "Descriptions", + }; + builder.Authors.Add("testAuthor"); + + var dependencies = new List(); + dependencies.Add(new PackageDependency("packageB", VersionRange.Parse("1.0.0"), null, new[] { "z" })); + + var tfmGroup = new PackageDependencyGroup(NuGetFramework.Parse(from), dependencies); + builder.DependencyGroups.Add(tfmGroup); + + using (var ms = new MemoryStream()) + { + builder.Save(ms); + + ms.Seek(0, SeekOrigin.Begin); + + var manifestStream = GetManifestStream(ms); + + var result = manifestStream.ReadToEnd(); + + // Assert + Assert.Equal($@" + + + A + 1.0.0 + testAuthor + false + Descriptions + + + + + + +".Replace("\r\n", "\n"), result.Replace("\r\n", "\n")); + } + } + + [Fact] public void CreatePackageWithNuspecIncludeExclude() { @@ -150,8 +204,8 @@ public void CreatePackageWithNuspecIncludeExclude() var dependencies45 = new List(); dependencies45.Add(new PackageDependency("packageB", VersionRange.Parse("1.0.0"), null, new[] { "z" })); - var dependencies46 = new List(); - dependencies46.Add(new PackageDependency( + var dependencies50 = new List(); + dependencies50.Add(new PackageDependency( "packageC", VersionRange.Parse("1.0.0"), new[] { "a", "b", "c" }, @@ -160,8 +214,8 @@ public void CreatePackageWithNuspecIncludeExclude() var net45 = new PackageDependencyGroup(new NuGetFramework(".NETFramework", new Version(4, 5)), dependencies45); builder.DependencyGroups.Add(net45); - var net46 = new PackageDependencyGroup(new NuGetFramework(".NETFramework", new Version(4, 6)), dependencies46); - builder.DependencyGroups.Add(net46); + var net50win = new PackageDependencyGroup(new NuGetFramework(".NETCoreApp", new Version(5, 0), "windows", new Version(0, 0)), dependencies50); + builder.DependencyGroups.Add(net50win); using (var ms = new MemoryStream()) { @@ -186,7 +240,7 @@ public void CreatePackageWithNuspecIncludeExclude() - + @@ -1874,6 +1928,8 @@ public void ReadingPackageManifestRecognizeMultipleDependenciesWithTargetFramewo + + "; @@ -1882,10 +1938,11 @@ public void ReadingPackageManifestRecognizeMultipleDependenciesWithTargetFramewo PackageBuilder builder = new PackageBuilder(spec.AsStream(), null); // Assert - Assert.Equal(3, builder.DependencyGroups.Count); + Assert.Equal(4, builder.DependencyGroups.Count); var dependencyGroup1 = builder.DependencyGroups.ElementAt(0); var dependencyGroup2 = builder.DependencyGroups.ElementAt(1); var dependencyGroup3 = builder.DependencyGroups.ElementAt(2); + var dependencyGroup4 = builder.DependencyGroups.ElementAt(3); Assert.Equal(NuGetFramework.Parse("Silverlight, Version=4.0"), dependencyGroup1.TargetFramework); var dependencies1 = dependencyGroup1.Packages.ToList(); @@ -1903,6 +1960,9 @@ public void ReadingPackageManifestRecognizeMultipleDependenciesWithTargetFramewo Assert.Equal(NuGetFramework.Parse(".NETFramework, Version=4.0, Profile=Client"), dependencyGroup3.TargetFramework); Assert.False(dependencyGroup3.Packages.Any()); + + Assert.Equal(NuGetFramework.Parse("net5.0-windows"), dependencyGroup4.TargetFramework); + Assert.False(dependencyGroup4.Packages.Any()); } [Fact] @@ -2633,9 +2693,14 @@ private static IPackageFile CreatePackageFile(string name) file.Setup(f => f.LastWriteTime).Returns(DateTimeOffset.UtcNow); string effectivePath; - var fx = FrameworkNameUtility.ParseFrameworkNameFromFilePath(name, out effectivePath); + var nufx = FrameworkNameUtility.ParseNuGetFrameworkFromFilePath(name, out effectivePath); file.SetupGet(f => f.EffectivePath).Returns(effectivePath); + file.SetupGet(f => f.NuGetFramework).Returns(nufx); + + var fx = FrameworkNameUtility.ParseFrameworkNameFromFilePath(name, out effectivePath); +#pragma warning disable CS0618 // Type or member is obsolete file.SetupGet(f => f.TargetFramework).Returns(fx); +#pragma warning restore CS0618 // Type or member is obsolete return file.Object; } diff --git a/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestPackageUtility.cs b/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestPackageUtility.cs index c7fef935a78..06fd9e4ba48 100644 --- a/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestPackageUtility.cs +++ b/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestPackageUtility.cs @@ -14,6 +14,7 @@ using System.Xml.Linq; using NuGet.Common; using NuGet.Configuration; +using NuGet.Frameworks; using NuGet.Packaging; using NuGet.Packaging.Core; using NuGet.Packaging.PackageExtraction; @@ -622,9 +623,16 @@ private static IPackageFile CreatePackageFile(string name) }; string effectivePath; - var fx = FrameworkNameUtility.ParseFrameworkNameFromFilePath(name, out effectivePath); + var fx = FrameworkNameUtility.ParseNuGetFrameworkFromFilePath(name, out effectivePath); file.EffectivePath = effectivePath; - file.TargetFramework = fx; + if (fx != null) + { + file.NuGetFramework = fx; + if (fx.Version.Major < 5) + { + file.TargetFramework = new FrameworkName(fx.DotNetFrameworkName); + } + } return file; } @@ -639,6 +647,8 @@ private class InMemoryFile : IPackageFile public FrameworkName TargetFramework { get; set; } + public NuGetFramework NuGetFramework { get; set; } + public MemoryStream Stream { get; set; } public Stream GetStream()