Skip to content

Commit 9a97844

Browse files
Add advanced log methods
1 parent e6c1349 commit 9a97844

Some content is hidden

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

58 files changed

+326
-152
lines changed

Build/Program.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,8 @@
267267
Info("Pushing NuGet packages was skipped.");
268268
}
269269

270-
Info($"Tool and package version: {packageVersion}");
271-
Info($"Template version: {packageVersion}");
272-
Info($"The coverage percentage: {coveragePercentage}");
270+
Summary("Package version: ".WithColor(Color.Header), packageVersion.ToString().WithColor(Color.Details));
271+
Summary("The coverage percentage: ".WithColor(Color.Header), coveragePercentage.ToString().WithColor(Color.Details));
273272

274273
return 0;
275274

CSharpInteractive.HostApi/Color.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace HostApi;
88
/// </code>
99
/// </example>
1010
/// </summary>
11-
/// <seealso cref="IHost.WriteLine"/>
11+
/// <seealso cref="IHost.WriteLine()"/>
1212
public enum Color
1313
{
1414
/// <summary>

CSharpInteractive.HostApi/IHost.cs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,18 @@ 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+
void WriteLine(params Text[] line);
78+
6779
/// <summary>
6880
/// Writes an error to stdErr. This error will affect the summary run statistics.
6981
/// <example>
@@ -77,6 +89,29 @@ public interface IHost
7789
/// <param name="errorId">Unique error identifier, optional.</param>
7890
void Error(string? error, string? errorId = null);
7991

92+
/// <summary>
93+
/// Writes an error to stdErr. This error will affect the summary run statistics.
94+
/// <example>
95+
/// <code>
96+
/// Error(new Text("Some "), new Text("error", Color.Error));
97+
/// </code>
98+
/// </example>
99+
/// </summary>
100+
/// <param name="error">Error message.</param>
101+
void Error(params Text[] error);
102+
103+
/// <summary>
104+
/// Writes an error to stdErr. This error will affect the summary run statistics.
105+
/// <example>
106+
/// <code>
107+
/// Error("ERR327", new Text("Some "), new Text("error", Color.Error));
108+
/// </code>
109+
/// </example>
110+
/// </summary>
111+
/// <param name="errorId">Unique error identifier, optional.</param>
112+
/// <param name="error">Error message.</param>
113+
void Error(string errorId, params Text[] error);
114+
80115
/// <summary>
81116
/// Writes a warning to stdOut. This warning will affect the summary run statistics.
82117
/// <example>
@@ -88,17 +123,39 @@ public interface IHost
88123
/// <param name="warning">Warning message.</param>
89124
void Warning(string? warning);
90125

126+
/// <summary>
127+
/// Writes a warning to stdOut. This warning will affect the summary run statistics.
128+
/// <example>
129+
/// <code>
130+
/// Warning(new Text("Some "), new Text("warning", Color.Warning));
131+
/// </code>
132+
/// </example>
133+
/// </summary>
134+
/// <param name="warning">Warning message.</param>
135+
void Warning(params Text[] warning);
136+
91137
/// <summary>
92138
/// Writes a summary message to stdOut.
93139
/// <example>
94140
/// <code>
95-
/// Info("Some info");
141+
/// Info("Some summary");
96142
/// </code>
97143
/// </example>
98144
/// </summary>
99145
/// <param name="summary">Summary message.</param>
100146
void Summary(string? summary);
101147

148+
/// <summary>
149+
/// Writes a summary message to stdOut.
150+
/// <example>
151+
/// <code>
152+
/// Summary(new Text("Some "), new Text("summary", Color.Highlighted));
153+
/// </code>
154+
/// </example>
155+
/// </summary>
156+
/// <param name="summary">Summary message.</param>
157+
void Summary(params Text[] summary);
158+
102159
/// <summary>
103160
/// Writes an information message to stdOut.
104161
/// <example>
@@ -110,6 +167,17 @@ public interface IHost
110167
/// <param name="text">Information message.</param>
111168
void Info(string? text);
112169

170+
/// <summary>
171+
/// Writes an information message to stdOut.
172+
/// <example>
173+
/// <code>
174+
/// Ingo(new Text("Some "), new Text("info", Color.Highlighted));
175+
/// </code>
176+
/// </example>
177+
/// </summary>
178+
/// <param name="text">Information message.</param>
179+
void Info(params Text[] text);
180+
113181
/// <summary>
114182
/// Writes a trace message to stdOut for the appropriate logging level.
115183
/// <example>

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
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

20+
/// <summary>
21+
/// Creates text with the default color.
22+
/// </summary>
23+
/// <param name="value">Text.</param>
1524
public Text(string value)
1625
// ReSharper disable once IntroduceOptionalParameters.Global
1726
: this(value, Color.Default)
@@ -57,4 +66,8 @@ public override string ToString()
5766
Array.Copy(text, 0, newText, 1, text.Length);
5867
return newText;
5968
}
69+
70+
public bool Equals(Text other) => Value == other.Value && Color == other.Color;
71+
72+
public override int GetHashCode() => Value.GetHashCode() ^ 33 + (int)Color;
6073
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace HostApi;
2+
3+
public static 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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,26 @@ 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(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+
78+
public void Error(string errorId, params Text[] error) => Composition.Shared.Root.Host.Error(errorId, error.WithDefaultColor(Color.Error));
79+
7480
public void Warning(string? warning) => Composition.Shared.Root.Host.Warning(warning);
7581

82+
public void Warning(params Text[] warning) => Composition.Shared.Root.Host.Warning(warning.WithDefaultColor(Color.Warning));
83+
7684
public void Summary(string? summary) => Composition.Shared.Root.Host.Summary(summary);
7785

86+
public void Summary(params Text[] summary) => Composition.Shared.Root.Host.Summary(summary.WithDefaultColor(Color.Highlighted));
87+
7888
public void Info(string? text) => Composition.Shared.Root.Host.Info(text);
7989

90+
public void Info(params Text[] text) => Composition.Shared.Root.Host.Info(text);
91+
8092
public void Trace(string? trace, string? origin = null) => Composition.Shared.Root.Host.Trace(trace, origin);
8193

8294
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.Tests/UsageScenarios/WriteLineWithColourScenario.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public void Run()
1717
// $description=Writing a line highlighted with "Header" color to a build log
1818
// {
1919
WriteLine("Hello", Header);
20+
WriteLine(new Text("Hello ", Header), new Text("world!", Details));
2021
// }
2122
}
2223
}

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)

0 commit comments

Comments
 (0)