Skip to content

Commit 4bb9903

Browse files
Add advanced log methods
1 parent e6c1349 commit 4bb9903

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+290
-146
lines changed

CSharpInteractive.HostApi/IHost.cs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,19 @@ public interface IHost
6464
/// <typeparam name="T">The type of the value to be converted to a line.</typeparam>
6565
void WriteLine<T>(T line, Color color = Color.Default);
6666

67+
/// <summary>
68+
/// Writes a line to stdOut.
69+
/// <example>
70+
/// <code>
71+
/// WriteLine("Hello !");
72+
/// WriteLine("Hello !!!", Color.Highlighted);
73+
/// </code>
74+
/// </example>
75+
/// </summary>
76+
/// <param name="line">Any value that will be converted to a line.</param>
77+
/// <typeparam name="T">The type of the value to be converted to a line.</typeparam>
78+
void WriteLine<T>(params Text[] line);
79+
6780
/// <summary>
6881
/// Writes an error to stdErr. This error will affect the summary run statistics.
6982
/// <example>
@@ -77,6 +90,17 @@ public interface IHost
7790
/// <param name="errorId">Unique error identifier, optional.</param>
7891
void Error(string? error, string? errorId = null);
7992

93+
/// <summary>
94+
/// Writes an error to stdErr. This error will affect the summary run statistics.
95+
/// <example>
96+
/// <code>
97+
/// Error(new Text("Some "), new Text("error", Color.Error));
98+
/// </code>
99+
/// </example>
100+
/// </summary>
101+
/// <param name="error">Error message.</param>
102+
void Error(params Text[] error);
103+
80104
/// <summary>
81105
/// Writes a warning to stdOut. This warning will affect the summary run statistics.
82106
/// <example>
@@ -88,17 +112,39 @@ public interface IHost
88112
/// <param name="warning">Warning message.</param>
89113
void Warning(string? warning);
90114

115+
/// <summary>
116+
/// Writes a warning to stdOut. This warning will affect the summary run statistics.
117+
/// <example>
118+
/// <code>
119+
/// Warning(new Text("Some "), new Text("warning", Color.Warning));
120+
/// </code>
121+
/// </example>
122+
/// </summary>
123+
/// <param name="warning">Warning message.</param>
124+
void Warning(params Text[] warning);
125+
91126
/// <summary>
92127
/// Writes a summary message to stdOut.
93128
/// <example>
94129
/// <code>
95-
/// Info("Some info");
130+
/// Info("Some summary");
96131
/// </code>
97132
/// </example>
98133
/// </summary>
99134
/// <param name="summary">Summary message.</param>
100135
void Summary(string? summary);
101136

137+
/// <summary>
138+
/// Writes a summary message to stdOut.
139+
/// <example>
140+
/// <code>
141+
/// Summary(new Text("Some "), new Text("summary", Color.Highlighted));
142+
/// </code>
143+
/// </example>
144+
/// </summary>
145+
/// <param name="summary">Summary message.</param>
146+
void Summary(params Text[] summary);
147+
102148
/// <summary>
103149
/// Writes an information message to stdOut.
104150
/// <example>
@@ -110,6 +156,17 @@ public interface IHost
110156
/// <param name="text">Information message.</param>
111157
void Info(string? text);
112158

159+
/// <summary>
160+
/// Writes an information message to stdOut.
161+
/// <example>
162+
/// <code>
163+
/// Ingo(new Text("Some "), new Text("info", Color.Highlighted));
164+
/// </code>
165+
/// </example>
166+
/// </summary>
167+
/// <param name="text">Information message.</param>
168+
void Info(params Text[] text);
169+
113170
/// <summary>
114171
/// Writes a trace message to stdOut for the appropriate logging level.
115172
/// <example>

CSharpInteractive/Core/Text.cs renamed to CSharpInteractive.HostApi/Text.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
namespace CSharpInteractive.Core;
1+
namespace HostApi;
22

33
using System.Text;
4-
using HostApi;
54

