private WorkItem ReplayRevisions(List <RevisionItem> revisionsToMigrate, WorkItem sourceWorkItem, WorkItem targetWorkItem, Project destProject, WorkItemStoreContext sourceStore,
                                         int current,
                                         WorkItemStoreContext targetStore)
        {
            try
            {
                foreach (var revision in revisionsToMigrate)
                {
                    var currentRevisionWorkItem = sourceStore.GetRevision(sourceWorkItem, revision.Number);
                    TraceWriteLine(currentRevisionWorkItem, $" Processing Revision[{revision.Number}");
                    // Decide on WIT
                    string destType = currentRevisionWorkItem.Type.Name;
                    if (me.WorkItemTypeDefinitions.ContainsKey(destType))
                    {
                        destType =
                            me.WorkItemTypeDefinitions[destType].Map(currentRevisionWorkItem);
                    }
                    //If work item hasn't been created yet, create a shell
                    if (targetWorkItem == null)
                    {
                        targetWorkItem = CreateWorkItem_Shell(destProject, currentRevisionWorkItem, destType);
                    }
                    //If the work item already exists and its type has changed, update its type. Done this way because there doesn't appear to be a way to do this through the store.
                    else if (targetWorkItem.Type.Name != destType)
                    {
                        Debug.WriteLine($"Work Item type change! '{targetWorkItem.Title}': From {targetWorkItem.Type.Name} to {destType}");
                        var typePatch = new JsonPatchOperation()
                        {
                            Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
                            Path      = "/fields/System.WorkItemType",
                            Value     = destType
                        };
                        var datePatch = new JsonPatchOperation()
                        {
                            Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
                            Path      = "/fields/System.ChangedDate",
                            Value     = currentRevisionWorkItem.Revisions[revision.Index].Fields["System.ChangedDate"].Value
                        };

                        var patchDoc = new JsonPatchDocument();
                        patchDoc.Add(typePatch);
                        patchDoc.Add(datePatch);
                        _witClient.UpdateWorkItemAsync(patchDoc, targetWorkItem.Id, bypassRules: true).Wait();
                    }

                    PopulateWorkItem(currentRevisionWorkItem, targetWorkItem, destType);
                    me.ApplyFieldMappings(currentRevisionWorkItem, targetWorkItem);

                    targetWorkItem.Fields["System.ChangedBy"].Value =
                        currentRevisionWorkItem.Revisions[revision.Index].Fields["System.ChangedBy"].Value;

                    targetWorkItem.Fields["System.History"].Value =
                        currentRevisionWorkItem.Revisions[revision.Index].Fields["System.History"].Value;
                    //Debug.WriteLine("Discussion:" + currentRevisionWorkItem.Revisions[revision.Index].Fields["System.History"].Value);


                    var fails = targetWorkItem.Validate();

                    foreach (Field f in fails)
                    {
                        TraceWriteLine(currentRevisionWorkItem,
                                       $"{current} - Invalid: {currentRevisionWorkItem.Id}-{currentRevisionWorkItem.Type.Name}-{f.ReferenceName}-{sourceWorkItem.Title} Value: {f.Value}");
                    }

                    targetWorkItem.Save();
                    TraceWriteLine(currentRevisionWorkItem,
                                   $" Saved TargetWorkItem {targetWorkItem.Id}. Replayed revision {revision.Number} of {currentRevisionWorkItem.Revisions.Count}");
                }

                if (targetWorkItem != null)
                {
                    ProcessWorkItemAttachments(sourceWorkItem, targetWorkItem, false);
                    ProcessWorkItemLinks(sourceStore, targetStore, sourceWorkItem, targetWorkItem, false);
                    string reflectedUri = sourceStore.CreateReflectedWorkItemId(sourceWorkItem);
                    if (targetWorkItem.Fields.Contains(me.Target.Config.ReflectedWorkItemIDFieldName))
                    {
                        targetWorkItem.Fields[me.Target.Config.ReflectedWorkItemIDFieldName].Value = reflectedUri;
                    }
                    var history = new StringBuilder();
                    history.Append(
                        $"This work item was migrated from a different project or organization. You can find the old version at <a href=\"{reflectedUri}\">{reflectedUri}</a>.");
                    targetWorkItem.History = history.ToString();
                    SaveWorkItem(targetWorkItem);

                    attachmentOMatic.CleanUpAfterSave(targetWorkItem);
                    TraceWriteLine(sourceWorkItem, $"...Saved as {targetWorkItem.Id}");

                    if (_config.UpdateSourceReflectedId && sourceWorkItem.Fields.Contains(me.Source.Config.ReflectedWorkItemIDFieldName))
                    {
                        sourceWorkItem.Fields[me.Source.Config.ReflectedWorkItemIDFieldName].Value =
                            targetStore.CreateReflectedWorkItemId(targetWorkItem);
                        SaveWorkItem(sourceWorkItem);
                        TraceWriteLine(sourceWorkItem, $"...and Source Updated {sourceWorkItem.Id}");
                    }
                }
            }
            catch (Exception ex)
            {
                TraceWriteLine(sourceWorkItem, "...FAILED to Save");

                if (targetWorkItem != null)
                {
                    foreach (Field f in targetWorkItem.Fields)
                    {
                        TraceWriteLine(sourceWorkItem, $"{f.ReferenceName} ({f.Name}) | {f.Value}");
                    }
                }
                TraceWriteLine(sourceWorkItem, ex.ToString());
            }
            return(targetWorkItem);
        }
