From be3b3d0a8eb38a8f9b4dce25f61984d86fb31221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Standa=20Luke=C5=A1?= Date: Sat, 28 Jan 2023 11:05:22 +0100 Subject: [PATCH] Fix Process disposal --- .../testoutputs/SomeTest.BiggerTable.txt | 1 - ...omeTest.ShortTableWithManualProperties.txt | 1 - src/CheckTestOutput.csproj | 1 - src/OutputChecker.cs | 76 +++++++++++-------- 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/exampleTest/testoutputs/SomeTest.BiggerTable.txt b/exampleTest/testoutputs/SomeTest.BiggerTable.txt index f22edab..3a66748 100644 --- a/exampleTest/testoutputs/SomeTest.BiggerTable.txt +++ b/exampleTest/testoutputs/SomeTest.BiggerTable.txt @@ -200,4 +200,3 @@ ID Age Title SomeText Something PolymorphicSomething 197 47 X197 198 18 X198 199 49 X199 - diff --git a/exampleTest/testoutputs/SomeTest.ShortTableWithManualProperties.txt b/exampleTest/testoutputs/SomeTest.ShortTableWithManualProperties.txt index d72a727..d3d6603 100644 --- a/exampleTest/testoutputs/SomeTest.ShortTableWithManualProperties.txt +++ b/exampleTest/testoutputs/SomeTest.ShortTableWithManualProperties.txt @@ -4,4 +4,3 @@ Yes 1 10 hmm "please no" 2 20 1 "I don't know" 3 20 ... 4 20 - diff --git a/src/CheckTestOutput.csproj b/src/CheckTestOutput.csproj index 3ca99e5..bafc457 100644 --- a/src/CheckTestOutput.csproj +++ b/src/CheckTestOutput.csproj @@ -32,7 +32,6 @@ - diff --git a/src/OutputChecker.cs b/src/OutputChecker.cs index 0c4c9e8..7b81271 100644 --- a/src/OutputChecker.cs +++ b/src/OutputChecker.cs @@ -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") { @@ -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(); - 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); @@ -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(); while (!reader.EndOfStream && reader.ReadLine() is {} line) - lines.Add(line); + if (line.Length > 0) + lines.Add(line); return lines.ToArray(); } @@ -205,7 +217,7 @@ private byte[] GetOldBinaryContent(string file) var data = RunGitBinaryCommand("cat-file", "blob", hash); - return data; + return data.ToArray(); } else {