/// <summary> /// The deep copy. /// </summary> /// <returns> /// The <see cref="Issue"/>. /// </returns> public Issue DeepCopy() { var copyIssue = new Issue { Id = this.Id, Key = this.Key, Line = this.Line, Message = this.Message, Project = this.Project, Resolution = this.Resolution, Rule = this.Rule, Severity = this.Severity, Status = this.Status, UpdateDate = this.UpdateDate, CloseDate = this.CloseDate, Component = this.Component, CreationDate = this.CreationDate, EffortToFix = this.EffortToFix, Debt = this.Debt, ViolationId = this.ViolationId, Assignee = this.Assignee, ActionPlan = this.ActionPlan, IssueTrackerId = this.IssueTrackerId, Comments = new List<Comment>() }; foreach (var comment in this.Comments) { var copyComment = new Comment { CreatedAt = comment.CreatedAt, HtmlText = comment.HtmlText, Id = comment.Id, Key = comment.Key, Login = comment.Login }; copyIssue.Comments.Add(copyComment); } return copyIssue; }
/// <summary> /// The filter by resolution. /// </summary> /// <param name="parameter"> /// The parameter. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> private bool FilterByResolution(Issue parameter) { if (this.filterOption.FilterTermResolution == null) { return true; } if (this.filterOption.FilterTermResolution.Equals(parameter.Resolution)) { return true; } return false; }
/// <summary> /// The filter by severity. /// </summary> /// <param name="parameter"> /// The parameter. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> private bool FilterBySeverity(Issue parameter) { if (this.filterOption.FilterTermSeverity == null) { return true; } if (this.filterOption.FilterTermSeverity.Equals(parameter.Severity)) { return true; } return false; }
/// <summary> /// The filter by issue status. /// </summary> /// <param name="parameter"> /// The parameter. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> private bool FilterByIssueStatus(Issue parameter) { if (this.filterOption.FilterTermStatus == null) { return true; } if (this.filterOption.FilterTermStatus.Equals(parameter.Status)) { return true; } return false; }
/// <summary> /// Filters the by issue tracker. /// </summary> /// <param name="parameter">The parameter.</param> /// <returns>true if filtered</returns> private bool FilterByIssueTracker(Issue parameter) { if (this.filterOption.FilterTermIssueTrackerId == null) { return true; } if (parameter.IssueTrackerId == null) { return false; } return parameter.IssueTrackerId.IndexOf(this.filterOption.FilterTermIssueTrackerId, StringComparison.InvariantCultureIgnoreCase) >= 0; }
/// <summary> /// Filters the issues by SSCM. /// </summary> /// <param name="issue">The issue.</param> /// <returns> /// Returns issue. /// </returns> private Issue FilterIssuesBySSCM(Issue issue) { // file level issues are returned regardless if (issue.Line == 0) { return issue; } try { var blameLine = this.restSourceModel.GetBlameByLine(new Resource { Key = issue.Component }, issue.Line); if (blameLine != null) { if (blameLine.Date < this.issuesSearchViewModel.CreatedSinceDate) { return null; } } else { if (this.associatedProject == null) { this.notificationmanager.ReportMessage( new Message { Id = "IssuesSearchModel", Data = "Blame info not available in server, local blame available only associated : " + issue.Component + " : " + issue.Line }); return issue; } var translatedPath = string.Empty; try { translatedPath = this.keyTranslator.TranslateKey(issue.Component, this.visualStudioHelper, this.associatedProject.BranchName); if (!File.Exists(translatedPath)) { var message = "Search Model Failed : Translator Failed: Key : " + issue.Component + " - Path : " + translatedPath + " - KeyType : " + this.keyTranslator.GetLookupType().ToString(); this.notificationmanager.ReportMessage(new Message { Id = "IssuesSearchModel", Data = message }); return issue; } } catch (Exception ex) { IssueGridViewModel.ReportTranslationException(issue, translatedPath, this.notificationmanager, this.restService, this.associatedProject, ex); return issue; } var blameLocalLine = this.sourceModel.GetBlameByLine(translatedPath, issue.Line); if (blameLocalLine != null) { if (blameLocalLine.Date < this.issuesSearchViewModel.CreatedSinceDate) { return null; } } this.notificationmanager.ReportMessage( new Message { Id = "IssuesSearchModel", Data = "Blame Failed, Filtering Not Available for : " + translatedPath + " : " + issue.Line }); } } catch (Exception ex) { this.notificationmanager.ReportMessage( new Message { Id = "IssuesSearchModel", Data = "Blame throw exception, please report: " + ex.Message }); this.notificationmanager.ReportException(ex); } return issue; }
/// <summary> /// The filter by is new. /// </summary> /// <param name="parameter"> /// The parameter. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> private bool FilterByIsNew(Issue parameter) { if (this.filterOption.FilterTermIsNew == null) { return true; } if (parameter.IsNew && this.filterOption.FilterTermIsNew.Contains("yes")) { return true; } if (!parameter.IsNew && this.filterOption.FilterTermIsNew.Contains("no")) { return true; } return false; }
/// <summary> /// Assigns the issue to user. /// </summary> /// <param name="users">The users.</param> /// <param name="issue">The issue.</param> private void AssignIssueToUser(List<User> users, Issue issue) { if (this.assignProject == null) { return; } try { var translatedPath = this.tranlator.TranslateKey(issue.Component, this.vshelper, this.assignProject.BranchName); var blameLine = this.sourceControl.GetBlameByLine(translatedPath, issue.Line); if (blameLine != null) { foreach (var user in users) { var emailBlame = blameLine.Email.ToLower().Trim(); var emailSq = user.Email.ToLower().Trim(); if (emailBlame.Equals(emailSq)) { var issues = new List<Issue>(); issues.Add(issue); this.rest.AssignIssuesToUser(AuthtenticationHelper.AuthToken, issues, user, "VSSonarQube Extension Auto Assign"); this.manager.ReportMessage(new Message { Id = "SourceControlMenu : ", Data = "assign issue to: " + blameLine.Author + " ok" }); return; } } } else { this.manager.ReportMessage(new Message { Id = "SourceControlMenu : ", Data = "Cannot assign issue: source control information not available" }); } } catch (Exception ex) { this.manager.ReportMessage(new Message { Id = "SourceControlMenu", Data = "Failed to assign issue" + issue.Message }); this.manager.ReportException(ex); throw; } }
/// <summary> /// Populates the statistics. /// </summary> /// <param name="issue">The issue.</param> private void PopulateStatistics(Issue issue) { switch (issue.Severity) { case Severity.BLOCKER: this.NumberOfBlockers++; break; case Severity.CRITICAL: this.NumberOfCriticals++; break; case Severity.MAJOR: this.NumberOfMajors++; break; default: break; } if (!string.IsNullOrEmpty(issue.Effort)) { try { var debt = issue.Effort.Replace("min", "").Replace("sec", "").Replace("hour", "").Replace("day", "").Replace("d", "").Replace("h", ""); this.TechnicalDebt += int.Parse(debt); } catch (Exception ex) { Debug.WriteLine(ex.Message); } } }
/// <summary> /// The is not filtered. /// </summary> /// <param name="issue"> /// The issue. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> public bool IsNotFiltered(Issue issue) { return this.filter.FilterFunction(issue); }
/// <summary> /// Assigns the issue to author. /// </summary> /// <param name="users">The users.</param> /// <param name="issue">The issue.</param> private void AssignIssueToAuthor(List<User> users, Issue issue) { try { foreach (var user in users) { var emailAuthor = issue.Author; var emailSq = user.Email.ToLower().Trim(); if (emailAuthor.Equals(emailSq)) { var issues = new List<Issue>(); issues.Add(issue); this.rest.AssignIssuesToUser(this.config, issues, user, "VSSonarQube Extension Auto Assign"); this.manager.ReportMessage(new Message { Id = "SourceControlMenu : ", Data = "assign issue to: " + user.Name + " ok" }); return; } } this.manager.ReportMessage(new Message { Id = "SourceControlMenu : ", Data = "assign issue to: " + issue.Author + " failed, unable to find user by this email" }); } catch (Exception ex) { this.manager.ReportMessage(new Message { Id = "SourceControlMenu", Data = "Failed to assign issue" + issue.Message }); this.manager.ReportException(ex); throw; } }
/// <summary> /// Reports the translation exception. /// </summary> /// <param name="issue">The issue.</param> /// <param name="translatedPath">The translated path.</param> /// <param name="ex">The ex.</param> public static void ReportTranslationException(Issue issue, string translatedPath, INotificationManager manager, ISonarRestService service, Resource associatedProject, Exception ex = null) { if (ex != null) { manager.ReportMessage(new Message() { Id = "OnInEditor", Data = ex.Message + " : " + issue.Component }); manager.ReportException(ex); } manager.ReportMessage(new Message() { Id = "OnInEditor ", Data = "Was Not Able To Translate Path For Resource: " + issue.Component }); manager.ReportMessage(new Message() { Id = "OnInEditor ", Data = "Solution = " + associatedProject.SolutionRoot }); manager.ReportMessage(new Message() { Id = "OnInEditor", Data = "Translated Path = " + translatedPath }); try { service.GetResourcesData(AuthtenticationHelper.AuthToken, issue.Component); } catch (Exception exConnection) { manager.ReportMessage(new Message() { Id = "OnInEditor : Failed to get Data For Resource", Data = exConnection.Message + " : " + issue.Component }); manager.ReportException(exConnection); } }
/// <summary> /// Creates the menu items for existent issues. /// </summary> /// <param name="issue">The issue.</param> private void CreateMenuItemsForExistentIssues(Issue issue) { if (this.issueDefectCache.ContainsKey(issue.Key)) { this.GenerateSubMenus(this.issueDefectCache[issue.Key].Id); } else { var path = this.translator.TranslateKey(issue.Component, this.vshelper, this.associatedProject.BranchName); var message = this.sourceModel.GetBlameByLine(path, issue.Line); if (message != null) { var defect = this.issueTrackerPlugin.GetDefectFromCommitMessage(message.Summary); if (defect != null) { this.GenerateSubMenus(defect.Id); } if (!this.defectCache.ContainsKey(defect.Id)) { this.defectCache.Add(defect.Id, defect); } this.issueDefectCache.Add(issue.Key, defect); } else { this.manager.ReportMessage( new Message { Id = "IssueTrackerMenu", Data = "Source Control Plugin Not Available" }); } } }
/// <summary> /// Creates the menu for issue reference. /// </summary> /// <param name="issue">The issue.</param> private void CreateMenuForIssueReference(Issue issue) { if (string.IsNullOrEmpty(issue.IssueTrackerId)) { if (issue.Comments.Count == 0) { return; } foreach (var comment in issue.Comments) { if (comment.HtmlText.StartsWith(CommentMessageForIssue)) { issue.IssueTrackerId = this.GenerateIdFromMessage(comment.HtmlText); } } } if (!this.defectCache.ContainsKey(issue.IssueTrackerId)) { var defect = this.issueTrackerPlugin.GetDefect(issue.IssueTrackerId); this.defectCache.Add(issue.IssueTrackerId, defect); } this.GenerateSubMenus(issue.IssueTrackerId); }
/// <summary> /// Filters the issues by SSCM. /// </summary> /// <param name="issue">The issue.</param> /// <returns> /// Returns issue. /// </returns> private Issue FilterIssuesBySSCM(Issue issue) { // file level issues are returned regardless if (issue.Line == 0) { return issue; } var translatedPath = this.keyTranslator.TranslateKey(issue.Component, this.visualStudioHelper, this.associatedProject.BranchName); if (!File.Exists(translatedPath)) { var message = "Search Model Failed : Translator Failed: Key : " + issue.Component + " - Path : " + translatedPath + " - KeyType : " + this.keyTranslator.GetLookupType().ToString(); this.notificationmanager.ReportMessage(new Message { Id = "IssuesSearchModel", Data = message }); return null; } try { var blameLine = this.sourceModel.GetBlameByLine(translatedPath, issue.Line); if (blameLine != null) { if (blameLine.Date < this.issuesSearchViewModel.CreatedSinceDate) { return null; } } else { this.notificationmanager.ReportMessage( new Message { Id = "IssuesSearchModel", Data = "Blame Failed, Filtering Not Available. Check if a compatible source control plugin is available" }); return issue; } } catch (Exception ex) { this.notificationmanager.ReportMessage( new Message { Id = "IssuesSearchModel", Data = "Blame thorw exception, please report: " + ex.Message }); this.notificationmanager.ReportException(ex); return issue; } return issue; }
/// <summary> /// Reports the translation exception. /// </summary> /// <param name="issue">The issue.</param> /// <param name="translatedPath">The translated path.</param> /// <param name="ex">The ex.</param> private void ReportTranslationException(Issue issue, string translatedPath, Exception ex = null) { if (ex != null) { this.notificationManager.ReportMessage(new Message() { Id = "OnInEditor", Data = ex.Message + " : " + issue.Component }); this.notificationManager.ReportException(ex); } this.notificationManager.ReportMessage(new Message() { Id = "OnInEditor ", Data = "Was Not Able To Translate Path For Componenent: " + issue.Component }); this.notificationManager.ReportMessage(new Message() { Id = "OnInEditor ", Data = "Solution = " + this.sourceWorkDir }); this.notificationManager.ReportMessage(new Message() { Id = "OnInEditor", Data = "Project = " + this.sourceWorkDir }); this.notificationManager.ReportMessage(new Message() { Id = "OnInEditor", Data = "Translated Path = " + translatedPath }); try { this.restService.GetResourcesData(AuthtenticationHelper.AuthToken, issue.Component); } catch (Exception exConnection) { this.notificationManager.ReportMessage(new Message() { Id = "OnInEditor : Failed to get Data For Resource", Data = exConnection.Message + " : " + issue.Component }); this.notificationManager.ReportException(exConnection); } }