/// <summary> /// Executes the given <see cref="IMercurialCommand"/> command against /// the Mercurial repository. /// </summary> /// <param name="command"> /// The <see cref="IMercurialCommand"/> command to execute. /// </param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="command"/> is <c>null</c>.</para> /// </exception> /// <exception cref="MercurialException"> /// HG did not complete within the allotted time. /// </exception> public void Execute(IMercurialCommand command) { if (command == null) { throw new ArgumentNullException("command"); } if (_Process == null) { StartPersistentMercurialClient(); } command.Validate(); command.Before(); IEnumerable <string> arguments = new[] { command.Command, "--noninteractive", }; arguments = arguments.Concat(command.Arguments.Where(a => !StringEx.IsNullOrWhiteSpace(a))); arguments = arguments.Concat(command.AdditionalArguments.Where(a => !StringEx.IsNullOrWhiteSpace(a))); 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) { commandArguments = string.Join(" ", commandParts.Skip(1).ToArray()); command.Observer.Executing(command.Command, commandArguments); } MemoryStream output = new MemoryStream(); MemoryStream error = new MemoryStream(); var outputs = new Dictionary <CommandChannel, Stream>() { { CommandChannel.Output, output }, { CommandChannel.Error, error }, }; var _codec = ClientExecutable.GetMainEncoding(); int resultCode = RunCommand(commandParts, outputs, null); var result = new CommandResult(_codec.GetString(output.GetBuffer(), 0, (int)output.Length), _codec.GetString(error.GetBuffer(), 0, (int)error.Length), resultCode); if (resultCode == 0 || !string.IsNullOrEmpty(result.Output)) { 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; } StopPersistentMercurialClient(); throw new MercurialExecutionException( string.IsNullOrEmpty(result.Error) ? "Unable to decode output from executing command, spinning down persistent client" : result.Error); }
/// <summary> /// Executes the given <see cref="IMercurialCommand"/> command against /// the Mercurial repository. /// </summary> /// <param name="command"> /// The <see cref="IMercurialCommand"/> command to execute. /// </param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="command"/> is <c>null</c>.</para> /// </exception> /// <exception cref="MercurialException"> /// HG did not complete within the allotted time. /// </exception> public void Execute(IMercurialCommand command) { if (command == null) { throw new ArgumentNullException("command"); } if (_Process == null) { StartPersistentMercurialClient(); } command.Validate(); command.Before(); IEnumerable <string> arguments = new[] { command.Command, "--noninteractive", "--encoding", ClientExecutable.TextEncodingName, }; arguments = arguments.Concat(command.Arguments.Where(a => !StringEx.IsNullOrWhiteSpace(a))); arguments = arguments.Concat(command.AdditionalArguments.Where(a => !StringEx.IsNullOrWhiteSpace(a))); 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) { commandArguments = string.Join(" ", commandParts.Skip(1).ToArray()); command.Observer.Executing(command.Command, commandArguments); } byte[] buffer = ClientExecutable.TextEncoding.GetBytes(commandBuffer.ToString()); foreach (byte b in buffer) { _Process.StandardInput.BaseStream.WriteByte(b); _Process.StandardInput.BaseStream.Flush(); } string standardOutput; string standardError; int exitCode; if (CommandServerOutputDecoder.GetOutput(_Process.StandardOutput, out standardOutput, out standardError, out exitCode)) { if (command.Observer != null) { using (var lineReader = new StringReader(standardOutput)) { string line; while ((line = lineReader.ReadLine()) != null) { command.Observer.Output(line); } } using (var lineReader = new StringReader(standardError)) { string line; while ((line = lineReader.ReadLine()) != null) { command.Observer.ErrorOutput(line); } } command.Observer.Executed(command.Command, commandArguments, exitCode, standardOutput, standardError); } command.After(exitCode, standardOutput, standardError); return; } StopPersistentMercurialClient(); throw new MercurialExecutionException("Unable to decode output from executing command, spinning down persistent client"); }
/// <summary> /// Executes the given <see cref="IMercurialCommand"/> command against /// the Mercurial repository. /// </summary> /// <param name="command"> /// The <see cref="IMercurialCommand"/> command to execute. /// </param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="command"/> is <c>null</c>.</para> /// </exception> /// <exception cref="MercurialException"> /// HG did not complete within the allotted time. /// </exception> public void Execute(IMercurialCommand command) { if (command == null) throw new ArgumentNullException("command"); if (_Process == null) StartPersistentMercurialClient(); command.Validate(); command.Before(); IEnumerable<string> arguments = new[] { command.Command, "--noninteractive", "--encoding", "cp1252", }; arguments = arguments.Concat(command.Arguments.Where(a => !StringEx.IsNullOrWhiteSpace(a))); arguments = arguments.Concat(command.AdditionalArguments.Where(a => !StringEx.IsNullOrWhiteSpace(a))); 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) { commandArguments = string.Join(" ", commandParts.Skip(1).ToArray()); command.Observer.Executing(command.Command, commandArguments); } byte[] buffer = Encoding.GetEncoding("iso-8859-1").GetBytes(commandBuffer.ToString()); foreach (byte b in buffer) { _Process.StandardInput.BaseStream.WriteByte(b); _Process.StandardInput.BaseStream.Flush(); } string standardOutput; string standardError; int exitCode; if (CommandServerOutputDecoder.GetOutput(_Process.StandardOutput, out standardOutput, out standardError, out exitCode)) { if (command.Observer != null) { using (var lineReader = new StringReader(standardOutput)) { string line; while ((line = lineReader.ReadLine()) != null) command.Observer.Output(line); } using (var lineReader = new StringReader(standardError)) { string line; while ((line = lineReader.ReadLine()) != null) command.Observer.ErrorOutput(line); } command.Observer.Executed(command.Command, commandArguments, exitCode, standardOutput, standardError); } command.After(exitCode, standardOutput, standardError); return; } StopPersistentMercurialClient(); throw new MercurialExecutionException("Unable to decode output from executing command, spinning down persistent client"); }