From 7da41bc04d9e2da5f62a8fe88570b915f5bc1cc4 Mon Sep 17 00:00:00 2001 From: Dean Ferreyra Date: Thu, 30 Sep 2021 11:31:09 -0700 Subject: [PATCH] Fixes and improvements to PersistentClient Change `Execute()` so that it doesn't throw an exception saying "Unable to decode output from executing command..." for non-zero return codes and empty output. This allows regular Mercurial errors to be reported like they would in the non-persistent client. This also eliminates the exception when running the incoming and outgoing commands when there are no incoming or outgoing commits triggered by the return code of 1. Change `IsSupported()` to not require the existence of a ".hg" folder under the repositoryPath. This allow the persistent client to be used in more cases, like when calling "hg init". This also allows more unit tests to use the persistent client when the "PERSISTENTCLIENT" environment variable is set to "1". Trim quotes on arguments to "runcommand". For the non-persistent client, for arguments passed to `WithAdditionalArgument()` that contain spaces, you need to wrap the argument in quotes for the command processor to interpret the argument correctly. On the other hand, in the persistent client, quoted arguments can result in errors. By trimming quotes automatically in the persistent client, one set of arguments can work for both clients. This also fixes some unit test failures due to quoted arguments when the "PERSISTENTCLIENT" environment variable is set to "1". Remove unused command encoding code that itself trimmed quotes from arguments, but was not actually being used. --- src/Mercurial.Net/PersistentClient.cs | 37 +++++---------------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/src/Mercurial.Net/PersistentClient.cs b/src/Mercurial.Net/PersistentClient.cs index ab9a0ec..9640c45 100644 --- a/src/Mercurial.Net/PersistentClient.cs +++ b/src/Mercurial.Net/PersistentClient.cs @@ -108,16 +108,6 @@ public void Execute(IMercurialCommand command) var commandParts = arguments.ToArray(); - string commandEncoded = string.Join("\0", commandParts.Select(p => p.Trim('"')).ToArray()); - int length = commandEncoded.Length; - var commandBuffer = new StringBuilder(); - commandBuffer.Append("runcommand\n"); - commandBuffer.Append((char)((length >> 24) & 0xff)); - commandBuffer.Append((char)((length >> 16) & 0xff)); - commandBuffer.Append((char)((length >> 8) & 0xff)); - commandBuffer.Append((char)(length & 0xff)); - commandBuffer.Append(commandEncoded); - string commandArguments = null; if (command.Observer != null) { @@ -139,23 +129,13 @@ public void Execute(IMercurialCommand command) _codec.GetString(error.GetBuffer(), 0, (int)error.Length), resultCode); - if (resultCode == 0 || !string.IsNullOrEmpty(result.Output)) + if (command.Observer != null) { - if (command.Observer != null) - { - command.Observer.Output(result.Output); - command.Observer.ErrorOutput(result.Error); - command.Observer.Executed(command.Command, commandArguments, resultCode, result.Output, result.Error); - } - command.After(resultCode, result.Output, result.Error); - return; + command.Observer.Output(result.Output); + command.Observer.ErrorOutput(result.Error); + command.Observer.Executed(command.Command, commandArguments, resultCode, result.Output, result.Error); } - - StopPersistentMercurialClient(); - throw new MercurialExecutionException( - string.IsNullOrEmpty(result.Error) ? - "Unable to decode output from executing command, spinning down persistent client" - : result.Error); + command.After(resultCode, result.Output, result.Error); } internal static int ReadInt(byte[] buffer, int offset) @@ -179,7 +159,8 @@ private int RunCommand(IList command, byte[] argumentBuffer; argumentBuffer = command.Aggregate(new List(), (bytes, arg) => { - bytes.AddRange(_codec.GetBytes(arg)); + // Trim surrounding double quotes for persistent client + bytes.AddRange(_codec.GetBytes(arg.Trim('"'))); bytes.Add(0); return bytes; }, @@ -394,10 +375,6 @@ public static bool IsSupported(string repositoryPath) if (!Directory.Exists(repositoryPath)) return false; - // TODO: Determine if we need to check if the .hg folder is an actual repository - if (!Directory.Exists(Path.Combine(repositoryPath, ".hg"))) - return false; - if (ClientExecutable.CurrentVersion < new Version(1, 9, 0, 0)) return false;