Skip to content

Commit 956d44c

Browse files
committed
chore: refactor codes that write clickable link
1 parent 82e72e0 commit 956d44c

5 files changed

Lines changed: 68 additions & 45 deletions

File tree

src/BenchmarkDotNet/Helpers/ConsoleHelper.cs

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,51 +17,29 @@ internal static class ConsoleHelper
1717
private const string ST = ESC + @"\"; // String Terminator
1818

1919
/// <summary>
20-
/// Write clickable link to console.
21-
/// If console doesn't support OSC 8 hyperlinks. It writes plain link.
20+
/// Try to gets clickable link text for console.
21+
/// If console doesn't support clickable link, it returns false.
2222
/// </summary>
23-
public static void WriteLineAsClickableLink(ILogger consoleLogger, string link, string? linkCaption = null, LogKind logKind = LogKind.Info, string prefixText = "", string suffixText = "")
23+
public static bool TryGetClickableLink(string link, string? linkCaption, out string result)
2424
{
25-
if (prefixText != "")
26-
consoleLogger.Write(logKind, prefixText);
27-
28-
WriteAsClickableLink(consoleLogger, link, linkCaption, logKind);
29-
30-
// On Windows Terminal environment.
31-
// It need to write extra space to avoid link style corrupted issue that occurred when window resized.
32-
if (IsWindowsTerminal.Value && IsClickableLinkSupported.Value && suffixText == "")
33-
suffixText = " ";
34-
35-
if (suffixText != "")
36-
consoleLogger.Write(logKind, suffixText);
37-
38-
consoleLogger.WriteLine();
39-
}
40-
41-
/// <summary>
42-
/// Write clickable link to console.
43-
/// If console doesn't support OSC 8 hyperlinks. It writes plain link.
44-
/// </summary>
45-
public static void WriteAsClickableLink(ILogger consoleLogger, string link, string? linkCaption = null, LogKind logKind = LogKind.Info)
46-
{
47-
if (consoleLogger.Id != nameof(ConsoleLogger))
48-
throw new NotSupportedException("This method is expected logger that has ConsoleLogger id.");
49-
50-
// If clickable link supported. Write clickable link with OSC8.
51-
if (IsClickableLinkSupported.Value)
25+
if (!IsClickableLinkSupported)
5226
{
53-
consoleLogger.Write(logKind, @$"{OSC8}{link}{ST}{linkCaption ?? link}{OSC8}{ST}");
54-
return;
27+
result = "";
28+
return false;
5529
}
5630

57-
// Write link as plain text. (linkCaption is ignored)
58-
consoleLogger.Write(logKind, link);
31+
result = @$"{OSC8}{link}{ST}{linkCaption ?? link}{OSC8}{ST}";
32+
return true;
5933
}
6034

61-
private static readonly Lazy<bool> IsWindowsTerminal = new(()
35+
public static bool IsWindowsTerminal => _isWindowsTerminal.Value;
36+
37+
public static bool IsClickableLinkSupported => _isClickableLinkSupported.Value;
38+
39+
private static readonly Lazy<bool> _isWindowsTerminal = new(()
6240
=> Environment.GetEnvironmentVariable("WT_SESSION") != null);
6341

64-
private static readonly Lazy<bool> IsClickableLinkSupported = new(() =>
42+
private static readonly Lazy<bool> _isClickableLinkSupported = new(() =>
6543
{
6644
if (Console.IsOutputRedirected)
6745
return false;
@@ -114,7 +92,6 @@ public static void WriteAsClickableLink(ILogger consoleLogger, string link, stri
11492
[SupportedOSPlatform("windows")]
11593
private static bool IsVirtualTerminalProcessingEnabled()
11694
{
117-
// Try to get Virtual Terminal Processing enebled or not.
11895
const uint STD_OUTPUT_HANDLE = unchecked((uint)-11);
11996
IntPtr handle = NativeMethods.GetStdHandle(STD_OUTPUT_HANDLE);
12097
if (handle == IntPtr.Zero)

src/BenchmarkDotNet/Loggers/CompositeLogger.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,9 @@ public void Flush()
6262
}
6363
}
6464

65-
/// <summary>
66-
/// Try to gets logger that has id of ConsoleLogger.
67-
/// </summary>
68-
public bool TryGetConsoleLogger([NotNullWhen(true)] out ILogger? consoleLogger)
65+
public bool TryGetConsoleLogger([NotNullWhen(true)] out IConsoleLogger? consoleLogger)
6966
{
70-
consoleLogger = loggers.FirstOrDefault(x => x.Id == nameof(ConsoleLogger));
67+
consoleLogger = loggers.OfType<IConsoleLogger>().SingleOrDefault();
7168
return consoleLogger != null;
7269
}
7370
}

src/BenchmarkDotNet/Loggers/ConsoleLogger.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace BenchmarkDotNet.Loggers
1111
{
12-
public sealed class ConsoleLogger : ILogger
12+
public sealed class ConsoleLogger : ILogger, IConsoleLogger
1313
{
1414
private const ConsoleColor DefaultColor = ConsoleColor.Gray;
1515

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using BenchmarkDotNet.Helpers;
2+
using System.Text;
3+
4+
namespace BenchmarkDotNet.Loggers;
5+
6+
/// <summary>
7+
/// Marker interface for logger that support clickable link with ANSI escape sequence.
8+
/// </summary>
9+
internal interface IConsoleLogger : ILogger
10+
{
11+
}
12+
13+
/// <summary>
14+
/// ExtensionMethods for IConsoleLogger interface.
15+
/// </summary>
16+
internal static class IConsoleLoggerExtensions
17+
{
18+
/// <summary>
19+
/// Write clickable link to console.
20+
/// If console doesn't support clickable link. It writes plain link.
21+
/// </summary>
22+
public static void WriteLineLink(this IConsoleLogger logger, string link, string? linkCaption = null, LogKind logKind = LogKind.Info, string prefixText = "", string suffixText = "")
23+
{
24+
var sb = new StringBuilder();
25+
26+
if (prefixText != "")
27+
sb.Append(prefixText);
28+
29+
if (ConsoleHelper.TryGetClickableLink(link, linkCaption, out var linkText))
30+
{
31+
sb.Append(linkText);
32+
33+
// Temporary workaround for Windows Terminal.
34+
// To avoid link style corruption issue when output ends with a clickable link and window is resized.
35+
if (ConsoleHelper.IsWindowsTerminal && suffixText == "")
36+
sb.Append(' ');
37+
}
38+
else
39+
{
40+
sb.Append(link); // Write plain link.
41+
}
42+
43+
if (suffixText != "")
44+
sb.Append(suffixText);
45+
46+
logger.WriteLine(logKind, sb.ToString());
47+
}
48+
}

src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,9 @@ internal static Summary[] Run(BenchmarkRunInfo[] benchmarkRunInfos)
202202

203203
consoleLogger.WriteLine();
204204
consoleLogger.WriteLineHeader("// * Benchmark LogFile *");
205-
ConsoleHelper.WriteLineAsClickableLink(consoleLogger, artifactDirectoryFullPath);
206-
ConsoleHelper.WriteLineAsClickableLink(consoleLogger, logFileFullPath, linkCaption: logFileRelativePath, prefixText: " ");
205+
consoleLogger.WriteLineLink(artifactDirectoryFullPath);
206+
consoleLogger.WriteLineLink(logFileFullPath, linkCaption: logFileRelativePath, prefixText: " ");
207+
consoleLogger.Flush();
207208
}
208209

209210
eventProcessor.OnEndRunStage();

0 commit comments

Comments
 (0)