Skip to content

Commit cbfd66e

Browse files
authored
Isolate the collection of the ProcessData (#289)
1 parent 5c55d2c commit cbfd66e

File tree

4 files changed

+105
-35
lines changed

4 files changed

+105
-35
lines changed

src/Buildalyzer/Environment/DotNetInfoResolver.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ private DotNetInfo Execute(IOPath projectPath, IOPath dotNetExePath)
4242
processRunner.Start();
4343
processRunner.WaitForExit(GetWaitTime());
4444

45-
var info = DotNetInfo.Parse(processRunner.Output);
45+
var info = DotNetInfo.Parse(processRunner.Data.Output);
4646
Cache[projectPath] = info;
4747
return info;
4848
}

src/Buildalyzer/Environment/ProcessRunner.cs

+44-34
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33

44
namespace Buildalyzer.Environment;
55

6-
internal class ProcessRunner : IDisposable
6+
internal sealed class ProcessRunner : IDisposable
77
{
88
private readonly ILogger Logger;
9-
10-
public List<string> Output { get; } = new List<string>();
11-
public List<string> Error { get; } = new List<string>();
9+
private readonly ProcessDataCollector Collector;
1210

1311
public int ExitCode => Process.ExitCode;
1412

13+
public ProcessData Data => Collector.Data;
14+
1515
private Process Process { get; }
1616

1717
public Action Exited { get; set; }
@@ -35,7 +35,10 @@ public ProcessRunner(
3535
UseShellExecute = false,
3636
RedirectStandardOutput = true,
3737
RedirectStandardError = true
38-
}
38+
},
39+
40+
// Raises Process.Exited immediately instead of when checked via .WaitForExit() or .HasExited
41+
EnableRaisingEvents = true,
3942
};
4043

4144
// Copy over environment variables
@@ -48,25 +51,11 @@ public ProcessRunner(
4851
}
4952
}
5053

51-
Process.EnableRaisingEvents = true; // Raises Process.Exited immediately instead of when checked via .WaitForExit() or .HasExited
52-
Process.Exited += ProcessExited;
54+
Process.OutputDataReceived += OutputDataReceived;
55+
Process.ErrorDataReceived += ErrorDataReceived;
56+
Process.Exited += OnExit;
5357

54-
Process.OutputDataReceived += (_, e) =>
55-
{
56-
if (!string.IsNullOrEmpty(e.Data))
57-
{
58-
Output.Add(e.Data);
59-
Logger.LogDebug("{Data}{NewLine}", e.Data, System.Environment.NewLine);
60-
}
61-
};
62-
Process.ErrorDataReceived += (_, e) =>
63-
{
64-
if (!string.IsNullOrEmpty(e.Data))
65-
{
66-
Error.Add(e.Data);
67-
Logger.LogDebug("{Data}{NewLine}", e.Data, System.Environment.NewLine);
68-
}
69-
};
58+
Collector = new(Process);
7059
}
7160

7261
public ProcessRunner Start()
@@ -83,16 +72,6 @@ public ProcessRunner Start()
8372
return this;
8473
}
8574

86-
private void ProcessExited(object? sender, EventArgs e)
87-
{
88-
Exited?.Invoke();
89-
Logger.LogDebug(
90-
"Process {Id} exited with code {ExitCode}{NewLine}",
91-
Process.Id,
92-
Process.ExitCode,
93-
System.Environment.NewLine);
94-
}
95-
9675
public void WaitForExit() => Process.WaitForExit();
9776

9877
public bool WaitForExit(int timeout)
@@ -108,9 +87,40 @@ public bool WaitForExit(int timeout)
10887
return exited;
10988
}
11089

90+
private void OutputDataReceived(object sender, DataReceivedEventArgs e)
91+
{
92+
if (!string.IsNullOrEmpty(e.Data))
93+
{
94+
Logger.LogDebug("{Data}{NewLine}", e.Data, NewLine);
95+
}
96+
}
97+
98+
private void ErrorDataReceived(object sender, DataReceivedEventArgs e)
99+
{
100+
if (!string.IsNullOrEmpty(e.Data))
101+
{
102+
Logger.LogError("{Data}{NewLine}", e.Data, NewLine);
103+
}
104+
}
105+
106+
private void OnExit(object? sender, EventArgs e)
107+
{
108+
Exited?.Invoke();
109+
Logger.LogDebug(
110+
"Process {Id} exited with code {ExitCode}{NewLine}",
111+
Process.Id,
112+
Process.ExitCode,
113+
NewLine);
114+
}
115+
111116
public void Dispose()
112117
{
113-
Process.Exited -= ProcessExited;
118+
Process.OutputDataReceived -= OutputDataReceived;
119+
Process.ErrorDataReceived -= ErrorDataReceived;
120+
Process.Exited -= OnExit;
114121
Process.Close();
122+
Collector.Dispose();
115123
}
124+
125+
private static string NewLine => System.Environment.NewLine;
116126
}

src/Buildalyzer/ProcessData.cs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace Buildalyzer;
2+
3+
/// <summary>The data received during a <see cref="Process" />.</summary>
4+
[DebuggerDisplay("Output = {Output.Length}, Error = {Error.Length}")]
5+
public sealed class ProcessData(
6+
ImmutableArray<string> output,
7+
ImmutableArray<string> error)
8+
{
9+
/// <summary>The collected output of the process.</summary>
10+
public ImmutableArray<string> Output { get; } = output;
11+
12+
/// <summary>The collected errors of the process.</summary>
13+
public ImmutableArray<string> Error { get; } = error;
14+
}
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
namespace Buildalyzer;
2+
3+
/// <summary>Collects the <see cref="ProcessData"/> durring a <see cref="System.Diagnostics.Process"/>.</summary>
4+
[DebuggerDisplay("ExitCode = {Process.ExitCode}, Output = {Process.Output.Length}, Error = {Process.Error.Length}")]
5+
internal sealed class ProcessDataCollector : IDisposable
6+
{
7+
private readonly Process Process;
8+
private readonly List<string> Output = [];
9+
private readonly List<string> Error = [];
10+
11+
public ProcessDataCollector(Process process)
12+
{
13+
Process = process;
14+
Process.OutputDataReceived += OutputDataReceived;
15+
Process.ErrorDataReceived += ErrorDataReceived;
16+
}
17+
18+
public ProcessData Data => new(
19+
Output.ToImmutableArray(),
20+
Error.ToImmutableArray());
21+
22+
private void OutputDataReceived(object? sender, DataReceivedEventArgs e) => Add(e.Data, Output);
23+
24+
private void ErrorDataReceived(object? sender, DataReceivedEventArgs e) => Add(e.Data, Error);
25+
26+
private static void Add(string? value, List<string> buffer)
27+
{
28+
if (value is { Length: > 0 })
29+
{
30+
buffer.Add(value);
31+
}
32+
}
33+
34+
/// <inheritdoc />
35+
public void Dispose()
36+
{
37+
if (!Disposed)
38+
{
39+
Process.OutputDataReceived -= OutputDataReceived;
40+
Process.ErrorDataReceived -= ErrorDataReceived;
41+
Disposed = true;
42+
}
43+
}
44+
45+
private bool Disposed;
46+
}

0 commit comments

Comments
 (0)