diff --git a/Versions.props b/Versions.props
index 50d24fc6..4cf15ae8 100644
--- a/Versions.props
+++ b/Versions.props
@@ -8,7 +8,7 @@
3.6.133
5.0.0
1.0.0-alpha.160
- 2.5.0-pre.26
+ 2.5.0-pre.32
diff --git a/src/xunit.runner.visualstudio/Utility/AssemblyExtensions.cs b/src/xunit.runner.visualstudio/Utility/AssemblyExtensions.cs
index 7d92079e..5cf731d4 100644
--- a/src/xunit.runner.visualstudio/Utility/AssemblyExtensions.cs
+++ b/src/xunit.runner.visualstudio/Utility/AssemblyExtensions.cs
@@ -1,5 +1,3 @@
-#if NETFRAMEWORK
-
using System;
using System.IO;
using System.Reflection;
@@ -8,6 +6,7 @@ internal static class AssemblyExtensions
{
public static string? GetLocalCodeBase(this Assembly assembly)
{
+#if NETFRAMEWORK
string? codeBase = assembly.CodeBase;
if (codeBase == null)
return null;
@@ -20,7 +19,9 @@ internal static class AssemblyExtensions
return "/" + codeBase;
return codeBase.Replace('/', Path.DirectorySeparatorChar);
+#else
+ return assembly.Location;
+#endif
}
}
-#endif
diff --git a/src/xunit.runner.visualstudio/VsTestRunner.cs b/src/xunit.runner.visualstudio/VsTestRunner.cs
index 7d970109..9a77c961 100644
--- a/src/xunit.runner.visualstudio/VsTestRunner.cs
+++ b/src/xunit.runner.visualstudio/VsTestRunner.cs
@@ -4,7 +4,6 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
@@ -608,19 +607,19 @@ void handler()
}
public static IRunnerReporter GetRunnerReporter(
- LoggerHelper logger,
+ LoggerHelper? logger,
RunSettings runSettings,
IReadOnlyList assemblyFileNames)
{
var reporter = default(IRunnerReporter);
- var availableReporters = new Lazy>(() => GetAvailableRunnerReporters(assemblyFileNames));
+ var availableReporters = new Lazy>(() => GetAvailableRunnerReporters(logger, assemblyFileNames));
try
{
if (!string.IsNullOrEmpty(runSettings.ReporterSwitch))
{
reporter = availableReporters.Value.FirstOrDefault(r => string.Equals(r.RunnerSwitch, runSettings.ReporterSwitch, StringComparison.OrdinalIgnoreCase));
- if (reporter is null)
+ if (reporter is null && logger is not null)
logger.LogWarning("Could not find requested reporter '{0}'", runSettings.ReporterSwitch);
}
@@ -632,119 +631,30 @@ public static IRunnerReporter GetRunnerReporter(
return reporter ?? new DefaultRunnerReporterWithTypes();
}
- static IReadOnlyList GetAvailableRunnerReporters(IReadOnlyList sources)
+ public static IReadOnlyList GetAvailableRunnerReporters(
+ LoggerHelper? logger,
+ IReadOnlyList sources)
{
-#if NETCOREAPP
- // Combine all input libs and merge their contexts to find the potential reporters
var result = new List();
- var dcjr = new DependencyContextJsonReader();
- var deps =
- sources
- .Select(Path.GetFullPath)
- .Select(s => s.Replace(".dll", ".deps.json"))
- .Where(File.Exists)
- .Select(f => new MemoryStream(Encoding.UTF8.GetBytes(File.ReadAllText(f))))
- .Select(dcjr.Read);
- var ctx = deps.Aggregate(DependencyContext.Default, (context, dependencyContext) => context.Merge(dependencyContext));
- dcjr.Dispose();
-
- var depsAssms = ctx.GetRuntimeAssemblyNames(InternalRuntimeEnvironment.GetRuntimeIdentifier()).ToList();
-
- // Make sure to also check assemblies within the directory of the sources
- var dllsInSources =
+
+ // We need to combine the source folders with our folder to find all potential runners
+ var folders =
sources
- .Select(Path.GetFullPath)
- .Select(Path.GetDirectoryName)
- .Distinct(StringComparer.OrdinalIgnoreCase)
+ .Select(s => Path.GetDirectoryName(Path.GetFullPath(s)))
.WhereNotNull()
- .SelectMany(p => Directory.GetFiles(p, "*.dll").Select(f => Path.Combine(p, f)))
- .Select(f => new AssemblyName { Name = Path.GetFileNameWithoutExtension(f) })
- .ToList();
+ .Concat(new[] { Path.GetDirectoryName(typeof(VsTestRunner).Assembly.GetLocalCodeBase()) })
+ .Distinct();
- foreach (var assemblyName in depsAssms.Concat(dllsInSources))
+ foreach (var folder in folders)
{
- try
- {
- var assembly = Assembly.Load(assemblyName);
- foreach (var type in assembly.DefinedTypes)
- {
-#pragma warning disable CS0618
- if (type == null || type.IsAbstract || type == typeof(DefaultRunnerReporter).GetTypeInfo() || type == typeof(DefaultRunnerReporterWithTypes).GetTypeInfo() || type.ImplementedInterfaces.All(i => i != typeof(IRunnerReporter)))
- continue;
-#pragma warning restore CS0618
-
- var ctor = type.DeclaredConstructors.FirstOrDefault(c => c.GetParameters().Length == 0);
- if (ctor == null)
- {
- ConsoleHelper.SetForegroundColor(ConsoleColor.Yellow);
- Console.WriteLine($"Type {type.FullName} in assembly {assembly} appears to be a runner reporter, but does not have an empty constructor.");
- ConsoleHelper.ResetColor();
- continue;
- }
+ result.AddRange(RunnerReporterUtility.GetAvailableRunnerReporters(folder, out var messages));
- result.Add((IRunnerReporter)ctor.Invoke(Array.Empty