/// <summary> /// Creates a string collection of task numbers with their respective /// task synopsis, for use by <see cref="Parse"/>. /// </summary> /// <param name="comments">One or more lines of comments from a Synergy task query.</param> /// <returns>A non-null collection, with zero or more tasks with their comments.</returns> public Hashtable ParseTasks(string comments) { Hashtable retVal = new Hashtable(); // substitute the parameter values in the formatted regex pattern Regex grep = new Regex(TaskFormat, RegexOptions.CultureInvariant); // look for modifications in the output from the finduse command MatchCollection matches = grep.Matches(comments); // add each task number/comment to the foreach (Match match in matches) { try { SynergyTaskInfo info = new SynergyTaskInfo(); info.DisplayName = match.Groups["displayname"].Value; info.TaskNumber = int.Parse(match.Groups["task_number"].Value, CultureInfo.InvariantCulture); if (null != match.Groups["completion_date"] && "<void>" != match.Groups["completion_date"].Value) { info.CompletionDate = DateTime.Parse(match.Groups["completion_date"].Value, CultureInfo.InvariantCulture); } if (null != match.Groups["resolver"]) { info.Resolver = match.Groups["resolver"].Value; } if (null != match.Groups["task_synopsis"]) { info.TaskSynopsis = match.Groups["task_synopsis"].Value; } retVal.Add(info.DisplayName, info); } catch (FormatException ex) { // Handle parse errors gracefully in a RELEASE build, so that // the server does not hang when a parse error occurs Debug.Assert(false, "Failed to parse task " + match.Groups["displayname"].Value, ex.Message); } } return(retVal); }
/// <summary> /// Creates a string collection of task numbers with their respective /// task synopsis, for use by <see cref="Parse"/>. /// </summary> /// <param name="comments">One or more lines of comments from a Synergy task query.</param> /// <returns>A non-null collection, with zero or more tasks with their comments.</returns> public Hashtable ParseTasks(string comments) { Hashtable retVal = new Hashtable(); // substitute the parameter values in the formatted regex pattern Regex grep = new Regex(TaskFormat, RegexOptions.CultureInvariant); // look for modifications in the output from the finduse command MatchCollection matches = grep.Matches(comments); // add each task number/comment to the foreach (Match match in matches) { try { SynergyTaskInfo info = new SynergyTaskInfo(); info.DisplayName = match.Groups["displayname"].Value; info.TaskNumber = int.Parse(match.Groups["task_number"].Value, CultureInfo.InvariantCulture); if (null != match.Groups["completion_date"] && "<void>" != match.Groups["completion_date"].Value) info.CompletionDate = DateTime.Parse(match.Groups["completion_date"].Value, CultureInfo.InvariantCulture); if (null != match.Groups["resolver"]) info.Resolver = match.Groups["resolver"].Value; if (null != match.Groups["task_synopsis"]) info.TaskSynopsis = match.Groups["task_synopsis"].Value; retVal.Add(info.DisplayName, info); } catch (FormatException ex) { // Handle parse errors gracefully in a RELEASE build, so that // the server does not hang when a parse error occurs Debug.Assert(false, "Failed to parse task " + match.Groups["displayname"].Value, ex.Message); } } return retVal; }
/// <summary> /// Creates a string collection of task numbers with their respective /// task synopsis, for use by <see cref="Parse"/>. /// </summary> /// <param name="comments">One or more lines of comments from a Synergy task query.</param> /// <returns>A non-null collection, with zero or more tasks with their comments.</returns> public Hashtable ParseTasks(string comments) { Hashtable retVal = new Hashtable(); // substitute the parameter values in the formatted regex pattern Regex grep = new Regex(TaskFormat, RegexOptions.CultureInvariant); // look for modifications in the output from the finduse command MatchCollection matches = grep.Matches(comments); // add each task number/comment to the foreach (Match match in matches) { try { SynergyTaskInfo info = new SynergyTaskInfo(); info.DisplayName = match.Groups["displayname"].Value; info.TaskNumber = int.Parse(match.Groups["task_number"].Value, CultureInfo.InvariantCulture); if (null != match.Groups["completion_date"] && "<void>" != match.Groups["completion_date"].Value) info.CompletionDate = DateTime.Parse(match.Groups["completion_date"].Value, CultureInfo.InvariantCulture); if (null != match.Groups["resolver"]) info.Resolver = match.Groups["resolver"].Value; if (null != match.Groups["task_synopsis"]) info.TaskSynopsis = match.Groups["task_synopsis"].Value; retVal.Add(info.DisplayName, info); } catch (FormatException ex) { throw new CruiseControlException("Failed to parse task " + match.Groups["displayname"].Value, ex); } } return retVal; }
/// <summary> /// Synergy specific implemtation of <see cref="IHistoryParser.Parse"/> /// </summary> /// <remarks> /// Processes both the task query and the object query to fully populate each /// <see cref="Modification"/> object in the returned array. /// </remarks> /// <param name="newTasks"> /// Standard output stream from the Synergy query command. /// </param> /// <param name="newObjects"> /// Standard output stream from the Synergy finduse command. /// </param> /// <param name="from"> /// The date since the last successful integration run. Not used, since the finduse /// query includes this parameter. /// </param> /// <returns> /// <c>null</c> by default. /// If changes have occurred since the last integration attempt, an array containing /// each new modification is returned. /// </returns> public virtual Modification[] Parse(string newTasks, string newObjects, DateTime from) { ArrayList modifications = new ArrayList(); Hashtable tasks = new Hashtable(); // don't bother doing anything if no modified objects were found if (StringUtil.IsBlank(newObjects)) { return(new Modification[0]); } // optionally, parse the comments from each associated task if (!StringUtil.IsBlank(newTasks)) { tasks = ParseTasks(newTasks); } // look for modifications in the output from the finduse command Regex grep = new Regex(ObjectFormat, RegexOptions.CultureInvariant); MatchCollection matches = grep.Matches(newObjects); // each match is a detected modification foreach (Match match in matches) { Modification modification = new Modification(); modification.FolderName = match.Groups["folder"].Value; modification.FileName = match.Groups["displayname"].Value; modification.Type = match.Groups["cvtype"].Value; modification.EmailAddress = match.Groups["resolver"].Value; modification.UserName = match.Groups["resolver"].Value; /* normalize the folder path to resemble other SCM systems * vis a vis the "$/project/folder/file" format */ if (modification.FolderName.Length > 0) { modification.FolderName = String.Concat("$/", modification.FolderName.Replace('\\', '/')); } // Retrieve the comment, if available CaptureCollection captures = match.Groups["task"].Captures; if (null != captures) { foreach (Capture capture in captures) { SynergyTaskInfo info = (SynergyTaskInfo)tasks[capture.Value]; if (info == null) { modification.ChangeNumber = Int32.Parse(Regex.Match(capture.Value, @"\d+").Value); } else { modification.ChangeNumber = info.TaskNumber; modification.ModifiedTime = info.CompletionDate; if (null != info.TaskSynopsis) { modification.Comment = info.TaskSynopsis; } } } } modifications.Add(modification); } return((Modification[])modifications.ToArray(typeof(Modification))); }