aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs
diff options
context:
space:
mode:
authorShlomo Hecht <shlomo@twine-s.com>2018-05-02 17:36:54 +0300
committerShlomo Hecht <shlomo@twine-s.com>2018-05-02 17:36:54 +0300
commitee697f7a3350d0a97bddee4de3a2ae4f9d285052 (patch)
tree2dc2e3bb811b0d89a3c4c51801c1572966fcee7c /Software/Visual_Studio/Tango.TFS/TeamFoundationServiceClient.cs
parent73c4b814f1f28170ae72723568189096413c3564 (diff)
downloadTango-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.cs248
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
}
}