5+
/// <summary>
6+
/// Represents text with a color.
7+
/// </summary>
8+
/// <param name="Value">Text.</param>
9+
/// <param name="Color">Color of text.</param>
610
[ExcludeFromCodeCoverage]
7-
internal readonly record struct Text(string Value, Color Color)
11+
[Target]
12+
public readonly record struct Text(string Value = "", Color Color = Color.Default)
813
{
914
// ReSharper disable once UnusedMember.Global
1015
public static readonly Text Empty = new(string.Empty);
11-
public static readonly Text NewLine = new(System.Environment.NewLine);
16+
public static readonly Text NewLine = new(Environment.NewLine);
1217
public static readonly Text Space = new(" ");
1318
public static readonly Text Tab = new(" ");
1419

@@ -57,4 +62,8 @@ public override string ToString()
5762
Array.Copy(text, 0, newText, 1, text.Length);
5863
return newText;
5964
}
65+
66+
public bool Equals(Text other) => Value == other.Value && Color == other.Color;
67+
68+
public override int GetHashCode() => Value.GetHashCode() ^ 197 + (int)Color;
6069
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace HostApi;
2+
3+
public partial class TextExtensions
4+
{
5+
public static Text WithColor(this string text, Color color) => new(text, color);
6+
}

CSharpInteractive.Tests/ProcessOutputWriterTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void ShouldWriteStdErr()
3131
writer.Write(new Output(Mock.Of<IStartInfo>(), true, "Err", 11));
3232

3333
// Then
34-
_console.Verify(i => i.WriteToErr("Err", Environment.NewLine));
34+
_console.Verify(i => i.WriteToErr(new ValueTuple<ConsoleColor?, string>(null, "Err"), new ValueTuple<ConsoleColor?, string>(null, Environment.NewLine)));
3535
}
3636

3737
private ProcessOutputWriter CreateInstance() =>

CSharpInteractive.Tests/ProgramTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public ProgramTests()
3030
_active = new Mock<IActive>();
3131
_active.Setup(i => i.Activate()).Returns(_activationToken.Object);
3232
_statistics = new Mock<IStatistics>();
33-
_statistics.SetupGet(i => i.Errors).Returns(Array.Empty<Text[]>());
33+
_statistics.SetupGet(i => i.Items).Returns(Array.Empty<StatisticsItem>());
3434
}
3535

3636
[Fact]
@@ -107,7 +107,7 @@ public void ShouldFailedWhenHasErrors()
107107
var program = CreateInstance();
108108

109109
// When
110-
_statistics.SetupGet(i => i.Errors).Returns([new Text("some error")]);
110+
_statistics.SetupGet(i => i.Items).Returns([new StatisticsItem(StatisticsType.Error, new Text("some error"))]);
111111
var actualResult = program.Run();
112112

113113
// Then

CSharpInteractive.Tests/ScriptRunnerTests.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ internal void ShouldRun(CommandResult[] results, string[] errors, string[] warni
3030
// Given
3131
var runner = CreateInstance();
3232
_commandsRunner.Setup(i => i.Run(It.IsAny<IEnumerable<ICommand>>())).Returns(results);
33-
_statistics.SetupGet(i => i.Errors).Returns(errors.Select(i => new Text[] {new(i)}).ToArray);
34-
_statistics.SetupGet(i => i.Warnings).Returns(warnings.Select(i => new Text[] {new(i)}).ToArray);
33+
_statistics.SetupGet(i => i.Items).Returns(errors.Select(i => new StatisticsItem(StatisticsType.Error, [new Text(i)])).Concat(warnings.Select(i => new StatisticsItem(StatisticsType.Warning, [new Text(i)]))).ToArray);
3534

3635
// When
3736
var actualExitCode = runner.Run();
@@ -120,7 +119,7 @@ public void ShouldShowErrorWhenScriptIsUncompleted()
120119
var runner = CreateInstance();
121120
//_log.Setup(i => i.Error(ErrorId.UncompletedScript, It.IsAny<string>()));
122121
_commandSource.Setup(i => i.GetCommands()).Returns([new ScriptCommand(string.Empty, string.Empty), new CodeCommand()]);
123-
_statistics.Setup(i => i.Errors).Returns(new List<Text[]>());
122+
_statistics.Setup(i => i.Items).Returns(new List<StatisticsItem>());
124123
// ReSharper disable once ReturnValueOfPureMethodIsNotUsed
125124
_commandsRunner.Setup(i => i.Run(It.IsAny<IEnumerable<ICommand>>())).Callback<IEnumerable<ICommand>>(i => i.Count()).Returns([new CommandResult(new ScriptCommand(string.Empty, string.Empty), true)]);
126125

CSharpInteractive.Tests/StatisticsTests.cs

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,22 @@ public void ShouldTrackTimeElapsed()
1818
statistics.TimeElapsed.ShouldNotBe(TimeSpan.Zero);
1919
}
2020

