7 private readonly
object _sync =
new();
8 private readonly
bool _interactive;
9 private DirectoryVerificationCampaignStage? _lastStage;
10 private int _lastRenderedWidth;
11 private int _lastRedirectedFileCount = -1;
12 private int _lastRedirectedCandidateCount = -1;
16 _interactive = !Console.IsErrorRedirected;
19 public void Report(DirectoryVerificationCampaignProgress value)
21 ArgumentNullException.ThrowIfNull(value);
27 RenderInteractive(value);
31 RenderRedirected(value);
34 _lastStage = value.Stage;
42 if (_interactive && _lastRenderedWidth > 0)
44 Console.Error.WriteLine();
45 _lastRenderedWidth = 0;
50 private void RenderInteractive(
51 DirectoryVerificationCampaignProgress value)
53 string text = Format(value);
54 int padding = Math.Max(0, _lastRenderedWidth - text.Length);
56 Console.Error.Write(
'\r');
57 Console.Error.Write(text);
61 Console.Error.Write(
new string(
' ', padding));
62 Console.Error.Write(
new string(
'\b', padding));
65 _lastRenderedWidth = text.Length;
67 if (value.Stage == DirectoryVerificationCampaignStage.Completed)
69 Console.Error.WriteLine();
70 _lastRenderedWidth = 0;
74 private void RenderRedirected(
75 DirectoryVerificationCampaignProgress value)
77 bool stageChanged = _lastStage != value.Stage;
81 value.Stage == DirectoryVerificationCampaignStage.Completed;
83 if (value.Stage == DirectoryVerificationCampaignStage.LoadingFiles &&
84 value.ProcessedFileCount > 0 &&
85 (value.ProcessedFileCount == value.DiscoveredFileCount ||
86 value.ProcessedFileCount - _lastRedirectedFileCount >= 100))
89 _lastRedirectedFileCount = value.ProcessedFileCount;
92 if (value.Stage == DirectoryVerificationCampaignStage.VerifyingCandidates &&
93 value.CompletedCandidateCount > 0 &&
94 (value.CompletedCandidateCount == value.CandidateCount ||
95 value.CompletedCandidateCount - _lastRedirectedCandidateCount >= 25))
98 _lastRedirectedCandidateCount = value.CompletedCandidateCount;
103 Console.Error.WriteLine(Format(value));
107 private static string Format(
108 DirectoryVerificationCampaignProgress value)
110 return value.Stage
switch
112 DirectoryVerificationCampaignStage.DiscoveringFiles =>
113 "Discovering XML files...",
115 DirectoryVerificationCampaignStage.LoadingFiles =>
116 $
"Loading XML files: {value.ProcessedFileCount}/{value.DiscoveredFileCount} " +
117 $
"(instances={value.LoadedInstanceCount})",
119 DirectoryVerificationCampaignStage.VerifyingCandidates =>
120 $
"Checking candidates: {value.CompletedCandidateCount}/{value.CandidateCount}",
122 DirectoryVerificationCampaignStage.WritingReports =>
123 "Writing campaign reports...",
125 DirectoryVerificationCampaignStage.Completed =>
126 $
"Campaign complete: candidates={value.CandidateCount}",
129 value.Stage.ToString()