Skip to content

Commit

Permalink
Fix Process disposal
Browse files Browse the repository at this point in the history
  • Loading branch information
exyi committed Jan 28, 2023
1 parent 10567e7 commit be3b3d0
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 35 deletions.
1 change: 0 additions & 1 deletion exampleTest/testoutputs/SomeTest.BiggerTable.txt
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,3 @@ ID Age Title SomeText Something PolymorphicSomething
197 47 X197
198 18 X198
199 49 X199

Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ Yes 1 10 hmm
"please no" 2 20 1
"I don't know" 3 20
... 4 20

1 change: 0 additions & 1 deletion src/CheckTestOutput.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Text.Json" Version="5.0.2" />
<PackageReference Include="MedallionShell.StrongName" Version="1.6.2" />
</ItemGroup>

<ItemGroup>
Expand Down
76 changes: 44 additions & 32 deletions src/OutputChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ private Process StartGitProcess(params string[] args)
#if DEBUG
Console.WriteLine("Running git command: " + string.Join(" ", args));
#endif
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
// run `git ...args` in CheckDirectory working directory with 3 second timeout
var procInfo = new ProcessStartInfo("git")
{
Expand All @@ -101,53 +100,64 @@ private Process StartGitProcess(params string[] args)
StandardOutputEncoding = System.Text.Encoding.UTF8,
StandardErrorEncoding = System.Text.Encoding.UTF8,
};
#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
foreach (var a in args)
procInfo.ArgumentList.Add(a);
return Process.Start(procInfo);
#else
// Old frameworks don't support ArgumentList, so I rather pull in a dependency than write my own escaping
var command = Medallion.Shell.Shell.Default.Run("git", args, options => options.WorkingDirectory(CheckDirectory).Timeout(TimeSpan.FromSeconds(15)));
return command.Process;
procInfo.Arguments = WindowsEscapeArguments(args);
#endif
return Process.Start(procInfo);
}

private void HandleProcessExit(Process proc, Task outputReaderTask, params string[] args)

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

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

outputReaderTask.Wait();
return string.Join(" ", args.Select(a => {
a = Regex.Replace(a, @"(\\*)" + "\"", @"$1$1\" + "\"");
return "\"" + Regex.Replace(a, @"(\\+)$", @"$1$1") + "\"";
}));
}
#endif

private string[] RunGitCommand(params string[] args)
{
var proc = StartGitProcess(args);

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

HandleProcessExit(proc, outputReaderTask, args);
if (proc.ExitCode != 0)
throw new Exception($"`git {string.Join(" ", args)}` command failed: " + proc.StandardError.ReadToEnd());

outputReaderTask.Wait();
}
finally
{
proc.Dispose();
}
}

private string[] RunGitCommand(params string[] args)
{
var output = RunGitBinaryCommand(args);

return outputLines.ToArray();
using var reader = new StreamReader(output);
return ReadAllLines(reader);
}

private byte[] RunGitBinaryCommand(params string[] args)
private MemoryStream RunGitBinaryCommand(params string[] args)
{
var proc = StartGitProcess(args);

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

HandleProcessExit(proc, outputReaderTask, args);

return ret.ToArray();
ret.Position = 0;
return ret;
}

static string[] ReadAllLines(StreamReader reader)
{
var lines = new List<string>();
while (!reader.EndOfStream && reader.ReadLine() is {} line)
lines.Add(line);
if (line.Length > 0)
lines.Add(line);
return lines.ToArray();
}

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

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

return data;
return data.ToArray();
}
else
{
Expand Down

0 comments on commit be3b3d0

Please sign in to comment.