Skip to content

Commit d3e2c36

Browse files
authored
Support Multiple Baselines (#46)
* report decimal information to user * Support multiple baselines and verification result is able to categorize findings * add origin information * CRC guard uses correct file exists reassurance * support multiple baselines, even for creating baselines * parallel runs are not supported for baselines
1 parent c88191e commit d3e2c36

28 files changed

Lines changed: 526 additions & 294 deletions

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,22 @@ Uses manual mod setup, including sub-mods and the EaW fallback game, and uses th
116116
--useDefaultBaseline
117117
```
118118

119+
#### Example 3: Layering a mod-specific baseline on top of the default baseline
120+
A typical mod-dev workflow: filter the base game's known findings with the embedded default baseline, *and* filter your mod's own accepted findings with your own baseline. The two baselines stay independent — you can regenerate your mod baseline without touching the default.
121+
122+
**Windows:**
123+
```bat
124+
.\ModVerify.exe verify --path "C:\My Games\FoC\Mods\MyMod" --useDefaultBaseline --baseline ./myModBaseline.json
125+
```
126+
127+
**Linux:**
128+
```bash
129+
./ModVerify verify \
130+
--path "/home/user/games/FoC/Mods/MyMod" \
131+
--useDefaultBaseline \
132+
--baseline ./myModBaseline.json
133+
```
134+
119135
---
120136

121137
## Available Checks
@@ -156,3 +172,22 @@ ModVerify.exe createBaseline --outFile myBaseline.json --path "C:\My Games\FoC\M
156172
--outFile myBaseline.json \
157173
--path "C:\My Games\FoC\Mods\MyMod"
158174
```
175+
176+
### Creating a mod baseline on top of a base baseline
177+
178+
If you maintain a mod and only want your baseline to contain findings your mod is responsible for, supply the base baselines you want to subtract out. Findings already covered by the base baselines are excluded from the new file. The base baselines themselves are not modified, so they can keep being maintained independently.
179+
180+
**Windows**
181+
```bat
182+
.\ModVerify.exe createBaseline --outFile myModBaseline.json --path "C:\My Games\FoC\Mods\MyMod" --useDefaultBaseline
183+
```
184+
185+
**Linux**
186+
```bash
187+
./ModVerify createBaseline \
188+
--outFile myModBaseline.json \
189+
--path "/home/user/games/FoC/Mods/MyMod" \
190+
--useDefaultBaseline
191+
```
192+
193+
You can also chain a custom base baseline via `--baseline <path>`, and combine it with `--useDefaultBaseline`.

src/ModVerify.CliApp/App/CreateBaselineAction.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
using AET.ModVerify.App.Reporting;
1+
using AET.ModVerify.App.Reporting;
22
using AET.ModVerify.App.Settings;
33
using AET.ModVerify.App.Utilities;
44
using AET.ModVerify.Reporting;
5-
using AET.ModVerify.Reporting.Baseline;
65
using Microsoft.Extensions.DependencyInjection;
76
using Microsoft.Extensions.Logging;
87
using System;
@@ -15,7 +14,7 @@ internal sealed class CreateBaselineAction(AppBaselineSettings settings, IServic
1514
: ModVerifyApplicationAction<AppBaselineSettings>(settings, serviceProvider)
1615
{
1716
private readonly IFileSystem _fileSystem = serviceProvider.GetRequiredService<IFileSystem>();
18-
17+
1918
protected override void PrintAction(VerificationTarget target)
2019
{
2120
Console.WriteLine();
@@ -29,11 +28,11 @@ protected override void PrintAction(VerificationTarget target)
2928
protected override async Task<int> ProcessResult(VerificationResult result)
3029
{
3130
var baselineFactory = ServiceProvider.GetRequiredService<IBaselineFactory>();
32-
var baseline = baselineFactory.CreateBaseline(result.Target, Settings, result.Errors);
31+
var baseline = baselineFactory.CreateBaseline(result.Target, Settings, result.Errors.NewErrors);
3332

3433
var fullPath = _fileSystem.Path.GetFullPath(Settings.NewBaselinePath);
35-
Logger?.LogInformation(ModVerifyConstants.ConsoleEventId,
36-
"Writing Baseline to '{FullPath}' with {Number} findings", fullPath, result.Errors.Count);
34+
Logger?.LogInformation(ModVerifyConstants.ConsoleEventId,
35+
"Writing Baseline to '{FullPath}' with {Number} findings", fullPath, result.Errors.NewErrors.Count);
3736

3837
await baselineFactory.WriteBaselineAsync(baseline, Settings.NewBaselinePath);
3938

@@ -46,9 +45,4 @@ protected override async Task<int> ProcessResult(VerificationResult result)
4645

4746
return ModVerifyConstants.Success;
4847
}
49-
50-
protected override VerificationBaseline GetBaseline(VerificationTarget verificationTarget)
51-
{
52-
return VerificationBaseline.Empty;
53-
}
5448
}

src/ModVerify.CliApp/App/ModVerifyApplicationAction.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using AET.ModVerify.App.Reporting;
77
using AET.ModVerify.App.Settings;
88
using AET.ModVerify.App.TargetSelectors;
9+
using AET.ModVerify.App.Utilities;
910
using AET.ModVerify.Reporting;
1011
using AET.ModVerify.Reporting.Baseline;
1112
using AET.ModVerify.Reporting.Suppressions;
@@ -105,14 +106,30 @@ private int ReportVerificationFailure(Exception verificationException)
105106
}
106107

107108
protected abstract Task<int> ProcessResult(VerificationResult result);
108-
109-
protected abstract VerificationBaseline GetBaseline(VerificationTarget verificationTarget);
109+
110+
protected virtual BaselineCollection GetBaselines(VerificationTarget verificationTarget)
111+
{
112+
var baselineSelector = new BaselineSelector(Settings, ServiceProvider);
113+
var baselines = baselineSelector.SelectBaselines(verificationTarget);
114+
if (!baselines.IsEmpty)
115+
{
116+
Console.WriteLine();
117+
ModVerifyConsoleUtilities.WriteBaselineInfo(baselines);
118+
foreach (var entry in baselines)
119+
{
120+
Logger?.LogDebug("Using baseline {Baseline} from source '{Identifier}'",
121+
entry.Baseline.ToString(), entry.Identifier);
122+
}
123+
Console.WriteLine();
124+
}
125+
return baselines;
126+
}
110127

111128
private async Task<VerificationResult> VerifyTargetAsync(VerificationTarget verificationTarget)
112129
{
113130
var progressReporter = new VerifyConsoleProgressReporter(verificationTarget.Name, Settings.ReportSettings);
114131

115-
var baseline = GetBaseline(verificationTarget);
132+
var baselines = GetBaselines(verificationTarget);
116133
var suppressions = GetSuppressions();
117134

118135
try
@@ -122,11 +139,11 @@ private async Task<VerificationResult> VerifyTargetAsync(VerificationTarget veri
122139
Logger?.LogInformation(ModVerifyConstants.ConsoleEventId, "Verifying '{Target}'...", verificationTarget.Name);
123140

124141
var verificationResult = await verifierService.VerifyAsync(
125-
verificationTarget,
142+
verificationTarget,
126143
Settings.VerifierServiceSettings,
127-
baseline,
144+
baselines,
128145
suppressions,
129-
progressReporter,
146+
progressReporter,
130147
new EngineInitializeProgressReporter(verificationTarget.Engine));
131148

132149
progressReporter.Report(string.Empty, 1.0);

src/ModVerify.CliApp/App/VerifyAction.cs

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using AET.ModVerify.App.Reporting;
2-
using AET.ModVerify.App.Settings;
1+
using AET.ModVerify.App.Settings;
32
using AET.ModVerify.App.Utilities;
43
using AET.ModVerify.Reporting;
54
using Microsoft.Extensions.Logging;
@@ -8,7 +7,6 @@
87
using System.Linq;
98
using System.Threading.Tasks;
109
using AET.ModVerify.Reporting.Reporters;
11-
using AET.ModVerify.Reporting.Baseline;
1210

1311
namespace AET.ModVerify.App;
1412

@@ -41,7 +39,7 @@ protected override async Task<int> ProcessResult(VerificationResult result)
4139
await reportBroker.ReportAsync(result);
4240

4341
if (Settings.AppFailsOnMinimumSeverity.HasValue &&
44-
result.Errors.Any(x => x.Severity >= Settings.AppFailsOnMinimumSeverity))
42+
result.Errors.NewErrors.Any(x => x.Severity >= Settings.AppFailsOnMinimumSeverity))
4543
{
4644
Logger?.LogInformation(ModVerifyConstants.ConsoleEventId,
4745
"The verification of {Target} completed with findings of the specified failure severity {Severity}",
@@ -53,32 +51,18 @@ protected override async Task<int> ProcessResult(VerificationResult result)
5351
return ModVerifyConstants.Success;
5452
}
5553

56-
protected override VerificationBaseline GetBaseline(VerificationTarget verificationTarget)
57-
{
58-
var baselineSelector = new BaselineSelector(Settings, ServiceProvider);
59-
var baseline = baselineSelector.SelectBaseline(verificationTarget, out var baselinePath);
60-
if (!baseline.IsEmpty)
61-
{
62-
Console.WriteLine();
63-
ModVerifyConsoleUtilities.WriteBaselineInfo(baseline, baselinePath);
64-
Logger?.LogDebug("Using baseline {Baseline} from location '{Path}'",
65-
baseline.ToString(), baselinePath ?? "Embedded");
66-
Console.WriteLine();
67-
}
68-
return baseline;
69-
}
70-
7154
private IReadOnlyCollection<IVerificationReporter> CreateReporters()
7255
{
73-
var reporters = new List<IVerificationReporter>();
74-
75-
reporters.Add(IVerificationReporter.CreateConsole(new ConsoleReporterSettings
56+
var reporters = new List<IVerificationReporter>
7657
{
77-
Verbose = Settings.ReportSettings.Verbose,
78-
MinimumReportSeverity = Settings.VerifierServiceSettings.FailFastSettings.IsFailFast
79-
? VerificationSeverity.Information
80-
: VerificationSeverity.Error
81-
}, ServiceProvider));
58+
IVerificationReporter.CreateConsole(new ConsoleReporterSettings
59+
{
60+
Verbose = Settings.ReportSettings.Verbose,
61+
MinimumReportSeverity = Settings.VerifierServiceSettings.FailFastSettings.IsFailFast
62+
? VerificationSeverity.Information
63+
: VerificationSeverity.Error
64+
}, ServiceProvider)
65+
};
8266

8367
var outputDirectory = Settings.ReportDirectory;
8468
reporters.Add(IVerificationReporter.CreateJson(new JsonReporterSettings

src/ModVerify.CliApp/Properties/launchSettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
},
77
"Verify (Interactive)": {
88
"commandName": "Project",
9-
"commandLineArgs": "verify -o verifyResults --offline --minFailSeverity Information --searchBaseline"
9+
"commandLineArgs": "verify -o verifyResults --offline --minFailSeverity Information --useDefaultBaseline"
1010
},
1111
"Verify (Automatic Target Selection)": {
1212
"commandName": "Project",

0 commit comments

Comments
 (0)