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