Skip to content

Commit

Permalink
Implement most of the suggestion
Browse files Browse the repository at this point in the history
  • Loading branch information
Genbox committed Jan 2, 2025
1 parent 94aa84c commit b7b2130
Show file tree
Hide file tree
Showing 15 changed files with 149 additions and 115 deletions.
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet/Configs/DebugConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public abstract class DebugConfig : IConfig
public IEnumerable<IValidator> GetValidators() => Array.Empty<IValidator>();
public IEnumerable<IColumnProvider> GetColumnProviders() => DefaultColumnProviders.Instance;
public IEnumerable<IExporter> GetExporters() => Array.Empty<IExporter>();
public IEnumerable<ILocator> GetLocators() => new[] { ProjectLocator.Default };
public IEnumerable<IFileLocator> GetFileLocators() => new[] { ProjectFileLocator.Default };
public IEnumerable<ILogger> GetLoggers() => new[] { ConsoleLogger.Default };
public IEnumerable<IDiagnoser> GetDiagnosers() => Array.Empty<IDiagnoser>();
public IEnumerable<IAnalyser> GetAnalysers() => Array.Empty<IAnalyser>();
Expand Down
4 changes: 2 additions & 2 deletions src/BenchmarkDotNet/Configs/DefaultConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ public IEnumerable<IExporter> GetExporters()
yield return HtmlExporter.Default;
}

public IEnumerable<ILocator> GetLocators()
public IEnumerable<IFileLocator> GetFileLocators()
{
yield return ProjectLocator.Default;
yield return ProjectFileLocator.Default;
}

