예제 #1
0
        public static async Task <string> GetOutputAsync(
            this IExecutable executable,
            ArgumentString arguments  = default,
            byte[] input              = null,
            Encoding outputEncoding   = null,
            CommandCache cache        = null,
            bool stripAnsiEscapeCodes = true)
        {
            if (outputEncoding == null)
            {
                outputEncoding = _defaultOutputEncoding.Value;
            }

            if (cache != null && cache.TryGet(arguments, out var output, out var error))
            {
                return(ComposeOutput());
            }

            using (var process = executable.Start(
                       arguments,
                       createWindow: false,
                       redirectInput: input != null,
                       redirectOutput: true,
                       outputEncoding))
            {
                if (input != null)
                {
                    await process.StandardInput.BaseStream.WriteAsync(input, 0, input.Length);

                    process.StandardInput.Close();
                }

                var outputBuffer = new MemoryStream();
                var errorBuffer  = new MemoryStream();
                var outputTask   = process.StandardOutput.BaseStream.CopyToAsync(outputBuffer);
                var errorTask    = process.StandardError.BaseStream.CopyToAsync(errorBuffer);
                var exitTask     = process.WaitForExitAsync();

                await Task.WhenAll(outputTask, errorTask, exitTask);

                output = outputBuffer.ToArray();
                error  = errorBuffer.ToArray();

                if (cache != null && await exitTask == 0)
                {
                    cache.Add(arguments, output, error);
                }

                return(ComposeOutput());
            }

            string ComposeOutput()
            {
                return(CleanString(
                           stripAnsiEscapeCodes,
                           EncodingHelper.DecodeString(output, error, ref outputEncoding)));
            }
        }
예제 #2
0
 public static bool RunCommand(
     this IExecutable executable,
     ArgumentString arguments = default,
     byte[]?input             = null,
     bool createWindow        = false)
 {
     return(GitUI.ThreadHelper.JoinableTaskFactory.Run(
                () => executable.RunCommandAsync(arguments, input, createWindow)));
 }
예제 #3
0
 public static ExecutionResult Execute(
     this IExecutable executable,
     ArgumentString arguments,
     Action <StreamWriter>?writeInput = null,
     Encoding?outputEncoding          = null,
     bool stripAnsiEscapeCodes        = true)
 {
     return(GitUI.ThreadHelper.JoinableTaskFactory.Run(
                () => executable.ExecuteAsync(arguments, writeInput, outputEncoding, stripAnsiEscapeCodes)));
 }
예제 #4
0
 public static string GetOutput(
     this IExecutable executable,
     ArgumentString arguments  = default,
     byte[]?input              = null,
     Encoding?outputEncoding   = null,
     CommandCache?cache        = null,
     bool stripAnsiEscapeCodes = true)
 {
     return(GitUI.ThreadHelper.JoinableTaskFactory.Run(
                () => executable.GetOutputAsync(arguments, input, outputEncoding, cache, stripAnsiEscapeCodes)));
 }
예제 #5
0
        public static async Task <IEnumerable <string> > GetOutputLinesAsync(
            this IExecutable executable,
            ArgumentString arguments         = default,
            Action <StreamWriter>?writeInput = null,
            Encoding?outputEncoding          = null,
            bool stripAnsiEscapeCodes        = true)
        {
            var result = await executable.ExecuteAsync(arguments, writeInput, outputEncoding, stripAnsiEscapeCodes);

            return(result.StandardOutput.SplitLines().Concat(result.StandardError.SplitLines()));
        }
예제 #6
0
        public IProcess Start(ArgumentString arguments = default, bool createWindow = false, bool redirectInput = false, bool redirectOutput = false, Encoding outputEncoding = null)
        {
            // TODO should we set these on the child process only?
            EnvironmentConfiguration.SetEnvironmentVariables();

            var args = (arguments.Arguments ?? "").Replace("$QUOTE$", "\\\"");

            var fileName = _fileNameProvider();

            return(new ProcessWrapper(fileName, args, _workingDir, createWindow, redirectInput, redirectOutput, outputEncoding));
        }
예제 #7
0
        public IProcess RunDetached(
            ArgumentString arguments = default,
            bool createWindow        = false,
            bool redirectInput       = false,
            bool redirectOutput      = false,
            Encoding outputEncoding  = null)
        {
            if (outputEncoding is null && redirectOutput)
            {
                outputEncoding = _defaultEncoding();
            }

            return(_gitExecutable.Start(arguments, createWindow, redirectInput, redirectOutput, outputEncoding));
        }
예제 #8
0
        public static IEnumerable <string> GetOutputLines(
            this IExecutable executable,
            ArgumentString arguments  = default,
            byte[] input              = null,
            Encoding outputEncoding   = null,
            bool stripAnsiEscapeCodes = true)
        {
            // TODO make this method async, maybe via IAsyncEnumerable<...>?

            if (outputEncoding == null)
            {
                outputEncoding = _defaultOutputEncoding.Value;
            }

            using (var process = executable.Start(arguments, createWindow: false, redirectInput: input != null, redirectOutput: true, outputEncoding))
            {
                if (input != null)
                {
                    process.StandardInput.BaseStream.Write(input, 0, input.Length);
                    process.StandardInput.Close();
                }

                while (true)
                {
                    var line = process.StandardOutput.ReadLine();

                    if (line == null)
                    {
                        break;
                    }

                    yield return(CleanString(stripAnsiEscapeCodes, line));
                }

                while (true)
                {
                    var line = process.StandardError.ReadLine();

                    if (line == null)
                    {
                        break;
                    }

                    yield return(CleanString(stripAnsiEscapeCodes, line));
                }

                process.WaitForExit();
            }
        }
