Skip to content

Commit

Permalink
Add advanced log methods
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolayPianikov committed Feb 9, 2025
1 parent e6c1349 commit abf75f5
Show file tree
Hide file tree
Showing 75 changed files with 467 additions and 186 deletions.
11 changes: 4 additions & 7 deletions Build/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@
GetNextNuGetVersion(new NuGetRestoreSettings(packageId), defaultVersion)
}.Max()!;

Info(packageVersion.ToString());

const int minSdk = 6;
var maxSdk = minSdk;
new DotNet().WithVersion(true)
Expand All @@ -49,8 +47,8 @@
var frameworks = string.Join(";", allFrameworks);
var framework = $"net{maxSdk}.0";

Info($"frameworks: {frameworks}");
Info($"framework: {framework}");
Summary("Frameworks: ".WithColor(Color.Header), frameworks.WithColor(Color.Details));
Summary("Framework: ".WithColor(Color.Header), framework.WithColor(Color.Details));

var packages = new[]
{
Expand Down Expand Up @@ -267,9 +265,8 @@
Info("Pushing NuGet packages was skipped.");
}

Info($"Tool and package version: {packageVersion}");
Info($"Template version: {packageVersion}");
Info($"The coverage percentage: {coveragePercentage}");
Summary("Package version: ".WithColor(Color.Header), packageVersion.WithColor(Color.Details));
Summary("Coverage percentage: ".WithColor(Color.Header), coveragePercentage.WithColor(Color.Details));

return 0;

