Skip to content

Commit d8f383e

Browse files
committed
status reporting
1 parent c1e5602 commit d8f383e

File tree

63 files changed

+594
-453
lines changed

Some content is hidden

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

63 files changed

+594
-453
lines changed

src/ModVerify.CliApp/ModSelectors/ConsoleModSelector.cs

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ private static IPhysicalPlayableObject SelectPlayableObject(GameFinderResult fin
2828
var game = finderResult.Game;
2929
list.Add(finderResult.Game);
3030

31+
Console.WriteLine();
3132
Console.WriteLine("=================");
3233
Console.WriteLine();
3334
Console.WriteLine($"0: {game.Name}");

src/ModVerify.CliApp/ModSelectors/SettingsBasedModSelector.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace AET.ModVerifyTool.ModSelectors;
88

99
internal class SettingsBasedModSelector(IServiceProvider serviceProvider)
1010
{
11-
public VerifyGameInstallationData CreateInstallationDataFromSettings(GameInstallationsSettings settings)
11+
public VerifyInstallationInformation CreateInstallationDataFromSettings(GameInstallationsSettings settings)
1212
{
1313
var gameLocations = new ModSelectorFactory(serviceProvider)
1414
.CreateSelector(settings)
@@ -20,7 +20,7 @@ public VerifyGameInstallationData CreateInstallationDataFromSettings(GameInstall
2020
if (engineType is null)
2121
throw new InvalidOperationException("Engine type not specified.");
2222

23-
return new VerifyGameInstallationData
23+
return new VerifyInstallationInformation
2424
{
2525
EngineType = engineType.Value,
2626
GameLocations = gameLocations,

src/ModVerify.CliApp/ModVerify.CliApp.csproj

+1-5
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414
<PackageTags>alamo,petroglyph,glyphx</PackageTags>
1515
</PropertyGroup>
1616

17-
<PropertyGroup>
18-
<GenerateDocumentationFile>true</GenerateDocumentationFile>
19-
<InheritDocEnabled>true</InheritDocEnabled>
20-
</PropertyGroup>
21-
2217
<ItemGroup>
2318
<PackageReference Include="AlamoEngineTools.PG.StarWarsGame.Infrastructure" Version="4.0.35" />
2419
<PackageReference Include="AlamoEngineTools.PG.StarWarsGame.Infrastructure.Steam" Version="4.0.35" />
@@ -50,6 +45,7 @@
5045
<PrivateAssets>all</PrivateAssets>
5146
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
5247
</PackageReference>
48+
<PackageReference Include="ShellProgressBar" Version="5.2.0" />
5349
</ItemGroup>
5450

5551
<ItemGroup>

src/ModVerify.CliApp/ModVerifyApp.cs

+59-25
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
using System.IO;
1010
using System.IO.Abstractions;
1111
using System.Linq;
12+
using System.Threading;
1213
using System.Threading.Tasks;
1314
using AET.ModVerify.Pipeline;
14-
using AnakinRaW.CommonUtilities.SimplePipeline.Progress;
15+
using AET.ModVerifyTool.Reporting;
16+
using PG.StarWarsGame.Engine;
1517

1618
namespace AET.ModVerifyTool;
1719

@@ -48,20 +50,68 @@ public async Task<int> RunApplication()
4850
return 0;
4951
}
5052

51-
private async Task<IReadOnlyCollection<VerificationError>> Verify(VerifyGameInstallationData installData)
53+
private async Task<IReadOnlyCollection<VerificationError>> Verify(VerifyInstallationInformation installInformation)
5254
{
55+
var gameEngineService = services.GetRequiredService<IPetroglyphStarWarsGameEngineService>();
56+
var engineErrorReporter = new ConcurrentGameEngineErrorReporter();
57+
58+
IStarWarsGameEngine gameEngine;
59+
60+
try
61+
{
62+
var initProgress = new Progress<string>();
63+
var initProgressReporter = new EngineInitializeProgressReporter(initProgress);
64+
65+
try
66+
{
67+
_logger?.LogInformation($"Creating Game Engine '{installInformation.EngineType}'");
68+
gameEngine = await gameEngineService.InitializeAsync(
69+
installInformation.EngineType,
70+
installInformation.GameLocations,
71+
engineErrorReporter,
72+
initProgress,
73+
false,
74+
CancellationToken.None).ConfigureAwait(false);
75+
_logger?.LogInformation($"Game Engine created");
76+
}
77+
finally
78+
{
79+
initProgressReporter.Dispose();
80+
}
81+
}
82+
catch (Exception e)
83+
{
84+
_logger?.LogError(e, $"Creating game engine failed: {e.Message}");
85+
throw;
86+
}
87+
88+
var progressReporter = new VerifyConsoleProgressReporter(installInformation.Name);
89+
5390
using var verifyPipeline = new GameVerifyPipeline(
54-
installData.EngineType,
55-
installData.GameLocations,
91+
gameEngine,
92+
engineErrorReporter,
5693
settings.VerifyPipelineSettings,
5794
settings.GlobalReportSettings,
58-
new VerifyConsoleProgressReporter(),
95+
progressReporter,
5996
services);
6097

6198
try
6299
{
63-
_logger?.LogInformation($"Verifying '{installData.Name}'...");
64-
await verifyPipeline.RunAsync().ConfigureAwait(false);
100+
try
101+
{
102+
_logger?.LogInformation($"Verifying '{installInformation.Name}'...");
103+
await verifyPipeline.RunAsync().ConfigureAwait(false);
104+
progressReporter.Report(string.Empty, 1.0);
105+
}
106+
catch
107+
{
108+
progressReporter.ReportError("Verification failed", null);
109+
throw;
110+
}
111+
finally
112+
{
113+
progressReporter.Dispose();
114+
}
65115
}
66116
catch (OperationCanceledException)
67117
{
@@ -72,11 +122,8 @@ private async Task<IReadOnlyCollection<VerificationError>> Verify(VerifyGameInst
72122
_logger?.LogError(e, $"Verification failed: {e.Message}");
73123
throw;
74124
}
75-
finally
76-
{
77-
_logger?.LogInformation("Finished verification");
78-
}
79125

126+
_logger?.LogInformation("Finished verification");
80127
return verifyPipeline.FilteredErrors;
81128
}
82129

@@ -91,8 +138,7 @@ private async Task ReportErrors(IReadOnlyCollection<VerificationError> errors)
91138
if (errors.Any(x => x.Severity >= settings.AppThrowsOnMinimumSeverity))
92139
throw new GameVerificationException(errors);
93140
}
94-
95-
141+
96142
private async Task WriteBaseline(IEnumerable<VerificationError> errors, string baselineFile)
97143
{
98144
var baseline = new VerificationBaseline(settings.GlobalReportSettings.MinimumReportSeverity, errors);
@@ -106,16 +152,4 @@ private async Task WriteBaseline(IEnumerable<VerificationError> errors, string b
106152
using var fs = _fileSystem.FileStream.New(fullPath, FileMode.Create, FileAccess.Write, FileShare.None);
107153
await baseline.ToJsonAsync(fs);
108154
}
109-
}
110-
111-
public class VerifyConsoleProgressReporter : IVerifyProgressReporter
112-
{
113-
public void Report(string progressText, double progress, ProgressType type, VerifyProgressInfo detailedProgress)
114-
{
115-
if (type != VerifyProgress.ProgressType)
116-
return;
117-
118-
119-
Console.WriteLine(progressText);
120-
}
121155
}

src/ModVerify.CliApp/Options/CommandLine/BaseModVerifyOptions.cs

+5
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,9 @@ internal abstract class BaseModVerifyOptions
5151
HelpText = "Additional fallback paths, which may contain assets that shall be included when doing the verification. Do not add EaW here. " +
5252
"Multiple paths can be separated using the ';' (semicolon) character.")]
5353
public IList<string>? AdditionalFallbackPath { get; set; }
54+
55+
[Option("sequential", Default = false,
56+
HelpText = "When set, game verifiers will run sequentially and not in parallel. " +
57+
"This increases analysis duration but may help in debugging sessions.")]
58+
public bool Sequential { get; set; }
5459
}

src/ModVerify.CliApp/Program.cs

+30-18
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ internal class Program
4545
private const string GameInfrastructureNamespace = "PG.StarWarsGame.Infrastructure";
4646
private static readonly string GameVerifierStepNamespace = typeof(GameVerifierPipelineStep).FullName!;
4747

48+
private static readonly string ModVerifyRootNameSpace = typeof(Program).Namespace!;
49+
4850
private static async Task<int> Main(string[] args)
4951
{
5052
PrintHeader();
@@ -194,29 +196,39 @@ private static void ConfigureLogging(ILoggingBuilder loggingBuilder, IFileSystem
194196
loggingBuilder.AddSerilog(fileLogger);
195197

196198
var cLogger = new LoggerConfiguration()
197-
.WriteTo.Async(c =>
198-
{
199-
c.Console(
200-
logLevel,
201-
theme: AnsiConsoleTheme.Code,
202-
outputTemplate: "[{Level:u3}] {Message:lj}{NewLine}{Exception}");
203-
})
204-
.Filter.ByExcluding(x =>
199+
200+
.WriteTo.Console(
201+
logLevel,
202+
theme: AnsiConsoleTheme.Code,
203+
outputTemplate: "[{Level:u3}] {Message:lj}{NewLine}{Exception}")
204+
.Filter.ByIncludingOnly(x =>
205205
{
206206
if (!x.Properties.TryGetValue("SourceContext", out var value))
207207
return true;
208+
208209
var source = value.ToString().AsSpan().Trim('\"');
209210

210-
if (source.StartsWith(EngineParserNamespace.AsSpan()))
211-
return true;
212-
if (source.StartsWith(ParserNamespace.AsSpan()))
213-
return true;
214-
if (source.StartsWith(GameInfrastructureNamespace.AsSpan()))
215-
return true;
216-
if (source.StartsWith(GameVerifierStepNamespace.AsSpan()))
211+
if (source.StartsWith(ModVerifyRootNameSpace.AsSpan()))
217212
return true;
213+
218214
return false;
219215
})
216+
//.Filter.ByExcluding(x =>
217+
//{
218+
// if (!x.Properties.TryGetValue("SourceContext", out var value))
219+
// return true;
220+
// var source = value.ToString().AsSpan().Trim('\"');
221+
222+
// if (source.StartsWith(EngineParserNamespace.AsSpan()))
223+
// return true;
224+
// if (source.StartsWith(ParserNamespace.AsSpan()))
225+
// return true;
226+
// if (source.StartsWith(GameInfrastructureNamespace.AsSpan()))
227+
// return true;
228+
// if (source.StartsWith(GameVerifierStepNamespace.AsSpan()))
229+
// return true;
230+
// return false;
231+
//})
220232
.CreateLogger();
221233
loggingBuilder.AddSerilog(cLogger);
222234
}
@@ -259,11 +271,11 @@ private static void PrintHeader()
259271
private static void PrintApplicationFailure()
260272
{
261273
Console.WriteLine();
262-
Console.WriteLine("**************");
274+
Console.WriteLine("********************");
263275
Console.ForegroundColor = ConsoleColor.DarkRed;
264-
Console.WriteLine(" App Failure! ");
276+
Console.WriteLine(" ModVerify Failure! ");
265277
Console.ResetColor();
266-
Console.WriteLine("**************");
278+
Console.WriteLine("********************");
267279
Console.WriteLine();
268280
Console.WriteLine("The application encountered an unexpected error and will terminate now!");
269281
Console.WriteLine();

src/ModVerify.CliApp/Properties/launchSettings.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"profiles": {
33
"Interactive Verify": {
44
"commandName": "Project",
5-
"commandLineArgs": "verify -o verifyResults --minFailSeverity Information --baseline focBaseline.json --offline"
5+
"commandLineArgs": "verify -o verifyResults --minFailSeverity Information --baseline focBaseline.json --offline --sequential"
66
},
77
"Interactive Baseline": {
88
"commandName": "Project",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
3+
namespace AET.ModVerifyTool.Reporting;
4+
5+
internal sealed class EngineInitializeProgressReporter : IDisposable
6+
{
7+
private Progress<string>? _progress;
8+
9+
public EngineInitializeProgressReporter(Progress<string>? progress)
10+
{
11+
if (progress is null)
12+
return;
13+
progress.ProgressChanged += OnProgress;
14+
}
15+
16+
private void OnProgress(object sender, string e)
17+
{
18+
Console.ForegroundColor = ConsoleColor.DarkGray;
19+
Console.WriteLine(e);
20+
Console.ResetColor();
21+
}
22+
23+
public void Dispose()
24+
{
25+
Console.WriteLine();
26+
if (_progress is not null)
27+
_progress.ProgressChanged -= OnProgress;
28+
_progress = null;
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using AET.ModVerify.Pipeline;
2+
using AnakinRaW.CommonUtilities;
3+
using AnakinRaW.CommonUtilities.SimplePipeline.Progress;
4+
using ShellProgressBar;
5+
using System;
6+
using System.Threading;
7+
8+
namespace AET.ModVerifyTool.Reporting;
9+
10+
public sealed class VerifyConsoleProgressReporter(string toVerifyName) : DisposableObject, IVerifyProgressReporter
11+
{
12+
private static readonly ProgressBarOptions ProgressBarOptions = new()
13+
{
14+
BackgroundColor = ConsoleColor.DarkGray,
15+
ForegroundColorError = ConsoleColor.DarkRed,
16+
ProgressCharacter = '─',
17+
WriteQueuedMessage = WriteQueuedMessage,
18+
};
19+
20+
private ProgressBar? _progressBar;
21+
22+
public void ReportError(string message, string? errorLine)
23+
{
24+
var progressBar = EnsureProgressBar();
25+
progressBar.WriteErrorLine(errorLine);
26+
progressBar.Message = message;
27+
}
28+
29+
public void Report(string message, double progress)
30+
{
31+
Report(message, progress, VerifyProgress.ProgressType, default);
32+
}
33+
34+
public void Report(string progressText, double progress, ProgressType type, VerifyProgressInfo detailedProgress)
35+
{
36+
if (type != VerifyProgress.ProgressType)
37+
return;
38+
39+
var progressBar = EnsureProgressBar();
40+
41+
if (progress >= 1.0)
42+
progressBar.Message = $"Verified '{toVerifyName}'";
43+
44+
var cpb = progressBar.AsProgress<double>();
45+
cpb.Report(progress);
46+
progressBar.WriteLine(progressText);
47+
}
48+
49+
protected override void DisposeResources()
50+
{
51+
base.DisposeResources();
52+
_progressBar?.Dispose();
53+
Console.WriteLine();
54+
}
55+
56+
private ProgressBar EnsureProgressBar()
57+
{
58+
return LazyInitializer.EnsureInitialized(ref _progressBar,
59+
() => new ProgressBar(100, $"Verifying '{toVerifyName}'", ProgressBarOptions))!;
60+
}
61+
62+
private static int WriteQueuedMessage(ConsoleOutLine arg)
63+
{
64+
if (string.IsNullOrEmpty(arg.Line))
65+
return 0;
66+
67+
var writer = Console.Out;
68+
Console.ForegroundColor = ConsoleColor.DarkGray;
69+
try
70+
{
71+
writer.WriteLine(arg.Line);
72+
return 1;
73+
}
74+
finally
75+
{
76+
Console.ResetColor();
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)