using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace Nuclex.NAnt.Tasks { /// Invokes the Subversion command line client executable public static class Subversion { #region class ErrorCapturer /// Captures the error message reported by Subversion, if any private class ErrorCapturer { /// Called when Subversion outputs data to the stderr stream /// Process that is outputting data /// Contains the data that was sent to stderr public void SubversionErrorDataReceived( object sender, DataReceivedEventArgs arguments ) { if(this.errorMessageBuilder == null) { this.errorMessageBuilder = new StringBuilder(); this.errorMessageBuilder.AppendLine(); } if(!string.IsNullOrEmpty(arguments.Data)) { this.errorMessageBuilder.AppendLine(arguments.Data); this.gotError = true; } } /// Called when Subversion outputs data to the stderr stream /// Process that is outputting data /// Contains the data that was sent to stderr public void SubversionOutputDataReceived( object sender, DataReceivedEventArgs arguments ) { Debug.WriteLine("stdout: " + arguments.Data); } /// The error message if an error has occured public string ErrorMessage { get { return this.errorMessageBuilder.ToString(); } } /// Whether an error has occured at all public bool ErrorOccured { get { return this.gotError; } } /// True if an error has occured private bool gotError; /// The suspected error message from Subversion private StringBuilder errorMessageBuilder; } #endregion // class ErrorCapturer /// Quotes an argument for the subversion executable /// Argument that will be quoted /// The quoted argument public static string QuoteArgument(string argument) { int additional = Math.Max(argument.Length / 2, 3); StringBuilder builder = new StringBuilder(argument.Length + additional); builder.Append('"'); //argument.IndexOf('"'); builder.Append('"'); return builder.ToString(); } /// Runs the Subversion executable /// Working directory in which to start Subversion /// Command line arguments to pass to Subversion public static void Run(string workingDirectory, string commandLine) { ErrorCapturer errorCapturer = new ErrorCapturer(); // Configure the startup options for the Subversion process Process subversion = new Process(); subversion.StartInfo.Arguments = commandLine; subversion.StartInfo.CreateNoWindow = true; subversion.StartInfo.FileName = Helpers.SubversionLocator.Location; subversion.StartInfo.WorkingDirectory = workingDirectory; subversion.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; subversion.StartInfo.RedirectStandardOutput = true; subversion.StartInfo.RedirectStandardError = true; subversion.StartInfo.UseShellExecute = false; subversion.OutputDataReceived += new DataReceivedEventHandler( errorCapturer.SubversionOutputDataReceived ); subversion.ErrorDataReceived += new DataReceivedEventHandler( errorCapturer.SubversionErrorDataReceived ); // Start the Subversion process and wait for it to end subversion.Start(); subversion.BeginOutputReadLine(); subversion.BeginErrorReadLine(); subversion.WaitForExit(); // Check if Subversion failed and throw an exception if it did int exitCode = subversion.ExitCode; if(exitCode != 0) { throw new InvalidOperationException(errorCapturer.ErrorMessage ?? "unknown error"); } } } } // namespace Nuclex.NAnt.Tasks