From 0343ad1fbe3d4b8a12de500108de722396ac2af2 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Sat, 10 Jan 2026 13:22:48 +0900 Subject: [PATCH 01/15] Fix Nuget package file name that generated by _GetTargetFrameworksOutput target in Nuget.Build.Tasks.Pack.targets. --- NuGet.sln | 3 + .../GetPackOutputItemsTask.cs | 30 +- .../NuGet.Build.Tasks.Pack/PackTaskLogic.cs | 31 +- .../NuGet.Build.Tasks.Pack.targets | 2 + .../PackageNameTests.cs | 386 ++++++++++++++++++ 5 files changed, 438 insertions(+), 14 deletions(-) create mode 100644 test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs diff --git a/NuGet.sln b/NuGet.sln index 8645845aa8f..846bbcc7bfd 100644 --- a/NuGet.sln +++ b/NuGet.sln @@ -161,6 +161,9 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGet.XPlat.FuncTest", "test\NuGet.Core.FuncTests\NuGet.XPlat.FuncTest\NuGet.XPlat.FuncTest.csproj", "{2034C981-C938-4F0F-8F3B-528B83CB8F7D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGet.Build.Tasks.Pack.Test", "test\NuGet.Core.Tests\NuGet.Build.Tasks.Pack.Test\NuGet.Build.Tasks.Pack.Test.csproj", "{8BF8279D-196F-481A-9659-488864D93D2D}" + ProjectSection(ProjectDependencies) = postProject + {3B96F91B-3B58-40ED-B06E-5CD133A79A63} = {3B96F91B-3B58-40ED-B06E-5CD133A79A63} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGet.Build.Tasks.Pack", "src\NuGet.Core\NuGet.Build.Tasks.Pack\NuGet.Build.Tasks.Pack.csproj", "{16863138-7C0E-49ED-A1C8-B9165FED9920}" EndProject diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs index 8a4efe84194..02324c06cb6 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs @@ -29,6 +29,10 @@ public class GetPackOutputItemsTask : Microsoft.Build.Utilities.Task [Required] public string NuspecOutputPath { get; set; } + public string NuspecInputFilePath { get; set; } + + public string[] NuspecProperties { get; set; } + public bool IncludeSymbols { get; set; } public bool IncludeSource { get; set; } @@ -43,18 +47,32 @@ public class GetPackOutputItemsTask : Microsoft.Build.Utilities.Task public override bool Execute() { + var packageId = PackageId; + var packageVersion = PackageVersion; + + if (!string.IsNullOrWhiteSpace(NuspecInputFilePath)) + { + var nuspecReader = new NuGet.Packaging.NuspecReader(NuspecInputFilePath); + packageId = nuspecReader.GetId(); + packageVersion = nuspecReader.GetVersion().ToNormalizedString(); + + PackArgs packArgs = new PackArgs() { Version = packageVersion }; + PackTaskLogic.SetPackArgsPropertiesFromNuspecProperties(packArgs, MSBuildStringUtility.TrimAndExcludeNullOrEmpty(NuspecProperties), NuspecInputFilePath); + packageVersion = packArgs.Version; + } + NuGetVersion version; - if (!NuGetVersion.TryParse(PackageVersion, out version)) + if (!NuGetVersion.TryParse(packageVersion, out version)) { throw new ArgumentException(string.Format( CultureInfo.CurrentCulture, Strings.InvalidPackageVersion, - PackageVersion)); + packageVersion)); } var symbolPackageFormat = PackArgs.GetSymbolPackageFormat(MSBuildStringUtility.TrimAndGetNullForEmpty(SymbolPackageFormat)); - var nupkgFileName = PackCommandRunner.GetOutputFileName(PackageId, version, isNupkg: true, symbols: false, symbolPackageFormat: symbolPackageFormat); - var nuspecFileName = PackCommandRunner.GetOutputFileName(PackageId, version, isNupkg: false, symbols: false, symbolPackageFormat: symbolPackageFormat); + var nupkgFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: true, symbols: false, symbolPackageFormat: symbolPackageFormat); + var nuspecFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: false, symbols: false, symbolPackageFormat: symbolPackageFormat); var outputs = new List(); outputs.Add(new TaskItem(Path.Combine(PackageOutputPath, nupkgFileName))); @@ -62,8 +80,8 @@ public override bool Execute() if (IncludeSource || IncludeSymbols) { - var nupkgSymbolsFileName = PackCommandRunner.GetOutputFileName(PackageId, version, isNupkg: true, symbols: true, symbolPackageFormat: symbolPackageFormat); - var nuspecSymbolsFileName = PackCommandRunner.GetOutputFileName(PackageId, version, isNupkg: false, symbols: true, symbolPackageFormat: symbolPackageFormat); + var nupkgSymbolsFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: true, symbols: true, symbolPackageFormat: symbolPackageFormat); + var nuspecSymbolsFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: false, symbols: true, symbolPackageFormat: symbolPackageFormat); outputs.Add(new TaskItem(Path.Combine(PackageOutputPath, nupkgSymbolsFileName))); outputs.Add(new TaskItem(Path.Combine(NuspecOutputPath, nuspecSymbolsFileName))); diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs index feee7a8a888..45dbd28dbbb 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs @@ -75,14 +75,7 @@ public PackArgs GetPackArgs(IPackTaskRequest request) if (!string.IsNullOrEmpty(request.NuspecFile)) { - if (request.NuspecProperties != null && request.NuspecProperties.Any()) - { - packArgs.Properties.AddRange(ParsePropertiesAsDictionary(request.NuspecProperties)); - if (packArgs.Properties.TryGetValue("version", out var version)) - { - packArgs.Version = version; - } - } + SetPackArgsPropertiesFromNuspecProperties(packArgs, request.NuspecProperties, request.NuspecFile); } else { @@ -1091,6 +1084,28 @@ private static IDictionary ParsePropertiesAsDictionary(string[] return dictionary; } + internal static void SetPackArgsPropertiesFromNuspecProperties(PackArgs packArgs, string[] nuspecProperties, string nuspecInputFilePath) + { + if (!string.IsNullOrWhiteSpace(nuspecInputFilePath)) + { + if (nuspecProperties != null && nuspecProperties.Any()) + { + packArgs.Properties.AddRange(ParsePropertiesAsDictionary(nuspecProperties)); + if (packArgs.Properties.TryGetValue("version", out var packageVersion)) + { + if (!NuGetVersion.TryParse(packageVersion, out var version)) + { + throw new ArgumentException(string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageVersion, + packageVersion)); + } + packArgs.Version = version.ToNormalizedString(); + } + } + } + } + private HashSet InitOutputExtensions(IEnumerable outputExtensions) { return new HashSet(outputExtensions.Distinct(StringComparer.OrdinalIgnoreCase)); diff --git a/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets index cd86627edcb..c73e438b30d 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets +++ b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets @@ -111,6 +111,8 @@ Copyright (c) .NET Foundation. All rights reserved. + /// The _GetOutputItemsFromPack target inside the NuGet.Build.Tasks.Pack.targets file is the subject of the test, so the project that includes NuGet.Build.Tasks.Pack.targets must be registered as a build dependency. + public class PackageFileNameTests + { + #region constructor and fields + +#if DEBUG + const string CONFIGURATION = "Debug"; +#else + const string CONFIGURATION = "Release"; +#endif + + const string FILENAME_DLL = "NuGet.Build.Tasks.Pack.dll"; + const string FILENAME_TARGETS = "NuGet.Build.Tasks.Pack.targets"; + const string FILENAME_PROJECT_FILE = "test.csproj"; + const string FILENAME_NUSPEC_FILE = "test.nuspec"; + + private readonly bool _isDotNetFramework = false; + private readonly string _testFrameworkMoniker = "netstandard2.0"; + + private readonly string _pathDotnetExe = ""; + private readonly string _pathMSBuildExe = ""; + private readonly string _pathDllFile; + private readonly string _pathTargetsFile; + + private readonly ITestOutputHelper _testOutputHelper; + + public PackageFileNameTests(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + + _pathDotnetExe = NuGet.Test.Utility.TestFileSystemUtility.GetDotnetCli(); + _pathMSBuildExe = GetMsBuildExePath(); + _testFrameworkMoniker = GetFrameworkMoniker(typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask), out var isDotNetFramework); + _isDotNetFramework = isDotNetFramework; + + var dllLocation = typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask).Assembly.Location; + var artifactsDirectory = NuGet.Test.Utility.TestFileSystemUtility.GetArtifactsDirectoryInRepo(); + + var dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); + if (!System.IO.Directory.Exists(dllDirectory)) + { + _testFrameworkMoniker = GetFrameworkMoniker(typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask), out var isDotnetFramework); + dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); + } + + _pathDllFile = Path.Combine(dllDirectory, FILENAME_DLL); + + // https://github.com/NuGet/NuGet.Client/pull/6712 + // NuGet.Build.Tasks.Pack.targets has been moved to in NuGet.Build.Tasks project. + // Therefore, NuGet.Build.Tasks project must be built before runnig this test. + var tfmTargets = GetFrameworkMoniker(typeof(PackageFileNameTests), out var _); + _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, tfmTargets, FILENAME_TARGETS); + if (!System.IO.File.Exists(_pathTargetsFile)) + { + _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, _testFrameworkMoniker, FILENAME_TARGETS); + if (!System.IO.File.Exists(_pathTargetsFile)) + { + _pathTargetsFile = Path.Combine(dllDirectory, FILENAME_TARGETS); + } + } + + Assert.True(System.IO.File.Exists(_pathDllFile), $"{FILENAME_DLL} missing"); + Assert.True(System.IO.File.Exists(_pathTargetsFile), $"{FILENAME_TARGETS} missing"); + } + + #endregion + + public static System.Collections.Generic.IEnumerable TestCases + { + get + { + var cases = new object[][] + { + // without nuspec input + new object[]{"proj.1.9.0.nupkg", "proj", "nusp", "1.9", "", "", false}, + new object[]{"proj.2.0.0.nupkg", "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", false}, + new object[]{"proj.2.0.0.1.nupkg", "proj", "nusp", "2.0.0.1", " ", "4.0.0.1", false}, + new object[]{"proj.2.0.0.2.nupkg", "proj", "nusp", "2.0.0.2", "3.0.0.2", "4.0.0.2", false}, + new object[]{"proj.2.0.0.3-preview.nupkg", "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false}, + + // with nuspec input + new object[]{"nusp.4.0.0.nupkg", "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true}, + new object[]{"nusp.4.0.0.3.nupkg", "proj", "nusp", "2.0.0.3", " ", "4.0.0.3", true}, + new object[]{"nusp.3.0.0.4.nupkg", "proj", "nusp", "2.0.0.4", "3.0.0.4", "4.0.0.4", true}, + new object[]{"nusp.5.0.0-preview.nupkg", "proj", "nusp", "2.0.0.0", " ", "5.0.0.0-preview", true}, + new object[]{"nusp.5.0.0.2-preview.nupkg", "proj", "nusp", "2.0.0.0", " ", "5.0.0.2-preview", true}, + new object[]{"nusp.6.0.0-beta.nupkg", "proj", "nusp", "2.0.0.0", "6-beta", "5.0.0.3-preview", true}, + + // has symbol + new object[]{"proj.2.1.0.snupkg", "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, true,NuGet.Commands.SymbolPackageFormat.Snupkg }, + new object[]{"nusp.7.1.2.snupkg", "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, true,NuGet.Commands.SymbolPackageFormat.Snupkg }, + + new object[]{"proj.2.2.0.nupkg;proj.2.2.0.symbols.nupkg", "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, true,NuGet.Commands.SymbolPackageFormat.SymbolsNupkg }, + new object[]{"nusp.7.2.2.nupkg;nusp.7.2.2.symbols.nupkg", "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, true,NuGet.Commands.SymbolPackageFormat.SymbolsNupkg }, + }; + + // for view order in test explorer + for (int i = 0; i < cases.Length; i++) + { + cases[i][0] = string.Join(";", cases[i][0].ToString()!.Split(';').Select(fileName => $"{i:00}_{fileName}").OfType()); + for (int j = 1; j < 3; j++) + { + cases[i][j] = $"{i:00}_{cases[i][j]}"; + } + } + return cases; + } + } + + [PlatformTheory(Platform.Windows)] + [MemberData(nameof(TestCases))] + public void GetPackOutputItemsTask_PackageFileName + (string outputNupkgNames + , string idProjProp + , string idNuspecMeta + , string versionProjProp + , string versionNuspecProperties + , string versionNuspecMeta + , bool useNuspecFile + , bool includeSymbols = false + , NuGet.Commands.SymbolPackageFormat symbolPackageFormat = Commands.SymbolPackageFormat.Snupkg) + { + const string projectFileName = "test.csproj"; + const string nuspecFileName = "test.nuspec"; + + string[] outputExtensions = GetOutputExtensions(includeSymbols, symbolPackageFormat); + + var outputItemTask = new NuGet.Build.Tasks.Pack.GetPackOutputItemsTask(); + outputItemTask.PackageId = idProjProp; + outputItemTask.PackageVersion = versionProjProp; + outputItemTask.IncludeSymbols = includeSymbols; + outputItemTask.SymbolPackageFormat = GetSymbolPackageFormatText(symbolPackageFormat); + if (!string.IsNullOrWhiteSpace(versionNuspecProperties)) + { + outputItemTask.NuspecProperties = new string[] { $"version={versionNuspecProperties}" }; + } + + using (var testDirectory = TestDirectory.Create()) + { + outputItemTask.PackageOutputPath = testDirectory.Path; + outputItemTask.NuspecOutputPath = testDirectory.Path; + if (useNuspecFile) + { + outputItemTask.NuspecInputFilePath = System.IO.Path.Combine(testDirectory.Path, nuspecFileName); + } + + CreateTestProjectFileAndNuspecFile(testDirectory, projectFileName, nuspecFileName, idProjProp, idNuspecMeta, versionProjProp, versionNuspecProperties, versionNuspecMeta, useNuspecFile, includeSymbols, symbolPackageFormat); + + Assert.True(outputItemTask.Execute()); + + foreach (string outputNupkgName in outputNupkgNames.Split(';')) + { + string[] itemSpecs = outputItemTask.OutputPackItems.Select(item => item.ItemSpec).ToArray(); + var matchCount = GetNameMatchFilePathCount(outputNupkgName, itemSpecs); + Assert.True(matchCount == 1, $"{outputNupkgName} is not found in output. [{string.Join(" , ", itemSpecs.Select(_ => System.IO.Path.GetFileName(_)))}]"); + } + } + } + + + [PlatformTheory(Platform.Windows)] + [MemberData(nameof(TestCases))] + public void PackTask_PackageFileName_FromProjectFileWithNuspecFile + (string outputNupkgNames + , string idProjProp + , string idNuspecMeta + , string versionProjProp + , string versionNuspecProperties + , string versionNuspecMeta + , bool useNuspecFile + , bool includeSymbols = false + , NuGet.Commands.SymbolPackageFormat symbolPackageFormat = Commands.SymbolPackageFormat.Snupkg) + { + string[] outputExtensions = GetOutputExtensions(includeSymbols, symbolPackageFormat); + + using (var testDirectory = TestDirectory.Create()) + { + CreateTestProjectFileAndNuspecFile(testDirectory, FILENAME_PROJECT_FILE, FILENAME_NUSPEC_FILE, idProjProp, idNuspecMeta, versionProjProp, versionNuspecProperties, versionNuspecMeta, useNuspecFile, includeSymbols, symbolPackageFormat); + + CommandRunnerResult runresultDotnetPack; + if (_isDotNetFramework) + { + // As noted in #6703, since the .NetStandard2.0 library has been removed, + // running tests on .net Framework requires invoking msbuild.exe. + runresultDotnetPack = CommandRunner.Run( + _pathMSBuildExe, + testDirectory, + $"/t:Restore;Build;Pack /p:Configuration={CONFIGURATION} /p:UsingMicrosoftNetSdk=true {FILENAME_PROJECT_FILE} ", + testOutputHelper: _testOutputHelper); + } + else + { + // dotnet build + runresultDotnetPack = CommandRunner.Run( + _pathDotnetExe, + testDirectory, + $"build -p:Configuration={CONFIGURATION} {FILENAME_PROJECT_FILE}", + testOutputHelper: _testOutputHelper); + } + Assert.True(0 == runresultDotnetPack.ExitCode, runresultDotnetPack.Output + " " + runresultDotnetPack.Errors); + + var objFolder = System.IO.Path.Combine(testDirectory, "obj"); + var log = System.IO.File.ReadAllLines(System.IO.Path.Combine(objFolder, "_OutputPackItems.txt")); + var lines = log.Where(line => !line.StartsWith(objFolder)).ToArray(); + + var nupkgGneratedFiles = outputExtensions + .SelectMany(outputExtension => Directory.GetFiles(testDirectory, $"*{outputExtension}", SearchOption.AllDirectories)) + .Where(line => !line.StartsWith(objFolder)) + .Distinct().ToArray(); + Assert.Equal(outputExtensions.Length, nupkgGneratedFiles.Length); + + foreach (string outputNupkgName in outputNupkgNames.Split(';')) + { + var matchCountInFileSystem = GetNameMatchFilePathCount(outputNupkgName, nupkgGneratedFiles); + Assert.True(matchCountInFileSystem == 1, $"{outputNupkgName} is not found in filesystem. [{string.Join(" , ", nupkgGneratedFiles.Select(_ => System.IO.Path.GetFileName(_)))}]"); + + var matchCountInOutputPackItems = GetNameMatchFilePathCount(outputNupkgName, lines); + Assert.True(matchCountInOutputPackItems == 1, $"{outputNupkgName} is not found in OutputPackItems. [{string.Join(" , ", lines.Select(_ => System.IO.Path.GetFileName(_)))}]"); + } + } + } + + private void CreateTestProjectFileAndNuspecFile + (string testDirectory + , string projectFileName + , string nuspecFileName + , string idProjProp + , string idNuspecMeta + , string versionProjProp + , string versionNuspecProperties + , string versionNuspecMeta + , bool useNuspecFile + , bool includeSymbols + , NuGet.Commands.SymbolPackageFormat symbolPackageFormat) + { + + var csprojPath = Path.Combine(testDirectory, projectFileName); + var nuspecPath = Path.Combine(testDirectory, nuspecFileName); + + var csprojContent = $""" + + + + {_pathDllFile} + + + + {_testFrameworkMoniker} + + + true + + true + false + True + + {idProjProp} + {versionProjProp} + tagA;tagB + + {nuspecFileName} + version={versionNuspecProperties} + + {includeSymbols} + {GetSymbolPackageFormatText(symbolPackageFormat)} + + + + + + + + + + + + + +"""; + + var nuspecContent = $""" + + + + {idNuspecMeta} + {versionNuspecMeta?.Trim()} + Unit Test + Sample Description + en-US + + +"""; + + File.WriteAllText(csprojPath, csprojContent, System.Text.Encoding.Unicode); + if (useNuspecFile) + { + File.WriteAllText(nuspecPath, nuspecContent, new System.Text.UTF8Encoding(true)); + } + + } + + private static string GetSymbolPackageFormatText(NuGet.Commands.SymbolPackageFormat symbolPackageFormat) + { + switch (symbolPackageFormat) + { + case Commands.SymbolPackageFormat.Snupkg: return "snupkg"; + case Commands.SymbolPackageFormat.SymbolsNupkg: return "symbols.nupkg"; + default: throw new System.ArgumentOutOfRangeException(); + } + } + + private static string[] GetOutputExtensions(bool includeSymbols, NuGet.Commands.SymbolPackageFormat symbolPackageFormat) + { + if (includeSymbols) + { + switch (symbolPackageFormat) + { + case Commands.SymbolPackageFormat.Snupkg: return new string[] { ".snupkg" }; + case Commands.SymbolPackageFormat.SymbolsNupkg: return new string[] { ".nupkg", ".symbols.nupkg" }; + default: throw new System.ArgumentOutOfRangeException(); + } + } + else + { + return new string[] { ".nupkg" }; + } + } + + private int GetNameMatchFilePathCount(string fileName, System.Collections.Generic.IEnumerable fullpaths) + { + return fullpaths.Count(file => string.Equals(fileName, System.IO.Path.GetFileName(file), System.StringComparison.OrdinalIgnoreCase)); + } + + private static string GetFrameworkMoniker(Type typeInAssembly, out bool isDotNetFramework) + { + var assembly = typeInAssembly.Assembly; + var targetFrameworkAttribute + = assembly.GetCustomAttributes(typeof(System.Runtime.Versioning.TargetFrameworkAttribute), false) + .OfType().FirstOrDefault(); + + Assert.True(targetFrameworkAttribute != null, "Can't get targetFramework version"); + + isDotNetFramework = targetFrameworkAttribute.FrameworkName.Contains(".NETFramework"); + return NuGetFramework.Parse(targetFrameworkAttribute.FrameworkName).GetShortFolderName(); + } + + private static string GetMsBuildExePath() + { + if (System.Environment.OSVersion.Platform == System.PlatformID.Win32NT) + { + var msbuildexe = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", "msbuild.exe"); + + var vswhereexe = @"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"; + var runresult = CommandRunner.Run( + vswhereexe, + System.Environment.CurrentDirectory, + @" -latest -find MSBuild\**\Bin\MSBuild.exe"); + if (runresult.Success) + { + msbuildexe = new System.IO.StringReader(runresult.Output).ReadLine() ?? ""; + } + return msbuildexe; + } + else + { + return ""; + } + } + } +} From c1d3899e8e8d304105df054ce3bd94fcd4955483 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Sat, 31 Jan 2026 14:59:29 +0900 Subject: [PATCH 02/15] Fix OutputFileNamesWithoutVersion --- .../GetPackOutputItemsTask.cs | 10 +- .../NuGet.Build.Tasks.Pack/PackTaskLogic.cs | 29 +-- .../NuGet.Build.Tasks.Pack.targets | 6 +- .../PackageNameTests.cs | 198 ++++++++++-------- 4 files changed, 139 insertions(+), 104 deletions(-) diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs index 02324c06cb6..c0f0b96b040 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs @@ -39,6 +39,8 @@ public class GetPackOutputItemsTask : Microsoft.Build.Utilities.Task public string SymbolPackageFormat { get; set; } + public bool OutputFileNamesWithoutVersion { get; set; } + /// /// Output items /// @@ -71,8 +73,8 @@ public override bool Execute() } var symbolPackageFormat = PackArgs.GetSymbolPackageFormat(MSBuildStringUtility.TrimAndGetNullForEmpty(SymbolPackageFormat)); - var nupkgFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: true, symbols: false, symbolPackageFormat: symbolPackageFormat); - var nuspecFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: false, symbols: false, symbolPackageFormat: symbolPackageFormat); + var nupkgFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: true, symbols: false, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); + var nuspecFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: false, symbols: false, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); var outputs = new List(); outputs.Add(new TaskItem(Path.Combine(PackageOutputPath, nupkgFileName))); @@ -80,8 +82,8 @@ public override bool Execute() if (IncludeSource || IncludeSymbols) { - var nupkgSymbolsFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: true, symbols: true, symbolPackageFormat: symbolPackageFormat); - var nuspecSymbolsFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: false, symbols: true, symbolPackageFormat: symbolPackageFormat); + var nupkgSymbolsFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: true, symbols: true, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); + var nuspecSymbolsFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: false, symbols: true, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); outputs.Add(new TaskItem(Path.Combine(PackageOutputPath, nupkgSymbolsFileName))); outputs.Add(new TaskItem(Path.Combine(NuspecOutputPath, nuspecSymbolsFileName))); diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs index 45dbd28dbbb..06302883188 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs @@ -1086,24 +1086,25 @@ private static IDictionary ParsePropertiesAsDictionary(string[] internal static void SetPackArgsPropertiesFromNuspecProperties(PackArgs packArgs, string[] nuspecProperties, string nuspecInputFilePath) { - if (!string.IsNullOrWhiteSpace(nuspecInputFilePath)) + if (string.IsNullOrWhiteSpace(nuspecInputFilePath) || nuspecProperties == null || !nuspecProperties.Any()) { - if (nuspecProperties != null && nuspecProperties.Any()) + return; + } + + packArgs.Properties.AddRange(ParsePropertiesAsDictionary(nuspecProperties)); + if (packArgs.Properties.TryGetValue("version", out var packageVersion)) + { + if (!NuGetVersion.TryParse(packageVersion, out var version)) { - packArgs.Properties.AddRange(ParsePropertiesAsDictionary(nuspecProperties)); - if (packArgs.Properties.TryGetValue("version", out var packageVersion)) - { - if (!NuGetVersion.TryParse(packageVersion, out var version)) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Strings.InvalidPackageVersion, - packageVersion)); - } - packArgs.Version = version.ToNormalizedString(); - } + throw new ArgumentException(string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageVersion, + packageVersion)); } + packArgs.Version = version.ToNormalizedString(); } + + } private HashSet InitOutputExtensions(IEnumerable outputExtensions) diff --git a/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets index c73e438b30d..dfac24c00e5 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets +++ b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets @@ -112,13 +112,13 @@ Copyright (c) .NET Foundation. All rights reserved. PackageOutputPath="$(PackageOutputAbsolutePath)" NuspecOutputPath="$(NuspecOutputAbsolutePath)" NuspecInputFilePath="$(NuspecFile)" - NuspecProperties="$(NuspecProperties)" + NuspecProperties="$(NuspecProperties)" PackageId="$(PackageId)" PackageVersion="$(PackageVersion)" IncludeSymbols="$(IncludeSymbols)" IncludeSource="$(IncludeSource)" - SymbolPackageFormat="$(SymbolPackageFormat)"> - + SymbolPackageFormat="$(SymbolPackageFormat)" + OutputFileNamesWithoutVersion="$(OutputFileNamesWithoutVersion)"> diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs index 533d3550421..01e7e5b49d4 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs @@ -63,7 +63,7 @@ public PackageFileNameTests(ITestOutputHelper testOutputHelper) // https://github.com/NuGet/NuGet.Client/pull/6712 // NuGet.Build.Tasks.Pack.targets has been moved to in NuGet.Build.Tasks project. - // Therefore, NuGet.Build.Tasks project must be built before runnig this test. + // Therefore, NuGet.Build.Tasks project must be built before running this test. var tfmTargets = GetFrameworkMoniker(typeof(PackageFileNameTests), out var _); _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, tfmTargets, FILENAME_TARGETS); if (!System.IO.File.Exists(_pathTargetsFile)) @@ -85,86 +85,80 @@ public static System.Collections.Generic.IEnumerable TestCases { get { - var cases = new object[][] + var cases = new PackageFileNameTestCase[] { // without nuspec input - new object[]{"proj.1.9.0.nupkg", "proj", "nusp", "1.9", "", "", false}, - new object[]{"proj.2.0.0.nupkg", "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", false}, - new object[]{"proj.2.0.0.1.nupkg", "proj", "nusp", "2.0.0.1", " ", "4.0.0.1", false}, - new object[]{"proj.2.0.0.2.nupkg", "proj", "nusp", "2.0.0.2", "3.0.0.2", "4.0.0.2", false}, - new object[]{"proj.2.0.0.3-preview.nupkg", "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false}, + new PackageFileNameTestCase("000",["proj.1.9.0.nupkg" ], "proj", "nusp", "1.9", "", "", false), + new PackageFileNameTestCase("001",["proj.2.0.0.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", false), + new PackageFileNameTestCase("002",["proj.2.0.0.1.nupkg" ], "proj", "nusp", "2.0.0.1", " ", "4.0.0.1", false), + new PackageFileNameTestCase("003",["proj.2.0.0.2.nupkg" ], "proj", "nusp", "2.0.0.2", "3.0.0.2", "4.0.0.2", false), + new PackageFileNameTestCase("004",["proj.2.0.0.3-preview.nupkg"], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false), + new PackageFileNameTestCase("100",["proj.nupkg" ], "proj", "nusp", "1.9", "", "", false, OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("104",["proj.nupkg" ], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false,OutputFileNamesWithoutVersion:true), // with nuspec input - new object[]{"nusp.4.0.0.nupkg", "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true}, - new object[]{"nusp.4.0.0.3.nupkg", "proj", "nusp", "2.0.0.3", " ", "4.0.0.3", true}, - new object[]{"nusp.3.0.0.4.nupkg", "proj", "nusp", "2.0.0.4", "3.0.0.4", "4.0.0.4", true}, - new object[]{"nusp.5.0.0-preview.nupkg", "proj", "nusp", "2.0.0.0", " ", "5.0.0.0-preview", true}, - new object[]{"nusp.5.0.0.2-preview.nupkg", "proj", "nusp", "2.0.0.0", " ", "5.0.0.2-preview", true}, - new object[]{"nusp.6.0.0-beta.nupkg", "proj", "nusp", "2.0.0.0", "6-beta", "5.0.0.3-preview", true}, + new PackageFileNameTestCase("010",["nusp.4.0.0.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true), + new PackageFileNameTestCase("011",["nusp.4.0.0.3.nupkg" ], "proj", "nusp", "2.0.0.3", " ", "4.0.0.3", true), + new PackageFileNameTestCase("012",["nusp.3.0.0.4.nupkg" ], "proj", "nusp", "2.0.0.4", "3.0.0.4", "4.0.0.4", true), + new PackageFileNameTestCase("013",["nusp.5.0.0-preview.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "5.0.0.0-preview", true), + new PackageFileNameTestCase("014",["nusp.5.0.0.2-preview.nupkg"], "proj", "nusp", "2.0.0.0", " ", "5.0.0.2-preview", true), + new PackageFileNameTestCase("015",["nusp.6.0.0-beta.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true), + new PackageFileNameTestCase("110",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true, OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("115",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true, OutputFileNamesWithoutVersion:true), // has symbol - new object[]{"proj.2.1.0.snupkg", "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, true,NuGet.Commands.SymbolPackageFormat.Snupkg }, - new object[]{"nusp.7.1.2.snupkg", "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, true,NuGet.Commands.SymbolPackageFormat.Snupkg }, + new PackageFileNameTestCase("020",["proj.2.1.0.snupkg"], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), + new PackageFileNameTestCase("021",["nusp.7.1.2.snupkg"], "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), + new PackageFileNameTestCase("120",["proj.snupkg" ], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ,OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("121",["nusp.snupkg" ], "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ,OutputFileNamesWithoutVersion:true), - new object[]{"proj.2.2.0.nupkg;proj.2.2.0.symbols.nupkg", "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, true,NuGet.Commands.SymbolPackageFormat.SymbolsNupkg }, - new object[]{"nusp.7.2.2.nupkg;nusp.7.2.2.symbols.nupkg", "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, true,NuGet.Commands.SymbolPackageFormat.SymbolsNupkg }, - }; + new PackageFileNameTestCase("022",["proj.2.2.0.nupkg", "proj.2.2.0.symbols.nupkg"], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), + new PackageFileNameTestCase("023",["nusp.7.2.2.nupkg", "nusp.7.2.2.symbols.nupkg"], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), + new PackageFileNameTestCase("122",["proj.nupkg", "proj.symbols.nupkg" ], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("123",["nusp.nupkg", "nusp.symbols.nupkg" ], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, OutputFileNamesWithoutVersion:true), + // NoVersion + }; - // for view order in test explorer - for (int i = 0; i < cases.Length; i++) - { - cases[i][0] = string.Join(";", cases[i][0].ToString()!.Split(';').Select(fileName => $"{i:00}_{fileName}").OfType()); - for (int j = 1; j < 3; j++) - { - cases[i][j] = $"{i:00}_{cases[i][j]}"; - } - } - return cases; + + return (object[][])cases.Select((c, i) => new object[] { c }).ToArray(); } } - [PlatformTheory(Platform.Windows)] + [Theory] [MemberData(nameof(TestCases))] - public void GetPackOutputItemsTask_PackageFileName - (string outputNupkgNames - , string idProjProp - , string idNuspecMeta - , string versionProjProp - , string versionNuspecProperties - , string versionNuspecMeta - , bool useNuspecFile - , bool includeSymbols = false - , NuGet.Commands.SymbolPackageFormat symbolPackageFormat = Commands.SymbolPackageFormat.Snupkg) + public void GetPackOutputItemsTask_PackageFileName(PackageFileNameTestCase testCase) { + const string projectFileName = "test.csproj"; const string nuspecFileName = "test.nuspec"; - string[] outputExtensions = GetOutputExtensions(includeSymbols, symbolPackageFormat); + string[] outputExtensions = GetOutputExtensions(testCase.IncludeSymbols, testCase.SymbolPackageFormat); var outputItemTask = new NuGet.Build.Tasks.Pack.GetPackOutputItemsTask(); - outputItemTask.PackageId = idProjProp; - outputItemTask.PackageVersion = versionProjProp; - outputItemTask.IncludeSymbols = includeSymbols; - outputItemTask.SymbolPackageFormat = GetSymbolPackageFormatText(symbolPackageFormat); - if (!string.IsNullOrWhiteSpace(versionNuspecProperties)) + outputItemTask.PackageId = testCase.IdProjProp; + outputItemTask.PackageVersion = testCase.VersionProjProp; + outputItemTask.IncludeSymbols = testCase.IncludeSymbols; + outputItemTask.SymbolPackageFormat = GetSymbolPackageFormatText(testCase.SymbolPackageFormat); + outputItemTask.OutputFileNamesWithoutVersion = testCase.OutputFileNamesWithoutVersion; + if (!string.IsNullOrWhiteSpace(testCase.VersionNuspecProperties)) { - outputItemTask.NuspecProperties = new string[] { $"version={versionNuspecProperties}" }; + outputItemTask.NuspecProperties = new string[] { $"version={testCase.VersionNuspecProperties}" }; } using (var testDirectory = TestDirectory.Create()) { outputItemTask.PackageOutputPath = testDirectory.Path; outputItemTask.NuspecOutputPath = testDirectory.Path; - if (useNuspecFile) + if (testCase.UseNuspecFile) { outputItemTask.NuspecInputFilePath = System.IO.Path.Combine(testDirectory.Path, nuspecFileName); } - CreateTestProjectFileAndNuspecFile(testDirectory, projectFileName, nuspecFileName, idProjProp, idNuspecMeta, versionProjProp, versionNuspecProperties, versionNuspecMeta, useNuspecFile, includeSymbols, symbolPackageFormat); + CreateTestProjectFileAndNuspecFile(testDirectory, projectFileName, nuspecFileName, testCase);// idProjProp, idNuspecMeta, versionProjProp, versionNuspecProperties, versionNuspecMeta, useNuspecFile, includeSymbols, symbolPackageFormat); Assert.True(outputItemTask.Execute()); - foreach (string outputNupkgName in outputNupkgNames.Split(';')) + foreach (string outputNupkgName in testCase.OutputNupkgNames) { string[] itemSpecs = outputItemTask.OutputPackItems.Select(item => item.ItemSpec).ToArray(); var matchCount = GetNameMatchFilePathCount(outputNupkgName, itemSpecs); @@ -176,22 +170,13 @@ public void GetPackOutputItemsTask_PackageFileName [PlatformTheory(Platform.Windows)] [MemberData(nameof(TestCases))] - public void PackTask_PackageFileName_FromProjectFileWithNuspecFile - (string outputNupkgNames - , string idProjProp - , string idNuspecMeta - , string versionProjProp - , string versionNuspecProperties - , string versionNuspecMeta - , bool useNuspecFile - , bool includeSymbols = false - , NuGet.Commands.SymbolPackageFormat symbolPackageFormat = Commands.SymbolPackageFormat.Snupkg) + public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNameTestCase testCase) { - string[] outputExtensions = GetOutputExtensions(includeSymbols, symbolPackageFormat); + string[] outputExtensions = GetOutputExtensions(testCase.IncludeSymbols, testCase.SymbolPackageFormat); using (var testDirectory = TestDirectory.Create()) { - CreateTestProjectFileAndNuspecFile(testDirectory, FILENAME_PROJECT_FILE, FILENAME_NUSPEC_FILE, idProjProp, idNuspecMeta, versionProjProp, versionNuspecProperties, versionNuspecMeta, useNuspecFile, includeSymbols, symbolPackageFormat); + CreateTestProjectFileAndNuspecFile(testDirectory, FILENAME_PROJECT_FILE, FILENAME_NUSPEC_FILE, testCase);// idProjProp, idNuspecMeta, versionProjProp, versionNuspecProperties, versionNuspecMeta, useNuspecFile, includeSymbols, symbolPackageFormat); CommandRunnerResult runresultDotnetPack; if (_isDotNetFramework) @@ -225,7 +210,7 @@ public void PackTask_PackageFileName_FromProjectFileWithNuspecFile .Distinct().ToArray(); Assert.Equal(outputExtensions.Length, nupkgGneratedFiles.Length); - foreach (string outputNupkgName in outputNupkgNames.Split(';')) + foreach (string outputNupkgName in testCase.OutputNupkgNames) { var matchCountInFileSystem = GetNameMatchFilePathCount(outputNupkgName, nupkgGneratedFiles); Assert.True(matchCountInFileSystem == 1, $"{outputNupkgName} is not found in filesystem. [{string.Join(" , ", nupkgGneratedFiles.Select(_ => System.IO.Path.GetFileName(_)))}]"); @@ -240,14 +225,7 @@ private void CreateTestProjectFileAndNuspecFile (string testDirectory , string projectFileName , string nuspecFileName - , string idProjProp - , string idNuspecMeta - , string versionProjProp - , string versionNuspecProperties - , string versionNuspecMeta - , bool useNuspecFile - , bool includeSymbols - , NuGet.Commands.SymbolPackageFormat symbolPackageFormat) + , PackageFileNameTestCase testCase) { var csprojPath = Path.Combine(testDirectory, projectFileName); @@ -270,24 +248,26 @@ private void CreateTestProjectFileAndNuspecFile false True - {idProjProp} - {versionProjProp} + {testCase.IdProjProp} + {testCase.VersionProjProp} tagA;tagB - {nuspecFileName} - version={versionNuspecProperties} + {nuspecFileName} + version={testCase.VersionNuspecProperties} - {includeSymbols} - {GetSymbolPackageFormatText(symbolPackageFormat)} + {testCase.IncludeSymbols} + {GetSymbolPackageFormatText(testCase.SymbolPackageFormat)} + + {testCase.OutputFileNamesWithoutVersion} - - - + + + @@ -298,8 +278,8 @@ private void CreateTestProjectFileAndNuspecFile - {idNuspecMeta} - {versionNuspecMeta?.Trim()} + {testCase.IdNuspecMeta} + {testCase.VersionNuspecMeta?.Trim()} Unit Test Sample Description en-US @@ -308,7 +288,7 @@ private void CreateTestProjectFileAndNuspecFile """; File.WriteAllText(csprojPath, csprojContent, System.Text.Encoding.Unicode); - if (useNuspecFile) + if (testCase.UseNuspecFile) { File.WriteAllText(nuspecPath, nuspecContent, new System.Text.UTF8Encoding(true)); } @@ -366,7 +346,7 @@ private static string GetMsBuildExePath() { var msbuildexe = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", "msbuild.exe"); - var vswhereexe = @"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"; + var vswhereexe = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86), "Microsoft Visual Studio", "Installer", "vswhere.exe"); var runresult = CommandRunner.Run( vswhereexe, System.Environment.CurrentDirectory, @@ -383,4 +363,56 @@ private static string GetMsBuildExePath() } } } + + [method: Newtonsoft.Json.JsonConstructor] + public record class PackageFileNameTestCase + (string TestNumber + , string[] OutputNupkgNames + , string IdProjProp + , string IdNuspecMeta + , string VersionProjProp + , string VersionNuspecProperties + , string VersionNuspecMeta + , bool UseNuspecFile + , bool OutputFileNamesWithoutVersion = false + , bool IncludeSymbols = false + , NuGet.Commands.SymbolPackageFormat SymbolPackageFormat = Commands.SymbolPackageFormat.Snupkg + ) : IXunitSerializable + { + + + #region IXunitSerializable + + [System.Obsolete] + public PackageFileNameTestCase() : this("", [], "", "", "", "", "", false) { } + + private const string TestObjectKey = nameof(PackageFileNameTests); + private readonly Newtonsoft.Json.JsonSerializerSettings _settings = new Newtonsoft.Json.JsonSerializerSettings { MaxDepth = null }; + + void IXunitSerializable.Serialize(IXunitSerializationInfo info) + { + info.AddValue(TestObjectKey, Newtonsoft.Json.JsonConvert.SerializeObject(this)); + + } + void IXunitSerializable.Deserialize(IXunitSerializationInfo info) + { + var json = (string)info.GetValue(TestObjectKey, typeof(string)); + var x = Newtonsoft.Json.JsonConvert.DeserializeObject(json, _settings); + if (x == null) + { + return; + } + + var t = typeof(PackageFileNameTestCase); + var c = t.GetConstructors().Where(_ => _.GetParameters().Length != 0).ToArray()[0]; + + foreach (System.Reflection.ParameterInfo p in c.GetParameters()) + { + var pi = t.GetProperty(p.Name!); + pi!.SetValue(this, pi.GetValue(x)); + } + } + + #endregion + } } From a3031e3b113ea014dfd719eb7196ceaca98a4bd3 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Sat, 31 Jan 2026 15:33:07 +0900 Subject: [PATCH 03/15] Remove unnecessary comments --- .../NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs index 01e7e5b49d4..3c00b61d89b 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs @@ -154,7 +154,7 @@ public void GetPackOutputItemsTask_PackageFileName(PackageFileNameTestCase testC outputItemTask.NuspecInputFilePath = System.IO.Path.Combine(testDirectory.Path, nuspecFileName); } - CreateTestProjectFileAndNuspecFile(testDirectory, projectFileName, nuspecFileName, testCase);// idProjProp, idNuspecMeta, versionProjProp, versionNuspecProperties, versionNuspecMeta, useNuspecFile, includeSymbols, symbolPackageFormat); + CreateTestProjectFileAndNuspecFile(testDirectory, projectFileName, nuspecFileName, testCase); Assert.True(outputItemTask.Execute()); @@ -176,7 +176,7 @@ public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNa using (var testDirectory = TestDirectory.Create()) { - CreateTestProjectFileAndNuspecFile(testDirectory, FILENAME_PROJECT_FILE, FILENAME_NUSPEC_FILE, testCase);// idProjProp, idNuspecMeta, versionProjProp, versionNuspecProperties, versionNuspecMeta, useNuspecFile, includeSymbols, symbolPackageFormat); + CreateTestProjectFileAndNuspecFile(testDirectory, FILENAME_PROJECT_FILE, FILENAME_NUSPEC_FILE, testCase); CommandRunnerResult runresultDotnetPack; if (_isDotNetFramework) From 6af6b22b4f5cd512b26e45fa946e209b3a7c7362 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Tue, 17 Feb 2026 10:06:04 +0900 Subject: [PATCH 04/15] Fix build failure occurring in Azure Pipelines The build error was caused by project dependencies defined in the solution file. Dependencies were configured at the solution level, Azure Pipelines failed to build the affected project. --- NuGet.sln | 3 --- .../NuGet.Build.Tasks.Pack.Test.csproj | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/NuGet.sln b/NuGet.sln index 846bbcc7bfd..8645845aa8f 100644 --- a/NuGet.sln +++ b/NuGet.sln @@ -161,9 +161,6 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGet.XPlat.FuncTest", "test\NuGet.Core.FuncTests\NuGet.XPlat.FuncTest\NuGet.XPlat.FuncTest.csproj", "{2034C981-C938-4F0F-8F3B-528B83CB8F7D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGet.Build.Tasks.Pack.Test", "test\NuGet.Core.Tests\NuGet.Build.Tasks.Pack.Test\NuGet.Build.Tasks.Pack.Test.csproj", "{8BF8279D-196F-481A-9659-488864D93D2D}" - ProjectSection(ProjectDependencies) = postProject - {3B96F91B-3B58-40ED-B06E-5CD133A79A63} = {3B96F91B-3B58-40ED-B06E-5CD133A79A63} - EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGet.Build.Tasks.Pack", "src\NuGet.Core\NuGet.Build.Tasks.Pack\NuGet.Build.Tasks.Pack.csproj", "{16863138-7C0E-49ED-A1C8-B9165FED9920}" EndProject diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj index 91b23e340ff..83c7e3d7f69 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj @@ -10,6 +10,7 @@ + From 684f75d8bab421390a8c61bf986a9d1f06609fe2 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Fri, 20 Feb 2026 19:04:43 +0900 Subject: [PATCH 05/15] Fix environment variable for dotnet build in test --- .../GetPackOutputItemsTask.cs | 33 ++-- .../NuGet.Build.Tasks.Pack/PackTaskLogic.cs | 8 +- .../BuildFixture.cs | 146 ++++++++++++++++++ .../PackageNameTests.cs | 143 ++++------------- 4 files changed, 204 insertions(+), 126 deletions(-) create mode 100644 test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs index c0f0b96b040..d1d1e176602 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs @@ -54,27 +54,42 @@ public override bool Execute() if (!string.IsNullOrWhiteSpace(NuspecInputFilePath)) { + bool hasVersionInNuspecProperties = false; + if (NuspecProperties != null && NuspecProperties.Length > 0) + { + PackArgs packArgs = new PackArgs(); + PackTaskLogic.SetPackArgsPropertiesFromNuspecProperties(packArgs, MSBuildStringUtility.TrimAndExcludeNullOrEmpty(NuspecProperties)); + if (packArgs.Properties.ContainsKey("version")) + { + packageVersion = packArgs.Version; + hasVersionInNuspecProperties = true; + } + if (packArgs.Properties.TryGetValue("id", out var idTemp)) + { + packageId = idTemp; + } + } + var nuspecReader = new NuGet.Packaging.NuspecReader(NuspecInputFilePath); packageId = nuspecReader.GetId(); - packageVersion = nuspecReader.GetVersion().ToNormalizedString(); - - PackArgs packArgs = new PackArgs() { Version = packageVersion }; - PackTaskLogic.SetPackArgsPropertiesFromNuspecProperties(packArgs, MSBuildStringUtility.TrimAndExcludeNullOrEmpty(NuspecProperties), NuspecInputFilePath); - packageVersion = packArgs.Version; + if (!hasVersionInNuspecProperties) + { + packageVersion = nuspecReader.GetVersion().ToNormalizedString(); + } } - NuGetVersion version; - if (!NuGetVersion.TryParse(packageVersion, out version)) + if (!NuGetVersion.TryParse(packageVersion, out var versionTemp)) { throw new ArgumentException(string.Format( CultureInfo.CurrentCulture, Strings.InvalidPackageVersion, packageVersion)); } + NuGetVersion version = versionTemp!; var symbolPackageFormat = PackArgs.GetSymbolPackageFormat(MSBuildStringUtility.TrimAndGetNullForEmpty(SymbolPackageFormat)); - var nupkgFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: true, symbols: false, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); - var nuspecFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: false, symbols: false, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); + var nupkgFileName = PackCommandRunner.GetOutputFileName(packageId, version!, isNupkg: true, symbols: false, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); + var nuspecFileName = PackCommandRunner.GetOutputFileName(packageId, version!, isNupkg: false, symbols: false, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); var outputs = new List(); outputs.Add(new TaskItem(Path.Combine(PackageOutputPath, nupkgFileName))); diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs index 06302883188..da230ccde9e 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTaskLogic.cs @@ -75,7 +75,7 @@ public PackArgs GetPackArgs(IPackTaskRequest request) if (!string.IsNullOrEmpty(request.NuspecFile)) { - SetPackArgsPropertiesFromNuspecProperties(packArgs, request.NuspecProperties, request.NuspecFile); + SetPackArgsPropertiesFromNuspecProperties(packArgs, request.NuspecProperties); } else { @@ -1084,9 +1084,9 @@ private static IDictionary ParsePropertiesAsDictionary(string[] return dictionary; } - internal static void SetPackArgsPropertiesFromNuspecProperties(PackArgs packArgs, string[] nuspecProperties, string nuspecInputFilePath) + internal static void SetPackArgsPropertiesFromNuspecProperties(PackArgs packArgs, string[] nuspecProperties) { - if (string.IsNullOrWhiteSpace(nuspecInputFilePath) || nuspecProperties == null || !nuspecProperties.Any()) + if (nuspecProperties == null || !nuspecProperties.Any()) { return; } @@ -1103,8 +1103,6 @@ internal static void SetPackArgsPropertiesFromNuspecProperties(PackArgs packArgs } packArgs.Version = version.ToNormalizedString(); } - - } private HashSet InitOutputExtensions(IEnumerable outputExtensions) diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs new file mode 100644 index 00000000000..a422fa3f2e6 --- /dev/null +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs @@ -0,0 +1,146 @@ +// 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. +#nullable enable + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.Internal.NuGet.Testing.SignedPackages.ChildProcess; +using NuGet.Frameworks; +using NuGet.Test.Utility; +using Xunit; + +namespace NuGet.Build.Tasks.Pack.Test +{ + [CollectionDefinition(Name)] + public class FixtureCollection + : ICollectionFixture + { + internal const string Name = "Build Tests"; + } + + public class BuildFixture : IDisposable + { +#if DEBUG + const string CONFIGURATION = "Debug"; +#else + const string CONFIGURATION = "Release"; +#endif + + const string FILENAME_DLL = "NuGet.Build.Tasks.Pack.dll"; + const string FILENAME_TARGETS = "NuGet.Build.Tasks.Pack.targets"; + + internal readonly bool _isDotNetFramework = false; + internal readonly string _testFrameworkMoniker = "netstandard2.0"; + +#if IS_DESKTOP + private const string SdkVersion = "10"; + private const string SdkTfm = "net10.0"; +#endif + internal readonly string _pathDotnetExe; + internal readonly string _pathMSBuildExe; + internal readonly string _pathDllFile; + internal readonly string _pathTargetsFile; + + internal readonly IReadOnlyDictionary _dotnetEnvironments; + + public BuildFixture() + { + _pathDotnetExe = NuGet.Test.Utility.TestFileSystemUtility.GetDotnetCli(); + +#if IS_DESKTOP + var _cliDirectory = TestDotnetCLiUtility.CopyAndPatchLatestDotnetCli(SdkVersion, SdkTfm); +#else + string testAssemblyPath = Path.GetFullPath(System.Reflection.Assembly.GetExecutingAssembly().Location); + var _cliDirectory = TestDotnetCLiUtility.CopyAndPatchLatestDotnetCli(testAssemblyPath); +#endif + var dotnetExecutableName = NuGet.Common.RuntimeEnvironmentHelper.IsWindows ? "dotnet.exe" : "dotnet"; + _pathDotnetExe = Path.Combine(_cliDirectory, dotnetExecutableName); + + var sdkPath = Directory.EnumerateDirectories(Path.Combine(_cliDirectory, "sdk")) + .Single(d => !string.Equals(Path.GetFileName(d), "NuGetFallbackFolder", StringComparison.OrdinalIgnoreCase)); + + _pathMSBuildExe = GetMsBuildExePath(); + _testFrameworkMoniker = GetFrameworkMoniker(typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask), out var isDotNetFramework); + _isDotNetFramework = isDotNetFramework; + + var artifactsDirectory = NuGet.Test.Utility.TestFileSystemUtility.GetArtifactsDirectoryInRepo(); + var dllLocation = typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask).Assembly.Location; + var dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); + if (!System.IO.Directory.Exists(dllDirectory)) + { + dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); + } + + _pathDllFile = Path.Combine(dllDirectory, FILENAME_DLL); + + // https://github.com/NuGet/NuGet.Client/pull/6712 + // NuGet.Build.Tasks.Pack.targets has been moved to in NuGet.Build.Tasks project. + // Therefore, NuGet.Build.Tasks project must be built before running this test. + var tfmTargets = GetFrameworkMoniker(typeof(PackageFileNameTests), out var _); + _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, tfmTargets, FILENAME_TARGETS); + if (!System.IO.File.Exists(_pathTargetsFile)) + { + _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, _testFrameworkMoniker, FILENAME_TARGETS); + if (!System.IO.File.Exists(_pathTargetsFile)) + { + _pathTargetsFile = Path.Combine(dllDirectory, FILENAME_TARGETS); + } + } + + _dotnetEnvironments = new Dictionary() + { + ["MSBuildSDKsPath"] = Path.Combine(sdkPath, "Sdks"), + ["DOTNET_MULTILEVEL_LOOKUP"] = "0", + ["DOTNET_ROOT"] = _cliDirectory, + ["MSBuildExtensionsPath"] = new DirectoryInfo(sdkPath).FullName, + ["PATH"] = $"{_cliDirectory}{Path.PathSeparator}{Environment.GetEnvironmentVariable("PATH")}" + }; + + Assert.True(System.IO.File.Exists(_pathDllFile), $"{FILENAME_DLL} missing"); + Assert.True(System.IO.File.Exists(_pathTargetsFile), $"{FILENAME_TARGETS} missing"); + } + + private static string GetFrameworkMoniker(Type typeInAssembly, out bool isDotNetFramework) + { + var assembly = typeInAssembly.Assembly; + var targetFrameworkAttribute + = assembly.GetCustomAttributes(typeof(System.Runtime.Versioning.TargetFrameworkAttribute), false) + .OfType().FirstOrDefault(); + + Assert.True(targetFrameworkAttribute != null, "Can't get targetFramework version"); + + isDotNetFramework = targetFrameworkAttribute.FrameworkName.Contains(".NETFramework"); + return NuGetFramework.Parse(targetFrameworkAttribute.FrameworkName).GetShortFolderName(); + } + + private static string GetMsBuildExePath() + { + if (System.Environment.OSVersion.Platform == System.PlatformID.Win32NT) + { + var msbuildexe = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", "msbuild.exe"); + + var vswhereexe = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86), "Microsoft Visual Studio", "Installer", "vswhere.exe"); + var runresult = CommandRunner.Run( + vswhereexe, + System.Environment.CurrentDirectory, + @" -latest -find MSBuild\**\Bin\MSBuild.exe"); + if (runresult.Success) + { + msbuildexe = new System.IO.StringReader(runresult.Output).ReadLine() ?? ""; + } + return msbuildexe; + } + else + { + return ""; + } + } + + public void Dispose() + { + } + + } +} diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs index 3c00b61d89b..4efe74ae60f 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs @@ -2,19 +2,19 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. #nullable enable -using System; using System.IO; using System.Linq; using Microsoft.Internal.NuGet.Testing.SignedPackages.ChildProcess; -using NuGet.Frameworks; using NuGet.Test.Utility; using Xunit; using Xunit.Abstractions; namespace NuGet.Build.Tasks.Pack.Test { + /// /// The _GetOutputItemsFromPack target inside the NuGet.Build.Tasks.Pack.targets file is the subject of the test, so the project that includes NuGet.Build.Tasks.Pack.targets must be registered as a build dependency. + [Collection(FixtureCollection.Name)] public class PackageFileNameTests { #region constructor and fields @@ -25,58 +25,16 @@ public class PackageFileNameTests const string CONFIGURATION = "Release"; #endif - const string FILENAME_DLL = "NuGet.Build.Tasks.Pack.dll"; - const string FILENAME_TARGETS = "NuGet.Build.Tasks.Pack.targets"; const string FILENAME_PROJECT_FILE = "test.csproj"; const string FILENAME_NUSPEC_FILE = "test.nuspec"; - private readonly bool _isDotNetFramework = false; - private readonly string _testFrameworkMoniker = "netstandard2.0"; - - private readonly string _pathDotnetExe = ""; - private readonly string _pathMSBuildExe = ""; - private readonly string _pathDllFile; - private readonly string _pathTargetsFile; - + private readonly BuildFixture _testFixture; private readonly ITestOutputHelper _testOutputHelper; - public PackageFileNameTests(ITestOutputHelper testOutputHelper) + public PackageFileNameTests(BuildFixture testFixture, ITestOutputHelper testOutputHelper) { + _testFixture = testFixture; _testOutputHelper = testOutputHelper; - - _pathDotnetExe = NuGet.Test.Utility.TestFileSystemUtility.GetDotnetCli(); - _pathMSBuildExe = GetMsBuildExePath(); - _testFrameworkMoniker = GetFrameworkMoniker(typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask), out var isDotNetFramework); - _isDotNetFramework = isDotNetFramework; - - var dllLocation = typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask).Assembly.Location; - var artifactsDirectory = NuGet.Test.Utility.TestFileSystemUtility.GetArtifactsDirectoryInRepo(); - - var dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); - if (!System.IO.Directory.Exists(dllDirectory)) - { - _testFrameworkMoniker = GetFrameworkMoniker(typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask), out var isDotnetFramework); - dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); - } - - _pathDllFile = Path.Combine(dllDirectory, FILENAME_DLL); - - // https://github.com/NuGet/NuGet.Client/pull/6712 - // NuGet.Build.Tasks.Pack.targets has been moved to in NuGet.Build.Tasks project. - // Therefore, NuGet.Build.Tasks project must be built before running this test. - var tfmTargets = GetFrameworkMoniker(typeof(PackageFileNameTests), out var _); - _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, tfmTargets, FILENAME_TARGETS); - if (!System.IO.File.Exists(_pathTargetsFile)) - { - _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, _testFrameworkMoniker, FILENAME_TARGETS); - if (!System.IO.File.Exists(_pathTargetsFile)) - { - _pathTargetsFile = Path.Combine(dllDirectory, FILENAME_TARGETS); - } - } - - Assert.True(System.IO.File.Exists(_pathDllFile), $"{FILENAME_DLL} missing"); - Assert.True(System.IO.File.Exists(_pathTargetsFile), $"{FILENAME_TARGETS} missing"); } #endregion @@ -87,24 +45,26 @@ public static System.Collections.Generic.IEnumerable TestCases { var cases = new PackageFileNameTestCase[] { + // without nuspec input new PackageFileNameTestCase("000",["proj.1.9.0.nupkg" ], "proj", "nusp", "1.9", "", "", false), new PackageFileNameTestCase("001",["proj.2.0.0.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", false), new PackageFileNameTestCase("002",["proj.2.0.0.1.nupkg" ], "proj", "nusp", "2.0.0.1", " ", "4.0.0.1", false), new PackageFileNameTestCase("003",["proj.2.0.0.2.nupkg" ], "proj", "nusp", "2.0.0.2", "3.0.0.2", "4.0.0.2", false), new PackageFileNameTestCase("004",["proj.2.0.0.3-preview.nupkg"], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false), + new PackageFileNameTestCase("005",["proj.2.0.0.4-release.nupkg"], "proj", "$meta_id$", "2.0.0.4-release", "3.0.0.2", "$meta_version$", false), new PackageFileNameTestCase("100",["proj.nupkg" ], "proj", "nusp", "1.9", "", "", false, OutputFileNamesWithoutVersion:true), new PackageFileNameTestCase("104",["proj.nupkg" ], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false,OutputFileNamesWithoutVersion:true), // with nuspec input - new PackageFileNameTestCase("010",["nusp.4.0.0.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true), - new PackageFileNameTestCase("011",["nusp.4.0.0.3.nupkg" ], "proj", "nusp", "2.0.0.3", " ", "4.0.0.3", true), + new PackageFileNameTestCase("010",["nusp.4.0.0.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true), + new PackageFileNameTestCase("011",["nusp.4.0.0.3.nupkg" ], "proj", "nusp", "2.0.0.3", " ", "4.0.0.3", true), new PackageFileNameTestCase("012",["nusp.3.0.0.4.nupkg" ], "proj", "nusp", "2.0.0.4", "3.0.0.4", "4.0.0.4", true), - new PackageFileNameTestCase("013",["nusp.5.0.0-preview.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "5.0.0.0-preview", true), - new PackageFileNameTestCase("014",["nusp.5.0.0.2-preview.nupkg"], "proj", "nusp", "2.0.0.0", " ", "5.0.0.2-preview", true), - new PackageFileNameTestCase("015",["nusp.6.0.0-beta.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true), - new PackageFileNameTestCase("110",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true, OutputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("115",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true, OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("013",["nusp.5.0.0-preview.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "5.0.0.0-preview", true), + new PackageFileNameTestCase("014",["nusp.5.0.0.2-preview.nupkg"], "proj", "nusp", "2.0.0.0", " ", "5.0.0.2-preview", true), + new PackageFileNameTestCase("015",["nusp.6.0.0-beta.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true), + new PackageFileNameTestCase("110",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true, OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("115",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true, OutputFileNamesWithoutVersion:true), // has symbol new PackageFileNameTestCase("020",["proj.2.1.0.snupkg"], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), @@ -115,6 +75,7 @@ public static System.Collections.Generic.IEnumerable TestCases new PackageFileNameTestCase("022",["proj.2.2.0.nupkg", "proj.2.2.0.symbols.nupkg"], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), new PackageFileNameTestCase("023",["nusp.7.2.2.nupkg", "nusp.7.2.2.symbols.nupkg"], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), new PackageFileNameTestCase("122",["proj.nupkg", "proj.symbols.nupkg" ], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("123",["nusp.nupkg", "nusp.symbols.nupkg" ], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, OutputFileNamesWithoutVersion:true), // NoVersion }; @@ -128,10 +89,6 @@ public static System.Collections.Generic.IEnumerable TestCases [MemberData(nameof(TestCases))] public void GetPackOutputItemsTask_PackageFileName(PackageFileNameTestCase testCase) { - - const string projectFileName = "test.csproj"; - const string nuspecFileName = "test.nuspec"; - string[] outputExtensions = GetOutputExtensions(testCase.IncludeSymbols, testCase.SymbolPackageFormat); var outputItemTask = new NuGet.Build.Tasks.Pack.GetPackOutputItemsTask(); @@ -151,10 +108,10 @@ public void GetPackOutputItemsTask_PackageFileName(PackageFileNameTestCase testC outputItemTask.NuspecOutputPath = testDirectory.Path; if (testCase.UseNuspecFile) { - outputItemTask.NuspecInputFilePath = System.IO.Path.Combine(testDirectory.Path, nuspecFileName); + outputItemTask.NuspecInputFilePath = System.IO.Path.Combine(testDirectory.Path, FILENAME_NUSPEC_FILE); } - CreateTestProjectFileAndNuspecFile(testDirectory, projectFileName, nuspecFileName, testCase); + CreateTestProjectFileAndNuspecFile(testDirectory, FILENAME_PROJECT_FILE, FILENAME_NUSPEC_FILE, testCase); Assert.True(outputItemTask.Execute()); @@ -167,8 +124,7 @@ public void GetPackOutputItemsTask_PackageFileName(PackageFileNameTestCase testC } } - - [PlatformTheory(Platform.Windows)] + [PlatformTheory(Platform.Windows, Timeout = -1)] [MemberData(nameof(TestCases))] public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNameTestCase testCase) { @@ -179,12 +135,12 @@ public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNa CreateTestProjectFileAndNuspecFile(testDirectory, FILENAME_PROJECT_FILE, FILENAME_NUSPEC_FILE, testCase); CommandRunnerResult runresultDotnetPack; - if (_isDotNetFramework) + if (_testFixture._isDotNetFramework) { // As noted in #6703, since the .NetStandard2.0 library has been removed, // running tests on .net Framework requires invoking msbuild.exe. runresultDotnetPack = CommandRunner.Run( - _pathMSBuildExe, + _testFixture._pathMSBuildExe, testDirectory, $"/t:Restore;Build;Pack /p:Configuration={CONFIGURATION} /p:UsingMicrosoftNetSdk=true {FILENAME_PROJECT_FILE} ", testOutputHelper: _testOutputHelper); @@ -193,10 +149,11 @@ public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNa { // dotnet build runresultDotnetPack = CommandRunner.Run( - _pathDotnetExe, - testDirectory, - $"build -p:Configuration={CONFIGURATION} {FILENAME_PROJECT_FILE}", - testOutputHelper: _testOutputHelper); + _testFixture._pathDotnetExe, + testDirectory, + $"build -p:Configuration={CONFIGURATION} {FILENAME_PROJECT_FILE}", + environmentVariables: _testFixture._dotnetEnvironments, + testOutputHelper: _testOutputHelper); } Assert.True(0 == runresultDotnetPack.ExitCode, runresultDotnetPack.Output + " " + runresultDotnetPack.Errors); @@ -233,14 +190,16 @@ private void CreateTestProjectFileAndNuspecFile var csprojContent = $""" - + - {_pathDllFile} + {_testFixture._pathDllFile} - {_testFrameworkMoniker} + {_testFixture._testFrameworkMoniker} + NU5100;NU5119;CS2008 + true @@ -264,11 +223,7 @@ private void CreateTestProjectFileAndNuspecFile - - - - - + @@ -326,42 +281,6 @@ private int GetNameMatchFilePathCount(string fileName, System.Collections.Generi { return fullpaths.Count(file => string.Equals(fileName, System.IO.Path.GetFileName(file), System.StringComparison.OrdinalIgnoreCase)); } - - private static string GetFrameworkMoniker(Type typeInAssembly, out bool isDotNetFramework) - { - var assembly = typeInAssembly.Assembly; - var targetFrameworkAttribute - = assembly.GetCustomAttributes(typeof(System.Runtime.Versioning.TargetFrameworkAttribute), false) - .OfType().FirstOrDefault(); - - Assert.True(targetFrameworkAttribute != null, "Can't get targetFramework version"); - - isDotNetFramework = targetFrameworkAttribute.FrameworkName.Contains(".NETFramework"); - return NuGetFramework.Parse(targetFrameworkAttribute.FrameworkName).GetShortFolderName(); - } - - private static string GetMsBuildExePath() - { - if (System.Environment.OSVersion.Platform == System.PlatformID.Win32NT) - { - var msbuildexe = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", "msbuild.exe"); - - var vswhereexe = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86), "Microsoft Visual Studio", "Installer", "vswhere.exe"); - var runresult = CommandRunner.Run( - vswhereexe, - System.Environment.CurrentDirectory, - @" -latest -find MSBuild\**\Bin\MSBuild.exe"); - if (runresult.Success) - { - msbuildexe = new System.IO.StringReader(runresult.Output).ReadLine() ?? ""; - } - return msbuildexe; - } - else - { - return ""; - } - } } [method: Newtonsoft.Json.JsonConstructor] From 463a6db12f759c74d05f8f5990db438ed92e1384 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Fri, 20 Feb 2026 20:14:09 +0900 Subject: [PATCH 06/15] Change property name for nuspec file --- .../NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs | 6 +++--- .../NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets | 6 +++++- .../NuGet.Build.Tasks.Pack.Test.csproj | 1 + .../NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs index d1d1e176602..174189fdabd 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs @@ -29,7 +29,7 @@ public class GetPackOutputItemsTask : Microsoft.Build.Utilities.Task [Required] public string NuspecOutputPath { get; set; } - public string NuspecInputFilePath { get; set; } + public string NuspecFile { get; set; } public string[] NuspecProperties { get; set; } @@ -52,7 +52,7 @@ public override bool Execute() var packageId = PackageId; var packageVersion = PackageVersion; - if (!string.IsNullOrWhiteSpace(NuspecInputFilePath)) + if (!string.IsNullOrWhiteSpace(NuspecFile)) { bool hasVersionInNuspecProperties = false; if (NuspecProperties != null && NuspecProperties.Length > 0) @@ -70,7 +70,7 @@ public override bool Execute() } } - var nuspecReader = new NuGet.Packaging.NuspecReader(NuspecInputFilePath); + var nuspecReader = new NuGet.Packaging.NuspecReader(NuspecFile); packageId = nuspecReader.GetId(); if (!hasVersionInNuspecProperties) { diff --git a/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets index dfac24c00e5..06a8064ef88 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets +++ b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.Build.Tasks.Pack.targets @@ -108,10 +108,14 @@ Copyright (c) .NET Foundation. All rights reserved. + + + + $(TargetFrameworksUnitTest) + net10.0 Unit tests for NuGet.Build.Tasks.Pack. diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs index 4efe74ae60f..b3e0d116693 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs @@ -108,7 +108,7 @@ public void GetPackOutputItemsTask_PackageFileName(PackageFileNameTestCase testC outputItemTask.NuspecOutputPath = testDirectory.Path; if (testCase.UseNuspecFile) { - outputItemTask.NuspecInputFilePath = System.IO.Path.Combine(testDirectory.Path, FILENAME_NUSPEC_FILE); + outputItemTask.NuspecFile = System.IO.Path.Combine(testDirectory.Path, FILENAME_NUSPEC_FILE); } CreateTestProjectFileAndNuspecFile(testDirectory, FILENAME_PROJECT_FILE, FILENAME_NUSPEC_FILE, testCase); From dee289bfac751f39ea4e614215d99044d5b215d5 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Fri, 20 Feb 2026 20:30:42 +0900 Subject: [PATCH 07/15] Fix TargetFrameworks --- .../NuGet.Build.Tasks.Pack.Test.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj index 9cb4bbb2eec..83c7e3d7f69 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj @@ -1,7 +1,6 @@ $(TargetFrameworksUnitTest) - net10.0 Unit tests for NuGet.Build.Tasks.Pack. From b149c8df7bb1b9d502fd8dc0b1bd84981b03e99a Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Fri, 20 Feb 2026 21:18:05 +0900 Subject: [PATCH 08/15] Refine test configuration --- .../NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs index b3e0d116693..ac6e7f59f00 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs @@ -124,7 +124,7 @@ public void GetPackOutputItemsTask_PackageFileName(PackageFileNameTestCase testC } } - [PlatformTheory(Platform.Windows, Timeout = -1)] + [PlatformTheory(Platform.Windows)] [MemberData(nameof(TestCases))] public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNameTestCase testCase) { From 5e4993d5cfccf177d0cf02a4456ac12591646078 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Sat, 21 Feb 2026 15:06:21 +0900 Subject: [PATCH 09/15] Retry test --- .../NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs index ac6e7f59f00..203b18ae80d 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs @@ -75,9 +75,8 @@ public static System.Collections.Generic.IEnumerable TestCases new PackageFileNameTestCase("022",["proj.2.2.0.nupkg", "proj.2.2.0.symbols.nupkg"], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), new PackageFileNameTestCase("023",["nusp.7.2.2.nupkg", "nusp.7.2.2.symbols.nupkg"], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), new PackageFileNameTestCase("122",["proj.nupkg", "proj.symbols.nupkg" ], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, OutputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("123",["nusp.nupkg", "nusp.symbols.nupkg" ], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, OutputFileNamesWithoutVersion:true), - // NoVersion + }; From 3408ffc42c4196a23d2af6c57cf021507ed873ec Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Sun, 8 Mar 2026 19:40:09 +0900 Subject: [PATCH 10/15] Apply multiple fixes suggested by reviewer and copilot --- .../GetPackOutputItemsTask.cs | 10 +- .../BuildFixture.cs | 24 +-- .../PackageNameTests.cs | 148 +++++++++++------- 3 files changed, 115 insertions(+), 67 deletions(-) diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs index 174189fdabd..1ff7178945b 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs @@ -55,10 +55,12 @@ public override bool Execute() if (!string.IsNullOrWhiteSpace(NuspecFile)) { bool hasVersionInNuspecProperties = false; + bool hasIdInNuspecProperties = false; if (NuspecProperties != null && NuspecProperties.Length > 0) { - PackArgs packArgs = new PackArgs(); + PackArgs packArgs = new PackArgs() { Version = packageVersion }; PackTaskLogic.SetPackArgsPropertiesFromNuspecProperties(packArgs, MSBuildStringUtility.TrimAndExcludeNullOrEmpty(NuspecProperties)); + // If the logic depends only on checking for a non-null value, it may incorrectly detect cases where the parsing logic changes the version based on a key other than the "version" key. if (packArgs.Properties.ContainsKey("version")) { packageVersion = packArgs.Version; @@ -67,11 +69,15 @@ public override bool Execute() if (packArgs.Properties.TryGetValue("id", out var idTemp)) { packageId = idTemp; + hasIdInNuspecProperties = true; } } var nuspecReader = new NuGet.Packaging.NuspecReader(NuspecFile); - packageId = nuspecReader.GetId(); + if (!hasIdInNuspecProperties) + { + packageId = nuspecReader.GetId(); + } if (!hasVersionInNuspecProperties) { packageVersion = nuspecReader.GetVersion().ToNormalizedString(); diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs index a422fa3f2e6..4d0a2259385 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs @@ -20,7 +20,8 @@ public class FixtureCollection internal const string Name = "Build Tests"; } - public class BuildFixture : IDisposable + public class BuildFixture + : IDisposable { #if DEBUG const string CONFIGURATION = "Debug"; @@ -67,8 +68,8 @@ public BuildFixture() var artifactsDirectory = NuGet.Test.Utility.TestFileSystemUtility.GetArtifactsDirectoryInRepo(); var dllLocation = typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask).Assembly.Location; - var dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); - if (!System.IO.Directory.Exists(dllDirectory)) + var dllDirectory = Path.Combine(dllLocation, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); + if (!Directory.Exists(dllDirectory)) { dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); } @@ -80,10 +81,10 @@ public BuildFixture() // Therefore, NuGet.Build.Tasks project must be built before running this test. var tfmTargets = GetFrameworkMoniker(typeof(PackageFileNameTests), out var _); _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, tfmTargets, FILENAME_TARGETS); - if (!System.IO.File.Exists(_pathTargetsFile)) + if (!File.Exists(_pathTargetsFile)) { _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, _testFrameworkMoniker, FILENAME_TARGETS); - if (!System.IO.File.Exists(_pathTargetsFile)) + if (!File.Exists(_pathTargetsFile)) { _pathTargetsFile = Path.Combine(dllDirectory, FILENAME_TARGETS); } @@ -117,19 +118,22 @@ var targetFrameworkAttribute private static string GetMsBuildExePath() { - if (System.Environment.OSVersion.Platform == System.PlatformID.Win32NT) + if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - var msbuildexe = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", "msbuild.exe"); + var msbuildexe = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", "msbuild.exe"); + var vswhereexe = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft Visual Studio", "Installer", "vswhere.exe"); + Assert.True(File.Exists(vswhereexe), "vswhere not found"); - var vswhereexe = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86), "Microsoft Visual Studio", "Installer", "vswhere.exe"); var runresult = CommandRunner.Run( vswhereexe, - System.Environment.CurrentDirectory, + Environment.CurrentDirectory, @" -latest -find MSBuild\**\Bin\MSBuild.exe"); if (runresult.Success) { - msbuildexe = new System.IO.StringReader(runresult.Output).ReadLine() ?? ""; + msbuildexe = new StringReader(runresult.Output).ReadLine() ?? ""; } + + Assert.True(File.Exists(msbuildexe), "msbuild not found"); return msbuildexe; } else diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs index 203b18ae80d..5a0abe55b49 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs @@ -53,8 +53,8 @@ public static System.Collections.Generic.IEnumerable TestCases new PackageFileNameTestCase("003",["proj.2.0.0.2.nupkg" ], "proj", "nusp", "2.0.0.2", "3.0.0.2", "4.0.0.2", false), new PackageFileNameTestCase("004",["proj.2.0.0.3-preview.nupkg"], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false), new PackageFileNameTestCase("005",["proj.2.0.0.4-release.nupkg"], "proj", "$meta_id$", "2.0.0.4-release", "3.0.0.2", "$meta_version$", false), - new PackageFileNameTestCase("100",["proj.nupkg" ], "proj", "nusp", "1.9", "", "", false, OutputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("104",["proj.nupkg" ], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false,OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("100",["proj.nupkg" ], "proj", "nusp", "1.9", "", "", false, outputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("104",["proj.nupkg" ], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false,outputFileNamesWithoutVersion:true), // with nuspec input new PackageFileNameTestCase("010",["nusp.4.0.0.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true), @@ -63,33 +63,32 @@ public static System.Collections.Generic.IEnumerable TestCases new PackageFileNameTestCase("013",["nusp.5.0.0-preview.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "5.0.0.0-preview", true), new PackageFileNameTestCase("014",["nusp.5.0.0.2-preview.nupkg"], "proj", "nusp", "2.0.0.0", " ", "5.0.0.2-preview", true), new PackageFileNameTestCase("015",["nusp.6.0.0-beta.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true), - new PackageFileNameTestCase("110",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true, OutputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("115",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true, OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("110",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true, outputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("115",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true, outputFileNamesWithoutVersion:true), // has symbol - new PackageFileNameTestCase("020",["proj.2.1.0.snupkg"], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), - new PackageFileNameTestCase("021",["nusp.7.1.2.snupkg"], "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), - new PackageFileNameTestCase("120",["proj.snupkg" ], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ,OutputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("121",["nusp.snupkg" ], "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ,OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("020",["proj.2.1.0.snupkg"], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), + new PackageFileNameTestCase("021",["nusp.7.1.2.snupkg"], "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), + new PackageFileNameTestCase("120",["proj.snupkg" ], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ,outputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("121",["nusp.snupkg" ], "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ,outputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("022",["proj.2.2.0.nupkg", "proj.2.2.0.symbols.nupkg"], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), - new PackageFileNameTestCase("023",["nusp.7.2.2.nupkg", "nusp.7.2.2.symbols.nupkg"], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), - new PackageFileNameTestCase("122",["proj.nupkg", "proj.symbols.nupkg" ], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, OutputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("123",["nusp.nupkg", "nusp.symbols.nupkg" ], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, IncludeSymbols: true,SymbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, OutputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("022",["proj.2.2.0.nupkg", "proj.2.2.0.symbols.nupkg"], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), + new PackageFileNameTestCase("023",["nusp.7.2.2.nupkg", "nusp.7.2.2.symbols.nupkg"], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), + new PackageFileNameTestCase("122",["proj.nupkg", "proj.symbols.nupkg" ], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, outputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("123",["nusp.nupkg", "nusp.symbols.nupkg" ], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, outputFileNamesWithoutVersion:true), - }; + }; return (object[][])cases.Select((c, i) => new object[] { c }).ToArray(); } } + // This unit test verifies that GetPackOutputItemsTask outputs the expected file name. [Theory] [MemberData(nameof(TestCases))] public void GetPackOutputItemsTask_PackageFileName(PackageFileNameTestCase testCase) { - string[] outputExtensions = GetOutputExtensions(testCase.IncludeSymbols, testCase.SymbolPackageFormat); - var outputItemTask = new NuGet.Build.Tasks.Pack.GetPackOutputItemsTask(); outputItemTask.PackageId = testCase.IdProjProp; outputItemTask.PackageVersion = testCase.VersionProjProp; @@ -123,6 +122,11 @@ public void GetPackOutputItemsTask_PackageFileName(PackageFileNameTestCase testC } } + + // This unit test verifies that the output file names from GetPackOutputItemsTask matches the output file names from PackTask. + // Since PackTask does not expose the output file name as a property, + // the current implementation performs an actual build and inspects the generated file. + // If PackTask is updated in the future to return the output file name as a property, this test will no longer need a build. [PlatformTheory(Platform.Windows)] [MemberData(nameof(TestCases))] public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNameTestCase testCase) @@ -138,10 +142,19 @@ public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNa { // As noted in #6703, since the .NetStandard2.0 library has been removed, // running tests on .net Framework requires invoking msbuild.exe. + + var runresultDotnetRestore = CommandRunner.Run( + _testFixture._pathMSBuildExe, + testDirectory, + $"/t:Restore {FILENAME_PROJECT_FILE}", + environmentVariables: _testFixture._dotnetEnvironments, + testOutputHelper: _testOutputHelper); + Assert.True(0 == runresultDotnetRestore.ExitCode, runresultDotnetRestore.Output + " " + runresultDotnetRestore.Errors); + runresultDotnetPack = CommandRunner.Run( _testFixture._pathMSBuildExe, testDirectory, - $"/t:Restore;Build;Pack /p:Configuration={CONFIGURATION} /p:UsingMicrosoftNetSdk=true {FILENAME_PROJECT_FILE} ", + $"/t:Build;Pack /p:Configuration={CONFIGURATION} /p:UsingMicrosoftNetSdk=true {FILENAME_PROJECT_FILE} ", testOutputHelper: _testOutputHelper); } else @@ -160,16 +173,16 @@ public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNa var log = System.IO.File.ReadAllLines(System.IO.Path.Combine(objFolder, "_OutputPackItems.txt")); var lines = log.Where(line => !line.StartsWith(objFolder)).ToArray(); - var nupkgGneratedFiles = outputExtensions + var nupkgGeneratedFiles = outputExtensions .SelectMany(outputExtension => Directory.GetFiles(testDirectory, $"*{outputExtension}", SearchOption.AllDirectories)) .Where(line => !line.StartsWith(objFolder)) .Distinct().ToArray(); - Assert.Equal(outputExtensions.Length, nupkgGneratedFiles.Length); + Assert.Equal(outputExtensions.Length, nupkgGeneratedFiles.Length); foreach (string outputNupkgName in testCase.OutputNupkgNames) { - var matchCountInFileSystem = GetNameMatchFilePathCount(outputNupkgName, nupkgGneratedFiles); - Assert.True(matchCountInFileSystem == 1, $"{outputNupkgName} is not found in filesystem. [{string.Join(" , ", nupkgGneratedFiles.Select(_ => System.IO.Path.GetFileName(_)))}]"); + var matchCountInFileSystem = GetNameMatchFilePathCount(outputNupkgName, nupkgGeneratedFiles); + Assert.True(matchCountInFileSystem == 1, $"{outputNupkgName} is not found in filesystem. [{string.Join(" , ", nupkgGeneratedFiles.Select(_ => System.IO.Path.GetFileName(_)))}]"); var matchCountInOutputPackItems = GetNameMatchFilePathCount(outputNupkgName, lines); Assert.True(matchCountInOutputPackItems == 1, $"{outputNupkgName} is not found in OutputPackItems. [{string.Join(" , ", lines.Select(_ => System.IO.Path.GetFileName(_)))}]"); @@ -282,53 +295,78 @@ private int GetNameMatchFilePathCount(string fileName, System.Collections.Generi } } - [method: Newtonsoft.Json.JsonConstructor] - public record class PackageFileNameTestCase - (string TestNumber - , string[] OutputNupkgNames - , string IdProjProp - , string IdNuspecMeta - , string VersionProjProp - , string VersionNuspecProperties - , string VersionNuspecMeta - , bool UseNuspecFile - , bool OutputFileNamesWithoutVersion = false - , bool IncludeSymbols = false - , NuGet.Commands.SymbolPackageFormat SymbolPackageFormat = Commands.SymbolPackageFormat.Snupkg - ) : IXunitSerializable + public class PackageFileNameTestCase + : IXunitSerializable { - + public PackageFileNameTestCase + (string testNumber + , string[] outputNupkgNames + , string idProjProp + , string idNuspecMeta + , string versionProjProp + , string versionNuspecProperties + , string versionNuspecMeta + , bool useNuspecFile + , bool outputFileNamesWithoutVersion = false + , bool includeSymbols = false + , NuGet.Commands.SymbolPackageFormat symbolPackageFormat = Commands.SymbolPackageFormat.Snupkg) + { + TestNumber = testNumber; + OutputNupkgNames = outputNupkgNames; + IdProjProp = idProjProp; + IdNuspecMeta = idNuspecMeta; + VersionProjProp = versionProjProp; + VersionNuspecProperties = versionNuspecProperties; + VersionNuspecMeta = versionNuspecMeta; + UseNuspecFile = useNuspecFile; + OutputFileNamesWithoutVersion = outputFileNamesWithoutVersion; + IncludeSymbols = includeSymbols; + SymbolPackageFormat = symbolPackageFormat; + } + public string TestNumber { get; set; } = string.Empty; + public string[] OutputNupkgNames { get; set; } = System.Array.Empty(); + public string IdProjProp { get; set; } = string.Empty; + public string IdNuspecMeta { get; set; } = string.Empty; + public string VersionProjProp { get; set; } = string.Empty; + public string VersionNuspecProperties { get; set; } = string.Empty; + public string VersionNuspecMeta { get; set; } = string.Empty; + public bool UseNuspecFile { get; set; } + public bool OutputFileNamesWithoutVersion { get; set; } + public bool IncludeSymbols { get; set; } + public NuGet.Commands.SymbolPackageFormat SymbolPackageFormat { get; set; } = Commands.SymbolPackageFormat.Snupkg; #region IXunitSerializable [System.Obsolete] public PackageFileNameTestCase() : this("", [], "", "", "", "", "", false) { } - private const string TestObjectKey = nameof(PackageFileNameTests); - private readonly Newtonsoft.Json.JsonSerializerSettings _settings = new Newtonsoft.Json.JsonSerializerSettings { MaxDepth = null }; - void IXunitSerializable.Serialize(IXunitSerializationInfo info) { - info.AddValue(TestObjectKey, Newtonsoft.Json.JsonConvert.SerializeObject(this)); - + info.AddValue(nameof(TestNumber), TestNumber); + info.AddValue(nameof(OutputNupkgNames), OutputNupkgNames); + info.AddValue(nameof(IdProjProp), IdProjProp); + info.AddValue(nameof(IdNuspecMeta), IdNuspecMeta); + info.AddValue(nameof(VersionProjProp), VersionProjProp); + info.AddValue(nameof(VersionNuspecProperties), VersionNuspecProperties); + info.AddValue(nameof(VersionNuspecMeta), VersionNuspecMeta); + info.AddValue(nameof(UseNuspecFile), UseNuspecFile); + info.AddValue(nameof(OutputFileNamesWithoutVersion), OutputFileNamesWithoutVersion); + info.AddValue(nameof(IncludeSymbols), IncludeSymbols); + info.AddValue(nameof(SymbolPackageFormat), SymbolPackageFormat); } void IXunitSerializable.Deserialize(IXunitSerializationInfo info) { - var json = (string)info.GetValue(TestObjectKey, typeof(string)); - var x = Newtonsoft.Json.JsonConvert.DeserializeObject(json, _settings); - if (x == null) - { - return; - } - - var t = typeof(PackageFileNameTestCase); - var c = t.GetConstructors().Where(_ => _.GetParameters().Length != 0).ToArray()[0]; - - foreach (System.Reflection.ParameterInfo p in c.GetParameters()) - { - var pi = t.GetProperty(p.Name!); - pi!.SetValue(this, pi.GetValue(x)); - } + TestNumber = (string)info.GetValue(nameof(TestNumber), typeof(string)); + OutputNupkgNames = (string[])info.GetValue(nameof(OutputNupkgNames), typeof(string[])); + IdProjProp = (string)info.GetValue(nameof(IdProjProp), typeof(string)); + IdNuspecMeta = (string)info.GetValue(nameof(IdNuspecMeta), typeof(string)); + VersionProjProp = (string)info.GetValue(nameof(VersionProjProp), typeof(string)); + VersionNuspecProperties = (string)info.GetValue(nameof(VersionNuspecProperties), typeof(string)); + VersionNuspecMeta = (string)info.GetValue(nameof(VersionNuspecMeta), typeof(string)); + UseNuspecFile = (bool)info.GetValue(nameof(UseNuspecFile), typeof(bool)); + OutputFileNamesWithoutVersion = (bool)info.GetValue(nameof(OutputFileNamesWithoutVersion), typeof(bool)); + IncludeSymbols = (bool)info.GetValue(nameof(IncludeSymbols), typeof(bool)); + SymbolPackageFormat = (NuGet.Commands.SymbolPackageFormat)info.GetValue(nameof(SymbolPackageFormat), typeof(NuGet.Commands.SymbolPackageFormat)); } #endregion From 9cb19ec9bb41e077454c87fcbef58e4b4929c153 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Sun, 8 Mar 2026 20:29:14 +0900 Subject: [PATCH 11/15] Re-merge msbuild targets --- .../NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs index 5a0abe55b49..307b3820691 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs @@ -142,19 +142,10 @@ public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNa { // As noted in #6703, since the .NetStandard2.0 library has been removed, // running tests on .net Framework requires invoking msbuild.exe. - - var runresultDotnetRestore = CommandRunner.Run( - _testFixture._pathMSBuildExe, - testDirectory, - $"/t:Restore {FILENAME_PROJECT_FILE}", - environmentVariables: _testFixture._dotnetEnvironments, - testOutputHelper: _testOutputHelper); - Assert.True(0 == runresultDotnetRestore.ExitCode, runresultDotnetRestore.Output + " " + runresultDotnetRestore.Errors); - runresultDotnetPack = CommandRunner.Run( _testFixture._pathMSBuildExe, testDirectory, - $"/t:Build;Pack /p:Configuration={CONFIGURATION} /p:UsingMicrosoftNetSdk=true {FILENAME_PROJECT_FILE} ", + $"/t:Restore;Build;Pack /p:Configuration={CONFIGURATION} /p:UsingMicrosoftNetSdk=true {FILENAME_PROJECT_FILE} ", testOutputHelper: _testOutputHelper); } else From 10761cc6f39278a65c4461af4a3336f66d0aa805 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Sun, 29 Mar 2026 18:18:49 +0900 Subject: [PATCH 12/15] Split the test functions into integration tests and unit tests. --- .../GetPackOutputItemsLogic.cs | 115 ++++++ .../GetPackOutputItemsTask.cs | 78 +--- .../NuGet.Build.Tasks.Pack/IOutputFilePath.cs | 20 + .../IOutputFilePathProvider.cs | 36 ++ .../NuGet.Build.Tasks.Pack/PackTask.cs | 2 +- .../Dotnet.Integration.Test.csproj | 14 + .../Msbuild.Integration.Test.csproj | 21 +- .../PackageFileNameTests.cs | 259 +++++++++++++ .../BuildFixture.cs | 150 ------- .../GetPackOutputItemsTaskTests.cs | 63 +++ .../NuGet.Build.Tasks.Pack.Test.csproj | 6 +- .../PackTaskTests.cs | 155 ++++++++ .../PackageFileNameTestCase.cs | 262 +++++++++++++ .../PackageNameTests.cs | 365 ------------------ 14 files changed, 953 insertions(+), 593 deletions(-) create mode 100644 src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsLogic.cs create mode 100644 src/NuGet.Core/NuGet.Build.Tasks.Pack/IOutputFilePath.cs create mode 100644 src/NuGet.Core/NuGet.Build.Tasks.Pack/IOutputFilePathProvider.cs create mode 100644 test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs delete mode 100644 test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs create mode 100644 test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/GetPackOutputItemsTaskTests.cs create mode 100644 test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageFileNameTestCase.cs delete mode 100644 test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsLogic.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsLogic.cs new file mode 100644 index 00000000000..6bec686a34f --- /dev/null +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsLogic.cs @@ -0,0 +1,115 @@ +// 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. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using NuGet.Commands; +using NuGet.Common; +using NuGet.Versioning; + +namespace NuGet.Build.Tasks.Pack +{ + public static class GetPackOutputItemsLogic + { + public static void GetOutputFilePaths(IOutputFilePathProvider source, IOutputFilePath output) + { + var packageId = source.PackageId; + var packageVersion = source.PackageVersion; + + if (!string.IsNullOrWhiteSpace(source.NuspecFile)) + { + bool hasVersionInNuspecProperties = false; + bool hasIdInNuspecProperties = false; + if (source.NuspecProperties != null && source.NuspecProperties.Length > 0) + { + PackArgs packArgs = new PackArgs() { Version = packageVersion }; + PackTaskLogic.SetPackArgsPropertiesFromNuspecProperties(packArgs, MSBuildStringUtility.TrimAndExcludeNullOrEmpty(source.NuspecProperties)); + // If the logic depends only on checking for a non-null value, it may incorrectly detect cases where the parsing logic changes the version based on a key other than the "version" key. + if (packArgs.Properties.ContainsKey("version")) + { + packageVersion = packArgs.Version; + hasVersionInNuspecProperties = true; + } + if (packArgs.Properties.TryGetValue("id", out var idTemp)) + { + packageId = idTemp; + hasIdInNuspecProperties = true; + } + } + + var nuspecReader = new NuGet.Packaging.NuspecReader(source.NuspecFile); + if (!hasIdInNuspecProperties) + { + packageId = nuspecReader.GetId(); + } + if (!hasVersionInNuspecProperties) + { + packageVersion = nuspecReader.GetVersion().ToNormalizedString(); + } + } + + if (!NuGetVersion.TryParse(packageVersion, out var versionTemp)) + { + throw new ArgumentException(string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageVersion, + packageVersion)); + } + NuGetVersion version = versionTemp!; + + var symbolPackageFormat = PackArgs.GetSymbolPackageFormat(MSBuildStringUtility.TrimAndGetNullForEmpty(source.SymbolPackageFormat)); + var nupkgFileName = PackCommandRunner.GetOutputFileName(packageId, version!, isNupkg: true, symbols: false, symbolPackageFormat: symbolPackageFormat, excludeVersion: source.OutputFileNamesWithoutVersion); + var nuspecFileName = PackCommandRunner.GetOutputFileName(packageId, version!, isNupkg: false, symbols: false, symbolPackageFormat: symbolPackageFormat, excludeVersion: source.OutputFileNamesWithoutVersion); + + var outputs = new List(); + + output.OutputNupkgFilePath = Path.Combine(source.PackageOutputPath, nupkgFileName); + output.OutputNuspecFilePath = Path.Combine(source.NuspecOutputPath, nuspecFileName); + + outputs.Add(new TaskItem(output.OutputNupkgFilePath)); + outputs.Add(new TaskItem(output.OutputNuspecFilePath)); + + if (source.IncludeSource || source.IncludeSymbols) + { + var nupkgSymbolsFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: true, symbols: true, symbolPackageFormat: symbolPackageFormat, excludeVersion: source.OutputFileNamesWithoutVersion); + var nuspecSymbolsFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: false, symbols: true, symbolPackageFormat: symbolPackageFormat, excludeVersion: source.OutputFileNamesWithoutVersion); + + output.OutputNupkgSymbolsFilePath = Path.Combine(source.PackageOutputPath, nupkgSymbolsFileName); + output.OutputNuspecSymbolsFilePath = Path.Combine(source.NuspecOutputPath, nuspecSymbolsFileName); + + outputs.Add(new TaskItem(output.OutputNupkgSymbolsFilePath)); + outputs.Add(new TaskItem(output.OutputNuspecSymbolsFilePath)); + } + + output.OutputPackItems = outputs.ToArray(); + } + + public static IOutputFilePath GetOutputFilePaths(IOutputFilePathProvider source) + { + var output = new GetPackOutputItemsTask(); + Copy(source, output); + GetOutputFilePaths(source, output); + return output; + } + + public static void Copy(IOutputFilePathProvider source, IOutputFilePathProvider destination) + { + destination.PackageId = source.PackageId; + destination.PackageVersion = source.PackageVersion; + destination.PackageOutputPath = source.PackageOutputPath; + destination.NuspecOutputPath = source.NuspecOutputPath; + destination.NuspecFile = source.NuspecFile; + destination.NuspecProperties = source.NuspecProperties; + destination.IncludeSource = source.IncludeSource; + destination.IncludeSymbols = source.IncludeSymbols; + destination.SymbolPackageFormat = source.SymbolPackageFormat; + destination.OutputFileNamesWithoutVersion = source.OutputFileNamesWithoutVersion; + } + } +} diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs index 1ff7178945b..e46a2e0657e 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/GetPackOutputItemsTask.cs @@ -3,19 +3,11 @@ #nullable disable -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using NuGet.Commands; -using NuGet.Common; -using NuGet.Versioning; namespace NuGet.Build.Tasks.Pack { - public class GetPackOutputItemsTask : Microsoft.Build.Utilities.Task + public class GetPackOutputItemsTask : Microsoft.Build.Utilities.Task, IOutputFilePathProvider, IOutputFilePath { [Required] public string PackageId { get; set; } @@ -47,70 +39,14 @@ public class GetPackOutputItemsTask : Microsoft.Build.Utilities.Task [Output] public ITaskItem[] OutputPackItems { get; set; } + public string OutputNupkgFilePath { get; set; } + public string OutputNuspecFilePath { get; set; } + public string OutputNupkgSymbolsFilePath { get; set; } + public string OutputNuspecSymbolsFilePath { get; set; } + public override bool Execute() { - var packageId = PackageId; - var packageVersion = PackageVersion; - - if (!string.IsNullOrWhiteSpace(NuspecFile)) - { - bool hasVersionInNuspecProperties = false; - bool hasIdInNuspecProperties = false; - if (NuspecProperties != null && NuspecProperties.Length > 0) - { - PackArgs packArgs = new PackArgs() { Version = packageVersion }; - PackTaskLogic.SetPackArgsPropertiesFromNuspecProperties(packArgs, MSBuildStringUtility.TrimAndExcludeNullOrEmpty(NuspecProperties)); - // If the logic depends only on checking for a non-null value, it may incorrectly detect cases where the parsing logic changes the version based on a key other than the "version" key. - if (packArgs.Properties.ContainsKey("version")) - { - packageVersion = packArgs.Version; - hasVersionInNuspecProperties = true; - } - if (packArgs.Properties.TryGetValue("id", out var idTemp)) - { - packageId = idTemp; - hasIdInNuspecProperties = true; - } - } - - var nuspecReader = new NuGet.Packaging.NuspecReader(NuspecFile); - if (!hasIdInNuspecProperties) - { - packageId = nuspecReader.GetId(); - } - if (!hasVersionInNuspecProperties) - { - packageVersion = nuspecReader.GetVersion().ToNormalizedString(); - } - } - - if (!NuGetVersion.TryParse(packageVersion, out var versionTemp)) - { - throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, - Strings.InvalidPackageVersion, - packageVersion)); - } - NuGetVersion version = versionTemp!; - - var symbolPackageFormat = PackArgs.GetSymbolPackageFormat(MSBuildStringUtility.TrimAndGetNullForEmpty(SymbolPackageFormat)); - var nupkgFileName = PackCommandRunner.GetOutputFileName(packageId, version!, isNupkg: true, symbols: false, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); - var nuspecFileName = PackCommandRunner.GetOutputFileName(packageId, version!, isNupkg: false, symbols: false, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); - - var outputs = new List(); - outputs.Add(new TaskItem(Path.Combine(PackageOutputPath, nupkgFileName))); - outputs.Add(new TaskItem(Path.Combine(NuspecOutputPath, nuspecFileName))); - - if (IncludeSource || IncludeSymbols) - { - var nupkgSymbolsFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: true, symbols: true, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); - var nuspecSymbolsFileName = PackCommandRunner.GetOutputFileName(packageId, version, isNupkg: false, symbols: true, symbolPackageFormat: symbolPackageFormat, excludeVersion: OutputFileNamesWithoutVersion); - - outputs.Add(new TaskItem(Path.Combine(PackageOutputPath, nupkgSymbolsFileName))); - outputs.Add(new TaskItem(Path.Combine(NuspecOutputPath, nuspecSymbolsFileName))); - } - - OutputPackItems = outputs.ToArray(); + GetPackOutputItemsLogic.GetOutputFilePaths(this, this); return true; } } diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/IOutputFilePath.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/IOutputFilePath.cs new file mode 100644 index 00000000000..852b331ca3d --- /dev/null +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/IOutputFilePath.cs @@ -0,0 +1,20 @@ +// 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. + +#nullable disable + +using Microsoft.Build.Framework; + +namespace NuGet.Build.Tasks.Pack +{ + public interface IOutputFilePath + { + [Output] + public ITaskItem[] OutputPackItems { get; set; } + + public string OutputNupkgFilePath { get; set; } + public string OutputNuspecFilePath { get; set; } + public string OutputNupkgSymbolsFilePath { get; set; } + public string OutputNuspecSymbolsFilePath { get; set; } + } +} diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/IOutputFilePathProvider.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/IOutputFilePathProvider.cs new file mode 100644 index 00000000000..f277c62534a --- /dev/null +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/IOutputFilePathProvider.cs @@ -0,0 +1,36 @@ +// 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. + +#nullable disable + +using Microsoft.Build.Framework; + +namespace NuGet.Build.Tasks.Pack +{ + public interface IOutputFilePathProvider + { + [Required] + string PackageId { get; set; } + + [Required] + string PackageVersion { get; set; } + + [Required] + string PackageOutputPath { get; set; } + + [Required] + string NuspecOutputPath { get; set; } + + string NuspecFile { get; set; } + + string[] NuspecProperties { get; set; } + + bool IncludeSource { get; set; } + + bool IncludeSymbols { get; set; } + + string SymbolPackageFormat { get; set; } + + bool OutputFileNamesWithoutVersion { get; set; } + } +} diff --git a/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTask.cs b/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTask.cs index fc28b03d1ff..43dc1257fb8 100644 --- a/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTask.cs +++ b/src/NuGet.Core/NuGet.Build.Tasks.Pack/PackTask.cs @@ -16,7 +16,7 @@ namespace NuGet.Build.Tasks.Pack { - public class PackTask : Microsoft.Build.Utilities.Task, IPackTaskRequest + public class PackTask : Microsoft.Build.Utilities.Task, IPackTaskRequest, IOutputFilePathProvider { private readonly IEnvironmentVariableReader _environmentVariableReader; diff --git a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj index b1ef98a93ed..c1bbf30255c 100644 --- a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj +++ b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj @@ -4,11 +4,25 @@ Integration tests for NuGet-powered dotnet CLI commands such as pack/restore/list package and dotnet nuget. + + $(DefineConstants);TEST_FOR_DOTNET + + + + + + + + + + + + diff --git a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj index 75c9c3b47e5..19f882dea0d 100644 --- a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj +++ b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj @@ -1,15 +1,23 @@ - + $(NETFXTargetFramework) Integration tests for NuGet powered msbuild functionalities (restore/pack). None + + + $(DefineConstants);TEST_FOR_MSBUILD + + + + + @@ -19,10 +27,13 @@ - - + + + + + + + diff --git a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs new file mode 100644 index 00000000000..b756c890113 --- /dev/null +++ b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs @@ -0,0 +1,259 @@ +// 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. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.Internal.NuGet.Testing.SignedPackages.ChildProcess; +using NuGet.Frameworks; +using NuGet.Test.Utility; +using Xunit; +using Xunit.Abstractions; + +#if TEST_FOR_MSBUILD +namespace Msbuild.Integration.Test +#elif TEST_FOR_DOTNET +namespace Dotnet.Integration.Test +#endif +{ + /// + /// The _GetOutputItemsFromPack target inside the NuGet.Build.Tasks.Pack.targets file is the subject of the test, so the project that includes NuGet.Build.Tasks.Pack.targets must be registered as a build dependency. + [Collection(PackageFileNameBuildTestFixtureCollection.Name)] + public class PackageFileNameTests + { + private readonly PackageFileNameBuildTestFixture _testFixture; + private readonly ITestOutputHelper _testOutputHelper; + + public PackageFileNameTests(PackageFileNameBuildTestFixture testFixture, ITestOutputHelper testOutputHelper) + { + _testFixture = testFixture; + _testOutputHelper = testOutputHelper; + } + + public static System.Collections.Generic.IEnumerable PackageFileNameTestCases => PackageFileNameTestCase.TestCases; + + // This unit test verifies that the output file names from GetPackOutputItemsTask matches the output file names from PackTask. + // Since PackTask does not expose the output file name as a property, + // the current implementation performs an actual build and inspects the generated file. + [PlatformTheory(Platform.Windows)] + [MemberData(nameof(PackageFileNameTestCases))] + public void PackTask_PackageFileName(PackageFileNameTestCase testCase) + { + string[] outputExtensions = PackageFileNameTestsCommon.GetOutputExtensions(testCase.IncludeSymbols, testCase.SymbolPackageFormat); + + using (var testDirectory = TestDirectory.Create()) + { + PackageFileNameTestsCommon.CreateTestProjectFileAndNuspecFile(testCase, testDirectory, _testFixture._pathDllFile, _testFixture._pathTargetsFile, _testFixture._testFrameworkMoniker); + + CommandRunnerResult runresult; + if (_testFixture._isDotNetFramework) + { // This test is running on .Net Framework + + // As noted in #6703, since the .NetStandard2.0 library has been removed, + // running tests on .net Framework requires invoking msbuild.exe. + + // Restore (needs create project.assets.json) + _testFixture.Restore(testDirectory, PackageFileNameTestsCommon.FILENAME_PROJECT_FILE, _testOutputHelper); + + // msbuild.exe + runresult = CommandRunner.Run( + _testFixture._pathMSBuildExe, + testDirectory, + $"/t:Build;Pack /p:Configuration={PackageFileNameBuildTestFixture.CONFIGURATION} /p:UsingMicrosoftNetSdk=true {PackageFileNameTestsCommon.FILENAME_PROJECT_FILE}", + environmentVariables: _testFixture._dotnetEnvironments, + testOutputHelper: _testOutputHelper); + } + else + { + // dotnet.exe + runresult = CommandRunner.Run( + _testFixture._pathDotnetExe, + testDirectory, + $"build -p:Configuration={PackageFileNameBuildTestFixture.CONFIGURATION} {PackageFileNameTestsCommon.FILENAME_PROJECT_FILE}", + environmentVariables: _testFixture._dotnetEnvironments, + testOutputHelper: _testOutputHelper); + } + Assert.True(0 == runresult.ExitCode, runresult.Output + " " + runresult.Errors); + + var objFolder = System.IO.Path.Combine(testDirectory, "obj"); + var log = System.IO.File.ReadAllLines(System.IO.Path.Combine(objFolder, PackageFileNameTestsCommon.FILENAME_GETOUTPUTITEMSTASK_OUTPUTPACKITEMS_TEST)); + var lines = log.Where(line => !line.StartsWith(objFolder)).ToArray(); + + var nupkgGeneratedFiles = outputExtensions + .SelectMany(outputExtension => Directory.GetFiles(testDirectory, $"*{outputExtension}", SearchOption.AllDirectories)) + .Where(line => !line.StartsWith(objFolder)) + .Distinct().ToArray(); + Assert.Equal(outputExtensions.Length, nupkgGeneratedFiles.Length); + + foreach (string outputNupkgName in testCase.OutputNupkgNames) + { + var matchCountInFileSystem = PackageFileNameTestsCommon.GetNameMatchFilePathCount(outputNupkgName, nupkgGeneratedFiles); + Assert.True(matchCountInFileSystem == 1, $"{outputNupkgName} is not found in filesystem. [{string.Join(" , ", nupkgGeneratedFiles.Select(_ => System.IO.Path.GetFileName(_)))}]"); + + var matchCountInOutputPackItems = PackageFileNameTestsCommon.GetNameMatchFilePathCount(outputNupkgName, lines); + Assert.True(matchCountInOutputPackItems == 1, $"{outputNupkgName} is not found in OutputPackItems. [{string.Join(" , ", lines.Select(_ => System.IO.Path.GetFileName(_)))}]"); + } + } + } + } + + [CollectionDefinition(Name)] + public class PackageFileNameBuildTestFixtureCollection + : ICollectionFixture + { + internal const string Name = nameof(PackageFileNameBuildTestFixtureCollection) + "Collection"; + } + + public class PackageFileNameBuildTestFixture : IDisposable + { +#if DEBUG + public const string CONFIGURATION = "Debug"; +#else + public const string CONFIGURATION = "Release"; +#endif + + private const string FILENAME_DLL = "NuGet.Build.Tasks.Pack.dll"; + private const string FILENAME_TARGETS = "NuGet.Build.Tasks.Pack.targets"; + +#if IS_DESKTOP + private const string SdkVersion = "10"; + private const string SdkTfm = "net10.0"; +#endif + + internal readonly bool _isDotNetFramework = false; + internal readonly string _testFrameworkMoniker = "netstandard2.0"; + + internal readonly string _pathDotnetExe; + internal readonly string _pathMSBuildExe; + internal readonly string _pathDllFile; + internal readonly string _pathTargetsFile; + + internal readonly IReadOnlyDictionary _dotnetEnvironments = new Dictionary(); + + public PackageFileNameBuildTestFixture() + { + _pathDotnetExe = NuGet.Test.Utility.TestFileSystemUtility.GetDotnetCli(); + +#if IS_DESKTOP + var _cliDirectory = TestDotnetCLiUtility.CopyAndPatchLatestDotnetCli(SdkVersion, SdkTfm); +#else + string testAssemblyPath = Path.GetFullPath(System.Reflection.Assembly.GetExecutingAssembly().Location); + var _cliDirectory = TestDotnetCLiUtility.CopyAndPatchLatestDotnetCli(testAssemblyPath); +#endif + var dotnetExecutableName = NuGet.Common.RuntimeEnvironmentHelper.IsWindows ? "dotnet.exe" : "dotnet"; + _pathDotnetExe = Path.Combine(_cliDirectory, dotnetExecutableName); + + var sdkPath = Directory.EnumerateDirectories(Path.Combine(_cliDirectory, "sdk")) + .Single(d => !string.Equals(Path.GetFileName(d), "NuGetFallbackFolder", StringComparison.OrdinalIgnoreCase)); + + _pathMSBuildExe = GetMsBuildExePath(); + _testFrameworkMoniker = GetFrameworkMoniker(typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask), out var isDotNetFramework); + _isDotNetFramework = isDotNetFramework; + + var artifactsDirectory = NuGet.Test.Utility.TestFileSystemUtility.GetArtifactsDirectoryInRepo(); + var dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); + _pathDllFile = Path.Combine(dllDirectory, FILENAME_DLL); + + // https://github.com/NuGet/NuGet.Client/pull/6712 + // NuGet.Build.Tasks.Pack.targets has been moved to in NuGet.Build.Tasks project. + // Therefore, NuGet.Build.Tasks project must be built before running this test. + var tfmTargets = GetFrameworkMoniker(typeof(PackageFileNameTests), out var _); + _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, tfmTargets, FILENAME_TARGETS); + if (!File.Exists(_pathTargetsFile)) + { + _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, _testFrameworkMoniker, FILENAME_TARGETS); + if (!File.Exists(_pathTargetsFile)) + { + _pathTargetsFile = Path.Combine(dllDirectory, FILENAME_TARGETS); + } + } + + _dotnetEnvironments = new Dictionary() + { + ["MSBuildSDKsPath"] = Path.Combine(sdkPath, "Sdks"), + ["DOTNET_MULTILEVEL_LOOKUP"] = "0", + ["DOTNET_ROOT"] = _cliDirectory, + ["MSBuildExtensionsPath"] = new DirectoryInfo(sdkPath).FullName, + ["PATH"] = $"{_cliDirectory}{Path.PathSeparator}{Environment.GetEnvironmentVariable("PATH")}", + + //["DEBUG_RESTORE_TASK"] = $"{true}", + //["DEBUG_PACK_TASK"] = $"{true}" + }; + + Assert.True(System.IO.File.Exists(_pathDllFile), $"{FILENAME_DLL} missing"); + Assert.True(System.IO.File.Exists(_pathTargetsFile), $"{FILENAME_TARGETS} missing"); + } + + private static string GetFrameworkMoniker(Type typeInAssembly, out bool isDotNetFramework) + { + var assembly = typeInAssembly.Assembly; + var targetFrameworkAttribute + = assembly.GetCustomAttributes(typeof(System.Runtime.Versioning.TargetFrameworkAttribute), false) + .OfType().FirstOrDefault(); + + Assert.True(targetFrameworkAttribute != null, "Can't get targetFramework version"); + + isDotNetFramework = targetFrameworkAttribute.FrameworkName.Contains(".NETFramework"); + return NuGetFramework.Parse(targetFrameworkAttribute.FrameworkName).GetShortFolderName(); + } + + private static string GetMsBuildExePath() + { + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + { + var msbuildexe = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", "msbuild.exe"); + var vswhereexe = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft Visual Studio", "Installer", "vswhere.exe"); + Assert.True(File.Exists(vswhereexe), "vswhere not found"); + + var runresult = CommandRunner.Run( + vswhereexe, + Environment.CurrentDirectory, + @" -latest -find MSBuild\**\Bin\MSBuild.exe"); + if (runresult.Success) + { + msbuildexe = new StringReader(runresult.Output).ReadLine() ?? ""; + } + + Assert.True(File.Exists(msbuildexe), "msbuild not found"); + return msbuildexe; + } + else + { + return ""; + } + } + + //Create project.assets.json + public void Restore(string testDirectory, string pathProjectFile, ITestOutputHelper _testOutputHelper) + { + CommandRunnerResult runresult; + if (_isDotNetFramework) + { + runresult = CommandRunner.Run( + _pathMSBuildExe, + testDirectory, + $"/t:Restore /p:UsingMicrosoftNetSdk=true \"{pathProjectFile}\"", + environmentVariables: _dotnetEnvironments, + testOutputHelper: _testOutputHelper); + } + else + { + runresult = CommandRunner.Run( + _pathDotnetExe, + testDirectory, + $"restore \"{pathProjectFile}\"", + environmentVariables: _dotnetEnvironments, + testOutputHelper: _testOutputHelper); + } + Assert.True(runresult.ExitCode == 0, runresult.Output + " " + runresult.Errors); + } + public void Dispose() + { + } + + } + +} diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs deleted file mode 100644 index 4d0a2259385..00000000000 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/BuildFixture.cs +++ /dev/null @@ -1,150 +0,0 @@ -// 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. -#nullable enable - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.Internal.NuGet.Testing.SignedPackages.ChildProcess; -using NuGet.Frameworks; -using NuGet.Test.Utility; -using Xunit; - -namespace NuGet.Build.Tasks.Pack.Test -{ - [CollectionDefinition(Name)] - public class FixtureCollection - : ICollectionFixture - { - internal const string Name = "Build Tests"; - } - - public class BuildFixture - : IDisposable - { -#if DEBUG - const string CONFIGURATION = "Debug"; -#else - const string CONFIGURATION = "Release"; -#endif - - const string FILENAME_DLL = "NuGet.Build.Tasks.Pack.dll"; - const string FILENAME_TARGETS = "NuGet.Build.Tasks.Pack.targets"; - - internal readonly bool _isDotNetFramework = false; - internal readonly string _testFrameworkMoniker = "netstandard2.0"; - -#if IS_DESKTOP - private const string SdkVersion = "10"; - private const string SdkTfm = "net10.0"; -#endif - internal readonly string _pathDotnetExe; - internal readonly string _pathMSBuildExe; - internal readonly string _pathDllFile; - internal readonly string _pathTargetsFile; - - internal readonly IReadOnlyDictionary _dotnetEnvironments; - - public BuildFixture() - { - _pathDotnetExe = NuGet.Test.Utility.TestFileSystemUtility.GetDotnetCli(); - -#if IS_DESKTOP - var _cliDirectory = TestDotnetCLiUtility.CopyAndPatchLatestDotnetCli(SdkVersion, SdkTfm); -#else - string testAssemblyPath = Path.GetFullPath(System.Reflection.Assembly.GetExecutingAssembly().Location); - var _cliDirectory = TestDotnetCLiUtility.CopyAndPatchLatestDotnetCli(testAssemblyPath); -#endif - var dotnetExecutableName = NuGet.Common.RuntimeEnvironmentHelper.IsWindows ? "dotnet.exe" : "dotnet"; - _pathDotnetExe = Path.Combine(_cliDirectory, dotnetExecutableName); - - var sdkPath = Directory.EnumerateDirectories(Path.Combine(_cliDirectory, "sdk")) - .Single(d => !string.Equals(Path.GetFileName(d), "NuGetFallbackFolder", StringComparison.OrdinalIgnoreCase)); - - _pathMSBuildExe = GetMsBuildExePath(); - _testFrameworkMoniker = GetFrameworkMoniker(typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask), out var isDotNetFramework); - _isDotNetFramework = isDotNetFramework; - - var artifactsDirectory = NuGet.Test.Utility.TestFileSystemUtility.GetArtifactsDirectoryInRepo(); - var dllLocation = typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask).Assembly.Location; - var dllDirectory = Path.Combine(dllLocation, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); - if (!Directory.Exists(dllDirectory)) - { - dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); - } - - _pathDllFile = Path.Combine(dllDirectory, FILENAME_DLL); - - // https://github.com/NuGet/NuGet.Client/pull/6712 - // NuGet.Build.Tasks.Pack.targets has been moved to in NuGet.Build.Tasks project. - // Therefore, NuGet.Build.Tasks project must be built before running this test. - var tfmTargets = GetFrameworkMoniker(typeof(PackageFileNameTests), out var _); - _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, tfmTargets, FILENAME_TARGETS); - if (!File.Exists(_pathTargetsFile)) - { - _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, _testFrameworkMoniker, FILENAME_TARGETS); - if (!File.Exists(_pathTargetsFile)) - { - _pathTargetsFile = Path.Combine(dllDirectory, FILENAME_TARGETS); - } - } - - _dotnetEnvironments = new Dictionary() - { - ["MSBuildSDKsPath"] = Path.Combine(sdkPath, "Sdks"), - ["DOTNET_MULTILEVEL_LOOKUP"] = "0", - ["DOTNET_ROOT"] = _cliDirectory, - ["MSBuildExtensionsPath"] = new DirectoryInfo(sdkPath).FullName, - ["PATH"] = $"{_cliDirectory}{Path.PathSeparator}{Environment.GetEnvironmentVariable("PATH")}" - }; - - Assert.True(System.IO.File.Exists(_pathDllFile), $"{FILENAME_DLL} missing"); - Assert.True(System.IO.File.Exists(_pathTargetsFile), $"{FILENAME_TARGETS} missing"); - } - - private static string GetFrameworkMoniker(Type typeInAssembly, out bool isDotNetFramework) - { - var assembly = typeInAssembly.Assembly; - var targetFrameworkAttribute - = assembly.GetCustomAttributes(typeof(System.Runtime.Versioning.TargetFrameworkAttribute), false) - .OfType().FirstOrDefault(); - - Assert.True(targetFrameworkAttribute != null, "Can't get targetFramework version"); - - isDotNetFramework = targetFrameworkAttribute.FrameworkName.Contains(".NETFramework"); - return NuGetFramework.Parse(targetFrameworkAttribute.FrameworkName).GetShortFolderName(); - } - - private static string GetMsBuildExePath() - { - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - { - var msbuildexe = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", "msbuild.exe"); - var vswhereexe = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft Visual Studio", "Installer", "vswhere.exe"); - Assert.True(File.Exists(vswhereexe), "vswhere not found"); - - var runresult = CommandRunner.Run( - vswhereexe, - Environment.CurrentDirectory, - @" -latest -find MSBuild\**\Bin\MSBuild.exe"); - if (runresult.Success) - { - msbuildexe = new StringReader(runresult.Output).ReadLine() ?? ""; - } - - Assert.True(File.Exists(msbuildexe), "msbuild not found"); - return msbuildexe; - } - else - { - return ""; - } - } - - public void Dispose() - { - } - - } -} diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/GetPackOutputItemsTaskTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/GetPackOutputItemsTaskTests.cs new file mode 100644 index 00000000000..e501e02a004 --- /dev/null +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/GetPackOutputItemsTaskTests.cs @@ -0,0 +1,63 @@ +// 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. + +#nullable enable + +using System.Collections.Generic; +using System.Linq; +using NuGet.Test.Utility; +using Xunit; +using Xunit.Abstractions; + +namespace NuGet.Build.Tasks.Pack.Test +{ + public class GetPackOutputItemsTaskTests + { + private readonly ITestOutputHelper _testOutputHelper; + + public static IEnumerable PackageFileNameTestCases => PackageFileNameTestCase.TestCases; + + public GetPackOutputItemsTaskTests(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + } + + // This unit test verifies that GetPackOutputItemsTask outputs the expected file name. + [Theory] + [MemberData(nameof(PackageFileNameTestCases))] + public void GetPackOutputItemsTaskTests_Execute_CheckPackageFileName(PackageFileNameTestCase testCase) + { + var outputItemTask = new NuGet.Build.Tasks.Pack.GetPackOutputItemsTask(); + outputItemTask.PackageId = testCase.IdProjProp; + outputItemTask.PackageVersion = testCase.VersionProjProp; + outputItemTask.IncludeSymbols = testCase.IncludeSymbols; + outputItemTask.SymbolPackageFormat = PackageFileNameTestsCommon.GetSymbolPackageFormatText(testCase.SymbolPackageFormat); + outputItemTask.OutputFileNamesWithoutVersion = testCase.OutputFileNamesWithoutVersion; + if (!string.IsNullOrWhiteSpace(testCase.VersionNuspecProperties)) + { + outputItemTask.NuspecProperties = new string[] { $"version={testCase.VersionNuspecProperties}" }; + } + + using (var testDirectory = TestDirectory.Create()) + { + outputItemTask.PackageOutputPath = testDirectory.Path; + outputItemTask.NuspecOutputPath = testDirectory.Path; + if (testCase.UseNuspecFile) + { + outputItemTask.NuspecFile = System.IO.Path.Combine(testDirectory.Path, PackageFileNameTestsCommon.FILENAME_NUSPEC_FILE); + } + + PackageFileNameTestsCommon.CreateTestProjectFileAndNuspecFile(testCase, testDirectory); + + Assert.True(outputItemTask.Execute()); + + foreach (string outputNupkgName in testCase.OutputNupkgNames) + { + string[] itemSpecs = outputItemTask.OutputPackItems.Select(item => item.ItemSpec).ToArray(); + var matchCount = PackageFileNameTestsCommon.GetNameMatchFilePathCount(outputNupkgName, itemSpecs); + Assert.True(matchCount == 1, $"{outputNupkgName} is not found in output. [{string.Join(" , ", itemSpecs.Select(_ => System.IO.Path.GetFileName(_)))}]"); + } + } + } + } +} diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj index 83c7e3d7f69..19f4419a677 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/NuGet.Build.Tasks.Pack.Test.csproj @@ -1,9 +1,13 @@ - + $(TargetFrameworksUnitTest) Unit tests for NuGet.Build.Tasks.Pack. + + $(DefineConstants);TEST_FOR_UNIT + + diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackTaskTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackTaskTests.cs index dc9d3392522..b8bb42464f2 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackTaskTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackTaskTests.cs @@ -17,11 +17,19 @@ using NuGet.Packaging; using NuGet.Test.Utility; using Xunit; +using Xunit.Abstractions; namespace NuGet.Build.Tasks.Pack.Test { public class PackTaskTests { + private readonly ITestOutputHelper _testOutputHelper; + + public PackTaskTests(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + } + [Fact] public void PackTask_DelegatesToPackLogic() { @@ -435,5 +443,152 @@ protected override IList CreateProperties(Type type, MemberSeriali .ToList(); } } + + + public static IEnumerable PackageFileNameTestCases => PackageFileNameTestCase.TestCases; + + // This unit test verifies that GetPackOutputItemsTask outputs the expected file name. + [Theory] + [MemberData(nameof(PackageFileNameTestCases))] + public void PackTask_Execute_CheckPackageFileName(PackageFileNameTestCase testCase) + { + using (var testDirectory = TestDirectory.Create()) + { + string outputDir = System.IO.Path.Combine(testDirectory, "output"); + System.IO.Directory.CreateDirectory(outputDir); + System.IO.Directory.SetCurrentDirectory(testDirectory); + + string objDir = System.IO.Path.Combine(testDirectory, "obj"); + System.IO.Directory.CreateDirectory(objDir); + + if (testCase.IncludeSymbols) + { + //needs .pdb file (see PackCommandRunner.BuildSymbolsPackage) + + string binDir = System.IO.Path.Combine(testDirectory, "bin"); + System.IO.Directory.CreateDirectory(binDir); + System.IO.File.WriteAllBytes(System.IO.Path.Combine(binDir, "dummy.pdb"), new byte[0]); + } + + // Create .csproj and .nuspec + PackageFileNameTestsCommon.CreateTestProjectFileAndNuspecFile(testCase, testDirectory); + + // Create project.assets.json + var path = string.Join(".", typeof(PackTaskLogicTests).Namespace, "compiler.resources", "json.assets.project"); + using (var mstream = GetType().Assembly.GetManifestResourceStream(path)) + { + Assert.NotNull(mstream); + + using (var reader = new StreamReader(mstream)) + { + var contents = reader.ReadToEnd(); + File.WriteAllText(Path.Combine(objDir, "project.assets.json"), contents); + } + } + + // dummy BuildEngine + System.Text.StringBuilder logError = new System.Text.StringBuilder(); + System.Text.StringBuilder logWarning = new System.Text.StringBuilder(); + var mockEngine = new Moq.Mock(); + mockEngine.Setup(x => x.LogErrorEvent(Moq.It.IsAny())) + .Callback((e) => { logError.Append(e.Message); }); + mockEngine.Setup(x => x.LogWarningEvent(Moq.It.IsAny())) + .Callback((e) => { logWarning.Append(e.Message); }); + + var packTask = new NuGet.Build.Tasks.Pack.PackTask() + { + PackItem = FileTaskItem.FromPath(System.IO.Path.Combine(testDirectory, PackageFileNameTestsCommon.FILENAME_PROJECT_FILE)), + RestoreOutputPath = System.IO.Path.Combine(testDirectory, "obj"), + + Authors = ["Nuget Team"], + Description = "description", + BuildOutputInPackage = new Microsoft.Build.Framework.ITaskItem[0], + + ContinuePackingAfterGeneratingNuspec = true, + + + NuspecBasePath = testDirectory, + + // Dummy for Logger (see Microsoft.Build.Utilities.TaskLoggingHelper.LogWarning) + BuildEngine = mockEngine.Object + }; + + var filePathsSource = (NuGet.Build.Tasks.Pack.IOutputFilePathProvider)packTask; + filePathsSource.PackageId = testCase.IdProjProp; //Required + filePathsSource.PackageVersion = testCase.VersionProjProp;//Required + filePathsSource.PackageOutputPath = outputDir;//Required + filePathsSource.NuspecOutputPath = outputDir;//Required + + filePathsSource.NuspecFile = (testCase.UseNuspecFile ? System.IO.Path.Combine(testDirectory, PackageFileNameTestsCommon.FILENAME_NUSPEC_FILE) : null); + filePathsSource.NuspecProperties = (!string.IsNullOrWhiteSpace(testCase.VersionNuspecProperties) ? (new string[] { "version=" + testCase.VersionNuspecProperties }) : null); + filePathsSource.IncludeSymbols = testCase.IncludeSymbols; + filePathsSource.SymbolPackageFormat = PackageFileNameTestsCommon.GetSymbolPackageFormatText(testCase.SymbolPackageFormat); + filePathsSource.OutputFileNamesWithoutVersion = testCase.OutputFileNamesWithoutVersion; + + // Execute() + Assert.True(packTask.Execute(), "PackTask.Execute Fail\r\n" + logError.ToString()); + + _testOutputHelper.WriteLine(logWarning.ToString()); + _testOutputHelper.WriteLine(logError.ToString()); + + // get generated files + string[] outputExtensions = PackageFileNameTestsCommon.GetOutputExtensions(testCase.IncludeSymbols, testCase.SymbolPackageFormat); + var nupkgGeneratedFiles = outputExtensions + .SelectMany(outputExtension => Directory.GetFiles(testDirectory, $"*{outputExtension}", SearchOption.AllDirectories)) + .Where(line => !line.StartsWith(objDir)) + .Distinct().ToArray(); + + // compare generated and testCase + foreach (string outputNupkgName in testCase.OutputNupkgNames) + { + var matchCountInFileSystem = PackageFileNameTestsCommon.GetNameMatchFilePathCount(outputNupkgName, nupkgGeneratedFiles); + Assert.True(matchCountInFileSystem == 1, $"{outputNupkgName} is not found in filesystem. [{string.Join(" , ", nupkgGeneratedFiles.Select(_ => System.IO.Path.GetFileName(_)))}]"); + } + + // compare generated and GetPackOutputItemsTask + var outputPaths = NuGet.Build.Tasks.Pack.GetPackOutputItemsLogic.GetOutputFilePaths(filePathsSource).OutputPackItems; + foreach (var outputPath in outputPaths) + { + if (outputPath.GetMetadata("Extension") == ".nuspec" && testCase.UseNuspecFile) + { + continue; + } + Assert.True(System.IO.File.Exists(outputPath.GetMetadata("FullPath")), $"{outputPath} is not found in filesystem"); + } + } + } + + class FileTaskItem : Microsoft.Build.Framework.ITaskItem + { + public static FileTaskItem FromPath(string path) + { + var fullpath = System.IO.Path.GetFullPath(path); + + FileTaskItem item = new FileTaskItem(fullpath); + item.SetMetadata("RootDir", System.IO.Path.GetDirectoryName(fullpath) ?? ""); + item.SetMetadata("Directory", System.IO.Path.GetDirectoryName(fullpath) ?? ""); + item.SetMetadata("FileName", System.IO.Path.GetFileName(fullpath)); + item.SetMetadata("Extension", System.IO.Path.GetExtension(fullpath)); + item.SetMetadata("FullPath", fullpath); + return item; + } + + + private Dictionary _dic = new Dictionary(); + + public FileTaskItem(string itemSpec) + { + ItemSpec = itemSpec; + } + + public string GetMetadata(string metadataName) => _dic[metadataName]; + public void SetMetadata(string metadataName, string metadataValue) => _dic[metadataName] = metadataValue; + public void RemoveMetadata(string metadataName) => _dic.Remove(metadataName); + public void CopyMetadataTo(ITaskItem destinationItem) => throw new NotSupportedException(); + public System.Collections.IDictionary CloneCustomMetadata() => throw new NotSupportedException(); + public string ItemSpec { get; set; } = ""; + public System.Collections.ICollection MetadataNames => _dic.Keys; + public int MetadataCount => _dic.Count; + } } } diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageFileNameTestCase.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageFileNameTestCase.cs new file mode 100644 index 00000000000..9d4183f5cd7 --- /dev/null +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageFileNameTestCase.cs @@ -0,0 +1,262 @@ +// 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. + +#nullable enable + +using System.IO; +using System.Linq; +using Xunit.Abstractions; + +#if TEST_FOR_UNIT +namespace NuGet.Build.Tasks.Pack.Test +#elif TEST_FOR_MSBUILD +namespace Msbuild.Integration.Test +#else +namespace Dotnet.Integration.Test +#endif +{ + // NuGet.Build.Tasks.Pack.Test + /// + /// + /// + /// + /// + /// + public class PackageFileNameTestCase : IXunitSerializable + { + public static System.Collections.Generic.IEnumerable TestCases + { + get + { + var cases = new PackageFileNameTestCase[] + { + + //// without nuspec input + new PackageFileNameTestCase("000",["proj.1.9.0.nupkg" ], "proj", "nusp", "1.9", "", "", false), + new PackageFileNameTestCase("001",["proj.2.0.0.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", false), + new PackageFileNameTestCase("002",["proj.2.0.0.1.nupkg" ], "proj", "nusp", "2.0.0.1", " ", "4.0.0.1", false), + new PackageFileNameTestCase("003",["proj.2.0.0.2.nupkg" ], "proj", "nusp", "2.0.0.2", "3.0.0.2", "4.0.0.2", false), + new PackageFileNameTestCase("004",["proj.2.0.0.3-preview.nupkg"], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false), + new PackageFileNameTestCase("005",["proj.2.0.0.4-release.nupkg"], "proj", "$meta_id$", "2.0.0.4-release", "3.0.0.2", "$meta_version$", false), + new PackageFileNameTestCase("100",["proj.nupkg" ], "proj", "nusp", "1.9", "", "", false, outputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("104",["proj.nupkg" ], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false,outputFileNamesWithoutVersion:true), + + // with nuspec input + new PackageFileNameTestCase("010",["nusp.4.0.0.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true), + new PackageFileNameTestCase("011",["nusp.4.0.0.3.nupkg" ], "proj", "nusp", "2.0.0.3", " ", "4.0.0.3", true), + new PackageFileNameTestCase("012",["nusp.3.0.0.4.nupkg" ], "proj", "nusp", "2.0.0.4", "3.0.0.4", "4.0.0.4", true), + new PackageFileNameTestCase("013",["nusp.5.0.0-preview.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "5.0.0.0-preview", true), + new PackageFileNameTestCase("014",["nusp.5.0.0.2-preview.nupkg"], "proj", "nusp", "2.0.0.0", " ", "5.0.0.2-preview", true), + new PackageFileNameTestCase("015",["nusp.6.0.0-beta.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true), + new PackageFileNameTestCase("110",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true, outputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("115",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true, outputFileNamesWithoutVersion:true), + + // has symbol + new PackageFileNameTestCase("020",["proj.2.1.0.snupkg"], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), + new PackageFileNameTestCase("021",["nusp.7.1.2.snupkg"], "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), + new PackageFileNameTestCase("120",["proj.snupkg" ], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ,outputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("121",["nusp.snupkg" ], "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ,outputFileNamesWithoutVersion:true), + + new PackageFileNameTestCase("022",["proj.2.2.0.nupkg", "proj.2.2.0.symbols.nupkg"], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), + new PackageFileNameTestCase("023",["nusp.7.2.2.nupkg", "nusp.7.2.2.symbols.nupkg"], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), + new PackageFileNameTestCase("122",["proj.nupkg", "proj.symbols.nupkg" ], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, outputFileNamesWithoutVersion:true), + new PackageFileNameTestCase("123",["nusp.nupkg", "nusp.symbols.nupkg" ], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, outputFileNamesWithoutVersion:true), + + }; + + + return (object[][])cases.Select((c, i) => new object[] { c }).ToArray(); + } + } + + public PackageFileNameTestCase + (string testNumber + , string[] outputNupkgNames + , string idProjProp + , string idNuspecMeta + , string versionProjProp + , string versionNuspecProperties + , string versionNuspecMeta + , bool useNuspecFile + , bool outputFileNamesWithoutVersion = false + , bool includeSymbols = false + , NuGet.Commands.SymbolPackageFormat symbolPackageFormat = NuGet.Commands.SymbolPackageFormat.Snupkg) + { + CaseNumber = testNumber; + OutputNupkgNames = outputNupkgNames; + IdProjProp = idProjProp; + IdNuspecMeta = idNuspecMeta; + VersionProjProp = versionProjProp; + VersionNuspecProperties = versionNuspecProperties; + VersionNuspecMeta = versionNuspecMeta; + UseNuspecFile = useNuspecFile; + OutputFileNamesWithoutVersion = outputFileNamesWithoutVersion; + IncludeSymbols = includeSymbols; + SymbolPackageFormat = symbolPackageFormat; + } + + public string CaseNumber { get; set; } = string.Empty; + public string[] OutputNupkgNames { get; set; } = System.Array.Empty(); + public string IdProjProp { get; set; } = string.Empty; + public string IdNuspecMeta { get; set; } = string.Empty; + public string VersionProjProp { get; set; } = string.Empty; + public string VersionNuspecProperties { get; set; } = string.Empty; + public string VersionNuspecMeta { get; set; } = string.Empty; + public bool UseNuspecFile { get; set; } + public bool OutputFileNamesWithoutVersion { get; set; } + public bool IncludeSymbols { get; set; } + public NuGet.Commands.SymbolPackageFormat SymbolPackageFormat { get; set; } = NuGet.Commands.SymbolPackageFormat.Snupkg; + + #region IXunitSerializable + + [System.Obsolete] + public PackageFileNameTestCase() : this("", [], "", "", "", "", "", false) { } + + void IXunitSerializable.Serialize(IXunitSerializationInfo info) + { + info.AddValue(nameof(CaseNumber), CaseNumber); + info.AddValue(nameof(OutputNupkgNames), OutputNupkgNames); + info.AddValue(nameof(IdProjProp), IdProjProp); + info.AddValue(nameof(IdNuspecMeta), IdNuspecMeta); + info.AddValue(nameof(VersionProjProp), VersionProjProp); + info.AddValue(nameof(VersionNuspecProperties), VersionNuspecProperties); + info.AddValue(nameof(VersionNuspecMeta), VersionNuspecMeta); + info.AddValue(nameof(UseNuspecFile), UseNuspecFile); + info.AddValue(nameof(OutputFileNamesWithoutVersion), OutputFileNamesWithoutVersion); + info.AddValue(nameof(IncludeSymbols), IncludeSymbols); + info.AddValue(nameof(SymbolPackageFormat), SymbolPackageFormat); + } + void IXunitSerializable.Deserialize(IXunitSerializationInfo info) + { + CaseNumber = (string)info.GetValue(nameof(CaseNumber), typeof(string)); + OutputNupkgNames = (string[])info.GetValue(nameof(OutputNupkgNames), typeof(string[])); + IdProjProp = (string)info.GetValue(nameof(IdProjProp), typeof(string)); + IdNuspecMeta = (string)info.GetValue(nameof(IdNuspecMeta), typeof(string)); + VersionProjProp = (string)info.GetValue(nameof(VersionProjProp), typeof(string)); + VersionNuspecProperties = (string)info.GetValue(nameof(VersionNuspecProperties), typeof(string)); + VersionNuspecMeta = (string)info.GetValue(nameof(VersionNuspecMeta), typeof(string)); + UseNuspecFile = (bool)info.GetValue(nameof(UseNuspecFile), typeof(bool)); + OutputFileNamesWithoutVersion = (bool)info.GetValue(nameof(OutputFileNamesWithoutVersion), typeof(bool)); + IncludeSymbols = (bool)info.GetValue(nameof(IncludeSymbols), typeof(bool)); + SymbolPackageFormat = (NuGet.Commands.SymbolPackageFormat)info.GetValue(nameof(SymbolPackageFormat), typeof(NuGet.Commands.SymbolPackageFormat)); + } + #endregion + } + + internal static class PackageFileNameTestsCommon + { + public const string FILENAME_PROJECT_FILE = "test.csproj"; + public const string FILENAME_NUSPEC_FILE = "test.nuspec"; + public const string FILENAME_GETOUTPUTITEMSTASK_OUTPUTPACKITEMS_TEST = "_OutputPackItems.txt"; + public static void CreateTestProjectFileAndNuspecFile + (PackageFileNameTestCase testCase + , string testDirectory) + { + CreateTestProjectFileAndNuspecFile(testCase, testDirectory, null, null, "netstandard2.0"); + } + + public static void CreateTestProjectFileAndNuspecFile + (PackageFileNameTestCase testCase + , string testDirectory + , string? pathDllFile + , string? pathTargetsFile + , string testFrameworkMoniker) + { + + var csprojPath = Path.Combine(testDirectory, FILENAME_PROJECT_FILE); + var nuspecPath = Path.Combine(testDirectory, FILENAME_NUSPEC_FILE); + + var csprojContent = $""" + + + + {pathDllFile} + + + + {testFrameworkMoniker} + NU5100;NU5119;CS2008 + + + + true + + true + false + True + + {testCase.IdProjProp} + {testCase.VersionProjProp} + tagA;tagB + + {FILENAME_NUSPEC_FILE} + version={testCase.VersionNuspecProperties} + + {testCase.IncludeSymbols} + {GetSymbolPackageFormatText(testCase.SymbolPackageFormat)} + + {testCase.OutputFileNamesWithoutVersion} + + + + + + + + + +"""; + + var nuspecContent = $""" + + + + {testCase.IdNuspecMeta} + {testCase.VersionNuspecMeta?.Trim()} + Unit Test + Sample Description + en-US + + +"""; + + File.WriteAllText(csprojPath, csprojContent, System.Text.Encoding.Unicode); + if (testCase.UseNuspecFile) + { + File.WriteAllText(nuspecPath, nuspecContent, new System.Text.UTF8Encoding(true)); + } + } + + public static string GetSymbolPackageFormatText(NuGet.Commands.SymbolPackageFormat symbolPackageFormat) + { + switch (symbolPackageFormat) + { + case NuGet.Commands.SymbolPackageFormat.Snupkg: return "snupkg"; + case NuGet.Commands.SymbolPackageFormat.SymbolsNupkg: return "symbols.nupkg"; + default: throw new System.ArgumentOutOfRangeException(); + } + } + + public static string[] GetOutputExtensions(bool includeSymbols, NuGet.Commands.SymbolPackageFormat symbolPackageFormat) + { + if (includeSymbols) + { + switch (symbolPackageFormat) + { + case NuGet.Commands.SymbolPackageFormat.Snupkg: return new string[] { ".snupkg" }; + case NuGet.Commands.SymbolPackageFormat.SymbolsNupkg: return new string[] { ".nupkg", ".symbols.nupkg" }; + default: throw new System.ArgumentOutOfRangeException(); + } + } + else + { + return new string[] { ".nupkg" }; + } + } + + public static int GetNameMatchFilePathCount(string fileName, System.Collections.Generic.IEnumerable fullpaths) + { + return fullpaths.Count(file => string.Equals(fileName, System.IO.Path.GetFileName(file), System.StringComparison.OrdinalIgnoreCase)); + } + } +} diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs deleted file mode 100644 index 307b3820691..00000000000 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageNameTests.cs +++ /dev/null @@ -1,365 +0,0 @@ -// 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. -#nullable enable - -using System.IO; -using System.Linq; -using Microsoft.Internal.NuGet.Testing.SignedPackages.ChildProcess; -using NuGet.Test.Utility; -using Xunit; -using Xunit.Abstractions; - -namespace NuGet.Build.Tasks.Pack.Test -{ - - /// - /// The _GetOutputItemsFromPack target inside the NuGet.Build.Tasks.Pack.targets file is the subject of the test, so the project that includes NuGet.Build.Tasks.Pack.targets must be registered as a build dependency. - [Collection(FixtureCollection.Name)] - public class PackageFileNameTests - { - #region constructor and fields - -#if DEBUG - const string CONFIGURATION = "Debug"; -#else - const string CONFIGURATION = "Release"; -#endif - - const string FILENAME_PROJECT_FILE = "test.csproj"; - const string FILENAME_NUSPEC_FILE = "test.nuspec"; - - private readonly BuildFixture _testFixture; - private readonly ITestOutputHelper _testOutputHelper; - - public PackageFileNameTests(BuildFixture testFixture, ITestOutputHelper testOutputHelper) - { - _testFixture = testFixture; - _testOutputHelper = testOutputHelper; - } - - #endregion - - public static System.Collections.Generic.IEnumerable TestCases - { - get - { - var cases = new PackageFileNameTestCase[] - { - - // without nuspec input - new PackageFileNameTestCase("000",["proj.1.9.0.nupkg" ], "proj", "nusp", "1.9", "", "", false), - new PackageFileNameTestCase("001",["proj.2.0.0.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", false), - new PackageFileNameTestCase("002",["proj.2.0.0.1.nupkg" ], "proj", "nusp", "2.0.0.1", " ", "4.0.0.1", false), - new PackageFileNameTestCase("003",["proj.2.0.0.2.nupkg" ], "proj", "nusp", "2.0.0.2", "3.0.0.2", "4.0.0.2", false), - new PackageFileNameTestCase("004",["proj.2.0.0.3-preview.nupkg"], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false), - new PackageFileNameTestCase("005",["proj.2.0.0.4-release.nupkg"], "proj", "$meta_id$", "2.0.0.4-release", "3.0.0.2", "$meta_version$", false), - new PackageFileNameTestCase("100",["proj.nupkg" ], "proj", "nusp", "1.9", "", "", false, outputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("104",["proj.nupkg" ], "proj", "nusp", "2.0.0.3-preview", "3.0.0.2", "4.0.0.2", false,outputFileNamesWithoutVersion:true), - - // with nuspec input - new PackageFileNameTestCase("010",["nusp.4.0.0.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true), - new PackageFileNameTestCase("011",["nusp.4.0.0.3.nupkg" ], "proj", "nusp", "2.0.0.3", " ", "4.0.0.3", true), - new PackageFileNameTestCase("012",["nusp.3.0.0.4.nupkg" ], "proj", "nusp", "2.0.0.4", "3.0.0.4", "4.0.0.4", true), - new PackageFileNameTestCase("013",["nusp.5.0.0-preview.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "5.0.0.0-preview", true), - new PackageFileNameTestCase("014",["nusp.5.0.0.2-preview.nupkg"], "proj", "nusp", "2.0.0.0", " ", "5.0.0.2-preview", true), - new PackageFileNameTestCase("015",["nusp.6.0.0-beta.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true), - new PackageFileNameTestCase("110",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", " ", "4.0.0.0", true, outputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("115",["nusp.nupkg" ], "proj", "nusp", "2.0.0.0", "6-beta ", "5.0.0.3-preview", true, outputFileNamesWithoutVersion:true), - - // has symbol - new PackageFileNameTestCase("020",["proj.2.1.0.snupkg"], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), - new PackageFileNameTestCase("021",["nusp.7.1.2.snupkg"], "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ), - new PackageFileNameTestCase("120",["proj.snupkg" ], "proj", "nusp", "2.1.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ,outputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("121",["nusp.snupkg" ], "proj", "nusp", "2.0.0.0", "7.1.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.Snupkg ,outputFileNamesWithoutVersion:true), - - new PackageFileNameTestCase("022",["proj.2.2.0.nupkg", "proj.2.2.0.symbols.nupkg"], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), - new PackageFileNameTestCase("023",["nusp.7.2.2.nupkg", "nusp.7.2.2.symbols.nupkg"], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg ), - new PackageFileNameTestCase("122",["proj.nupkg", "proj.symbols.nupkg" ], "proj", "nusp", "2.2.0.0", "7.1.1", "5.0.0.3-preview", false, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, outputFileNamesWithoutVersion:true), - new PackageFileNameTestCase("123",["nusp.nupkg", "nusp.symbols.nupkg" ], "proj", "nusp", "2.0.0.0", "7.2.2", "5.0.0.4-preview", true, includeSymbols: true, symbolPackageFormat: NuGet.Commands.SymbolPackageFormat.SymbolsNupkg, outputFileNamesWithoutVersion:true), - - }; - - - return (object[][])cases.Select((c, i) => new object[] { c }).ToArray(); - } - } - - // This unit test verifies that GetPackOutputItemsTask outputs the expected file name. - [Theory] - [MemberData(nameof(TestCases))] - public void GetPackOutputItemsTask_PackageFileName(PackageFileNameTestCase testCase) - { - var outputItemTask = new NuGet.Build.Tasks.Pack.GetPackOutputItemsTask(); - outputItemTask.PackageId = testCase.IdProjProp; - outputItemTask.PackageVersion = testCase.VersionProjProp; - outputItemTask.IncludeSymbols = testCase.IncludeSymbols; - outputItemTask.SymbolPackageFormat = GetSymbolPackageFormatText(testCase.SymbolPackageFormat); - outputItemTask.OutputFileNamesWithoutVersion = testCase.OutputFileNamesWithoutVersion; - if (!string.IsNullOrWhiteSpace(testCase.VersionNuspecProperties)) - { - outputItemTask.NuspecProperties = new string[] { $"version={testCase.VersionNuspecProperties}" }; - } - - using (var testDirectory = TestDirectory.Create()) - { - outputItemTask.PackageOutputPath = testDirectory.Path; - outputItemTask.NuspecOutputPath = testDirectory.Path; - if (testCase.UseNuspecFile) - { - outputItemTask.NuspecFile = System.IO.Path.Combine(testDirectory.Path, FILENAME_NUSPEC_FILE); - } - - CreateTestProjectFileAndNuspecFile(testDirectory, FILENAME_PROJECT_FILE, FILENAME_NUSPEC_FILE, testCase); - - Assert.True(outputItemTask.Execute()); - - foreach (string outputNupkgName in testCase.OutputNupkgNames) - { - string[] itemSpecs = outputItemTask.OutputPackItems.Select(item => item.ItemSpec).ToArray(); - var matchCount = GetNameMatchFilePathCount(outputNupkgName, itemSpecs); - Assert.True(matchCount == 1, $"{outputNupkgName} is not found in output. [{string.Join(" , ", itemSpecs.Select(_ => System.IO.Path.GetFileName(_)))}]"); - } - } - } - - - // This unit test verifies that the output file names from GetPackOutputItemsTask matches the output file names from PackTask. - // Since PackTask does not expose the output file name as a property, - // the current implementation performs an actual build and inspects the generated file. - // If PackTask is updated in the future to return the output file name as a property, this test will no longer need a build. - [PlatformTheory(Platform.Windows)] - [MemberData(nameof(TestCases))] - public void PackTask_PackageFileName_FromProjectFileWithNuspecFile(PackageFileNameTestCase testCase) - { - string[] outputExtensions = GetOutputExtensions(testCase.IncludeSymbols, testCase.SymbolPackageFormat); - - using (var testDirectory = TestDirectory.Create()) - { - CreateTestProjectFileAndNuspecFile(testDirectory, FILENAME_PROJECT_FILE, FILENAME_NUSPEC_FILE, testCase); - - CommandRunnerResult runresultDotnetPack; - if (_testFixture._isDotNetFramework) - { - // As noted in #6703, since the .NetStandard2.0 library has been removed, - // running tests on .net Framework requires invoking msbuild.exe. - runresultDotnetPack = CommandRunner.Run( - _testFixture._pathMSBuildExe, - testDirectory, - $"/t:Restore;Build;Pack /p:Configuration={CONFIGURATION} /p:UsingMicrosoftNetSdk=true {FILENAME_PROJECT_FILE} ", - testOutputHelper: _testOutputHelper); - } - else - { - // dotnet build - runresultDotnetPack = CommandRunner.Run( - _testFixture._pathDotnetExe, - testDirectory, - $"build -p:Configuration={CONFIGURATION} {FILENAME_PROJECT_FILE}", - environmentVariables: _testFixture._dotnetEnvironments, - testOutputHelper: _testOutputHelper); - } - Assert.True(0 == runresultDotnetPack.ExitCode, runresultDotnetPack.Output + " " + runresultDotnetPack.Errors); - - var objFolder = System.IO.Path.Combine(testDirectory, "obj"); - var log = System.IO.File.ReadAllLines(System.IO.Path.Combine(objFolder, "_OutputPackItems.txt")); - var lines = log.Where(line => !line.StartsWith(objFolder)).ToArray(); - - var nupkgGeneratedFiles = outputExtensions - .SelectMany(outputExtension => Directory.GetFiles(testDirectory, $"*{outputExtension}", SearchOption.AllDirectories)) - .Where(line => !line.StartsWith(objFolder)) - .Distinct().ToArray(); - Assert.Equal(outputExtensions.Length, nupkgGeneratedFiles.Length); - - foreach (string outputNupkgName in testCase.OutputNupkgNames) - { - var matchCountInFileSystem = GetNameMatchFilePathCount(outputNupkgName, nupkgGeneratedFiles); - Assert.True(matchCountInFileSystem == 1, $"{outputNupkgName} is not found in filesystem. [{string.Join(" , ", nupkgGeneratedFiles.Select(_ => System.IO.Path.GetFileName(_)))}]"); - - var matchCountInOutputPackItems = GetNameMatchFilePathCount(outputNupkgName, lines); - Assert.True(matchCountInOutputPackItems == 1, $"{outputNupkgName} is not found in OutputPackItems. [{string.Join(" , ", lines.Select(_ => System.IO.Path.GetFileName(_)))}]"); - } - } - } - - private void CreateTestProjectFileAndNuspecFile - (string testDirectory - , string projectFileName - , string nuspecFileName - , PackageFileNameTestCase testCase) - { - - var csprojPath = Path.Combine(testDirectory, projectFileName); - var nuspecPath = Path.Combine(testDirectory, nuspecFileName); - - var csprojContent = $""" - - - - {_testFixture._pathDllFile} - - - - {_testFixture._testFrameworkMoniker} - NU5100;NU5119;CS2008 - - - - true - - true - false - True - - {testCase.IdProjProp} - {testCase.VersionProjProp} - tagA;tagB - - {nuspecFileName} - version={testCase.VersionNuspecProperties} - - {testCase.IncludeSymbols} - {GetSymbolPackageFormatText(testCase.SymbolPackageFormat)} - - {testCase.OutputFileNamesWithoutVersion} - - - - - - - - - -"""; - - var nuspecContent = $""" - - - - {testCase.IdNuspecMeta} - {testCase.VersionNuspecMeta?.Trim()} - Unit Test - Sample Description - en-US - - -"""; - - File.WriteAllText(csprojPath, csprojContent, System.Text.Encoding.Unicode); - if (testCase.UseNuspecFile) - { - File.WriteAllText(nuspecPath, nuspecContent, new System.Text.UTF8Encoding(true)); - } - - } - - private static string GetSymbolPackageFormatText(NuGet.Commands.SymbolPackageFormat symbolPackageFormat) - { - switch (symbolPackageFormat) - { - case Commands.SymbolPackageFormat.Snupkg: return "snupkg"; - case Commands.SymbolPackageFormat.SymbolsNupkg: return "symbols.nupkg"; - default: throw new System.ArgumentOutOfRangeException(); - } - } - - private static string[] GetOutputExtensions(bool includeSymbols, NuGet.Commands.SymbolPackageFormat symbolPackageFormat) - { - if (includeSymbols) - { - switch (symbolPackageFormat) - { - case Commands.SymbolPackageFormat.Snupkg: return new string[] { ".snupkg" }; - case Commands.SymbolPackageFormat.SymbolsNupkg: return new string[] { ".nupkg", ".symbols.nupkg" }; - default: throw new System.ArgumentOutOfRangeException(); - } - } - else - { - return new string[] { ".nupkg" }; - } - } - - private int GetNameMatchFilePathCount(string fileName, System.Collections.Generic.IEnumerable fullpaths) - { - return fullpaths.Count(file => string.Equals(fileName, System.IO.Path.GetFileName(file), System.StringComparison.OrdinalIgnoreCase)); - } - } - - public class PackageFileNameTestCase - : IXunitSerializable - { - public PackageFileNameTestCase - (string testNumber - , string[] outputNupkgNames - , string idProjProp - , string idNuspecMeta - , string versionProjProp - , string versionNuspecProperties - , string versionNuspecMeta - , bool useNuspecFile - , bool outputFileNamesWithoutVersion = false - , bool includeSymbols = false - , NuGet.Commands.SymbolPackageFormat symbolPackageFormat = Commands.SymbolPackageFormat.Snupkg) - { - TestNumber = testNumber; - OutputNupkgNames = outputNupkgNames; - IdProjProp = idProjProp; - IdNuspecMeta = idNuspecMeta; - VersionProjProp = versionProjProp; - VersionNuspecProperties = versionNuspecProperties; - VersionNuspecMeta = versionNuspecMeta; - UseNuspecFile = useNuspecFile; - OutputFileNamesWithoutVersion = outputFileNamesWithoutVersion; - IncludeSymbols = includeSymbols; - SymbolPackageFormat = symbolPackageFormat; - } - public string TestNumber { get; set; } = string.Empty; - public string[] OutputNupkgNames { get; set; } = System.Array.Empty(); - public string IdProjProp { get; set; } = string.Empty; - public string IdNuspecMeta { get; set; } = string.Empty; - public string VersionProjProp { get; set; } = string.Empty; - public string VersionNuspecProperties { get; set; } = string.Empty; - public string VersionNuspecMeta { get; set; } = string.Empty; - public bool UseNuspecFile { get; set; } - public bool OutputFileNamesWithoutVersion { get; set; } - public bool IncludeSymbols { get; set; } - public NuGet.Commands.SymbolPackageFormat SymbolPackageFormat { get; set; } = Commands.SymbolPackageFormat.Snupkg; - - #region IXunitSerializable - - [System.Obsolete] - public PackageFileNameTestCase() : this("", [], "", "", "", "", "", false) { } - - void IXunitSerializable.Serialize(IXunitSerializationInfo info) - { - info.AddValue(nameof(TestNumber), TestNumber); - info.AddValue(nameof(OutputNupkgNames), OutputNupkgNames); - info.AddValue(nameof(IdProjProp), IdProjProp); - info.AddValue(nameof(IdNuspecMeta), IdNuspecMeta); - info.AddValue(nameof(VersionProjProp), VersionProjProp); - info.AddValue(nameof(VersionNuspecProperties), VersionNuspecProperties); - info.AddValue(nameof(VersionNuspecMeta), VersionNuspecMeta); - info.AddValue(nameof(UseNuspecFile), UseNuspecFile); - info.AddValue(nameof(OutputFileNamesWithoutVersion), OutputFileNamesWithoutVersion); - info.AddValue(nameof(IncludeSymbols), IncludeSymbols); - info.AddValue(nameof(SymbolPackageFormat), SymbolPackageFormat); - } - void IXunitSerializable.Deserialize(IXunitSerializationInfo info) - { - TestNumber = (string)info.GetValue(nameof(TestNumber), typeof(string)); - OutputNupkgNames = (string[])info.GetValue(nameof(OutputNupkgNames), typeof(string[])); - IdProjProp = (string)info.GetValue(nameof(IdProjProp), typeof(string)); - IdNuspecMeta = (string)info.GetValue(nameof(IdNuspecMeta), typeof(string)); - VersionProjProp = (string)info.GetValue(nameof(VersionProjProp), typeof(string)); - VersionNuspecProperties = (string)info.GetValue(nameof(VersionNuspecProperties), typeof(string)); - VersionNuspecMeta = (string)info.GetValue(nameof(VersionNuspecMeta), typeof(string)); - UseNuspecFile = (bool)info.GetValue(nameof(UseNuspecFile), typeof(bool)); - OutputFileNamesWithoutVersion = (bool)info.GetValue(nameof(OutputFileNamesWithoutVersion), typeof(bool)); - IncludeSymbols = (bool)info.GetValue(nameof(IncludeSymbols), typeof(bool)); - SymbolPackageFormat = (NuGet.Commands.SymbolPackageFormat)info.GetValue(nameof(SymbolPackageFormat), typeof(NuGet.Commands.SymbolPackageFormat)); - } - - #endregion - } -} From 0d95d282ce192c15ed8a9357ffed5e226758f74c Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:34:32 +0900 Subject: [PATCH 13/15] Modify build conditions to use DefineConstants from common.targets --- .../Dotnet.Integration.Test/Dotnet.Integration.Test.csproj | 4 ---- .../Msbuild.Integration.Test/Msbuild.Integration.Test.csproj | 4 ---- .../Msbuild.Integration.Test/PackageFileNameTests.cs | 4 ++-- .../NuGet.Build.Tasks.Pack.Test/PackageFileNameTestCase.cs | 4 ++-- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj index c1bbf30255c..3823a20f662 100644 --- a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj +++ b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj @@ -4,10 +4,6 @@ Integration tests for NuGet-powered dotnet CLI commands such as pack/restore/list package and dotnet nuget. - - $(DefineConstants);TEST_FOR_DOTNET - - diff --git a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj index 19f882dea0d..34146a01b39 100644 --- a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj +++ b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj @@ -5,10 +5,6 @@ None - - $(DefineConstants);TEST_FOR_MSBUILD - - diff --git a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs index b756c890113..8bd04de8744 100644 --- a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs +++ b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs @@ -13,9 +13,9 @@ using Xunit; using Xunit.Abstractions; -#if TEST_FOR_MSBUILD +#if IS_DESKTOP namespace Msbuild.Integration.Test -#elif TEST_FOR_DOTNET +#elif IS_CORECLR namespace Dotnet.Integration.Test #endif { diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageFileNameTestCase.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageFileNameTestCase.cs index 9d4183f5cd7..7584d6f6d82 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageFileNameTestCase.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackageFileNameTestCase.cs @@ -9,9 +9,9 @@ #if TEST_FOR_UNIT namespace NuGet.Build.Tasks.Pack.Test -#elif TEST_FOR_MSBUILD +#elif IS_DESKTOP namespace Msbuild.Integration.Test -#else +#elif IS_CORECLR namespace Dotnet.Integration.Test #endif { From 6642de9a2829a05e4084f4294d4a825461046a98 Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Sun, 29 Mar 2026 23:33:45 +0900 Subject: [PATCH 14/15] Remove integration Tests --- .../Dotnet.Integration.Test.csproj | 10 - .../Msbuild.Integration.Test.csproj | 19 +- .../PackageFileNameTests.cs | 259 ------------------ 3 files changed, 6 insertions(+), 282 deletions(-) delete mode 100644 test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs diff --git a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj index 3823a20f662..b1ef98a93ed 100644 --- a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj +++ b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/Dotnet.Integration.Test.csproj @@ -4,21 +4,11 @@ Integration tests for NuGet-powered dotnet CLI commands such as pack/restore/list package and dotnet nuget. - - - - - - - - - - diff --git a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj index 34146a01b39..75c9c3b47e5 100644 --- a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj +++ b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/Msbuild.Integration.Test.csproj @@ -1,19 +1,15 @@ - + $(NETFXTargetFramework) Integration tests for NuGet powered msbuild functionalities (restore/pack). None - + - - - - @@ -23,13 +19,10 @@ - - - - - - - + + diff --git a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs deleted file mode 100644 index 8bd04de8744..00000000000 --- a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/PackageFileNameTests.cs +++ /dev/null @@ -1,259 +0,0 @@ -// 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. - -#nullable enable - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.Internal.NuGet.Testing.SignedPackages.ChildProcess; -using NuGet.Frameworks; -using NuGet.Test.Utility; -using Xunit; -using Xunit.Abstractions; - -#if IS_DESKTOP -namespace Msbuild.Integration.Test -#elif IS_CORECLR -namespace Dotnet.Integration.Test -#endif -{ - /// - /// The _GetOutputItemsFromPack target inside the NuGet.Build.Tasks.Pack.targets file is the subject of the test, so the project that includes NuGet.Build.Tasks.Pack.targets must be registered as a build dependency. - [Collection(PackageFileNameBuildTestFixtureCollection.Name)] - public class PackageFileNameTests - { - private readonly PackageFileNameBuildTestFixture _testFixture; - private readonly ITestOutputHelper _testOutputHelper; - - public PackageFileNameTests(PackageFileNameBuildTestFixture testFixture, ITestOutputHelper testOutputHelper) - { - _testFixture = testFixture; - _testOutputHelper = testOutputHelper; - } - - public static System.Collections.Generic.IEnumerable PackageFileNameTestCases => PackageFileNameTestCase.TestCases; - - // This unit test verifies that the output file names from GetPackOutputItemsTask matches the output file names from PackTask. - // Since PackTask does not expose the output file name as a property, - // the current implementation performs an actual build and inspects the generated file. - [PlatformTheory(Platform.Windows)] - [MemberData(nameof(PackageFileNameTestCases))] - public void PackTask_PackageFileName(PackageFileNameTestCase testCase) - { - string[] outputExtensions = PackageFileNameTestsCommon.GetOutputExtensions(testCase.IncludeSymbols, testCase.SymbolPackageFormat); - - using (var testDirectory = TestDirectory.Create()) - { - PackageFileNameTestsCommon.CreateTestProjectFileAndNuspecFile(testCase, testDirectory, _testFixture._pathDllFile, _testFixture._pathTargetsFile, _testFixture._testFrameworkMoniker); - - CommandRunnerResult runresult; - if (_testFixture._isDotNetFramework) - { // This test is running on .Net Framework - - // As noted in #6703, since the .NetStandard2.0 library has been removed, - // running tests on .net Framework requires invoking msbuild.exe. - - // Restore (needs create project.assets.json) - _testFixture.Restore(testDirectory, PackageFileNameTestsCommon.FILENAME_PROJECT_FILE, _testOutputHelper); - - // msbuild.exe - runresult = CommandRunner.Run( - _testFixture._pathMSBuildExe, - testDirectory, - $"/t:Build;Pack /p:Configuration={PackageFileNameBuildTestFixture.CONFIGURATION} /p:UsingMicrosoftNetSdk=true {PackageFileNameTestsCommon.FILENAME_PROJECT_FILE}", - environmentVariables: _testFixture._dotnetEnvironments, - testOutputHelper: _testOutputHelper); - } - else - { - // dotnet.exe - runresult = CommandRunner.Run( - _testFixture._pathDotnetExe, - testDirectory, - $"build -p:Configuration={PackageFileNameBuildTestFixture.CONFIGURATION} {PackageFileNameTestsCommon.FILENAME_PROJECT_FILE}", - environmentVariables: _testFixture._dotnetEnvironments, - testOutputHelper: _testOutputHelper); - } - Assert.True(0 == runresult.ExitCode, runresult.Output + " " + runresult.Errors); - - var objFolder = System.IO.Path.Combine(testDirectory, "obj"); - var log = System.IO.File.ReadAllLines(System.IO.Path.Combine(objFolder, PackageFileNameTestsCommon.FILENAME_GETOUTPUTITEMSTASK_OUTPUTPACKITEMS_TEST)); - var lines = log.Where(line => !line.StartsWith(objFolder)).ToArray(); - - var nupkgGeneratedFiles = outputExtensions - .SelectMany(outputExtension => Directory.GetFiles(testDirectory, $"*{outputExtension}", SearchOption.AllDirectories)) - .Where(line => !line.StartsWith(objFolder)) - .Distinct().ToArray(); - Assert.Equal(outputExtensions.Length, nupkgGeneratedFiles.Length); - - foreach (string outputNupkgName in testCase.OutputNupkgNames) - { - var matchCountInFileSystem = PackageFileNameTestsCommon.GetNameMatchFilePathCount(outputNupkgName, nupkgGeneratedFiles); - Assert.True(matchCountInFileSystem == 1, $"{outputNupkgName} is not found in filesystem. [{string.Join(" , ", nupkgGeneratedFiles.Select(_ => System.IO.Path.GetFileName(_)))}]"); - - var matchCountInOutputPackItems = PackageFileNameTestsCommon.GetNameMatchFilePathCount(outputNupkgName, lines); - Assert.True(matchCountInOutputPackItems == 1, $"{outputNupkgName} is not found in OutputPackItems. [{string.Join(" , ", lines.Select(_ => System.IO.Path.GetFileName(_)))}]"); - } - } - } - } - - [CollectionDefinition(Name)] - public class PackageFileNameBuildTestFixtureCollection - : ICollectionFixture - { - internal const string Name = nameof(PackageFileNameBuildTestFixtureCollection) + "Collection"; - } - - public class PackageFileNameBuildTestFixture : IDisposable - { -#if DEBUG - public const string CONFIGURATION = "Debug"; -#else - public const string CONFIGURATION = "Release"; -#endif - - private const string FILENAME_DLL = "NuGet.Build.Tasks.Pack.dll"; - private const string FILENAME_TARGETS = "NuGet.Build.Tasks.Pack.targets"; - -#if IS_DESKTOP - private const string SdkVersion = "10"; - private const string SdkTfm = "net10.0"; -#endif - - internal readonly bool _isDotNetFramework = false; - internal readonly string _testFrameworkMoniker = "netstandard2.0"; - - internal readonly string _pathDotnetExe; - internal readonly string _pathMSBuildExe; - internal readonly string _pathDllFile; - internal readonly string _pathTargetsFile; - - internal readonly IReadOnlyDictionary _dotnetEnvironments = new Dictionary(); - - public PackageFileNameBuildTestFixture() - { - _pathDotnetExe = NuGet.Test.Utility.TestFileSystemUtility.GetDotnetCli(); - -#if IS_DESKTOP - var _cliDirectory = TestDotnetCLiUtility.CopyAndPatchLatestDotnetCli(SdkVersion, SdkTfm); -#else - string testAssemblyPath = Path.GetFullPath(System.Reflection.Assembly.GetExecutingAssembly().Location); - var _cliDirectory = TestDotnetCLiUtility.CopyAndPatchLatestDotnetCli(testAssemblyPath); -#endif - var dotnetExecutableName = NuGet.Common.RuntimeEnvironmentHelper.IsWindows ? "dotnet.exe" : "dotnet"; - _pathDotnetExe = Path.Combine(_cliDirectory, dotnetExecutableName); - - var sdkPath = Directory.EnumerateDirectories(Path.Combine(_cliDirectory, "sdk")) - .Single(d => !string.Equals(Path.GetFileName(d), "NuGetFallbackFolder", StringComparison.OrdinalIgnoreCase)); - - _pathMSBuildExe = GetMsBuildExePath(); - _testFrameworkMoniker = GetFrameworkMoniker(typeof(NuGet.Build.Tasks.Pack.GetPackOutputItemsTask), out var isDotNetFramework); - _isDotNetFramework = isDotNetFramework; - - var artifactsDirectory = NuGet.Test.Utility.TestFileSystemUtility.GetArtifactsDirectoryInRepo(); - var dllDirectory = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks.Pack", "bin", CONFIGURATION, _testFrameworkMoniker); - _pathDllFile = Path.Combine(dllDirectory, FILENAME_DLL); - - // https://github.com/NuGet/NuGet.Client/pull/6712 - // NuGet.Build.Tasks.Pack.targets has been moved to in NuGet.Build.Tasks project. - // Therefore, NuGet.Build.Tasks project must be built before running this test. - var tfmTargets = GetFrameworkMoniker(typeof(PackageFileNameTests), out var _); - _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, tfmTargets, FILENAME_TARGETS); - if (!File.Exists(_pathTargetsFile)) - { - _pathTargetsFile = Path.Combine(artifactsDirectory, "NuGet.Build.Tasks", "bin", CONFIGURATION, _testFrameworkMoniker, FILENAME_TARGETS); - if (!File.Exists(_pathTargetsFile)) - { - _pathTargetsFile = Path.Combine(dllDirectory, FILENAME_TARGETS); - } - } - - _dotnetEnvironments = new Dictionary() - { - ["MSBuildSDKsPath"] = Path.Combine(sdkPath, "Sdks"), - ["DOTNET_MULTILEVEL_LOOKUP"] = "0", - ["DOTNET_ROOT"] = _cliDirectory, - ["MSBuildExtensionsPath"] = new DirectoryInfo(sdkPath).FullName, - ["PATH"] = $"{_cliDirectory}{Path.PathSeparator}{Environment.GetEnvironmentVariable("PATH")}", - - //["DEBUG_RESTORE_TASK"] = $"{true}", - //["DEBUG_PACK_TASK"] = $"{true}" - }; - - Assert.True(System.IO.File.Exists(_pathDllFile), $"{FILENAME_DLL} missing"); - Assert.True(System.IO.File.Exists(_pathTargetsFile), $"{FILENAME_TARGETS} missing"); - } - - private static string GetFrameworkMoniker(Type typeInAssembly, out bool isDotNetFramework) - { - var assembly = typeInAssembly.Assembly; - var targetFrameworkAttribute - = assembly.GetCustomAttributes(typeof(System.Runtime.Versioning.TargetFrameworkAttribute), false) - .OfType().FirstOrDefault(); - - Assert.True(targetFrameworkAttribute != null, "Can't get targetFramework version"); - - isDotNetFramework = targetFrameworkAttribute.FrameworkName.Contains(".NETFramework"); - return NuGetFramework.Parse(targetFrameworkAttribute.FrameworkName).GetShortFolderName(); - } - - private static string GetMsBuildExePath() - { - if (Environment.OSVersion.Platform == PlatformID.Win32NT) - { - var msbuildexe = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", "msbuild.exe"); - var vswhereexe = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft Visual Studio", "Installer", "vswhere.exe"); - Assert.True(File.Exists(vswhereexe), "vswhere not found"); - - var runresult = CommandRunner.Run( - vswhereexe, - Environment.CurrentDirectory, - @" -latest -find MSBuild\**\Bin\MSBuild.exe"); - if (runresult.Success) - { - msbuildexe = new StringReader(runresult.Output).ReadLine() ?? ""; - } - - Assert.True(File.Exists(msbuildexe), "msbuild not found"); - return msbuildexe; - } - else - { - return ""; - } - } - - //Create project.assets.json - public void Restore(string testDirectory, string pathProjectFile, ITestOutputHelper _testOutputHelper) - { - CommandRunnerResult runresult; - if (_isDotNetFramework) - { - runresult = CommandRunner.Run( - _pathMSBuildExe, - testDirectory, - $"/t:Restore /p:UsingMicrosoftNetSdk=true \"{pathProjectFile}\"", - environmentVariables: _dotnetEnvironments, - testOutputHelper: _testOutputHelper); - } - else - { - runresult = CommandRunner.Run( - _pathDotnetExe, - testDirectory, - $"restore \"{pathProjectFile}\"", - environmentVariables: _dotnetEnvironments, - testOutputHelper: _testOutputHelper); - } - Assert.True(runresult.ExitCode == 0, runresult.Output + " " + runresult.Errors); - } - public void Dispose() - { - } - - } - -} From 100e6b6b19579a6c5254ca119987aeae523e1cbf Mon Sep 17 00:00:00 2001 From: gekka <10055381+gekka@users.noreply.github.com> Date: Mon, 30 Mar 2026 00:27:46 +0900 Subject: [PATCH 15/15] Fix current directory --- .../NuGet.Build.Tasks.Pack.Test/PackTaskTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackTaskTests.cs b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackTaskTests.cs index b8bb42464f2..538abe23fc4 100644 --- a/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackTaskTests.cs +++ b/test/NuGet.Core.Tests/NuGet.Build.Tasks.Pack.Test/PackTaskTests.cs @@ -456,7 +456,6 @@ public void PackTask_Execute_CheckPackageFileName(PackageFileNameTestCase testCa { string outputDir = System.IO.Path.Combine(testDirectory, "output"); System.IO.Directory.CreateDirectory(outputDir); - System.IO.Directory.SetCurrentDirectory(testDirectory); string objDir = System.IO.Path.Combine(testDirectory, "obj"); System.IO.Directory.CreateDirectory(objDir);