Skip to content

Commit 1aab1c0

Browse files
Genboxtimcassell
andauthored
Add support for user-supplied project file detection (#2684)
* Add support for user-supplied project file detection * Make ProjectLocator fall back to other locators if enabled * Implement most of the suggestion * Use fallback logic instead * Add a few docs and use default code style * Include file locator paths in exception message and rename LocatorArgs to FileLocatorArgs * Update src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs Co-authored-by: Tim Cassell <[email protected]> * Create integration test * Support .NET Framework csproj tool chain as well --------- Co-authored-by: Tim Cassell <[email protected]>
1 parent 3337a09 commit 1aab1c0

File tree

19 files changed

+243
-17
lines changed

19 files changed

+243
-17
lines changed

BenchmarkDotNet.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkDotNet.Exporters.P
5959
EndProject
6060
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkDotNet.Exporters.Plotting.Tests", "tests\BenchmarkDotNet.Exporters.Plotting.Tests\BenchmarkDotNet.Exporters.Plotting.Tests.csproj", "{199AC83E-30BD-40CD-87CE-0C838AC0320D}"
6161
EndProject
62+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchmarkDotNet.IntegrationTests.FileLocators", "tests\BenchmarkDotNet.IntegrationTests.FileLocators\BenchmarkDotNet.IntegrationTests.FileLocators.csproj", "{7AD9FCF9-69B5-4984-93AC-D6E30344DADC}"
63+
EndProject
6264
Global
6365
GlobalSection(SolutionConfigurationPlatforms) = preSolution
6466
Debug|Any CPU = Debug|Any CPU
@@ -161,6 +163,10 @@ Global
161163
{199AC83E-30BD-40CD-87CE-0C838AC0320D}.Debug|Any CPU.Build.0 = Debug|Any CPU
162164
{199AC83E-30BD-40CD-87CE-0C838AC0320D}.Release|Any CPU.ActiveCfg = Release|Any CPU
163165
{199AC83E-30BD-40CD-87CE-0C838AC0320D}.Release|Any CPU.Build.0 = Release|Any CPU
166+
{7AD9FCF9-69B5-4984-93AC-D6E30344DADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
167+
{7AD9FCF9-69B5-4984-93AC-D6E30344DADC}.Debug|Any CPU.Build.0 = Debug|Any CPU
168+
{7AD9FCF9-69B5-4984-93AC-D6E30344DADC}.Release|Any CPU.ActiveCfg = Release|Any CPU
169+
{7AD9FCF9-69B5-4984-93AC-D6E30344DADC}.Release|Any CPU.Build.0 = Release|Any CPU
164170
EndGlobalSection
165171
GlobalSection(SolutionProperties) = preSolution
166172
HideSolutionNode = FALSE
@@ -190,6 +196,7 @@ Global
190196
{2E2283A3-6DA6-4482-8518-99D6D9F689AB} = {D6597E3A-6892-4A68-8E14-042FC941FDA2}
191197
{B92ECCEF-7C27-4012-9E19-679F3C40A6A6} = {D6597E3A-6892-4A68-8E14-042FC941FDA2}
192198
{199AC83E-30BD-40CD-87CE-0C838AC0320D} = {14195214-591A-45B7-851A-19D3BA2413F9}
199+
{7AD9FCF9-69B5-4984-93AC-D6E30344DADC} = {14195214-591A-45B7-851A-19D3BA2413F9}
193200
EndGlobalSection
194201
GlobalSection(ExtensibilityGlobals) = postSolution
195202
SolutionGuid = {4D9AF12B-1F7F-45A7-9E8C-E4E46ADCBD1F}

src/BenchmarkDotNet/Configs/DebugConfig.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using BenchmarkDotNet.Exporters;
99
using BenchmarkDotNet.Filters;
1010
using BenchmarkDotNet.Jobs;
11+
using BenchmarkDotNet.Locators;
1112
using BenchmarkDotNet.Loggers;
1213
using BenchmarkDotNet.Order;
1314
using BenchmarkDotNet.Reports;
@@ -58,6 +59,7 @@ public abstract class DebugConfig : IConfig
5859
public IEnumerable<IValidator> GetValidators() => Array.Empty<IValidator>();
5960
public IEnumerable<IColumnProvider> GetColumnProviders() => DefaultColumnProviders.Instance;
6061
public IEnumerable<IExporter> GetExporters() => Array.Empty<IExporter>();
62+
public IEnumerable<IFileLocator> GetFileLocators() => Array.Empty<IFileLocator>();
6163
public IEnumerable<ILogger> GetLoggers() => new[] { ConsoleLogger.Default };
6264
public IEnumerable<IDiagnoser> GetDiagnosers() => Array.Empty<IDiagnoser>();
6365
public IEnumerable<IAnalyser> GetAnalysers() => Array.Empty<IAnalyser>();

src/BenchmarkDotNet/Configs/DefaultConfig.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using BenchmarkDotNet.Exporters.Csv;
1212
using BenchmarkDotNet.Filters;
1313
using BenchmarkDotNet.Jobs;
14+
using BenchmarkDotNet.Locators;
1415
using BenchmarkDotNet.Loggers;
1516
using BenchmarkDotNet.Order;
1617
using BenchmarkDotNet.Portability;
@@ -40,6 +41,8 @@ public IEnumerable<IExporter> GetExporters()
4041
yield return HtmlExporter.Default;
4142
}
4243

44+
public IEnumerable<IFileLocator> GetFileLocators() => Array.Empty<IFileLocator>();
45+
4346
public IEnumerable<ILogger> GetLoggers()
4447
{
4548
if (LinqPadLogger.IsAvailable)

src/BenchmarkDotNet/Configs/IConfig.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using BenchmarkDotNet.Exporters;
99
using BenchmarkDotNet.Filters;
1010
using BenchmarkDotNet.Jobs;
11+
using BenchmarkDotNet.Locators;
1112
using BenchmarkDotNet.Loggers;
1213
using BenchmarkDotNet.Order;
1314
using BenchmarkDotNet.Reports;
@@ -20,6 +21,7 @@ public interface IConfig
2021
{
2122
IEnumerable<IColumnProvider> GetColumnProviders();
2223
IEnumerable<IExporter> GetExporters();
24+
IEnumerable<IFileLocator> GetFileLocators();
2325
IEnumerable<ILogger> GetLoggers();
2426
IEnumerable<IDiagnoser> GetDiagnosers();
2527
IEnumerable<IAnalyser> GetAnalysers();

src/BenchmarkDotNet/Configs/ImmutableConfig.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Collections.Immutable;
44
using System.Globalization;
@@ -10,6 +10,7 @@
1010
using BenchmarkDotNet.Exporters;
1111
using BenchmarkDotNet.Filters;
1212
using BenchmarkDotNet.Jobs;
13+
using BenchmarkDotNet.Locators;
1314
using BenchmarkDotNet.Loggers;
1415
using BenchmarkDotNet.Order;
1516
using BenchmarkDotNet.Reports;
@@ -24,6 +25,7 @@ public sealed class ImmutableConfig : IConfig
2425
// if something is an array here instead of hashset it means it must have a guaranteed order of elements
2526
private readonly ImmutableArray<IColumnProvider> columnProviders;
2627
private readonly ImmutableArray<IExporter> exporters;
28+
private readonly ImmutableArray<IFileLocator> fileLocators;
2729
private readonly ImmutableHashSet<ILogger> loggers;
2830
private readonly ImmutableHashSet<IDiagnoser> diagnosers;
2931
private readonly ImmutableHashSet<IAnalyser> analysers;
@@ -41,6 +43,7 @@ internal ImmutableConfig(
4143
ImmutableHashSet<HardwareCounter> uniqueHardwareCounters,
4244
ImmutableHashSet<IDiagnoser> uniqueDiagnosers,
4345
ImmutableArray<IExporter> uniqueExporters,
46+
ImmutableArray<IFileLocator> uniqueFileLocators,
4447
ImmutableHashSet<IAnalyser> uniqueAnalyzers,
4548
ImmutableHashSet<IValidator> uniqueValidators,
4649
ImmutableHashSet<IFilter> uniqueFilters,
@@ -63,6 +66,7 @@ internal ImmutableConfig(
6366
hardwareCounters = uniqueHardwareCounters;
6467
diagnosers = uniqueDiagnosers;
6568
exporters = uniqueExporters;
69+
fileLocators = uniqueFileLocators;
6670
analysers = uniqueAnalyzers;
6771
validators = uniqueValidators;
6872
filters = uniqueFilters;
@@ -92,6 +96,7 @@ internal ImmutableConfig(
9296

9397
public IEnumerable<IColumnProvider> GetColumnProviders() => columnProviders;
9498
public IEnumerable<IExporter> GetExporters() => exporters;
99+
public IEnumerable<IFileLocator> GetFileLocators() => fileLocators;
95100
public IEnumerable<ILogger> GetLoggers() => loggers;
96101
public IEnumerable<IDiagnoser> GetDiagnosers() => diagnosers;
97102
public IEnumerable<IAnalyser> GetAnalysers() => analysers;

src/BenchmarkDotNet/Configs/ImmutableConfigBuilder.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Generic;
22
using System.Collections.Immutable;
33
using System.Linq;
44
using BenchmarkDotNet.Analysers;
@@ -44,6 +44,7 @@ public static ImmutableConfig Create(IConfig source)
4444
var uniqueHardwareCounters = source.GetHardwareCounters().Where(counter => counter != HardwareCounter.NotSet).ToImmutableHashSet();
4545
var uniqueDiagnosers = GetDiagnosers(source.GetDiagnosers(), uniqueHardwareCounters);
4646
var uniqueExporters = GetExporters(source.GetExporters(), uniqueDiagnosers, configAnalyse);
47+
var uniqueFileLocators = source.GetFileLocators().ToImmutableArray();
4748
var uniqueAnalyzers = GetAnalysers(source.GetAnalysers(), uniqueDiagnosers);
4849

4950
var uniqueValidators = GetValidators(source.GetValidators(), MandatoryValidators, source.Options);
@@ -61,6 +62,7 @@ public static ImmutableConfig Create(IConfig source)
6162
uniqueHardwareCounters,
6263
uniqueDiagnosers,
6364
uniqueExporters,
65+
uniqueFileLocators,
6466
uniqueAnalyzers,
6567
uniqueValidators,
6668
uniqueFilters,

src/BenchmarkDotNet/Configs/ManualConfig.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.ComponentModel;
44
using System.Globalization;
@@ -11,6 +11,7 @@
1111
using BenchmarkDotNet.Extensions;
1212
using BenchmarkDotNet.Filters;
1313
using BenchmarkDotNet.Jobs;
14+
using BenchmarkDotNet.Locators;
1415
using BenchmarkDotNet.Loggers;
1516
using BenchmarkDotNet.Order;
1617
using BenchmarkDotNet.Reports;
@@ -26,6 +27,7 @@ public class ManualConfig : IConfig
2627

2728
private readonly List<IColumnProvider> columnProviders = new List<IColumnProvider>();
2829
private readonly List<IExporter> exporters = new List<IExporter>();
30+
private readonly List<IFileLocator> locators = new List<IFileLocator>();
2931
private readonly List<ILogger> loggers = new List<ILogger>();
3032
private readonly List<IDiagnoser> diagnosers = new List<IDiagnoser>();
3133
private readonly List<IAnalyser> analysers = new List<IAnalyser>();
@@ -39,6 +41,7 @@ public class ManualConfig : IConfig
3941

4042
public IEnumerable<IColumnProvider> GetColumnProviders() => columnProviders;
4143
public IEnumerable<IExporter> GetExporters() => exporters;
44+
public IEnumerable<IFileLocator> GetFileLocators() => locators;
4245
public IEnumerable<ILogger> GetLoggers() => loggers;
4346
public IEnumerable<IDiagnoser> GetDiagnosers() => diagnosers;
4447
public IEnumerable<IAnalyser> GetAnalysers() => analysers;
@@ -139,6 +142,12 @@ public ManualConfig AddExporter(params IExporter[] newExporters)
139142
return this;
140143
}
141144

145+
public ManualConfig AddFileLocator(params IFileLocator[] newLocators)
146+
{
147+
locators.AddRange(newLocators);
148+
return this;
149+
}
150+
142151
[EditorBrowsable(EditorBrowsableState.Never)]
143152
[Obsolete("This method will soon be removed, please start using .AddLogger() instead.")]
144153
public void Add(params ILogger[] newLoggers) => AddLogger(newLoggers);
@@ -256,6 +265,7 @@ public void Add(IConfig config)
256265
{
257266
columnProviders.AddRange(config.GetColumnProviders());
258267
exporters.AddRange(config.GetExporters());
268+
locators.AddRange(config.GetFileLocators());
259269
loggers.AddRange(config.GetLoggers());
260270
diagnosers.AddRange(config.GetDiagnosers());
261271
analysers.AddRange(config.GetAnalysers());
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using BenchmarkDotNet.Loggers;
2+
using BenchmarkDotNet.Running;
3+
4+
namespace BenchmarkDotNet.Locators;
5+
6+
public class FileLocatorArgs
7+
{
8+
public FileLocatorArgs(BenchmarkCase benchmarkCase, ILogger logger)
9+
{
10+
BenchmarkCase = benchmarkCase;
11+
Logger = logger;
12+
}
13+
14+
public BenchmarkCase BenchmarkCase { get; }
15+
public ILogger Logger { get; }
16+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace BenchmarkDotNet.Locators;
2+
3+
public enum FileLocatorType
4+
{
5+
Project
6+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.IO;
2+
3+
namespace BenchmarkDotNet.Locators;
4+
5+
/// <summary>
6+
/// Locators can be used to extend the default behavior of finding files
7+
/// </summary>
8+
public interface IFileLocator
9+
{
10+
/// <summary>
11+
/// The type of locator
12+
/// </summary>
13+
FileLocatorType LocatorType { get; }
14+
15+
/// <summary>
16+
/// Tries to locate a file
17+
/// </summary>
18+
/// <param name="fileLocatorArgs">The arguments such as benchmark and logger</param>
19+
/// <param name="fileInfo">The file is provided by the implementation</param>
20+
/// <returns>True when a file was successfully found, False otherwise.</returns>
21+
bool TryLocate(FileLocatorArgs fileLocatorArgs, out FileInfo fileInfo);
22+
}

0 commit comments

Comments
 (0)