17 using System.ComponentModel;
31 #region class variables
32 private int _retVal = -1;
33 private string _cmdResult;
52 _cmdResult = cmdresult;
62 get {
return _retVal; }
63 set { _retVal = value; }
71 get {
return _cmdResult ?? String.Empty; }
72 set { _cmdResult = value; }
89 bool isValid(
string command,
int retval);
122 public virtual bool isValid(
string command,
int retval)
124 if (retval == 0 || (retval == 1 && (
125 command.StartsWith(
"diff", StringComparison.OrdinalIgnoreCase) ||
126 command.StartsWith(
"merge", StringComparison.OrdinalIgnoreCase)))
140 #region class variables
141 private static readonly
int MaxConcurrencyDefault = 8;
142 private static TaskFactory _taskFactory;
154 string maxconcurrent = Environment.GetEnvironmentVariable(
"ACUTILS_MAXCONCURRENT");
155 int max = (maxconcurrent != null) ? Int32.Parse(maxconcurrent) : MaxConcurrencyDefault;
157 _taskFactory =
new TaskFactory(ts);
160 catch (Exception ecx)
162 AcDebug.
Log($
"Exception caught and logged in AcCommand constructor{Environment.NewLine}{ecx.Message}");
186 TaskCompletionSource<AcResult> tcs =
new TaskCompletionSource<AcResult>();
187 StringBuilder error =
new StringBuilder(512);
190 await _taskFactory.StartNew(() =>
192 using (Process process =
new Process())
194 process.StartInfo.FileName =
"accurev";
195 process.StartInfo.Arguments = command;
196 process.StartInfo.UseShellExecute =
false;
197 process.StartInfo.CreateNoWindow =
true;
198 process.StartInfo.RedirectStandardInput =
true;
199 process.StartInfo.RedirectStandardOutput =
true;
200 process.StartInfo.RedirectStandardError =
true;
201 process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
202 process.StartInfo.StandardErrorEncoding = Encoding.UTF8;
203 process.ErrorDataReceived += (sender, e) =>
205 error.AppendLine(e.Data);
208 process.BeginErrorReadLine();
209 Task<string> output = process.StandardOutput.ReadToEndAsync();
210 process.WaitForExit();
211 if (process.HasExited)
213 string err = error.ToString().Trim();
214 if (!String.IsNullOrEmpty(err) &&
215 !(String.Equals(
"You are not in a directory associated with a workspace", err)))
221 if (validate.
isValid(command, process.ExitCode))
223 tcs.SetResult(
new AcResult(process.ExitCode, output.Result));
227 tcs.SetException(
new AcUtilsException($
"AccuRev program return: {process.ExitCode}{Environment.NewLine}accurev {command}"));
231 }).ConfigureAwait(
false);
234 catch (Win32Exception ecx)
236 string msg = String.Format(
@"Win32Exception caught and logged in AcCommand.runAsync{0}{1}{0}""accurev {2}""{0}errorcode: {3}{0}native errorcode: {4}{0}{5}{0}{6}{0}{7}{0}{8}",
237 Environment.NewLine, ecx.Message, command, ecx.ErrorCode.ToString(), ecx.NativeErrorCode.ToString(), ecx.StackTrace, ecx.Source, ecx.GetBaseException().Message, error.ToString());
239 tcs.SetException(ecx);
242 catch (InvalidOperationException ecx)
244 string msg = String.Format(
@"InvalidOperationException caught and logged in AcCommand.runAsync{0}{1}{0}""accurev {2}""{0}{3}",
245 Environment.NewLine, ecx.Message, command, error.ToString());
247 tcs.SetException(ecx);
250 return await tcs.Task.ConfigureAwait(
false);
269 StringBuilder error =
new StringBuilder(512);
272 using (Process process =
new Process())
274 process.StartInfo.FileName =
"accurev";
275 process.StartInfo.Arguments = command;
276 process.StartInfo.UseShellExecute =
false;
277 process.StartInfo.CreateNoWindow =
true;
278 process.StartInfo.RedirectStandardInput =
true;
279 process.StartInfo.RedirectStandardOutput =
true;
280 process.StartInfo.RedirectStandardError =
true;
281 process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
282 process.StartInfo.StandardErrorEncoding = Encoding.UTF8;
283 process.ErrorDataReceived += (sender, e) =>
285 error.AppendLine(e.Data);
287 StringBuilder output =
new StringBuilder();
288 output.Capacity = 4096;
289 process.OutputDataReceived += (sender, e) =>
291 output.AppendLine(e.Data);
294 process.BeginErrorReadLine();
295 process.BeginOutputReadLine();
296 process.WaitForExit();
297 if (process.HasExited)
299 string err = error.ToString().Trim();
300 if (!String.IsNullOrEmpty(err) &&
301 !(String.Equals(
"You are not in a directory associated with a workspace", err)))
307 if (validate.
isValid(command, process.ExitCode))
309 result.
RetVal = process.ExitCode;
314 throw new AcUtilsException($
"AccuRev program return: {process.ExitCode}{Environment.NewLine}accurev {command}");
320 catch (Win32Exception ecx)
322 string msg = String.Format(
@"Win32Exception caught and logged in AcCommand.run{0}{1}{0}""accurev {2}""{0}errorcode: {3}{0}native errorcode: {4}{0}{5}{0}{6}{0}{7}{0}{8}",
323 Environment.NewLine, ecx.Message, command, ecx.ErrorCode.ToString(), ecx.NativeErrorCode.ToString(), ecx.StackTrace, ecx.Source, ecx.GetBaseException().Message, error.ToString());
327 catch (InvalidOperationException ecx)
329 string msg = String.Format(
@"InvalidOperationException caught and logged in AcCommand.run{0}{1}{0}""accurev {2}""{0}{3}",
330 Environment.NewLine, ecx.Message, command, error.ToString());
AccuRev program return value and command result.
The default logic for determining if an AcUtilsException should be thrown based on the command's Accu...
virtual bool isValid(string command, int retval)
Default logic used to determine if an AcUtilsException should be thrown based on AccuRev's program re...
AcResult()
Default constructor.
static AcResult run(string command, ICmdValidate validator=null)
Run the AccuRev command synchronously (blocks) on the current thread.
string CmdResult
The command result (usually XML) emitted by AccuRev.
int RetVal
The AccuRev program return value for the command, otherwise minus one (-1) on error.
static void Log(string message, bool formatting=true)
Write the message text to STDOUT, to weekly log files located in %LOCALAPPDATA%\AcTools\Logs, and to trigger.log in the AccuRev server's ..storage\site_slice\logs folder in the case of triggers.
Exception thrown when an AccuRev command fails. The AccuRev program return value is zero (0) on succe...
static AcCommand()
Initialize our task scheduler that allows no more than n tasks to execute simultaneously.
AccuRev command processing.
static async Task< AcResult > runAsync(string command, ICmdValidate validator=null)
Run the AccuRev command asynchronously with non-blocking I/O.
Use to log and display error and general purpose text messages, and to save the XML param data sent b...
AcResult(int retval, string cmdresult)
Constructor for object initialization with retval and cmdresult params.
Implement to change the default logic used to determine if an AcUtilsException should be thrown based...
bool isValid(string command, int retval)
Defines the logic used to determine if an AcUtilsException should be thrown based on the AccuRev prog...
Provides a task scheduler that ensures a maximum concurrency level while running on top of the Thread...