Beispiel #2
0
        private WorkItem ReplayRevisions(List <RevisionItem> revisionsToMigrate, WorkItem sourceWorkItem, WorkItem targetWorkItem, Project destProject, WorkItemStoreContext sourceStore,
                                         int current,
                                         WorkItemStoreContext targetStore)
        {
            try
            {
                var skipToFinalRevisedWorkItemType = _config.SkipToFinalRevisedWorkItemType;

                var last = sourceStore.GetRevision(sourceWorkItem, revisionsToMigrate.Last().Number);

                string finalDestType = last.Type.Name;

                if (skipToFinalRevisedWorkItemType && me.WorkItemTypeDefinitions.ContainsKey(finalDestType))
                {
                    finalDestType =
                        me.WorkItemTypeDefinitions[finalDestType].Map(last);
                }

                //If work item hasn't been created yet, create a shell
                if (targetWorkItem == null)
                {
                    targetWorkItem = CreateWorkItem_Shell(destProject, sourceWorkItem, skipToFinalRevisedWorkItemType ? finalDestType : sourceStore.GetRevision(sourceWorkItem, revisionsToMigrate.First().Number).Type.Name);
                }

                if (_config.CollapseRevisions)
                {
                    var data = revisionsToMigrate.Select(rev => sourceStore.GetRevision(sourceWorkItem, rev.Number)).Select(rev => new
                    {
                        rev.Id,
                        rev.Rev,
                        rev.RevisedDate,
                        Fields = rev.Fields.AsDictionary()
                    });

                    var fileData = JsonConvert.SerializeObject(data, new JsonSerializerSettings {
                        PreserveReferencesHandling = PreserveReferencesHandling.None
                    });
                    var filePath = Path.Combine(Path.GetTempPath(), $"{sourceWorkItem.Id}_PreMigrationHistory.json");

                    File.WriteAllText(filePath, fileData);
                    targetWorkItem.Attachments.Add(new Attachment(filePath, "History has been consolidated into the attached file."));

                    revisionsToMigrate = revisionsToMigrate.GetRange(revisionsToMigrate.Count - 1, 1);

                    TraceWriteLine(targetWorkItem, $" Attached a consolidated set of {data.Count()} revisions.");
                }

                foreach (var revision in revisionsToMigrate)
                {
                    var currentRevisionWorkItem = sourceStore.GetRevision(sourceWorkItem, revision.Number);

                    TraceWriteLine(currentRevisionWorkItem, $" Processing Revision [{revision.Number}]");

                    // Decide on WIT
                    string destType = currentRevisionWorkItem.Type.Name;
                    if (me.WorkItemTypeDefinitions.ContainsKey(destType))
                    {
                        destType =
                            me.WorkItemTypeDefinitions[destType].Map(currentRevisionWorkItem);
                    }

                    //If the work item already exists and its type has changed, update its type. Done this way because there doesn't appear to be a way to do this through the store.
                    if (!skipToFinalRevisedWorkItemType && targetWorkItem.Type.Name != finalDestType)

                    {
                        Debug.WriteLine($"Work Item type change! '{targetWorkItem.Title}': From {targetWorkItem.Type.Name} to {destType}");
                        var typePatch = new JsonPatchOperation()
                        {
                            Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
                            Path      = "/fields/System.WorkItemType",
                            Value     = destType
                        };
                        var datePatch = new JsonPatchOperation()
                        {
                            Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
                            Path      = "/fields/System.ChangedDate",
                            Value     = currentRevisionWorkItem.Revisions[revision.Index].Fields["System.ChangedDate"].Value
                        };

                        var patchDoc = new JsonPatchDocument();
                        patchDoc.Add(typePatch);
                        patchDoc.Add(datePatch);
                        _witClient.UpdateWorkItemAsync(patchDoc, targetWorkItem.Id, bypassRules: true).Wait();
                    }

                    PopulateWorkItem(currentRevisionWorkItem, targetWorkItem, destType);
                    me.ApplyFieldMappings(currentRevisionWorkItem, targetWorkItem);

                    targetWorkItem.Fields["System.ChangedBy"].Value =
                        currentRevisionWorkItem.Revisions[revision.Index].Fields["System.ChangedBy"].Value;

                    targetWorkItem.Fields["System.History"].Value =
                        currentRevisionWorkItem.Revisions[revision.Index].Fields["System.History"].Value;
                    //Debug.WriteLine("Discussion:" + currentRevisionWorkItem.Revisions[revision.Index].Fields["System.History"].Value);


                    var fails = targetWorkItem.Validate();

                    foreach (Field f in fails)
                    {
                        TraceWriteLine(currentRevisionWorkItem,
                                       $"{current} - Invalid: {currentRevisionWorkItem.Id}-{currentRevisionWorkItem.Type.Name}-{f.ReferenceName}-{sourceWorkItem.Title} Value: {f.Value}");
                    }

                    targetWorkItem.Save();
                    TraceWriteLine(currentRevisionWorkItem,
                                   $" Saved TargetWorkItem {targetWorkItem.Id}. Replayed revision {revision.Number} of {revisionsToMigrate.Count}");
                }

                if (targetWorkItem != null)
                {
                    ProcessWorkItemAttachments(sourceWorkItem, targetWorkItem, false);
                    ProcessWorkItemLinks(sourceStore, targetStore, sourceWorkItem, targetWorkItem, false);
                    string reflectedUri = sourceStore.CreateReflectedWorkItemId(sourceWorkItem);
                    if (targetWorkItem.Fields.Contains(me.Target.Config.ReflectedWorkItemIDFieldName))
                    {
                        targetWorkItem.Fields[me.Target.Config.ReflectedWorkItemIDFieldName].Value = reflectedUri;
                    }
                    var history = new StringBuilder();
                    history.Append(
                        $"This work item was migrated from a different project or organization. You can find the old version at <a href=\"{reflectedUri}\">{reflectedUri}</a>.");
                    targetWorkItem.History = history.ToString();
                    SaveWorkItem(targetWorkItem);

                    attachmentOMatic.CleanUpAfterSave(targetWorkItem);
                    TraceWriteLine(sourceWorkItem, $"...Saved as {targetWorkItem.Id}");

                    if (_config.UpdateSourceReflectedId && sourceWorkItem.Fields.Contains(me.Source.Config.ReflectedWorkItemIDFieldName))
                    {
                        sourceWorkItem.Fields[me.Source.Config.ReflectedWorkItemIDFieldName].Value =
                            targetStore.CreateReflectedWorkItemId(targetWorkItem);
                        SaveWorkItem(sourceWorkItem);
                        TraceWriteLine(sourceWorkItem, $"...and Source Updated {sourceWorkItem.Id}");
                    }
                }
            }
            catch (Exception ex)
            {
                TraceWriteLine(sourceWorkItem, "...FAILED to Save");

                if (targetWorkItem != null)
                {
                    foreach (Field f in targetWorkItem.Fields)
                    {
                        TraceWriteLine(sourceWorkItem, $"{f.ReferenceName} ({f.Name}) | {f.Value}");
                    }
                }
                TraceWriteLine(sourceWorkItem, ex.ToString());
            }

            return(targetWorkItem);
        }