Expand Down
2 changes: 1 addition & 1 deletion CSharpInteractive.HostApi/Color.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace HostApi;
/// </code>
/// </example>
/// </summary>
/// <seealso cref="IHost.WriteLine"/>
/// <seealso cref="IHost.WriteLine()"/>
public enum Color
{
/// <summary>
Expand Down
88 changes: 87 additions & 1 deletion CSharpInteractive.HostApi/IHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ public interface IHost
/// <typeparam name="T">The type of the value to be converted to a line.</typeparam>
void WriteLine<T>(T line, Color color = Color.Default);

/// <summary>
/// Writes a line to stdOut.
/// <example>
/// <code>
/// WriteLine("Hello !");
/// WriteLine("Hello !!!", Color.Highlighted);
/// </code>
/// </example>
/// </summary>
/// <param name="line">Any value that will be converted to a line.</param>
void WriteLine(params Text[] line);

/// <summary>
/// Writes an error to stdErr. This error will affect the summary run statistics.
/// <example>
Expand All @@ -77,6 +89,29 @@ public interface IHost
/// <param name="errorId">Unique error identifier, optional.</param>
void Error(string? error, string? errorId = null);

/// <summary>
/// Writes an error to stdErr. This error will affect the summary run statistics.
/// <example>
/// <code>
/// Error(new Text("Some "), new Text("error", Color.Error));
/// </code>
/// </example>
/// </summary>
/// <param name="error">Error message.</param>
void Error(params Text[] error);

/// <summary>
/// Writes an error to stdErr. This error will affect the summary run statistics.
/// <example>
/// <code>
/// Error("ERR327", new Text("Some "), new Text("error", Color.Error));
/// </code>
/// </example>
/// </summary>
/// <param name="errorId">Unique error identifier, optional.</param>
/// <param name="error">Error message.</param>
void Error(string errorId, params Text[] error);

/// <summary>
/// Writes a warning to stdOut. This warning will affect the summary run statistics.
/// <example>
Expand All @@ -88,17 +123,39 @@ public interface IHost
/// <param name="warning">Warning message.</param>
void Warning(string? warning);

/// <summary>
/// Writes a warning to stdOut. This warning will affect the summary run statistics.
/// <example>
/// <code>
/// Warning(new Text("Some "), new Text("warning", Color.Warning));
/// </code>
/// </example>
/// </summary>
/// <param name="warning">Warning message.</param>
void Warning(params Text[] warning);

/// <summary>
/// Writes a summary message to stdOut.
/// <example>
/// <code>
/// Info("Some info");
/// Info("Some summary");
/// </code>
/// </example>
/// </summary>
/// <param name="summary">Summary message.</param>
void Summary(string? summary);

/// <summary>
/// Writes a summary message to stdOut.
/// <example>
/// <code>
/// Summary(new Text("Some "), new Text("summary", Color.Highlighted));
/// </code>
/// </example>
/// </summary>
/// <param name="summary">Summary message.</param>
void Summary(params Text[] summary);

/// <summary>
/// Writes an information message to stdOut.
/// <example>
Expand All @@ -110,6 +167,17 @@ public interface IHost
/// <param name="text">Information message.</param>
void Info(string? text);

/// <summary>
/// Writes an information message to stdOut.
/// <example>
/// <code>
/// Ingo(new Text("Some "), new Text("info", Color.Highlighted));
/// </code>
/// </example>
/// </summary>
/// <param name="text">Information message.</param>
void Info(params Text[] text);

/// <summary>
/// Writes a trace message to stdOut for the appropriate logging level.
/// <example>
Expand All @@ -129,6 +197,24 @@ public interface IHost
/// <param name="origin">Source of the trace message, optional.</param>
void Trace(string? trace, string? origin = null);

/// <summary>
/// Writes a trace message to stdOut for the appropriate logging level.
/// <example>
/// <code>
/// Trace(new Text("Trace message", Color.Details));
/// </code>
/// </example>
/// <example>
/// When run as a script:
/// <code>
/// #l Diagnostic
/// Trace("Tracing ", "details".WithColor(Color.Details));
/// </code>
/// </example>
/// </summary>
/// <param name="trace">Trace message.</param>
void Trace(params Text[] trace);

/// <summary>
/// Provides an instance of a service by its type.
/// <example>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
namespace CSharpInteractive.Core;
namespace HostApi;

using System.Text;
using HostApi;

/// <summary>
/// Represents text with a color.
/// </summary>
/// <param name="Value">Text.</param>
/// <param name="Color">Color of text.</param>
[ExcludeFromCodeCoverage]
internal readonly record struct Text(string Value, Color Color)
[Target]
public readonly record struct Text(string Value = "", Color Color = Color.Default)
{
// ReSharper disable once UnusedMember.Global
public static readonly Text Empty = new(string.Empty);
public static readonly Text NewLine = new(System.Environment.NewLine);
public static readonly Text NewLine = new(Environment.NewLine);
public static readonly Text Space = new(" ");
public static readonly Text Tab = new(" ");

/// <summary>
/// Creates text with the default color.
/// </summary>
/// <param name="value">Text.</param>
public Text(string value)
// ReSharper disable once IntroduceOptionalParameters.Global
: this(value, Color.Default)
{ }

public static implicit operator Text[](Text text) => [text];

public static implicit operator Text (string text) => new(text);

public override string ToString()
{
var sb = new StringBuilder();
Expand Down Expand Up @@ -57,4 +68,8 @@ public override string ToString()
Array.Copy(text, 0, newText, 1, text.Length);
return newText;
}

public bool Equals(Text other) => Value == other.Value && Color == other.Color;

public override int GetHashCode() => Value.GetHashCode() ^ 33 + (int)Color;
}
15 changes: 15 additions & 0 deletions CSharpInteractive.HostApi/TextExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace HostApi;

/// <summary>
/// Text extensions.
/// </summary>
public static partial class TextExtensions
{
/// <summary>
/// Converts an object to text with color.
/// </summary>
/// <param name="it">The object to convert.</param>
/// <param name="color">Text color.</param>
/// <returns></returns>
public static Text WithColor<T>(this T it, Color color = Color.Default) => new(it?.ToString() ?? "", color);
}
19 changes: 16 additions & 3 deletions CSharpInteractive.Tests/HostServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void ShouldSendError()
host.Error("Err", "Id");

// Then
_log.Verify(i => i.Error(new ErrorId("Id"), It.Is<Text[]>(text => text.Length == 1 && text[0].Value == "Err" && text[0].Color == Color.Error)));
_log.Verify(i => i.Error(new ErrorId("Id"), "Err"));
}

[Fact]
Expand All @@ -84,7 +84,20 @@ public void ShouldSendWarning()
host.Warning("Warn");

