diff --git a/src/BenchmarkDotNet/Running/BuildPartition.cs b/src/BenchmarkDotNet/Running/BuildPartition.cs index 4ffc48d6c..2dc663bfb 100644 --- a/src/BenchmarkDotNet/Running/BuildPartition.cs +++ b/src/BenchmarkDotNet/Running/BuildPartition.cs @@ -23,7 +23,10 @@ namespace BenchmarkDotNet.Running Resolver = resolver; RepresentativeBenchmarkCase = benchmarks[0].BenchmarkCase; Benchmarks = benchmarks; - ProgramName = benchmarks[0].Config.Options.IsSet(ConfigOptions.KeepBenchmarkFiles) ? RepresentativeBenchmarkCase.Job.FolderInfo : Guid.NewGuid().ToString(); + var keepBenchmarkFiles = benchmarks[0].Config.Options.IsSet(ConfigOptions.KeepBenchmarkFiles); + var guid = Guid.NewGuid().ToString(); + ProgramName = keepBenchmarkFiles ? RepresentativeBenchmarkCase.Job.FolderInfo : guid; + ProgramDirectory = keepBenchmarkFiles ? Path.Combine(RepresentativeBenchmarkCase.Job.FolderInfo, guid) : guid; LogBuildOutput = benchmarks[0].Config.Options.IsSet(ConfigOptions.LogBuildOutput); GenerateMSBuildBinLog = benchmarks[0].Config.Options.IsSet(ConfigOptions.GenerateMSBuildBinLog); } @@ -32,6 +35,8 @@ namespace BenchmarkDotNet.Running public string ProgramName { get; } + public string ProgramDirectory { get; } + /// /// the benchmarks are grouped by the build settings /// so you can use this benchmark to get the runtime settings diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs index a432fbf88..24afe6810 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs @@ -36,11 +36,11 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli /// we are limited by xprojs (by default compiles all .cs files in all subfolders, Program.cs could be doubled and fail the build) /// and also by NuGet internal implementation like looking for global.json file in parent folders /// - protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName) + protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programDirectory) { if (GetSolutionRootDirectory(out var directoryInfo)) { - return Path.Combine(directoryInfo.FullName, programName); + return Path.Combine(directoryInfo.FullName, programDirectory); } // we did not find global.json or any Visual Studio solution file? @@ -48,7 +48,7 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli var parent = new DirectoryInfo(Directory.GetCurrentDirectory()).Parent; if (parent == null) throw new DirectoryNotFoundException("Parent directory for current directory"); - return Path.Combine(parent.FullName, programName); + return Path.Combine(parent.FullName, programDirectory); } internal static bool GetSolutionRootDirectory(out DirectoryInfo directoryInfo) diff --git a/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs b/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs index 020788cc5..407eca414 100644 --- a/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs +++ b/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs @@ -42,7 +42,7 @@ namespace BenchmarkDotNet.Toolchains /// /// returns a path to the folder where auto-generated project and code are going to be placed /// - [PublicAPI] protected abstract string GetBuildArtifactsDirectoryPath(BuildPartition assemblyLocation, string programName); + [PublicAPI] protected abstract string GetBuildArtifactsDirectoryPath(BuildPartition assemblyLocation, string programDirectory); /// /// returns a path where executable should be found after the build (usually \bin) @@ -128,10 +128,10 @@ namespace BenchmarkDotNet.Toolchains // its not ".cs" in order to avoid VS from displaying and compiling it with xprojs/csprojs that include all *.cs by default const string codeFileExtension = ".notcs"; - string programName = buildPartition.ProgramName; - string buildArtifactsDirectoryPath = GetBuildArtifactsDirectoryPath(buildPartition, programName); + string buildArtifactsDirectoryPath = GetBuildArtifactsDirectoryPath(buildPartition, buildPartition.ProgramDirectory); string binariesDirectoryPath = GetBinariesDirectoryPath(buildArtifactsDirectoryPath, buildPartition.BuildConfiguration); + string programName = buildPartition.ProgramName; string executablePath = GetExecutablePath(binariesDirectoryPath, programName); return new ArtifactsPaths( diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs index b3adfc3e3..6c6d7dd11 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs @@ -60,10 +60,10 @@ namespace BenchmarkDotNet.Toolchains.NativeAot protected override string GetExecutableExtension() => OsDetector.ExecutableExtension; - protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName) + protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programDirectory) => useTempFolderForRestore - ? Path.Combine(Path.GetTempPath(), programName) // store everything in temp to avoid collisions with IDE - : base.GetBuildArtifactsDirectoryPath(buildPartition, programName); + ? Path.Combine(Path.GetTempPath(), programDirectory) // store everything in temp to avoid collisions with IDE + : base.GetBuildArtifactsDirectoryPath(buildPartition, programDirectory); protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration) => Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker, runtimeIdentifier, "publish"); diff --git a/src/BenchmarkDotNet/Toolchains/Roslyn/Generator.cs b/src/BenchmarkDotNet/Toolchains/Roslyn/Generator.cs index 3ba7054f7..65b08798c 100644 --- a/src/BenchmarkDotNet/Toolchains/Roslyn/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/Roslyn/Generator.cs @@ -13,7 +13,7 @@ namespace BenchmarkDotNet.Toolchains.Roslyn [PublicAPI] public class Generator : GeneratorBase { - protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName) + protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programDirectory) => Path.GetDirectoryName(buildPartition.AssemblyLocation); [PublicAPI] diff --git a/tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs b/tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs index 706e74b56..e1f07c0dd 100644 --- a/tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs +++ b/tests/BenchmarkDotNet.Tests/CsProjGeneratorTests.cs @@ -220,9 +220,9 @@ namespace BenchmarkDotNet.Tests private class SteamLoadedBuildPartition : CsProjGenerator { - internal string ResolvePathForBinaries(BuildPartition buildPartition, string programName) + internal string ResolvePathForBinaries(BuildPartition buildPartition, string programDirectory) { - return base.GetBuildArtifactsDirectoryPath(buildPartition, programName); + return base.GetBuildArtifactsDirectoryPath(buildPartition, programDirectory); } public SteamLoadedBuildPartition(string targetFrameworkMoniker, string cliPath, string packagesPath, string runtimeFrameworkVersion, bool isNetCore)