21-
[Fact]
22-
public void ShouldRegisterError()
23-
{
24-
// Given
25-
var statistics = new Statistics();
26-
27-
// When
28-
statistics.RegisterError(new Text("error1"));
29-
statistics.RegisterError(Text.Empty);
30-
statistics.RegisterError(new Text(" "));
31-
statistics.RegisterError(new Text("error2"));
32-
33-
// Then
34-
statistics.Errors.ToArray().ShouldBe([new Text("error1"), new Text("error2")]);
35-
}
36-
37-
[Fact]
38-
public void ShouldRegisterWarning()
21+
[Theory]
22+
[InlineData(StatisticsType.Error)]
23+
[InlineData(StatisticsType.Warning)]
24+
[InlineData(StatisticsType.Summary)]
25+
internal void ShouldRegisterError(StatisticsType statisticsType)
3926
{
4027
// Given
4128
var statistics = new Statistics();
4229

4330
// When
44-
statistics.RegisterWarning(new Text("warning1"));
45-
statistics.RegisterWarning(Text.Empty);
46-
statistics.RegisterWarning(new Text(" "));
47-
statistics.RegisterWarning(new Text("warning2"));
31+
statistics.Register(statisticsType, new Text("Abc"));
32+
statistics.Register(statisticsType, Text.Empty);
33+
statistics.Register(statisticsType, new Text(" "));
34+
statistics.Register(statisticsType, new Text("Xyz"));
4835

4936
// Then
50-
statistics.Warnings.ToArray().ShouldBe([new Text("warning1"), new Text("warning2")]);
37+
statistics.Items.ShouldBe([new StatisticsItem(statisticsType, new Text("Abc")), new StatisticsItem(statisticsType, new Text("Xyz"))]);
5138
}
5239
}

CSharpInteractive.Tests/SummaryPresenterTests.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,20 @@ public void ShouldSummary(bool? success, bool hasError, bool hasWarning, string
2323
// Given
2424
var presenter = CreateInstance();
2525
_statistics.SetupGet(i => i.CommandLines).Returns(ArraySegment<CommandLineInfo>.Empty);
26+
var statisticsItems = new List<StatisticsItem>();
2627
if (hasError)
2728
{
28-
_statistics.SetupGet(i => i.Errors).Returns([new Text("Err")]);
29-
}
30-
else
31-
{
32-
_statistics.SetupGet(i => i.Errors).Returns([]);
29+
statisticsItems.Add(new StatisticsItem(StatisticsType.Error, new Text("Err")));
3330
}
3431

3532
if (hasWarning)
3633
{
37-
_statistics.SetupGet(i => i.Warnings).Returns([new Text("Warn")]);
38-
}
39-
else
40-
{
41-
_statistics.SetupGet(i => i.Warnings).Returns([]);
34+
statisticsItems.Add(new StatisticsItem(StatisticsType.Warning, new Text("Warn")));
4235
}
4336

44-
// When
37+
_statistics.SetupGet(i => i.Items).Returns(statisticsItems);
4538

39+
// When
4640
presenter.Show(new Summary(success));
4741

4842
// Then

CSharpInteractive.Tests/TeamCityLogTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ internal void ShouldSupportError(VerbosityLevel verbosityLevel)
3434

3535
// Then
3636
_teamCityWriter.Verify(i => i.WriteBuildProblem("id", "line1line2"));
37-
_statisticsRegistry.Verify(i => i.RegisterError(_text));
37+
_statisticsRegistry.Verify(i => i.Register(StatisticsType.Error, _text));
3838
}
3939

4040
[Theory]
@@ -52,7 +52,7 @@ internal void ShouldSupportWarning(VerbosityLevel verbosityLevel)
5252

5353
// Then
5454
_teamCityWriter.Verify(i => i.WriteWarning("line1line2"));
55-
_statisticsRegistry.Verify(i => i.RegisterWarning(_text));
55+
_statisticsRegistry.Verify(i => i.Register(StatisticsType.Warning, _text));
5656
}
5757

5858
[Theory]

CSharpInteractive.Tests/UsageScenarios/BaseScenario.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,24 @@ public bool HasSdk(string sdkVersion)
6969

7070
public void WriteLine<T>(T line, Color color = Color.Default) => Composition.Shared.Root.Host.WriteLine(line, color);
7171

72+
public void WriteLine<T>(params Text[] line) => Composition.Shared.Root.Host.WriteLine(line);
73+
7274
public void Error(string? error, string? errorId = null) => Composition.Shared.Root.Host.Error(error, errorId);
7375

