Skip to content

Commit be3b3d0

Browse files
committed
Fix Process disposal
1 parent 10567e7 commit be3b3d0

4 files changed

Lines changed: 44 additions & 35 deletions

File tree

exampleTest/testoutputs/SomeTest.BiggerTable.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,3 @@ ID Age Title SomeText Something PolymorphicSomething
200200
197 47 X197
201201
198 18 X198
202202
199 49 X199
203-

exampleTest/testoutputs/SomeTest.ShortTableWithManualProperties.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,3 @@ Yes 1 10 hmm
44
"please no" 2 20 1
55
"I don't know" 3 20
66
... 4 20
7-

src/CheckTestOutput.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
</ItemGroup>
3333
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
3434
<PackageReference Include="System.Text.Json" Version="5.0.2" />
35-
<PackageReference Include="MedallionShell.StrongName" Version="1.6.2" />
3635
</ItemGroup>
3736

3837
<ItemGroup>

src/OutputChecker.cs

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ private Process StartGitProcess(params string[] args)
8888
#if DEBUG
8989
Console.WriteLine("Running git command: " + string.Join(" ", args));
9090
#endif
91-
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
9291
// run `git ...args` in CheckDirectory working directory with 3 second timeout
9392
var procInfo = new ProcessStartInfo("git")
9493
{
@@ -101,53 +100,64 @@ private Process StartGitProcess(params string[] args)
101100
StandardOutputEncoding = System.Text.Encoding.UTF8,
102101
StandardErrorEncoding = System.Text.Encoding.UTF8,
103102
};
103+
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
104104
foreach (var a in args)
105105
procInfo.ArgumentList.Add(a);
106-
return Process.Start(procInfo);
107106
#else
108-
// Old frameworks don't support ArgumentList, so I rather pull in a dependency than write my own escaping
109-
var command = Medallion.Shell.Shell.Default.Run("git", args, options => options.WorkingDirectory(CheckDirectory).Timeout(TimeSpan.FromSeconds(15)));
110-
return command.Process;
107+
procInfo.Arguments = WindowsEscapeArguments(args);
111108
#endif
109+
return Process.Start(procInfo);
112110
}
113111

114-
private void HandleProcessExit(Process proc, Task outputReaderTask, params string[] args)
112+
113+
#if !(NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER)
114+
private static string WindowsEscapeArguments(params string[] args)
115115
{
116-
// Literally, a Raspberry PI with a shitty SD card has faster IO than Azure Windows VM
117-
var timeout = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 15_000 : 3_000;
118-
if (!proc.WaitForExit(timeout))
119-
{
120-
proc.Kill();
121-
throw new Exception($"`git {string.Join(" ", args)}` command timed out");
122-
}
116+
// based on the logic from http://stackoverflow.com/questions/5510343/escape-command-line-arguments-in-c-sharp.
123117

124-
if (proc.ExitCode != 0)
125-
throw new Exception($"`git {string.Join(" ", args)}` command failed: " + proc.StandardError.ReadToEnd());
118+
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
119+
throw new InvalidOperationException("The nestandard2.0 build is only supported on Windows old .NET Framework");
126120

127-
outputReaderTask.Wait();
121+
return string.Join(" ", args.Select(a => {
122+
a = Regex.Replace(a, @"(\\*)" + "\"", @"$1$1\" + "\"");
123+
return "\"" + Regex.Replace(a, @"(\\+)$", @"$1$1") + "\"";
124+
}));
128125
}
126+
#endif
129127

130-
private string[] RunGitCommand(params string[] args)
131-
{
132-
var proc = StartGitProcess(args);
133128

134-
var outputLines = new List<string>();
135-
var outputReaderTask = Task.Run(() =>
129+
private void HandleProcessExit(Process proc, Task outputReaderTask, params string[] args)
130+
{
131+
try
136132
{
137-
string line;
138-
while ((line = proc.StandardOutput.ReadLine()) != null)
133+
// Literally, a Raspberry PI with a shitty SD card has faster IO than Azure Windows VM
134+
var timeout = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 15_000 : 3_000;
135+
if (!proc.WaitForExit(timeout))
139136
{
140-
if (line.Length > 0)
141-
outputLines.Add(line);
137+
proc.Kill();
138+
throw new Exception($"`git {string.Join(" ", args)}` command timed out");
142139
}
143-
});
144140

145-
HandleProcessExit(proc, outputReaderTask, args);
141+
if (proc.ExitCode != 0)
142+
throw new Exception($"`git {string.Join(" ", args)}` command failed: " + proc.StandardError.ReadToEnd());
143+
144+
outputReaderTask.Wait();
145+
}
146+
finally
147+
{
148+
proc.Dispose();
149+
}
150+
}
151+
152+
private string[] RunGitCommand(params string[] args)
153+
{
154+
var output = RunGitBinaryCommand(args);
146155

147-
return outputLines.ToArray();
156+
using var reader = new StreamReader(output);
157+
return ReadAllLines(reader);
148158
}
149159

150-
private byte[] RunGitBinaryCommand(params string[] args)
160+
private MemoryStream RunGitBinaryCommand(params string[] args)
151161
{
152162
var proc = StartGitProcess(args);
153163

@@ -160,14 +170,16 @@ private byte[] RunGitBinaryCommand(params string[] args)
160170

161171
HandleProcessExit(proc, outputReaderTask, args);
162172

163-
return ret.ToArray();
173+
ret.Position = 0;
174+
return ret;
164175
}
165176

166177
static string[] ReadAllLines(StreamReader reader)
167178
{
168179
var lines = new List<string>();
169180
while (!reader.EndOfStream && reader.ReadLine() is {} line)
170-
lines.Add(line);
181+
if (line.Length > 0)
182+
lines.Add(line);
171183
return lines.ToArray();
172184
}
173185

@@ -205,7 +217,7 @@ private byte[] GetOldBinaryContent(string file)
205217

206218
var data = RunGitBinaryCommand("cat-file", "blob", hash);
207219

208-
return data;
220+
return data.ToArray();
209221
}
210222
else
211223
{

0 commit comments

Comments
 (0)