| File: Reporter.cs | Web Access |
| Project: src\sdk\src\Cli\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj (Microsoft.DotNet.Cli.Utils) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace Microsoft.DotNet.Cli.Utils; // Simple console manager public class Reporter : IReporter { private static SpinLock s_spinlock = new(); //cannot use auto properties, as those are static #pragma warning disable IDE0032 // Use auto property private static readonly Reporter s_consoleOutReporter = new(AnsiConsole.GetOutput()); private static readonly Reporter s_consoleErrReporter = new(AnsiConsole.GetError()); #pragma warning restore IDE0032 // Use auto property private static IReporter s_errorReporter = s_consoleErrReporter; private static IReporter s_outputReporter = s_consoleOutReporter; private static IReporter s_verboseReporter = s_consoleOutReporter; private readonly AnsiConsole? _console; static Reporter() { Reset(); } private Reporter(AnsiConsole? console) { _console = console; } public static Reporter NullReporter { get; } = new(console: null); public static Reporter ConsoleOutReporter => s_consoleOutReporter; public static Reporter ConsoleErrReporter => s_consoleErrReporter; public static IReporter Output { get; private set; } = NullReporter; public static IReporter Error { get; private set; } = NullReporter; public static IReporter Verbose { get; private set; } = NullReporter; /// <summary> /// Resets the reporters to write to the current reporters based on <see cref="CommandLoggingContext"/> settings. /// </summary> public static void Reset() { UseSpinLock(() => { ResetOutput(); ResetError(); ResetVerbose(); }); } /// <summary> /// Sets the output reporter to <paramref name="reporter"/>. /// The reporter won't be applied if disabled in <see cref="CommandLoggingContext"/>. /// </summary> /// <param name="reporter"></param> public static void SetOutput(IReporter reporter) { UseSpinLock(() => { s_outputReporter = reporter; ResetOutput(); }); } /// <summary> /// Sets the error reporter to <paramref name="reporter"/>. /// The reporter won't be applied if disabled in <see cref="CommandLoggingContext"/>. /// </summary> public static void SetError(IReporter reporter) { UseSpinLock(() => { s_errorReporter = reporter; ResetError(); }); } /// <summary> /// Sets the verbose reporter to <paramref name="reporter"/>. /// The reporter won't be applied if disabled in <see cref="CommandLoggingContext"/>. /// </summary> public static void SetVerbose(IReporter reporter) { UseSpinLock(() => { s_verboseReporter = reporter; ResetVerbose(); }); } private static void ResetOutput() { Output = CommandLoggingContext.OutputEnabled ? s_outputReporter : NullReporter; } private static void ResetError() { Error = CommandLoggingContext.ErrorEnabled ? s_errorReporter : NullReporter; } private static void ResetVerbose() { Verbose = CommandLoggingContext.IsVerbose ? (CommandLoggingContext.IsVerboseToStdErr && ReferenceEquals(s_verboseReporter, s_consoleOutReporter) ? s_consoleErrReporter : s_verboseReporter) : NullReporter; } public void WriteLine(string message) { UseSpinLock(() => { if (CommandLoggingContext.ShouldPassAnsiCodesThrough) { _console?.Writer?.WriteLine(message); } else { _console?.WriteLine(message); } }); } public void WriteLine() { UseSpinLock(() => _console?.Writer?.WriteLine()); } public void Write(string message) { UseSpinLock(() => { if (CommandLoggingContext.ShouldPassAnsiCodesThrough) { _console?.Writer?.Write(message); } else { _console?.Write(message); } }); } public void WriteLine(string format, params object?[] args) => WriteLine(string.Format(format, args)); public static void UseSpinLock(Action action) { bool lockTaken = false; try { s_spinlock.Enter(ref lockTaken); action(); } finally { if (lockTaken) { s_spinlock.Exit(false); } } } }