76+
public void Error(params Text[] error) => Composition.Shared.Root.Host.Error(error.WithDefaultColor(Color.Error));
77+
7478
public void Warning(string? warning) => Composition.Shared.Root.Host.Warning(warning);
7579

80+
public void Warning(params Text[] warning) => Composition.Shared.Root.Host.Warning(warning.WithDefaultColor(Color.Warning));
81+
7682
public void Summary(string? summary) => Composition.Shared.Root.Host.Summary(summary);
7783

84+
public void Summary(params Text[] summary) => Composition.Shared.Root.Host.Summary(summary.WithDefaultColor(Color.Highlighted));
85+
7886
public void Info(string? text) => Composition.Shared.Root.Host.Info(text);
7987

88+
public void Info(params Text[] text) => Composition.Shared.Root.Host.Info(text);
89+
8090
public void Trace(string? trace, string? origin = null) => Composition.Shared.Root.Host.Trace(trace, origin);
8191

8292
private class Properties : IProperties

CSharpInteractive.Tests/UsageScenarios/LogErrorScenario.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public void Run()
1818
// $description=Registering errors in the build log
1919
// {
2020
Error("Error info", "Error identifier");
21+
Error(new Text("Error: "), new Text("datails").WithColor(Color.Details));
2122
// }
2223
}
2324
}

CSharpInteractive/Core/AddNuGetReferenceCommandFactory.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace CSharpInteractive.Core;
44

55
using System.Text.RegularExpressions;
6+
using HostApi;
67
using NuGet.Versioning;
78

89
[SuppressMessage("Performance", "SYSLIB1045:Convert to \'GeneratedRegexAttribute\'.")]

CSharpInteractive/Core/AssembliesScriptOptionsProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace CSharpInteractive.Core;
55

66
using System.Net.Http;
77
using System.Reflection;
8+
using HostApi;
89
using Microsoft.CodeAnalysis.Scripting;
910
using Microsoft.Extensions.DependencyInjection;
1011

CSharpInteractive/Core/CSharpScriptRunner.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace CSharpInteractive.Core;
44

55
using System.Diagnostics;
6+
using HostApi;
67
using Microsoft.CodeAnalysis.CSharp.Scripting;
78
using Microsoft.CodeAnalysis.Scripting;
89

CSharpInteractive/Core/Cleaner.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace CSharpInteractive.Core;
44

5+
using HostApi;
6+
57
internal class Cleaner(ILog<Cleaner> log, IFileSystem fileSystem) : ICleaner
68
{
79
public IDisposable Track(string path)

CSharpInteractive/Core/CodeSourceCommandFactory.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace CSharpInteractive.Core;
55

66
using System.Text;
7+
using HostApi;
78

89
internal class CodeSourceCommandFactory : ICommandFactory<ICodeSource>
910
{

CSharpInteractive/Core/Console.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,21 @@ public void WriteToOut(params (ConsoleColor? color, string output)[] text)
4141
}
4242
}
4343

44-
public void WriteToErr(params string[] text)
44+
public void WriteToErr(params (ConsoleColor? color, string output)[] text)
4545
{
4646
lock (_lockObject)
4747
{
4848
var foregroundColor = System.Console.ForegroundColor;
4949
try
5050
{
51-
System.Console.ForegroundColor = _errorColor;
52-
foreach (var error in text)
51+
foreach (var (color, error) in text)
5352
{
53+
System.Console.ForegroundColor = _errorColor;
54+
if (color.HasValue)
55+
{
56+
System.Console.ForegroundColor = color.Value;
57+
}
58+
5459
if (ErrorHandler is { } errorHandler)
5560
{
5661
errorHandler(this, error);

CSharpInteractive/Core/ConsoleInOut.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
namespace CSharpInteractive.Core;
22

3+
using HostApi;
4+
35
// ReSharper disable once ClassNeverInstantiated.Global
46
[ExcludeFromCodeCoverage]
57
internal class ConsoleInOut(
@@ -13,5 +15,5 @@ internal class ConsoleInOut(
1315

1416
void IStdOut.WriteLine(params Text[] line) => Write(line + Text.NewLine);
1517

16-
private void WriteStdErr(params Text[] text) => console.WriteToErr(text.Select(i => i.Value).ToArray());
18+
private void WriteStdErr(params Text[] text) => console.WriteToErr(text.SelectMany(i => textToColorStrings.Convert(i.Value, colorTheme.GetConsoleColor(i.Color))).ToArray());
1719
}

0 commit comments

Comments
 (0)