public IEnumerable<ILogger> GetLoggers()
Expand Down
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet/Configs/IConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public interface IConfig
{
IEnumerable<IColumnProvider> GetColumnProviders();
IEnumerable<IExporter> GetExporters();
IEnumerable<ILocator> GetLocators();
IEnumerable<IFileLocator> GetFileLocators();
IEnumerable<ILogger> GetLoggers();
IEnumerable<IDiagnoser> GetDiagnosers();
IEnumerable<IAnalyser> GetAnalysers();
Expand Down
8 changes: 4 additions & 4 deletions src/BenchmarkDotNet/Configs/ImmutableConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public sealed class ImmutableConfig : IConfig
// if something is an array here instead of hashset it means it must have a guaranteed order of elements
private readonly ImmutableArray<IColumnProvider> columnProviders;
private readonly ImmutableArray<IExporter> exporters;
private readonly ImmutableArray<ILocator> locators;
private readonly ImmutableArray<IFileLocator> fileLocators;
private readonly ImmutableHashSet<ILogger> loggers;
private readonly ImmutableHashSet<IDiagnoser> diagnosers;
private readonly ImmutableHashSet<IAnalyser> analysers;
Expand All @@ -43,7 +43,7 @@ internal ImmutableConfig(
ImmutableHashSet<HardwareCounter> uniqueHardwareCounters,
ImmutableHashSet<IDiagnoser> uniqueDiagnosers,
ImmutableArray<IExporter> uniqueExporters,
ImmutableArray<ILocator> uniqueLocators,
ImmutableArray<IFileLocator> uniqueFileLocators,
ImmutableHashSet<IAnalyser> uniqueAnalyzers,
ImmutableHashSet<IValidator> uniqueValidators,
ImmutableHashSet<IFilter> uniqueFilters,
Expand All @@ -66,7 +66,7 @@ internal ImmutableConfig(
hardwareCounters = uniqueHardwareCounters;
diagnosers = uniqueDiagnosers;
exporters = uniqueExporters;
locators = uniqueLocators;
fileLocators = uniqueFileLocators;
analysers = uniqueAnalyzers;
validators = uniqueValidators;
filters = uniqueFilters;
Expand Down Expand Up @@ -96,7 +96,7 @@ internal ImmutableConfig(

public IEnumerable<IColumnProvider> GetColumnProviders() => columnProviders;
public IEnumerable<IExporter> GetExporters() => exporters;
public IEnumerable<ILocator> GetLocators() => locators;
public IEnumerable<IFileLocator> GetFileLocators() => fileLocators;
public IEnumerable<ILogger> GetLoggers() => loggers;
public IEnumerable<IDiagnoser> GetDiagnosers() => diagnosers;
public IEnumerable<IAnalyser> GetAnalysers() => analysers;
Expand Down
4 changes: 2 additions & 2 deletions src/BenchmarkDotNet/Configs/ImmutableConfigBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static ImmutableConfig Create(IConfig source)
var uniqueHardwareCounters = source.GetHardwareCounters().Where(counter => counter != HardwareCounter.NotSet).ToImmutableHashSet();
var uniqueDiagnosers = GetDiagnosers(source.GetDiagnosers(), uniqueHardwareCounters);
var uniqueExporters = GetExporters(source.GetExporters(), uniqueDiagnosers, configAnalyse);
var uniqueLocators = source.GetLocators().ToImmutableArray();
var uniqueFileLocators = source.GetFileLocators().ToImmutableArray();
var uniqueAnalyzers = GetAnalysers(source.GetAnalysers(), uniqueDiagnosers);

var uniqueValidators = GetValidators(source.GetValidators(), MandatoryValidators, source.Options);
Expand All @@ -62,7 +62,7 @@ public static ImmutableConfig Create(IConfig source)
uniqueHardwareCounters,
uniqueDiagnosers,
uniqueExporters,
uniqueLocators,
uniqueFileLocators,
uniqueAnalyzers,
uniqueValidators,
uniqueFilters,
Expand Down
10 changes: 5 additions & 5 deletions src/BenchmarkDotNet/Configs/ManualConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class ManualConfig : IConfig

private readonly List<IColumnProvider> columnProviders = new List<IColumnProvider>();
private readonly List<IExporter> exporters = new List<IExporter>();
private readonly List<ILocator> locators = new List<ILocator>();
private readonly List<IFileLocator> locators = new List<IFileLocator>();
private readonly List<ILogger> loggers = new List<ILogger>();
private readonly List<IDiagnoser> diagnosers = new List<IDiagnoser>();
private readonly List<IAnalyser> analysers = new List<IAnalyser>();
Expand All @@ -41,7 +41,7 @@ public class ManualConfig : IConfig

public IEnumerable<IColumnProvider> GetColumnProviders() => columnProviders;
public IEnumerable<IExporter> GetExporters() => exporters;
public IEnumerable<ILocator> GetLocators() => locators;
public IEnumerable<IFileLocator> GetFileLocators() => locators;
public IEnumerable<ILogger> GetLoggers() => loggers;
public IEnumerable<IDiagnoser> GetDiagnosers() => diagnosers;
public IEnumerable<IAnalyser> GetAnalysers() => analysers;
Expand Down Expand Up @@ -142,7 +142,7 @@ public ManualConfig AddExporter(params IExporter[] newExporters)
return this;
}

public ManualConfig AddLocator(params ILocator[] newLocators)
public ManualConfig AddFileLocator(params IFileLocator[] newLocators)
{
locators.AddRange(newLocators);
return this;
Expand Down Expand Up @@ -265,7 +265,7 @@ public void Add(IConfig config)
{
columnProviders.AddRange(config.GetColumnProviders());
exporters.AddRange(config.GetExporters());
locators.AddRange(config.GetLocators());
locators.AddRange(config.GetFileLocators());
loggers.AddRange(config.GetLoggers());
diagnosers.AddRange(config.GetDiagnosers());
analysers.AddRange(config.GetAnalysers());
Expand Down Expand Up @@ -297,7 +297,7 @@ public void Add(IConfig config)
public static ManualConfig CreateMinimumViable()
=> CreateEmpty()
.AddColumnProvider(DefaultColumnProviders.Instance)
.AddLocator(ProjectLocator.Default)
.AddFileLocator(ProjectFileLocator.Default)
.AddLogger(ConsoleLogger.Default);

public static ManualConfig Create(IConfig config)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace BenchmarkDotNet.Locators;

public enum LocatorType
public enum FileLocatorType
{
ProjectFile
Project
}
9 changes: 9 additions & 0 deletions src/BenchmarkDotNet/Locators/IFileLocator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.IO;

namespace BenchmarkDotNet.Locators;

public interface IFileLocator
{
FileLocatorType LocatorType { get; }
bool TryLocate(LocatorArgs locatorArgs, out FileInfo fileInfo);
}
10 changes: 0 additions & 10 deletions src/BenchmarkDotNet/Locators/ILocator.cs

This file was deleted.

16 changes: 16 additions & 0 deletions src/BenchmarkDotNet/Locators/LocatorArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Running;

namespace BenchmarkDotNet.Locators;

public class LocatorArgs
{
public LocatorArgs(BenchmarkCase benchmarkCase, ILogger logger)
{
BenchmarkCase = benchmarkCase;
Logger = logger;
}

public BenchmarkCase BenchmarkCase { get; }
public ILogger Logger { get; }
}
85 changes: 85 additions & 0 deletions src/BenchmarkDotNet/Locators/ProjectFileLocator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using BenchmarkDotNet.Exporters;
using BenchmarkDotNet.Running;

namespace BenchmarkDotNet.Locators;

public class ProjectFileLocator : IFileLocator
{
private static readonly string[] ProjectExtensions = { ".csproj", ".fsproj", ".vbroj" };

public static ProjectFileLocator Default { get; } = new ProjectFileLocator();

public FileLocatorType LocatorType => FileLocatorType.Project;

public bool TryLocate(LocatorArgs locatorArgs, out FileInfo fileInfo)
{
if (!GetRootDirectory(IsRootSolutionFolder, out var rootDirectory) && !GetRootDirectory(IsRootProjectFolder, out rootDirectory))
{
rootDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
}

// important assumption! project's file name === output dll name
var type = locatorArgs.BenchmarkCase.Descriptor.Type;
var projectName = type.GetTypeInfo().Assembly.GetName().Name;

var possibleNames = new HashSet<string> { $"{projectName}.csproj", $"{projectName}.fsproj", $"{projectName}.vbproj" };
var projectFiles = rootDirectory
.EnumerateFiles("*proj", SearchOption.AllDirectories)
.Where(file => possibleNames.Contains(file.Name))
.ToArray();

if (projectFiles.Length == 0)
{
fileInfo = null;
return false;
}

if (projectFiles.Length > 1)
{
throw new InvalidOperationException(
$"Found more than one matching project file for {projectName} in {rootDirectory.FullName} and its subfolders: {string.Join(",", projectFiles.Select(pf => $"'{pf.FullName}'"))}. Benchmark project names needs to be unique.");
}

fileInfo = projectFiles[0];
return true;
}

private static bool GetRootDirectory(Func<DirectoryInfo, bool> condition, out DirectoryInfo? directoryInfo)
{
directoryInfo = null;
try
{
directoryInfo = new DirectoryInfo(Directory.GetCurrentDirectory());
while (directoryInfo != null)
{
if (condition(directoryInfo))
{
return true;
}

directoryInfo = directoryInfo.Parent;
}
}
catch
{
return false;
}

return false;
}

private static bool IsRootSolutionFolder(DirectoryInfo directoryInfo)
=> directoryInfo
.GetFileSystemInfos()
.Any(fileInfo => fileInfo.Extension == ".sln" || fileInfo.Name == "global.json");

private static bool IsRootProjectFolder(DirectoryInfo directoryInfo)
=> directoryInfo
.GetFileSystemInfos()
.Any(fileInfo => ProjectExtensions.Contains(fileInfo.Extension));
}
40 changes: 0 additions & 40 deletions src/BenchmarkDotNet/Locators/ProjectLocator.cs

This file was deleted.

35 changes: 13 additions & 22 deletions src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using BenchmarkDotNet.Characteristics;
Expand Down Expand Up @@ -249,33 +247,26 @@ private static string GetIndentedXmlString(XmlDocument doc)
[PublicAPI]
protected virtual FileInfo GetProjectFilePath(BenchmarkCase benchmark, ILogger logger)
{
var benchmarkTarget = benchmark.Descriptor.Type;
var notFound = new List<string>();
var args = new LocatorArgs(benchmark, logger);

if (!GetSolutionRootDirectory(out var rootDirectory) && !GetProjectRootDirectory(out rootDirectory))
foreach (var locator in benchmark.Config.GetFileLocators())
{
logger.WriteLineError(
$"Unable to find .sln or .csproj file. Will use current directory {Directory.GetCurrentDirectory()} to search for project file. If you don't use .sln file on purpose it should not be a problem.");
rootDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
}

List<string> notFound = new List<string>();
foreach (ILocator locator in benchmark.Config.GetLocators())
{
if (locator.LocatorType != LocatorType.ProjectFile)
continue;

var path = locator.Locate(rootDirectory, benchmarkTarget);

if (path == null)
if (locator.LocatorType != FileLocatorType.Project)
{
continue;
}

if (path.Exists)
return path;
if (locator.TryLocate(args, out var fileInfo))
{
if (fileInfo.Exists)
return fileInfo;

notFound.Add(path.FullName);
notFound.Add(fileInfo.FullName);
}
}

throw new NotSupportedException($"Unable to find project file in {rootDirectory}. Attempted location(s): " + string.Join(", ", notFound));
throw new FileNotFoundException("Unable to find project file. Attempted location(s): " + string.Join(", ", notFound));
}

public override bool Equals(object obj) => obj is CsProjGenerator other && Equals(other);
Expand Down
Loading

0 comments on commit b7b2130

Please sign in to comment.