private void GetWorkItemTypes(object argument) { var teamProjects = this.SelectedTeamProjects.ToList(); var task = new ApplicationTask("Retrieving work item types", teamProjects.Count, true); PublishStatus(new StatusEventArgs(task)); var step = 0; var worker = new BackgroundWorker(); worker.DoWork += (sender, e) => { var tfs = GetSelectedTfsTeamProjectCollection(); var store = tfs.GetService <WorkItemStore>(); var results = new List <WorkItemTypeInfo>(); foreach (var teamProject in teamProjects) { task.SetProgress(step++, string.Format(CultureInfo.CurrentCulture, "Processing Team Project \"{0}\"", teamProject.Name)); try { var project = store.Projects[teamProject.Name]; var categoriesXml = WorkItemConfigurationItemImportExport.GetCategoriesXml(project); var categoryList = WorkItemCategoryList.Load(categoriesXml); foreach (WorkItemType workItemType in project.WorkItemTypes) { var parameters = new Dictionary <string, object>() { { "WorkItemType", workItemType.Name }, { "TeamProject", workItemType.Project.Name } }; var workItemCount = default(int?); try { workItemCount = store.QueryCount("SELECT [System.Id] FROM WorkItems WHERE [System.WorkItemType] = @WorkItemType AND [System.TeamProject] = @TeamProject", parameters); } catch (ClientException) { // Exceptions while running the query are not important and can be ignored. // An example is "VS402337: The number of work items returned exceeds the size limit of 20000". } var referencingCategories = categoryList.Categories.Where(c => c.WorkItemTypes.Concat(new WorkItemTypeReference[] { c.DefaultWorkItemType }).Any(w => string.Equals(w.Name, workItemType.Name, StringComparison.OrdinalIgnoreCase))).Select(c => c.Name); var workItemTypeDefinition = default(WorkItemTypeDefinition); try { workItemTypeDefinition = WorkItemTypeDefinition.FromXml(workItemType.Export(false)); } catch (VssServiceResponseException) { // A VssServiceResponseException with message "VS403207: The object does not exist or access is denied" // happens when trying to export a work item type in the inherited model. workItemTypeDefinition = new WorkItemTypeDefinition(workItemType.Name, null); } results.Add(new WorkItemTypeInfo(teamProject, workItemType.Name, workItemType.Description, workItemCount, referencingCategories.ToList(), workItemTypeDefinition)); } } catch (Exception exc) { task.SetWarning(string.Format(CultureInfo.CurrentCulture, "An error occurred while processing Team Project \"{0}\"", teamProject.Name), exc); } if (task.IsCanceled) { task.Status = "Canceled"; break; } } e.Result = results; }; worker.RunWorkerCompleted += (sender, e) => { if (e.Error != null) { Logger.Log("An unexpected exception occurred while retrieving work item types", e.Error); task.SetError(e.Error); task.SetComplete("An unexpected exception occurred"); } else { this.WorkItemTypes = (ICollection <WorkItemTypeInfo>)e.Result; task.SetComplete("Retrieved " + this.WorkItemTypes.Count.ToCountString("work item type")); } }; worker.RunWorkerAsync(); }
private void ApplyTransformations(object argument) { var simulate = this.Simulate; var saveCopy = this.SaveCopy; if (!simulate) { var result = MessageBox.Show("This will apply the specified transformations to all selected Team Projects. Are you sure you want to continue?", "Confirm Transformation", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result != MessageBoxResult.Yes) { return; } } var teamProjects = this.SelectedTeamProjects.ToList(); var transformations = this.Transformations.ToList(); var task = new ApplicationTask("Transforming work item configuration", teamProjects.Count, true); PublishStatus(new StatusEventArgs(task)); var step = 0; var worker = new BackgroundWorker(); worker.DoWork += (sender, e) => { var tfs = GetSelectedTfsTeamProjectCollection(); var store = tfs.GetService <WorkItemStore>(); var numTransformations = 0; foreach (var teamProject in teamProjects) { task.SetProgress(step++, string.Format(CultureInfo.CurrentCulture, "Processing Team Project \"{0}\"", teamProject.Name)); try { var project = store.Projects[teamProject.Name]; // Apply the transformations only if everything succeeded for the Team Project; cache them in the mean time. var transformedItems = new List <WorkItemConfigurationItem>(); foreach (var transformation in transformations) { if (transformation.WorkItemConfigurationItemType == WorkItemConfigurationItemType.WorkItemType) { // Apply work item type definition transformation, which can apply to multiple work item type definitions (semicolon separated). // If no work item type names are specified, apply to all work item types in the project. var workItemTypeNames = (string.IsNullOrEmpty(transformation.WorkItemTypeNames) ? project.WorkItemTypes.Cast <WorkItemType>().Select(w => w.Name) : transformation.WorkItemTypeNames.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)); foreach (var workItemTypeName in workItemTypeNames) { // If the work item type has already been processed before, continue with that version. var itemToTransform = transformedItems.FirstOrDefault(w => string.Equals(w.Name, workItemTypeName, StringComparison.OrdinalIgnoreCase)); if (itemToTransform == null) { // If the work item type wasn't processed yet, find the one with the specified name (if it exists). var wit = project.WorkItemTypes.Cast <WorkItemType>().FirstOrDefault(w => string.Equals(w.Name, workItemTypeName, StringComparison.OrdinalIgnoreCase)); if (wit != null) { try { itemToTransform = WorkItemTypeDefinition.FromXml(wit.Export(false)); } catch (VssServiceResponseException) { // A VssServiceResponseException with message "VS403207: The object does not exist or access is denied" // happens when trying to export a work item type in the inherited model. task.Status = string.Format(CultureInfo.CurrentCulture, "Skipping work item type \"{0}\" as it cannot be modified.", wit.Name); } } } if (itemToTransform != null) { task.Status = "Transforming " + itemToTransform.DisplayName; var transformed = WorkItemConfigurationTransformer.Transform(transformation.TransformationType, itemToTransform.XmlDefinition, transformation.TransformationXml); if (string.Equals(itemToTransform.XmlDefinition.DocumentElement.OuterXml, transformed.DocumentElement.OuterXml)) { task.Status = "The transformation was applied but did not result in any changes, skipping."; } else { itemToTransform.XmlDefinition = transformed; transformedItems.Add(itemToTransform); } } else { task.Status = "Skipping \"{0}\": a work item type with this name was not found in the Team Project".FormatCurrent(workItemTypeName); } } } else if (transformation.WorkItemConfigurationItemType == WorkItemConfigurationItemType.Categories) { var itemToTransform = transformedItems.FirstOrDefault(w => w.Type == WorkItemConfigurationItemType.Categories); if (itemToTransform == null) { itemToTransform = WorkItemConfigurationItemImportExport.GetCategories(project); } task.Status = "Transforming " + itemToTransform.DisplayName; var transformed = WorkItemConfigurationTransformer.Transform(transformation.TransformationType, itemToTransform.XmlDefinition, transformation.TransformationXml); if (string.Equals(itemToTransform.XmlDefinition.DocumentElement.OuterXml, transformed.DocumentElement.OuterXml)) { task.Status = "The transformation was applied but did not result in any changes, skipping."; } else { itemToTransform.XmlDefinition = transformed; transformedItems.Add(itemToTransform); } } else if (transformation.WorkItemConfigurationItemType == WorkItemConfigurationItemType.AgileConfiguration) { var itemToTransform = transformedItems.FirstOrDefault(w => w.Type == WorkItemConfigurationItemType.AgileConfiguration); if (itemToTransform == null) { itemToTransform = WorkItemConfigurationItemImportExport.GetAgileConfiguration(project); } if (itemToTransform != null) { task.Status = "Transforming " + itemToTransform.DisplayName; var transformed = WorkItemConfigurationTransformer.Transform(transformation.TransformationType, itemToTransform.XmlDefinition, transformation.TransformationXml); if (string.Equals(itemToTransform.XmlDefinition.DocumentElement.OuterXml, transformed.DocumentElement.OuterXml)) { task.Status = "The transformation was applied but did not result in any changes, skipping."; } else { itemToTransform.XmlDefinition = transformed; transformedItems.Add(itemToTransform); } } } else if (transformation.WorkItemConfigurationItemType == WorkItemConfigurationItemType.CommonConfiguration) { var itemToTransform = transformedItems.FirstOrDefault(w => w.Type == WorkItemConfigurationItemType.CommonConfiguration); if (itemToTransform == null) { itemToTransform = WorkItemConfigurationItemImportExport.GetCommonConfiguration(project); } if (itemToTransform != null) { task.Status = "Transforming " + itemToTransform.DisplayName; var transformed = WorkItemConfigurationTransformer.Transform(transformation.TransformationType, itemToTransform.XmlDefinition, transformation.TransformationXml); if (string.Equals(itemToTransform.XmlDefinition.DocumentElement.OuterXml, transformed.DocumentElement.OuterXml)) { task.Status = "The transformation was applied but did not result in any changes, skipping."; } else { itemToTransform.XmlDefinition = transformed; transformedItems.Add(itemToTransform); } } } else if (transformation.WorkItemConfigurationItemType == WorkItemConfigurationItemType.ProcessConfiguration) { var itemToTransform = transformedItems.FirstOrDefault(w => w.Type == WorkItemConfigurationItemType.ProcessConfiguration); if (itemToTransform == null) { itemToTransform = WorkItemConfigurationItemImportExport.GetProcessConfiguration(project); } if (itemToTransform != null) { task.Status = "Transforming " + itemToTransform.DisplayName; var transformed = WorkItemConfigurationTransformer.Transform(transformation.TransformationType, itemToTransform.XmlDefinition, transformation.TransformationXml); if (string.Equals(itemToTransform.XmlDefinition.DocumentElement.OuterXml, transformed.DocumentElement.OuterXml)) { task.Status = "The transformation was applied but did not result in any changes, skipping."; } else { itemToTransform.XmlDefinition = transformed; transformedItems.Add(itemToTransform); } } } else { throw new ArgumentException("The Work Item Configuration Item Type is unknown: " + transformation.WorkItemConfigurationItemType.ToString()); } if (task.IsCanceled) { break; } } // Only apply the transformations if they all succeeded (i.e. there was no exception). if (task.IsCanceled) { break; } else { var teamProjectsWithConfigurationItems = new Dictionary <TeamProjectInfo, List <WorkItemConfigurationItem> >() { { teamProject, transformedItems } }; var options = ImportOptions.None; if (simulate) { options |= ImportOptions.Simulate; } if (saveCopy) { options |= ImportOptions.SaveCopy; } WorkItemConfigurationItemImportExport.Import(this.Logger, task, false, store, teamProjectsWithConfigurationItems, options); } numTransformations += transformedItems.Count; } catch (Exception exc) { task.SetWarning(string.Format(CultureInfo.CurrentCulture, "An error occurred while processing Team Project \"{0}\"", teamProject.Name), exc); } if (task.IsCanceled) { task.Status = "Canceled"; break; } } e.Result = numTransformations; }; worker.RunWorkerCompleted += (sender, e) => { if (e.Error != null) { Logger.Log("An unexpected exception occurred while transforming work item configuration", e.Error); task.SetError(e.Error); task.SetComplete("An unexpected exception occurred"); } else { var numTransformations = (int)e.Result; task.SetComplete("Applied transformation to " + numTransformations.ToCountString("work item configuration item")); } }; worker.RunWorkerAsync(); }