예제 #9
0
        /// <summary>
        /// Launches a process for the executable and returns <c>true</c> if its exit code is zero.
        /// </summary>
        /// <param name="executable">The executable from which to launch a process.</param>
        /// <param name="arguments">The arguments to pass to the executable.</param>
        /// <param name="input">Bytes to be written to the process's standard input stream, or <c>null</c> if no input is required.</param>
        /// <param name="createWindow">A flag indicating whether a console window should be created and bound to the process.</param>
        /// <returns>A task that yields <c>true</c> if the process's exit code was zero, otherwise <c>false</c>.</returns>
        public static async Task <bool> RunCommandAsync(
            this IExecutable executable,
            ArgumentString arguments = default,
            byte[]?input             = null,
            bool createWindow        = false)
        {
            using var process = executable.Start(arguments, createWindow: createWindow, redirectInput: input is not null);
            if (input is not null)
            {
                await process.StandardInput.BaseStream.WriteAsync(input, 0, input.Length);

                process.StandardInput.Close();
            }

            return(await process.WaitForExitAsync() == 0);
        }
        /// <summary>
        /// Launches a process for the executable and returns an object detailing exit code, standard output and standard error values.
        /// </summary>
        /// <param name="executable">The executable from which to launch a process.</param>
        /// <param name="arguments">The arguments to pass to the executable</param>
        /// <param name="writeInput">A callback that writes bytes to the process's standard input stream, or <c>null</c> if no input is required.</param>
        /// <param name="outputEncoding">The text encoding to use when decoding bytes read from the process's standard output and standard error streams, or <c>null</c> if the default encoding is to be used.</param>
        /// <param name="stripAnsiEscapeCodes">A flag indicating whether ANSI escape codes should be removed from output strings.</param>
        /// <returns>A task that yields an <see cref="ExecutionResult"/> object that gives access to exit code, standard output and standard error values.</returns>
        public static async Task <ExecutionResult> ExecuteAsync(
            this IExecutable executable,
            ArgumentString arguments,
            Action <StreamWriter> writeInput = null,
            Encoding outputEncoding          = null,
            bool stripAnsiEscapeCodes        = true)
        {
            if (outputEncoding == null)
            {
                outputEncoding = _defaultOutputEncoding.Value;
            }

            using (var process = executable.Start(arguments, createWindow: false, redirectInput: writeInput != null, redirectOutput: true, outputEncoding))
            {
                var outputBuffer = new MemoryStream();
                var errorBuffer  = new MemoryStream();
                var outputTask   = process.StandardOutput.BaseStream.CopyToAsync(outputBuffer);
                var errorTask    = process.StandardError.BaseStream.CopyToAsync(errorBuffer);

                if (writeInput != null)
                {
                    // TODO do we want to make this async?
                    writeInput(process.StandardInput);
                    process.StandardInput.Close();
                }

                var exitTask = process.WaitForExitAsync();

                await Task.WhenAll(outputTask, errorTask, exitTask);

                var output = outputEncoding.GetString(outputBuffer.GetBuffer(), 0, (int)outputBuffer.Length);
                var error  = outputEncoding.GetString(errorBuffer.GetBuffer(), 0, (int)errorBuffer.Length);

                var exitCode = await process.WaitForExitAsync();

                return(new ExecutionResult(
                           CleanString(stripAnsiEscapeCodes, output),
                           CleanString(stripAnsiEscapeCodes, error),
                           exitCode));
            }
        }
예제 #11
0
        /// <summary>
        /// Initialises a new <see cref="GitArgumentBuilder"/> for the given <paramref name="command"/>.
        /// </summary>
        /// <param name="command">The git command this builder is compiling arguments for.</param>
        /// <param name="commandConfiguration">Optional source for default command configuration items. Pass <c>null</c> to use the Git Extensions defaults.</param>
        /// <param name="gitOptions">Optional arguments that are for the git command.  EX: git --no-optional-locks status </param>
        /// <exception cref="ArgumentNullException"><paramref name="command"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException"><paramref name="command"/> is an invalid string.</exception>
        public GitArgumentBuilder([NotNull] string command, [CanBeNull] GitCommandConfiguration commandConfiguration = null, [CanBeNull] ArgumentString gitOptions = default)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            if (!_commandRegex.IsMatch(command))
            {
                throw new ArgumentException($"Git command \"{command}\" contains invalid characters.", nameof(command));
            }

            _command             = command;
            _gitArgs             = gitOptions;
            commandConfiguration = commandConfiguration ?? GitCommandConfiguration.Default;

            var defaultConfig = commandConfiguration.Get(command);

            _configItems = new List <GitConfigItem>(capacity: defaultConfig.Count + 2);
            if (defaultConfig.Count != 0)
            {
                _configItems.AddRange(defaultConfig);
            }
        }
예제 #12
0
 public string GetOutput(ArgumentString arguments)
 {
     return(this.GetOutput(arguments, null));
 }
예제 #13
0
 public BatchArgumentItem(ArgumentString argument, int count)
 {
     Argument        = argument;
     BatchItemsCount = count;
 }