diff options
| author | Shlomo Hecht <shlomo@twine-s.com> | 2018-05-02 17:36:54 +0300 |
|---|---|---|
| committer | Shlomo Hecht <shlomo@twine-s.com> | 2018-05-02 17:36:54 +0300 |
| commit | ee697f7a3350d0a97bddee4de3a2ae4f9d285052 (patch) | |
| tree | 2dc2e3bb811b0d89a3c4c51801c1572966fcee7c /Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs | |
| parent | 73c4b814f1f28170ae72723568189096413c3564 (diff) | |
| download | Tango-ee697f7a3350d0a97bddee4de3a2ae4f9d285052.tar.gz Tango-ee697f7a3350d0a97bddee4de3a2ae4f9d285052.zip | |
merge
Diffstat (limited to 'Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs')
| -rw-r--r-- | Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs | 248 |
1 files changed, 207 insertions, 41 deletions
diff --git a/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs b/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs index e6390260e..6eef1ef92 100644 --- a/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs +++ b/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs @@ -31,6 +31,9 @@ namespace Tango.TFS public const String PRIORITY = "Microsoft.VSTS.Common.Priority"; public const String STEPS_TO_REP = "Microsoft.VSTS.TCM.ReproSteps"; public const String SYSTEM_INFO = "Microsoft.VSTS.TCM.SystemInfo"; + public const String RESOLVED_BY = "Microsoft.VSTS.Common.ResolvedBy"; + public const String RESOLVED_DATE = "Microsoft.VSTS.Common.ResolvedDate"; + public const String RESOLVED_REASON = "Microsoft.VSTS.Common.ResolvedReason"; } #endregion @@ -86,14 +89,17 @@ namespace Tango.TFS VssConnection connection = CreateConnection(); + LogManager.Log("Retrieving project " + name + " details..."); ProjectHttpClient projectClient = connection.GetClient<ProjectHttpClient>(); - TeamProjectReference project = projectClient.GetProjects(null).Result.FirstOrDefault(x => x.Name == name); + TeamProjectReference project = projectClient.GetProjects().Result.FirstOrDefault(x => x.Name == name); if (project == null) { - throw new ArgumentException(String.Format("Project '{0}' could not be found.", name)); + throw LogManager.Log(new ArgumentException(String.Format("Project '{0}' could not be found.", name))); } + LogManager.Log("Project details successfully retrieved."); + p.Name = project.Name; p.ID = project.Id; p.URL = project.Url; @@ -128,7 +134,7 @@ namespace Tango.TFS }); } - var projCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(CollectionURL)); + var projCollection = new TfsTeamProjectCollection(new Uri(CollectionURL), connection.Credentials); var store = projCollection.GetService<WorkItemStore>(); WorkItemCollection queryResults = store.Query("Select [State], [Title] " + "From WorkItems " + "Where [Work Item Type] = 'User Story'"); @@ -213,6 +219,17 @@ namespace Tango.TFS }); } + if (!String.IsNullOrWhiteSpace(workItem.Comment)) + { + patchDocument.Add(new JsonPatchOperation + { + Operation = Operation.Add, + Path = GetFieldNameForWrite(CoreField.History), + Value = workItem.Comment, + From = workItem.CreatedBy.AssignName + }); + } + patchDocument.Add(new JsonPatchOperation { Operation = Operation.Add, @@ -367,72 +384,150 @@ namespace Tango.TFS { return Task.Factory.StartNew<WorkItem>(() => { - WorkItem workItem = new WorkItem(); - var connection = CreateConnection(); WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>(); var item = witClient.GetWorkItemAsync(id, expand: Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models.WorkItemExpand.All).Result; - workItem.ID = item.Id.Value; - workItem.Title = item.Fields[GetFieldNameForRead(CoreField.Title)].ToString(); - workItem.Description = TryGetField(item.Fields, GetFieldNameForRead(CoreField.Description)); - workItem.Area = new Area() - { - Path = item.Fields[GetFieldNameForRead(CoreField.AreaPath)].ToString(), - Name = Path.GetFileName(item.Fields[GetFieldNameForRead(CoreField.AreaPath)].ToString()), - }; - workItem.Iteration = new Iteration() - { - Path = item.Fields[GetFieldNameForRead(CoreField.IterationPath)].ToString(), - Name = Path.GetFileName(item.Fields[GetFieldNameForRead(CoreField.IterationPath)].ToString()), - }; + return ConvertToWorkItem(project, item); + }); + } - workItem.AssignedTo = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.AssignedTo))); - workItem.CreatedBy = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.CreatedBy))); - workItem.ChangedBy = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.ChangedBy))); - workItem.AuthorizedAs = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.AuthorizedAs))); + /// <summary> + /// Deletes the specified work item. + /// </summary> + /// <param name="project">The project.</param> + /// <param name="id">The identifier.</param> + /// <returns></returns> + public Task DeleteWorkItem(Project project, int id) + { + return Task.Factory.StartNew(() => + { + var connection = CreateConnection(); - workItem.Type = (WorkItemType)Enum.Parse(typeof(WorkItemType), item.Fields[GetFieldNameForRead(CoreField.WorkItemType)].ToString()); - workItem.URL = item.Url; + WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>(); + var result = witClient.DeleteWorkItemAsync(id, true).Result; + }); + } - if (item.Fields.ContainsKey(GetFieldNameForRead(CoreField.Tags))) + /// <summary> + /// Gets all the work items created by the specified team member. + /// </summary> + /// <param name="project">The project.</param> + /// <param name="member">The member.</param> + /// <returns></returns> + public Task<List<WorkItem>> GetWorkItemsCreatedBy(Project project, TeamMember member) + { + return Task.Factory.StartNew<List<WorkItem>>(() => + { + var connection = CreateConnection(); + + var projCollection = new TfsTeamProjectCollection(new Uri(CollectionURL), connection.Credentials); + var store = projCollection.GetService<WorkItemStore>(); + + WorkItemCollection queryResults = store.Query(String.Format("Select [Id]" + "From WorkItems " + "Where [Created By] = '{0}' And [Work Item Type] = 'Bug'", member.AssignName)); + var ids = queryResults.OfType<Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem>().Where(x => x.Project.Name == project.Name).ToList().Select(x => x.Id).ToList(); + + if (ids.Count == 0) return new List<WorkItem>(); + + WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>(); + + var items = witClient.GetWorkItemsAsync(ids).Result; + + return items.Select(x => ConvertToWorkItem(project, x)).ToList(); + }); + } + + /// <summary> + /// Sets the state of the work item. + /// </summary> + /// <param name="project">The project.</param> + /// <param name="item">The item.</param> + /// <param name="state">The state.</param> + /// <returns></returns> + public Task<WorkItem> SetWorkItemState(Project project, WorkItem item, State state) + { + return Task.Factory.StartNew<WorkItem>(() => + { + var connection = CreateConnection(); + + WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>(); + + var patchDocument = new JsonPatchDocument(); + + patchDocument.Add(new JsonPatchOperation { - List<String> tags = item.Fields[GetFieldNameForRead(CoreField.Tags)].ToString().Split(';').Select(x => x.Trim()).ToList(); - workItem.Tags = tags.Select(x => new Tag() { Name = x }).ToList(); - } + Operation = Operation.Replace, + Path = GetFieldNameForWrite(CoreField.State), + Value = state.ToString(), + }); - workItem.FoundInBuild = item.Fields[ExtensionFields.FOUND_IN_BUILD].ToString(); + var updatedItem = witClient.UpdateWorkItemAsync(patchDocument, item.ID).Result; - workItem.State = (State)Enum.Parse(typeof(State), item.Fields[GetFieldNameForRead(CoreField.State)].ToString()); + return ConvertToWorkItem(project, updatedItem); + }); + } - workItem.Severity = ParseEnumByDescription<Severity>(item.Fields[ExtensionFields.SEVERITY].ToString()); + /// <summary> + /// Adds a comment to the work item discussion. + /// </summary> + /// <param name="project">The project.</param> + /// <param name="item">The item.</param> + /// <param name="teamMember">Team member</param> + /// <param name="comment">The comment.</param> + /// <returns></returns> + public Task<WorkItem> AddWorkItemComment(Project project, WorkItem item, TeamMember teamMember, String comment) + { + return Task.Factory.StartNew<WorkItem>(() => + { + var connection = CreateConnection(); - workItem.Priority = (Priority)int.Parse(item.Fields[ExtensionFields.PRIORITY].ToString()); + WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>(); - workItem.StepsToReproduce = item.Fields[ExtensionFields.STEPS_TO_REP].ToString(); + var patchDocument = new JsonPatchDocument(); - workItem.SystemInformation = item.Fields[ExtensionFields.SYSTEM_INFO].ToString(); + patchDocument.Add(new JsonPatchOperation + { + Operation = Operation.Add, + Path = GetFieldNameForWrite(CoreField.History), + Value = comment, + From = teamMember.AssignName + }); - return workItem; + var updatedItem = witClient.UpdateWorkItemAsync(patchDocument, item.ID).Result; + + return ConvertToWorkItem(project, updatedItem); }); } /// <summary> - /// Deletes the specified work item. + /// Sets the work item assignment. /// </summary> /// <param name="project">The project.</param> - /// <param name="id">The identifier.</param> + /// <param name="item">The item.</param> + /// <param name="member">The member.</param> /// <returns></returns> - public Task DeleteWorkItem(Project project, int id) + public Task<WorkItem> SetWorkItemAssignment(Project project, WorkItem item, TeamMember member) { - return Task.Factory.StartNew(() => + return Task.Factory.StartNew<WorkItem>(() => { var connection = CreateConnection(); WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>(); - var result = witClient.DeleteWorkItemAsync(id, true).Result; + + var patchDocument = new JsonPatchDocument(); + + patchDocument.Add(new JsonPatchOperation + { + Operation = Operation.Replace, + Path = GetFieldNameForWrite(CoreField.AssignedTo), + Value = member.AssignName, + }); + + var updatedItem = witClient.UpdateWorkItemAsync(patchDocument, item.ID).Result; + + return ConvertToWorkItem(project, updatedItem); }); } @@ -446,7 +541,19 @@ namespace Tango.TFS /// <returns></returns> private VssConnection CreateConnection() { - VssConnection connection = new VssConnection(new Uri(CollectionURL), new VssBasicCredential(UserName, PersonalToken)); + LogManager.Log("Generating VSTS connection using personal token " + PersonalToken); + VssConnection connection = new VssConnection(new Uri(CollectionURL), new VssBasicCredential(String.Empty, PersonalToken)); + connection.Credentials.PromptType = CredentialPromptType.DoNotPrompt; + connection.ConnectAsync(VssConnectMode.User).SyncResult(); + LogManager.Log("VSS Connection established..."); + + LogManager.Log("Authenticated: " + connection.HasAuthenticated); + + if (connection.HasAuthenticated) + { + LogManager.Log("Authenticated Identity: " + connection.AuthorizedIdentity.DisplayName); + } + return connection; } @@ -514,6 +621,65 @@ namespace Tango.TFS return values[description]; } + private WorkItem ConvertToWorkItem(Project project, Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models.WorkItem item) + { + WorkItem workItem = new WorkItem(); + + + workItem.ID = item.Id.Value; + workItem.Title = item.Fields[GetFieldNameForRead(CoreField.Title)].ToString(); + workItem.CreatedDate = DateTime.Parse(item.Fields[GetFieldNameForRead(CoreField.CreatedDate)].ToString()); + workItem.Description = TryGetField(item.Fields, GetFieldNameForRead(CoreField.Description)); + workItem.Area = new Area() + { + Path = item.Fields[GetFieldNameForRead(CoreField.AreaPath)].ToString(), + Name = Path.GetFileName(item.Fields[GetFieldNameForRead(CoreField.AreaPath)].ToString()), + }; + workItem.Iteration = new Iteration() + { + Path = item.Fields[GetFieldNameForRead(CoreField.IterationPath)].ToString(), + Name = Path.GetFileName(item.Fields[GetFieldNameForRead(CoreField.IterationPath)].ToString()), + }; + + workItem.AssignedTo = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.AssignedTo))); + workItem.CreatedBy = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.CreatedBy))); + workItem.ChangedBy = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.ChangedBy))); + workItem.AuthorizedAs = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, GetFieldNameForRead(CoreField.AuthorizedAs))); + + workItem.ResolvedBy = project.Members.SingleOrDefault(x => x.AssignName == TryGetField(item.Fields, ExtensionFields.RESOLVED_BY)); + + if (item.Fields.ContainsKey(ExtensionFields.RESOLVED_REASON)) + { + workItem.ResolvedReason = ParseEnumByDescription<ResolvedReason>(item.Fields[ExtensionFields.RESOLVED_REASON].ToString()); + workItem.ResolvedDate = DateTime.Parse(item.Fields[ExtensionFields.RESOLVED_DATE].ToString()); + } + + workItem.Type = (WorkItemType)Enum.Parse(typeof(WorkItemType), item.Fields[GetFieldNameForRead(CoreField.WorkItemType)].ToString()); + workItem.URL = item.Url; + + if (item.Fields.ContainsKey(GetFieldNameForRead(CoreField.Tags))) + { + List<String> tags = item.Fields[GetFieldNameForRead(CoreField.Tags)].ToString().Split(';').Select(x => x.Trim()).ToList(); + workItem.Tags = tags.Select(x => new Tag() { Name = x }).ToList(); + } + + workItem.FoundInBuild = TryGetField(item.Fields, ExtensionFields.FOUND_IN_BUILD).ToString(); + + workItem.State = (State)Enum.Parse(typeof(State), item.Fields[GetFieldNameForRead(CoreField.State)].ToString()); + + workItem.Severity = ParseEnumByDescription<Severity>(item.Fields[ExtensionFields.SEVERITY].ToString()); + + workItem.Priority = (Priority)int.Parse(item.Fields[ExtensionFields.PRIORITY].ToString()); + + workItem.StepsToReproduce = TryGetField(item.Fields, ExtensionFields.STEPS_TO_REP).ToString(); + + workItem.SystemInformation = TryGetField(item.Fields, ExtensionFields.SYSTEM_INFO).ToString(); + + workItem.Comment = TryGetField(item.Fields, GetFieldNameForRead(CoreField.History)).ToString(); + + return workItem; + } + #endregion } } |