// Then
_log.Verify(i => i.Warning(It.Is<Text[]>(text => text.Length == 1 && text[0].Value == "Warn" && text[0].Color == Color.Warning)));
_log.Verify(i => i.Warning("Warn"));
}

[Fact]
public void ShouldSendSummary()
{
// Given
var host = CreateInstance();

// When
host.Summary("Summary message");

// Then
_log.Verify(i => i.Summary("Summary message"));
}

[Fact]
Expand All @@ -97,7 +110,7 @@ public void ShouldSendInfo()
host.Info("Info");

// Then
_log.Verify(i => i.Info(It.Is<Text[]>(text => text.Length == 1 && text[0].Value == "Info" && text[0].Color == Color.Default)));
_log.Verify(i => i.Info("Info"));
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion CSharpInteractive.Tests/ProcessOutputWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void ShouldWriteStdErr()
writer.Write(new Output(Mock.Of<IStartInfo>(), true, "Err", 11));

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

private ProcessOutputWriter CreateInstance() =>
Expand Down
4 changes: 2 additions & 2 deletions CSharpInteractive.Tests/ProgramTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public ProgramTests()
_active = new Mock<IActive>();
_active.Setup(i => i.Activate()).Returns(_activationToken.Object);
_statistics = new Mock<IStatistics>();
_statistics.SetupGet(i => i.Errors).Returns(Array.Empty<Text[]>());
_statistics.SetupGet(i => i.Items).Returns(Array.Empty<StatisticsItem>());
}

[Fact]
Expand Down Expand Up @@ -107,7 +107,7 @@ public void ShouldFailedWhenHasErrors()
var program = CreateInstance();

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

// Then
Expand Down
7 changes: 7 additions & 0 deletions CSharpInteractive.Tests/README_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ WriteLine("Hello");

``` CSharp
WriteLine("Hello", Header);
WriteLine("Hello ".WithColor(Header), "world!");
```

### Writing an empty line to a build log
Expand All @@ -128,31 +129,37 @@ WriteLine();
### Registering errors in the build log

``` CSharp
Error("Error info");
Error("Error info", "Error identifier");
Error("Error: ".WithColor(), "datails".WithColor(Color.Details));
```

### Registering warnings in the build log

``` CSharp
Warning("Warning info");
Warning("Warning ", "info".WithColor(Color.Details));
```

### Registering a summary in the build log

``` CSharp
Summary("Summary message");
Summary("Summary ", "message".WithColor(Color.Details));
```

### Registering information in the build log

``` CSharp
Info("Some info");
Info("Some ", "info".WithColor(Color.Details));
```

### Registering trace information in the build log

``` CSharp
Trace("Some trace info");
Trace("Some trace ", "info".WithColor(Color.Details));
```

## Arguments and parameters
Expand Down
5 changes: 2 additions & 3 deletions CSharpInteractive.Tests/ScriptRunnerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ internal void ShouldRun(CommandResult[] results, string[] errors, string[] warni
// Given
var runner = CreateInstance();
_commandsRunner.Setup(i => i.Run(It.IsAny<IEnumerable<ICommand>>())).Returns(results);
_statistics.SetupGet(i => i.Errors).Returns(errors.Select(i => new Text[] {new(i)}).ToArray);
_statistics.SetupGet(i => i.Warnings).Returns(warnings.Select(i => new Text[] {new(i)}).ToArray);
_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);

// When
var actualExitCode = runner.Run();
Expand Down Expand Up @@ -120,7 +119,7 @@ public void ShouldShowErrorWhenScriptIsUncompleted()
var runner = CreateInstance();
//_log.Setup(i => i.Error(ErrorId.UncompletedScript, It.IsAny<string>()));
_commandSource.Setup(i => i.GetCommands()).Returns([new ScriptCommand(string.Empty, string.Empty), new CodeCommand()]);
_statistics.Setup(i => i.Errors).Returns(new List<Text[]>());
_statistics.Setup(i => i.Items).Returns(new List<StatisticsItem>());
// ReSharper disable once ReturnValueOfPureMethodIsNotUsed
_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)]);

Expand Down
Loading

0 comments on commit abf75f5

Please sign in to comment.