Example #1
0
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            //////////////////////////////////////////////////
            WorkItemStoreContext sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.None);
            TfsQueryContext      tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Name);
            tfsqc.Query = @"SELECT [System.Id] FROM WorkItems WHERE  [System.TeamProject] = @TeamProject ";// AND [System.Id] = 188708 ";
            WorkItemCollection sourceWIS = tfsqc.Execute();

            Trace.WriteLine(string.Format("Migrate {0} work items?", sourceWIS.Count));
            //////////////////////////////////////////////////

            int current = sourceWIS.Count;

            foreach (WorkItem sourceWI in sourceWIS)
            {
                System.Threading.Thread.Sleep(10);
            }
            stopwatch.Stop();
            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            //////////////////////////////////////////////////



            WorkItemStoreContext sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.None);
            TfsQueryContext      tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Config.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY [System.ChangedDate] desc", _config.QueryBit);
            WorkItemCollection sourceWIS = tfsqc.Execute();

            int current        = sourceWIS.Count;
            var workItemServer = me.Source.Collection.GetService <WorkItemServer>();

            var invalidFileNameChars = Path.GetInvalidFileNameChars();

            foreach (WorkItem wi in sourceWIS)
            {
                WorkItemAttachmentExport(workItemServer, wi);
                current++;
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"EXPORT DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
Example #3
0
        public WorkItem FindReflectedWorkItemByReflectedWorkItemId(int refId, bool cache)
        {
            var sourceIdKey = ~refId;

            if (foundWis.TryGetValue(sourceIdKey, out var workItem))
            {
                return(workItem);
            }

            IEnumerable <WorkItem> QueryWorkItems()
            {
                TfsQueryContext query = new TfsQueryContext(this);

                query.Query = string.Format(@"SELECT [System.Id] FROM WorkItems  WHERE [System.TeamProject]=@TeamProject AND [{0}] Contains '@idToFind'", teamProjectContext.Config.ReflectedWorkItemIDFieldName);
                query.AddParameter("idToFind", refId.ToString());
                query.AddParameter("TeamProject", this.teamProjectContext.Config.Project);
                foreach (WorkItem wi in query.Execute())
                {
                    yield return(wi);
                }
            }

            var foundWorkItem = QueryWorkItems().FirstOrDefault(wi => wi.Fields[teamProjectContext.Config.ReflectedWorkItemIDFieldName].Value.ToString().EndsWith("/" + refId));

            if (cache && foundWorkItem != null)
            {
                foundWis[sourceIdKey] = foundWorkItem;
            }
            return(foundWorkItem);
        }
Example #4
0
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            //////////////////////////////////////////////////
            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            TfsQueryContext      tfsqc       = new TfsQueryContext(targetStore);

            tfsqc.AddParameter("TeamProject", me.Target.Config.Project);
            tfsqc.Query = string.Format(@"SELECT [System.Id] FROM WorkItems WHERE  [System.TeamProject] = @TeamProject  AND [System.AreaPath] UNDER '{0}\_DeleteMe'", me.Target.Config.Project);
            WorkItemCollection workitems = tfsqc.Execute();

            Trace.WriteLine(string.Format("Update {0} work items?", workitems.Count));
            //////////////////////////////////////////////////
            int current = workitems.Count;
            //int count = 0;
            //long elapsedms = 0;
            var tobegone = (from WorkItem wi in workitems where wi.AreaPath.Contains("_DeleteMe")  select wi.Id).ToList();

            foreach (int begone in tobegone)
            {
                targetStore.Store.DestroyWorkItems(new List <int>()
                {
                    begone
                });
                Trace.WriteLine(string.Format("Deleted {0}", begone));
            }


            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
Example #5
0
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            //////////////////////////////////////////////////



            WorkItemStoreContext sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.None);
            TfsQueryContext      tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY [System.ChangedDate] desc", _config.QueryBit);
            WorkItemCollection sourceWIS = tfsqc.Execute();

            int current        = sourceWIS.Count;
            var workItemServer = me.Source.Collection.GetService <WorkItemServer>();

            var invalidFileNameChars = Path.GetInvalidFileNameChars();

            foreach (WorkItem wi in sourceWIS)
            {
                Trace.Write(string.Format("Attachement Export: {0} of {1} - {2}", current, sourceWIS.Count, wi.Id));
                foreach (Attachment wia in wi.Attachments)
                {
                    string fname = string.Format("{0}#{1}", wi.Id, wia.Name);
                    fname = GetSafeFilename(fname);

                    Trace.Write("-");
                    Trace.Write(fname);

                    string fpath = Path.Combine(exportPath, fname);
                    if (!File.Exists(fpath))
                    {
                        Trace.Write("...downloading");
                        try
                        {
                            var fileLocation = workItemServer.DownloadFile(wia.Id);
                            File.Copy(fileLocation, fpath, true);
                            Trace.Write("...done");
                        }
                        catch (Exception ex)
                        {
                            Telemetry.Current.TrackException(ex);
                            Trace.Write($"\r\nException downloading attachements {ex.Message}");
                        }
                    }
                    else
                    {
                        Trace.Write("...skipping");
                    }
                    Trace.WriteLine("...done");
                }
                current--;
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"EXPORT DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            //////////////////////////////////////////////////
            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);

            TfsQueryContext tfsqc = new TfsQueryContext(targetStore);

            TfsTeamService            teamService = me.Target.Collection.GetService <TfsTeamService>();
            QueryHierarchy            qh          = targetStore.Store.Projects[me.Target.Config.Project].QueryHierarchy;
            List <TeamFoundationTeam> teamList    = teamService.QueryTeams(me.Target.Config.Project).ToList();

            Trace.WriteLine(string.Format("Found {0} teams?", teamList.Count));
            //////////////////////////////////////////////////
            int  current   = teamList.Count;
            int  count     = 0;
            long elapsedms = 0;

            foreach (TeamFoundationTeam team in teamList)
            {
                Stopwatch witstopwatch = Stopwatch.StartNew();

                Trace.Write(string.Format("Processing team {0}", team.Name));
                Regex  r = new Regex(@"^Project - ([a-zA-Z ]*)");
                string path;
                if (r.IsMatch(team.Name))
                {
                    Trace.Write(string.Format(" is a Project"));
                    path = string.Format(@"Projects\{0}", r.Match(team.Name).Groups[1].Value.Replace(" ", "-"));
                }
                else
                {
                    Trace.Write(string.Format(" is a Team"));
                    path = string.Format(@"Teams\{0}", team.Name.Replace(" ", "-"));
                }
                Trace.Write(string.Format(" and new path is {0}", path));
                //me.AddFieldMap("*", new RegexFieldMap("KM.Simulation.Team", "System.AreaPath", @"^Project - ([a-zA-Z ]*)", @"Nemo\Projects\$1"));

                string[] bits = path.Split(char.Parse(@"\"));

                CreateFolderHyerarchy(bits, qh["Shared Queries"]);

                //_me.ApplyFieldMappings(workitem);
                qh.Save();


                witstopwatch.Stop();
                elapsedms = elapsedms + witstopwatch.ElapsedMilliseconds;
                current--;
                count++;
                TimeSpan average   = new TimeSpan(0, 0, 0, 0, (int)(elapsedms / count));
                TimeSpan remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * current));
                Trace.WriteLine("");
                //Trace.WriteLine(string.Format("Average time of {0} per work item and {1} estimated to completion", string.Format(@"{0:s\:fff} seconds", average), string.Format(@"{0:%h} hours {0:%m} minutes {0:s\:fff} seconds", remaining)));
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
 public WorkItem FindReflectedWorkItemByTitle(string title)
 {
     TfsQueryContext query = new TfsQueryContext(this);
     query.Query = @"SELECT [System.Id] FROM WorkItems  WHERE [System.TeamProject]=@TeamProject AND [System.Title] = @TitleToFind";
     query.AddParameter("TitleToFind", title);
     query.AddParameter("TeamProject", this.targetTfs.Name);
     return FindWorkItemByQuery(query);
 }
 public WorkItem FindReflectedWorkItemByMigrationRef(string refId)
 {
     TfsQueryContext query = new TfsQueryContext(this);
     query.Query = @"SELECT [System.Id] FROM WorkItems  WHERE [System.TeamProject]=@TeamProject AND [System.Description] Contains @KeyToFind";
     query.AddParameter("KeyToFind", string.Format("##REF##{0}##", refId));
     query.AddParameter("TeamProject", this.targetTfs.Name);
     return FindWorkItemByQuery(query);
 }
 public WorkItem FindReflectedWorkItemByReflectedWorkItemId(string refId, string reflectedWotkItemIdField)
 {
     TfsQueryContext query = new TfsQueryContext(this);
     query.Query = string.Format(@"SELECT [System.Id] FROM WorkItems  WHERE [System.TeamProject]=@TeamProject AND [{0}] = @idToFind", reflectedWotkItemIdField);
     query.AddParameter("idToFind", refId.ToString());
     query.AddParameter("TeamProject", this.targetTfs.Name);
     return FindWorkItemByQuery(query);
 }
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            //////////////////////////////////////////////////



            WorkItemStoreContext sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.None);
            TfsQueryContext      tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY [System.ChangedDate] desc", _config.QueryBit);
            WorkItemCollection sourceWIS = tfsqc.Execute();

            WebClient webClient = new WebClient();

            webClient.Credentials = CredentialCache.DefaultNetworkCredentials;
            int current = sourceWIS.Count;

            foreach (WorkItem wi in sourceWIS)
            {
                Trace.Write(string.Format("Attachement Export: {0} of {1} - {2}", current, sourceWIS.Count, wi.Id));
                foreach (Attachment wia in wi.Attachments)
                {
                    string reflectedId = sourceStore.CreateReflectedWorkItemId(wi);
                    string fname       = string.Format("{0}#{1}", reflectedId.Replace("/", "-").Replace(":", "+"), wia.Name);
                    Trace.Write("-");
                    Trace.Write(fname);
                    string fpath = Path.Combine(exportPath, fname);
                    if (!File.Exists(fpath))
                    {
                        Trace.Write("...downloading");
                        try
                        {
                            webClient.DownloadFile(wia.Uri, fpath);
                            Trace.Write("...done");
                        }
                        catch (Exception ex)
                        {
                            Telemetry.Current.TrackException(ex);
                            Trace.Write("...failed");
                        }
                    }
                    else
                    {
                        Trace.Write("...skipping");
                    }
                    Trace.WriteLine("...done");
                }
                current--;
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"EXPORT DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
Example #11
0
        public WorkItem FindReflectedWorkItemByMigrationRef(string refId)
        {
            TfsQueryContext query        = new TfsQueryContext(this);
            StringBuilder   queryBuilder = FindReflectedWorkItemQueryBase(query);

            queryBuilder.Append(" [System.Description] Contains @KeyToFind");
            query.AddParameter("KeyToFind", string.Format("##REF##{0}##", refId));
            query.Query = queryBuilder.ToString();
            return(FindWorkItemByQuery(query));
        }
Example #12
0
        public WorkItem FindReflectedWorkItemByReflectedWorkItemId(string refId)
        {
            TfsQueryContext query        = new TfsQueryContext(this);
            StringBuilder   queryBuilder = FindReflectedWorkItemQueryBase(query);

            queryBuilder.AppendFormat("[{0}] = @idToFind", teamProjectContext.Config.ReflectedWorkItemIDFieldName);
            query.AddParameter("idToFind", refId.ToString());
            query.Query = queryBuilder.ToString();
            return(FindWorkItemByQuery(query));
        }
 public WorkItem FindWorkItemByQuery(TfsQueryContext query)
 {
     WorkItemCollection newFound;
     newFound = query.Execute();
     if (newFound.Count == 0)
     {
         return null;
     }
     return newFound[0];
 }
Example #14
0
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            TfsQueryContext      tfsqc       = new TfsQueryContext(targetStore);

            tfsqc.AddParameter("TeamProject", me.Target.Name);
            tfsqc.Query =
                $@"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {_config.QueryBit} ORDER BY [System.ChangedDate] desc";
            WorkItemCollection targetWIS = tfsqc.Execute();

            Trace.WriteLine($"Found {targetWIS.Count} work items...", Name);

            current = targetWIS.Count;

            string urlForMatch = me.Source.Collection.Uri.ToString();

            if (_config.FromAnyCollection)
            {
                var url = new Uri(me.Source.Collection.Uri.ToString());
                urlForMatch = url.GetLeftPart(UriPartial.Authority);
            }

            Trace.WriteLine($"Searching for urls: {urlForMatch} and {GetUrlWithOppositeSchema(urlForMatch)} {_config.SourceServerAliases?.Select(alias => "and " + alias)}");

            foreach (WorkItem targetWi in targetWIS)
            {
                Trace.WriteLine($"{current} - Fixing: {targetWi.Id}-{targetWi.Type.Name}", Name);

                // Decide on WIT
                if (me.WorkItemTypeDefinitions.ContainsKey(targetWi.Type.Name))
                {
                    FixHtmlAttachmentLinks(targetWi, urlForMatch, me.Target.Collection.Uri.ToString());
                }
                else
                {
                    Trace.WriteLine(
                        $"...the WITD named {targetWi.Type.Name} is not in the list provided in the configuration.json under WorkItemTypeDefinitions. Add it to the list to enable migration of this work item type.", Name);
                    skipped++;
                }

                current--;
                count++;

                Trace.Flush();
            }

            stopwatch.Stop();
            Trace.WriteLine($@"DONE in {stopwatch.Elapsed:%h} hours {stopwatch.Elapsed:%m} minutes {stopwatch.Elapsed:s\:fff} seconds - {targetWIS.Count} Items, {updated} Updated, {skipped} Skipped, {failures} Failures, {candidates} Possible Candidates, {notfound} Not Found", this.Name);
        }
        internal override void InternalExecute()
        {
            var stopwatch = Stopwatch.StartNew();
            //////////////////////////////////////////////////
            var sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.BypassRules);
            var tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Config.Project);
            tfsqc.Query =
                string.Format(
                    @"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY {1}",
                    _config.QueryBit, _config.OrderBit);
            var sourceQueryResult = tfsqc.Execute();
            var sourceWorkItems   = (from WorkItem swi in sourceQueryResult select swi).ToList();

            Trace.WriteLine($"Replay all revisions of {sourceWorkItems.Count} work items?", Name);
            //////////////////////////////////////////////////
            var targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            var destProject = targetStore.GetProject();

            Trace.WriteLine($"Found target project as {destProject.Name}", Name);
            //////////////////////////////////////////////////////////FilterCompletedByQuery
            if (_config.FilterWorkItemsThatAlreadyExistInTarget)
            {
                sourceWorkItems = FilterWorkItemsThatAlreadyExistInTarget(sourceWorkItems, targetStore);
            }
            //////////////////////////////////////////////////
            _current       = 1;
            _count         = sourceWorkItems.Count;
            _elapsedms     = 0;
            _totalWorkItem = sourceWorkItems.Count;

            //Validation: make sure that the ReflectedWorkItemId field name specified in the config exists in the target process, preferably on each work item type.
            ConfigValidation();

            foreach (WorkItem sourceWorkItem in sourceWorkItems)
            {
                ProcessWorkItem(sourceStore, targetStore, destProject, sourceWorkItem, _config.WorkItemCreateRetryLimit);
                if (_config.PauseAfterEachWorkItem)
                {
                    Console.WriteLine("Do you want to continue? (y/n)");
                    if (Console.ReadKey().Key != ConsoleKey.Y)
                    {
                        Trace.WriteLine("USER ABORTED", "[Warning]");
                        break;
                    }
                }
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();

            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
Example #16
0
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            //////////////////////////////////////////////////
            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            var targetQuery = new TfsQueryContext(targetStore);

            targetQuery.AddParameter("TeamProject", me.Target.Config.Project);
            targetQuery.Query =
                string.Format(
                    @"SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY {1}",
                    _config.QueryBit,
                    _config.OrderBit
                    );
            WorkItemCollection workitems = targetQuery.Execute();

            Trace.WriteLine(string.Format("Update {0} work items?", workitems.Count));
            //////////////////////////////////////////////////
            int  current   = workitems.Count;
            int  count     = 0;
            long elapsedms = 0;
            int  noteFound = 0;

            foreach (WorkItem workitem in workitems)
            {
                Stopwatch witstopwatch = Stopwatch.StartNew();
                workitem.Open();

                _RepoOMatic.FixExternalLinks(workitem, targetStore, null);

                if (workitem.IsDirty)
                {
                    Trace.WriteLine($"Saving {workitem.Id}");

                    workitem.Save();
                }

                witstopwatch.Stop();
                elapsedms = elapsedms + witstopwatch.ElapsedMilliseconds;
                current--;
                count++;
                TimeSpan average   = new TimeSpan(0, 0, 0, 0, (int)(elapsedms / count));
                TimeSpan remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * current));
                Trace.WriteLine(string.Format("Average time of {0} per work item and {1} estimated to completion",
                                              string.Format(@"{0:s\:fff} seconds", average),
                                              string.Format(@"{0:%h} hours {0:%m} minutes {0:s\:fff} seconds", remaining)));
            }
            Trace.WriteLine(string.Format("Did not find old repo for {0} links?", noteFound));
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
Example #17
0
        private StringBuilder FindReflectedWorkItemQueryBase(TfsQueryContext query)
        {
            StringBuilder s = new StringBuilder();

            s.Append("SELECT [System.Id] FROM WorkItems");
            s.Append(" WHERE ");
            if (!teamProjectContext.Config.AllowCrossProjectLinking)
            {
                s.Append("[System.TeamProject]=@TeamProject AND ");
                query.AddParameter("TeamProject", this.teamProjectContext.Config.Project);
            }
            return(s);
        }
Example #18
0
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            TfsQueryContext      tfsqc       = new TfsQueryContext(targetStore);

            tfsqc.AddParameter("TeamProject", me.Target.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY [System.Id] ", _config.QueryBit);
            WorkItemCollection targetWIS = tfsqc.Execute();

            Trace.WriteLine(string.Format("Found {0} work items...", targetWIS.Count), Name);

            current = targetWIS.Count;

            string urlForMatch = me.Source.Collection.Uri.ToString();

            if (_config.FromAnyCollection)
            {
                var url = new Uri(me.Source.Collection.Uri.ToString());
                urlForMatch = url.GetLeftPart(UriPartial.Authority);
            }

            Trace.WriteLine(String.Format("Searching for urls: {0} and {1}", urlForMatch, GetUrlWithOppositeSchema(urlForMatch)));

            foreach (WorkItem targetWi in targetWIS)
            {
                Trace.WriteLine(string.Format("{0} - Fixing: {1}-{2}", current, targetWi.Id, targetWi.Type.Name), Name);

                // Deside on WIT
                if (me.WorkItemTypeDefinitions.ContainsKey(targetWi.Type.Name))
                {
                    FixHtmlAttachmentLinks(targetWi, urlForMatch, me.Target.Collection.Uri.ToString());
                }
                else
                {
                    Trace.WriteLine("...not supported", Name);
                    skipped++;
                }

                current--;
                count++;

                Trace.Flush();
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Trace.WriteLine(string.Format(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds - {1} Items, {2} Updated, {3} Skipped, {4} Failures, {5} Possible Candidates", stopwatch.Elapsed, targetWIS.Count, updated, skipped, failures, candidates), this.Name);
        }
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            //////////////////////////////////////////////////
            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);

            TfsQueryContext tfsqc = new TfsQueryContext(targetStore);

            tfsqc.AddParameter("TeamProject", me.Target.Name);
            tfsqc.AddParameter("AreaPath", config.AreaIterationPath);
            tfsqc.Query = @"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE  [System.TeamProject] = @TeamProject and [System.AreaPath] under @AreaPath";
            WorkItemCollection workitems = tfsqc.Execute();

            Trace.WriteLine(string.Format("Update {0} work items?", workitems.Count));
            //////////////////////////////////////////////////
            int  current   = workitems.Count;
            int  count     = 0;
            long elapsedms = 0;

            foreach (WorkItem workitem in workitems)
            {
                Stopwatch witstopwatch = new Stopwatch();
                witstopwatch.Start();

                Trace.WriteLine(string.Format("{0} - Updating: {1}-{2}", current, workitem.Id, workitem.Type.Name));
                string        areaPath   = workitem.AreaPath;
                List <string> bits       = new List <string>(areaPath.Split(char.Parse(@"\"))).Skip(4).ToList();
                List <string> tags       = workitem.Tags.Split(char.Parse(@";")).ToList();
                List <string> newTags    = tags.Union(bits).ToList();
                string        newTagList = string.Join(";", newTags.ToArray());
                if (newTagList != workitem.Tags)
                {
                    workitem.Open();
                    workitem.Tags = newTagList;
                    workitem.Save();
                }

                witstopwatch.Stop();
                elapsedms = elapsedms + witstopwatch.ElapsedMilliseconds;
                current--;
                count++;
                TimeSpan average   = new TimeSpan(0, 0, 0, 0, (int)(elapsedms / count));
                TimeSpan remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * current));
                Trace.WriteLine(string.Format("Average time of {0} per work item and {1} estimated to completion", string.Format(@"{0:s\:fff} seconds", average), string.Format(@"{0:%h} hours {0:%m} minutes {0:s\:fff} seconds", remaining)));
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
Example #20
0
        private List <WorkItem> FilterWorkItemsThatAlreadyExistInTarget(List <WorkItem> sourceWorkItems, WorkItemStoreContext targetStore)
        {
            var targetQuery = new TfsQueryContext(targetStore);

            targetQuery.AddParameter("TeamProject", me.Target.Config.Name);
            targetQuery.Query =
                string.Format(
                    @"SELECT [System.Id], [{0}] FROM WorkItems WHERE [System.TeamProject] = @TeamProject ORDER BY [System.ChangedDate] desc", me.Target.Config.ReflectedWorkItemIDFieldName);
            var targetFoundItems = targetQuery.Execute();
            var targetFoundIds   = (from WorkItem twi in targetFoundItems select targetStore.GetReflectedWorkItemId(twi, me.Target.Config.ReflectedWorkItemIDFieldName)).ToList();

            //////////////////////////////////////////////////////////

            sourceWorkItems = sourceWorkItems.Where(p => !targetFoundIds.Any(p2 => p2 == p.Id)).ToList();
            return(sourceWorkItems);
        }
Example #21
0
        internal override void InternalExecute()
        {
            WorkItemStoreContext sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.BypassRules);
            TfsQueryContext      tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Config.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id] FROM WorkItems WHERE  [System.TeamProject] = @TeamProject {0} ORDER BY [System.ChangedDate] desc ", config.QueryBit); // AND  [Microsoft.VSTS.Common.ClosedDate] = ''
            WorkItemCollection sourceWIS = tfsqc.Execute();

            //////////////////////////////////////////////////

            Trace.WriteLine(string.Format("Migrate {0} work items links?", sourceWIS.Count), "LinkMigrationContext");
            int current = sourceWIS.Count;
            //////////////////////////////////////////////////
            WorkItemStoreContext targetWitsc = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            Project targetProj = targetWitsc.GetProject();
            //////////////////////////////////////////////////
            WorkItemLinkOMatic linkomatic = new WorkItemLinkOMatic();

            foreach (WorkItem wiSourceL in sourceWIS)
            {
                Trace.WriteLine(string.Format("Migrating Links for wiSourceL={0}", wiSourceL.Id), "LinkMigrationContext");
                WorkItem wiTargetL = null;
                try
                {
                    wiTargetL = targetWitsc.FindReflectedWorkItem(wiSourceL, true);
                }
                catch (Exception)
                {
                    Trace.WriteLine(string.Format("Cannot find twiTargetL matching wiSourceL={0} probably due to missing ReflectedWorkItemID", wiSourceL.Id), "LinkMigrationContext");
                }

                if (wiTargetL == null)
                {
                    //wiSourceL was not migrated, or the migrated work item has been deleted.
                    Trace.WriteLine(string.Format("[SKIP] Unable to migrate links where wiSourceL={0}, wiTargetL=NotFound",
                                                  wiSourceL.Id), "LinkMigrationContext");
                    continue;
                }
                Trace.WriteLine(string.Format("Found Target Left wiSourceL={0}, wiTargetL=NotFound",
                                              wiSourceL.Id), "LinkMigrationContext");

                linkomatic.MigrateLinks(wiSourceL, sourceStore, wiTargetL, targetWitsc);

                current--;
            }
        }
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            TfsQueryContext      tfsqc       = new TfsQueryContext(targetStore);

            tfsqc.AddParameter("TeamProject", me.Target.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject ORDER BY [System.ChangedDate] desc");
            WorkItemCollection targetWIS = tfsqc.Execute();

            Trace.WriteLine(string.Format("Found {0} work items...", targetWIS.Count), Name);

            int current  = targetWIS.Count;
            int count    = 0;
            int failures = 0;
            int imported = 0;
            int skipped  = 0;

            foreach (WorkItem targetWi in targetWIS)
            {
                Trace.WriteLine(string.Format("{0} - Fixing: {1}-{2}", current, targetWi.Id, targetWi.Type.Name), Name);

                // Deside on WIT
                if (me.WorkItemTypeDefinitions.ContainsKey(targetWi.Type.Name))
                {
                    FixHtmlAttachmentLinks(targetWi, me.Source.Collection.Uri.ToString(), me.Target.Collection.Uri.ToString());
                }
                else
                {
                    Trace.WriteLine("...not supported", Name);
                    skipped++;
                }

                current--;
                count++;

                Trace.Flush();
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Trace.WriteLine(string.Format(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds - {1} Items, {2} Imported, {3} Skipped, {4} Failures", stopwatch.Elapsed, targetWIS.Count, imported, skipped, failures), this.Name);
        }
Example #23
0
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            //////////////////////////////////////////////////
            WorkItemStoreContext sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.BypassRules);
            TfsQueryContext      tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY [System.ChangedDate] desc", _config.QueryBit);
            WorkItemCollection sourceWIS = tfsqc.Execute();

            Trace.WriteLine(string.Format("Migrate {0} work items?", sourceWIS.Count), this.Name);
            //////////////////////////////////////////////////
            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            Project destProject = targetStore.GetProject();

            Trace.WriteLine(string.Format("Found target project as {0}", destProject.Name), this.Name);

            int  current   = sourceWIS.Count;
            int  count     = 0;
            long elapsedms = 0;

            foreach (WorkItem sourceWI in sourceWIS)
            {
                Stopwatch witstopwatch = new Stopwatch();
                witstopwatch.Start();
                WorkItem targetFound;
                targetFound = targetStore.FindReflectedWorkItem(sourceWI, me.ReflectedWorkItemIdFieldName, false);
                Trace.WriteLine(string.Format("{0} - Migrating: {1}-{2}", current, sourceWI.Id, sourceWI.Type.Name), this.Name);
                if (targetFound == null)
                {
                    WorkItem newwit = null;
                    // Deside on WIT
                    if (me.WorkItemTypeDefinitions.ContainsKey(sourceWI.Type.Name))
                    {
                        newwit = CreateAndPopulateWorkItem(_config, sourceWI, destProject, me.WorkItemTypeDefinitions[sourceWI.Type.Name].Map(sourceWI));
                        if (newwit.Fields.Contains(me.ReflectedWorkItemIdFieldName))
                        {
                            newwit.Fields[me.ReflectedWorkItemIdFieldName].Value = sourceStore.CreateReflectedWorkItemId(sourceWI);
                        }
                        me.ApplyFieldMappings(sourceWI, newwit);
                        ArrayList fails = newwit.Validate();
                        foreach (Field f in fails)
                        {
                            Trace.WriteLine(string.Format("{0} - Invalid: {1}-{2}-{3}", current, sourceWI.Id, sourceWI.Type.Name, f.ReferenceName), this.Name);
                        }
                    }
                    else
                    {
                        Trace.WriteLine("...not supported", this.Name);
                    }

                    if (newwit != null)
                    {
                        try
                        {
                            if (_config.UpdateCreatedDate)
                            {
                                newwit.Fields["System.CreatedDate"].Value = sourceWI.Fields["System.CreatedDate"].Value;
                            }
                            if (_config.UpdateCreatedBy)
                            {
                                newwit.Fields["System.CreatedBy"].Value = sourceWI.Fields["System.CreatedBy"].Value;
                            }
                            newwit.Save();
                            newwit.Close();
                            Trace.WriteLine(string.Format("...Saved as {0}", newwit.Id), this.Name);
                            if (sourceWI.Fields.Contains(me.ReflectedWorkItemIdFieldName) && _config.UpdateSoureReflectedId)
                            {
                                sourceWI.Fields[me.ReflectedWorkItemIdFieldName].Value = targetStore.CreateReflectedWorkItemId(newwit);
                            }
                            sourceWI.Save();
                            Trace.WriteLine(string.Format("...and Source Updated {0}", sourceWI.Id), this.Name);
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine("...FAILED to Save", this.Name);
                            foreach (Field f in newwit.Fields)
                            {
                                Trace.WriteLine(string.Format("{0} | {1}", f.ReferenceName, f.Value), this.Name);
                            }
                            Trace.WriteLine(ex.ToString(), this.Name);
                        }
                    }
                }
                else
                {
                    Console.WriteLine("...Exists");

                    //  sourceWI.Open();
                    //  sourceWI.SyncToLatest();
                    //  sourceWI.Fields["TfsMigrationTool.ReflectedWorkItemId"].Value = destWIFound[0].Id;
                    //sourceWI.Save();
                }
                sourceWI.Close();
                witstopwatch.Stop();
                elapsedms = elapsedms + witstopwatch.ElapsedMilliseconds;
                current--;
                count++;
                TimeSpan average   = new TimeSpan(0, 0, 0, 0, (int)(elapsedms / count));
                TimeSpan remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * current));
                Trace.WriteLine(string.Format("Average time of {0} per work item and {1} estimated to completion", string.Format(@"{0:s\:fff} seconds", average), string.Format(@"{0:%h} hours {0:%m} minutes {0:s\:fff} seconds", remaining)), this.Name);
                Trace.Flush();
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
Example #24
0
        internal override void InternalExecute()
        {
            WorkItemStoreContext sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.BypassRules);
            TfsQueryContext      tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id] FROM WorkItems WHERE  [System.TeamProject] = @TeamProject {0} ORDER BY [System.ChangedDate] desc ", config.QueryBit); // AND  [Microsoft.VSTS.Common.ClosedDate] = ''
            WorkItemCollection sourceWIS = tfsqc.Execute();

            //////////////////////////////////////////////////

            Trace.WriteLine(string.Format("Migrate {0} work items links?", sourceWIS.Count), "LinkMigrationContext");
            int current = sourceWIS.Count;
            //////////////////////////////////////////////////
            WorkItemStoreContext targetWitsc = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            Project targetProj = targetWitsc.GetProject();

            //////////////////////////////////////////////////
            foreach (WorkItem wiSourceL in sourceWIS)
            {
                Trace.WriteLine(string.Format("Migrating Links for wiSourceL={0}", wiSourceL.Id), "LinkMigrationContext");
                WorkItem wiTargetL = null;
                try
                {
                    wiTargetL = targetWitsc.FindReflectedWorkItem(wiSourceL, me.ReflectedWorkItemIdFieldName, true);
                }
                catch (Exception)
                {
                    Trace.WriteLine(string.Format("Cannot find twiTargetL matching wiSourceL={0} probably due to missing ReflectedWorkItemID", wiSourceL.Id), "LinkMigrationContext");
                }

                if (wiTargetL == null)
                {
                    //wiSourceL was not migrated, or the migrated work item has been deleted.
                    Trace.WriteLine(string.Format("[SKIP] Unable to migrate links where wiSourceL={0}, wiTargetL=NotFound",
                                                  wiSourceL.Id), "LinkMigrationContext");
                    continue;
                }
                Trace.WriteLine(string.Format("Found Target Left wiSourceL={0}, wiTargetL=NotFound",
                                              wiSourceL.Id), "LinkMigrationContext");
                if (wiTargetL.Links.Count == wiSourceL.Links.Count)
                {
                    Trace.WriteLine(string.Format("[SKIP] Source and Target have same number of links  {0} - {1}", wiSourceL.Id, wiSourceL.Type.ToString()), "LinkMigrationContext");
                }
                else
                {
                    try
                    {
                        Trace.Indent();
                        foreach (Link item in wiSourceL.Links)
                        {
                            Trace.WriteLine(string.Format("Migrating link for {0} of type {1}",
                                                          wiSourceL.Id, item.GetType().Name), "LinkMigrationContext");
                            if (IsHyperlink(item))
                            {
                                CreateHyperlink((Hyperlink)item, wiTargetL);
                            }
                            else if (IsRelatedLink(item))
                            {
                                RelatedLink rl = (RelatedLink)item;
                                CreateRelatedLink(wiSourceL, rl, wiTargetL, sourceStore, targetWitsc);
                            }
                            else if (IsExternalLink(item))
                            {
                                ExternalLink rl = (ExternalLink)item;
                                CreateExternalLink((ExternalLink)item, wiTargetL);
                            }
                            else
                            {
                                UnknownLinkTypeException ex = new UnknownLinkTypeException(string.Format("  [UnknownLinkType] Unable to {0}", item.GetType().Name));
                                Telemetry.Current.TrackException(ex);
                                Trace.WriteLine(ex.ToString(), "LinkMigrationContext");
                                throw ex;
                            }
                        }
                    }
                    catch (WorkItemLinkValidationException ex)
                    {
                        wiSourceL.Reset();
                        wiTargetL.Reset();
                        Telemetry.Current.TrackException(ex);
                        Trace.WriteLine(string.Format("  [WorkItemLinkValidationException] Adding link for wiSourceL={0}", wiSourceL.Id), "LinkMigrationContext");
                        Trace.WriteLine(ex.ToString(), "LinkMigrationContext");
                    }
                    catch (Exception ex)
                    {
                        Telemetry.Current.TrackException(ex);
                        Trace.WriteLine(string.Format("  [CREATE-FAIL] Adding Link for wiSourceL={0}", wiSourceL.Id), "LinkMigrationContext");
                        Trace.WriteLine(ex.ToString(), "LinkMigrationContext");
                    }
                }
                if (wiSourceL.Type.Name == "Test Case")
                {
                    MigrateSharedSteps(wiSourceL, wiTargetL, sourceStore, targetWitsc);
                }

                current--;
            }
        }
        internal override void InternalExecute()
        {
            var stopwatch = Stopwatch.StartNew();
            //////////////////////////////////////////////////
            var sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.BypassRules);
            var tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Name);
            tfsqc.Query =
                string.Format(
                    @"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY [System.ChangedDate] desc",
                    _config.QueryBit);
            var sourceWorkItems = tfsqc.Execute();

            Trace.WriteLine($"Replay all revisions of {sourceWorkItems.Count} work items?", Name);

            //////////////////////////////////////////////////
            var targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            var destProject = targetStore.GetProject();

            Trace.WriteLine($"Found target project as {destProject.Name}", Name);

            var  current   = sourceWorkItems.Count;
            var  count     = 0;
            long elapsedms = 0;

            //Validation: make sure that the ReflectedWorkItemId field name specified in the config exists in the target process, preferably on each work item type.
            ConfigValidation();

            foreach (WorkItem sourceWorkItem in sourceWorkItems)
            {
                var witstopwatch = Stopwatch.StartNew();
                var targetFound  = targetStore.FindReflectedWorkItem(sourceWorkItem, me.ReflectedWorkItemIdFieldName, false);
                Trace.WriteLine($"{current} - Migrating: {sourceWorkItem.Id} - {sourceWorkItem.Type.Name}", Name);

                if (targetFound == null)
                {
                    ReplayRevisions(sourceWorkItem, destProject, sourceStore, current, targetStore);
                }
                else
                {
                    Console.WriteLine("...Exists");
                }

                sourceWorkItem.Close();
                witstopwatch.Stop();
                elapsedms += witstopwatch.ElapsedMilliseconds;
                current--;
                count++;
                var average   = new TimeSpan(0, 0, 0, 0, (int)(elapsedms / count));
                var remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * current));
                Trace.WriteLine(
                    string.Format("Average time of {0} per work item and {1} estimated to completion",
                                  string.Format(@"{0:s\:fff} seconds", average),
                                  string.Format(@"{0:%h} hours {0:%m} minutes {0:s\:fff} seconds", remaining)), Name);
                Trace.Flush();
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();

            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
        //private void PopulateIgnoreList()
        //      {
        //          _ignore = new List<string>();
        //          //ignore.Add("System.CreatedDate");
        //          //ignore.Add("System.CreatedBy");
        //          _ignore.Add("System.Rev");
        //          _ignore.Add("System.AreaId");
        //          _ignore.Add("System.IterationId");
        //          _ignore.Add("System.Id");
        //          //ignore.Add("System.ChangedDate");
        //          //ignore.Add("System.ChangedBy");
        //          _ignore.Add("System.RevisedDate");
        //          _ignore.Add("System.AttachedFileCount");
        //          _ignore.Add("System.TeamProject");
        //          _ignore.Add("System.NodeName");
        //          _ignore.Add("System.RelatedLinkCount");
        //          _ignore.Add("System.WorkItemType");
        //          _ignore.Add("Microsoft.VSTS.Common.ActivatedDate");
        //          _ignore.Add("Microsoft.VSTS.Common.StateChangeDate");
        //          _ignore.Add("System.ExternalLinkCount");
        //          _ignore.Add("System.HyperLinkCount");
        //          _ignore.Add("System.Watermark");
        //          _ignore.Add("System.AuthorizedDate");
        //          _ignore.Add("System.BoardColumn");
        //          _ignore.Add("System.BoardColumnDone");
        //          _ignore.Add("System.BoardLane");
        //          _ignore.Add("SLB.SWT.DateOfClientFeedback");
        //      }

        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            //////////////////////////////////////////////////
            WorkItemStoreContext sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.BypassRules);
            TfsQueryContext      tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY [System.Id] ", _config.QueryBit);
            WorkItemCollection sourceWIS = tfsqc.Execute();

            Trace.WriteLine(string.Format("Migrate {0} work items?", sourceWIS.Count), this.Name);
            //////////////////////////////////////////////////
            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            Project destProject = targetStore.GetProject();

            Trace.WriteLine(string.Format("Found target project as {0}", destProject.Name), this.Name);

            int  current   = sourceWIS.Count;
            int  count     = 0;
            int  failures  = 0;
            int  imported  = 0;
            int  skipped   = 0;
            long elapsedms = 0;

            foreach (WorkItem sourceWI in sourceWIS)
            {
                Stopwatch witstopwatch = new Stopwatch();
                witstopwatch.Start();
                WorkItem targetWit;
                targetWit = targetStore.FindReflectedWorkItem(sourceWI, me.ReflectedWorkItemIdFieldName, false);
                Trace.WriteLine(string.Format("{0} - Migrating: {1}-{2}", current, sourceWI.Id, sourceWI.Type.Name), this.Name);
                if (targetWit == null)
                {
                    WorkItem newwit = null;
                    // Deside on WIT
                    if (me.WorkItemTypeDefinitions.ContainsKey(sourceWI.Type.Name))
                    {
                        newwit = CreateAndPopulateWorkItem(_config, sourceWI, destProject, me.WorkItemTypeDefinitions[sourceWI.Type.Name].Map(sourceWI));
                        if (newwit.Fields.Contains(me.ReflectedWorkItemIdFieldName))
                        {
                            newwit.Fields[me.ReflectedWorkItemIdFieldName].Value = sourceStore.CreateReflectedWorkItemId(sourceWI);
                        }
                        me.ApplyFieldMappings(sourceWI, newwit);
                        if (newwit.Fields["System.History"].Value != null)
                        {
                            var history = $"{newwit.Fields["System.History"].Value}";
                            var witLink = "href=\"x-mvwit:workitem";
                            var extLink = "href=\"https://dev.azure.com/oemwork";

                            if (history.Contains(witLink) || history.Contains(extLink))
                            {
                                history = history.Replace(witLink, string.Empty);
                                history = history.Replace(extLink, string.Empty);
                                newwit.Fields["System.History"].Value = history;
                            }
                        }
                        if (newwit.Fields["System.ChangedBy"].Value.ToString().Contains("Ayuba Audu"))
                        {
                            newwit.Fields["System.ChangedBy"].Value = "wpicustm";
                        }
                        if (newwit.Fields["System.CreatedBy"].Value.ToString().Contains("Ayuba Audu"))
                        {
                            newwit.Fields["System.CreatedBy"].Value = "wpicustm";
                        }
                        ArrayList fails = newwit.Validate();
                        foreach (Field f in fails)
                        {
                            Trace.WriteLine(string.Format("{0} - Invalid: {1}-{2}-{3}", current, sourceWI.Id, sourceWI.Type.Name, f.ReferenceName), this.Name);
                        }
                    }
                    else
                    {
                        Trace.WriteLine("...not supported", this.Name);
                        skipped++;
                    }

                    if (newwit != null)
                    {
                        try
                        {
                            if (_config.UpdateCreatedDate)
                            {
                                newwit.Fields["System.CreatedDate"].Value = sourceWI.Fields["System.CreatedDate"].Value;
                            }
                            if (_config.UpdateCreatedBy)
                            {
                                newwit.Fields["System.CreatedBy"].Value = sourceWI.Fields["System.CreatedBy"].Value;
                            }
                            newwit.Save();
                            newwit.Close();
                            Trace.WriteLine(string.Format("...Saved as {0}", newwit.Id), this.Name);
                            if (!string.IsNullOrWhiteSpace(me.SourceReflectedWorkItemIdFieldName) && sourceWI.Fields.Contains(me.SourceReflectedWorkItemIdFieldName) && _config.UpdateSoureReflectedId)
                            {
                                sourceWI.Fields[me.SourceReflectedWorkItemIdFieldName].Value = targetStore.CreateReflectedWorkItemId(newwit);
                                sourceWI.Save();
                            }
                            Trace.WriteLine(string.Format("...and Source Updated {0}", sourceWI.Id), this.Name);
                            imported++;
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine("...FAILED to Save", this.Name);
                            failures++;
                            foreach (Field f in newwit.Fields)
                            {
                                Trace.WriteLine(string.Format("{0} | {1}", f.ReferenceName, f.Value), this.Name);
                            }
                            Trace.WriteLine(ex.ToString(), this.Name);
                        }
                    }
                }
                else if (_config.UpdateTargetIfAlreadyExists)
                {
                    Trace.WriteLine("Exists. Trying to update with latest snapshot", this.Name);
                    // Deside on WIT
                    if (me.WorkItemTypeDefinitions.ContainsKey(sourceWI.Type.Name))
                    {
                        targetWit = CreateAndPopulateWorkItem(_config, sourceWI, destProject, me.WorkItemTypeDefinitions[sourceWI.Type.Name].Map(sourceWI), targetWit);
                        me.ApplyFieldMappings(sourceWI, targetWit);
                        if (targetWit.Fields["System.History"].Value != null)
                        {
                            var history = $"{targetWit.Fields["System.History"].Value}";
                            var witLink = "href=\"x-mvwit:workitem";
                            var extLink = "href=\"https://dev.azure.com/oemwork";

                            if (history.Contains(witLink) || history.Contains(extLink))
                            {
                                history = history.Replace(witLink, string.Empty);
                                history = history.Replace(extLink, string.Empty);
                                targetWit.Fields["System.History"].Value = history;
                            }
                        }

                        if (targetWit.Fields["System.ChangedBy"].Value.ToString().Contains("Ayuba Audu"))
                        {
                            targetWit.Fields["System.ChangedBy"].Value = "wpicustm";
                        }
                        if (targetWit.Fields["System.CreatedBy"].Value.ToString().Contains("Ayuba Audu"))
                        {
                            targetWit.Fields["System.CreatedBy"].Value = "wpicustm";
                        }
                        ArrayList fails = targetWit.Validate();
                        foreach (Field f in fails)
                        {
                            Trace.WriteLine(string.Format("{0} - Invalid: {1}-{2}-{3}", current, sourceWI.Id, sourceWI.Type.Name, f.ReferenceName), this.Name);
                        }

                        try
                        {
                            targetWit.Save();
                            targetWit.Close();
                            Trace.WriteLine(
                                $" ...Updated {targetWit.Id}.",
                                Name);
                        }
                        catch (Exception e)
                        {
                            Trace.TraceError(e.Message);
                        }
                    }
                    else
                    {
                        Trace.WriteLine("...not supported", this.Name);
                        skipped++;
                    }
                }
                else
                {
                    //Trace.WriteLine("...Exists", this.Name);
                    skipped++;
                    //  sourceWI.Open();
                    //sourceWI.SyncToLatest();
                    //  sourceWI.Fields["TfsMigrationTool.ReflectedWorkItemId"].Value = destWIFound[0].Id;
                    //sourceWI.Save();
                }
                sourceWI.Close();
                witstopwatch.Stop();
                elapsedms = elapsedms + witstopwatch.ElapsedMilliseconds;
                current--;
                count++;
                TimeSpan average   = new TimeSpan(0, 0, 0, 0, (int)(elapsedms / count));
                TimeSpan remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * current));
                Trace.WriteLine(string.Format("Average time of {0} per work item and {1} estimated to completion", string.Format(@"{0:s\:fff} seconds", average), string.Format(@"{0:%h} hours {0:%m} minutes {0:s\:fff} seconds", remaining)), this.Name);
                Trace.Flush();
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Trace.WriteLine(string.Format(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds - {1} Items, {2} Imported, {3} Skipped, {4} Failures", stopwatch.Elapsed, sourceWIS.Count, imported, skipped, failures), this.Name);
        }
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            //////////////////////////////////////////////////
            var sourceGitRepoService = me.Source.Collection.GetService <GitRepositoryService>();
            var sourceGitRepos       = sourceGitRepoService.QueryRepositories(me.Source.Name);
            //////////////////////////////////////////////////
            var targetGitRepoService = me.Target.Collection.GetService <GitRepositoryService>();
            var targetGitRepos       = targetGitRepoService.QueryRepositories(me.Target.Name);

            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            TfsQueryContext      tfsqc       = new TfsQueryContext(targetStore);

            tfsqc.AddParameter("TeamProject", me.Target.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id] FROM WorkItems WHERE  [System.TeamProject] = @TeamProject {0}", _config.QueryBit);
            WorkItemCollection workitems = tfsqc.Execute();

            Trace.WriteLine(string.Format("Update {0} work items?", workitems.Count));
            //////////////////////////////////////////////////
            int  current   = workitems.Count;
            int  count     = 0;
            long elapsedms = 0;
            int  noteFound = 0;

            foreach (WorkItem workitem in workitems)
            {
                Stopwatch witstopwatch = new Stopwatch();
                witstopwatch.Start();
                workitem.Open();
                List <ExternalLink> newEL    = new List <ExternalLink>();
                List <ExternalLink> removeEL = new List <ExternalLink>();
                Trace.WriteLine(string.Format("WI: {0}?", workitem.Id));
                List <string> gitWits = new List <string>
                {
                    "Branch",
                    "Fixed in Commit",
                    "Pull Request"
                };

                foreach (Link l in workitem.Links)
                {
                    if (l is ExternalLink && gitWits.Contains(l.ArtifactLinkType.Name))
                    {
                        ExternalLink el = (ExternalLink)l;
                        //vstfs:///Git/Commit/25f94570-e3e7-4b79-ad19-4b434787fd5a%2f50477259-3058-4dff-ba4c-e8c179ec5327%2f41dd2754058348d72a6417c0615c2543b9b55535
                        string   guidbits     = el.LinkedArtifactUri.Substring(el.LinkedArtifactUri.LastIndexOf('/') + 1);
                        string[] bits         = Regex.Split(guidbits, "%2f", RegexOptions.IgnoreCase);
                        string   oldCommitId  = null;
                        string   oldGitRepoId = bits[1];
                        if (bits.Count() >= 3)
                        {
                            oldCommitId = $"{bits[2]}";
                            for (int i = 3; i < bits.Count(); i++)
                            {
                                oldCommitId += $"%2f{bits[i]}";
                            }
                        }
                        else
                        {
                            oldCommitId = bits[2];
                        }
                        var oldGitRepo =
                            (from g in sourceGitRepos where g.Id.ToString() == oldGitRepoId select g)
                            .SingleOrDefault();

                        if (oldGitRepo != null)
                        {
                            // Find the target git repo
                            GitRepository newGitRepo        = null;
                            var           repoNameToLookFor = !string.IsNullOrEmpty(_config.TargetRepository)
                                ? _config.TargetRepository
                                : oldGitRepo.Name;

                            // Source and Target project names match
                            if (oldGitRepo.ProjectReference.Name == me.Target.Name)
                            {
                                newGitRepo = (from g in targetGitRepos
                                              where
                                              g.Name == repoNameToLookFor &&
                                              g.ProjectReference.Name == oldGitRepo.ProjectReference.Name
                                              select g).SingleOrDefault();
                            }
                            // Source and Target project names do not match
                            else
                            {
                                newGitRepo = (from g in targetGitRepos
                                              where
                                              g.Name == repoNameToLookFor &&
                                              g.ProjectReference.Name != oldGitRepo.ProjectReference.Name
                                              select g).SingleOrDefault();
                            }

                            // Fix commit links if target repo has been found
                            if (newGitRepo != null)
                            {
                                Trace.WriteLine($"Fixing {oldGitRepo.RemoteUrl} to {newGitRepo.RemoteUrl}?");

                                // Create External Link object
                                ExternalLink newLink = null;
                                switch (l.ArtifactLinkType.Name)
                                {
                                case "Branch":
                                    newLink = new ExternalLink(targetStore.Store.RegisteredLinkTypes[ArtifactLinkIds.Branch],
                                                               $"vstfs:///git/ref/{newGitRepo.ProjectReference.Id}%2f{newGitRepo.Id}%2f{oldCommitId}");
                                    break;

                                case "Fixed in Commit":
                                    newLink = new ExternalLink(targetStore.Store.RegisteredLinkTypes[ArtifactLinkIds.Commit],
                                                               $"vstfs:///git/commit/{newGitRepo.ProjectReference.Id}%2f{newGitRepo.Id}%2f{oldCommitId}");
                                    break;

                                case "Pull Request":
                                    newLink = new ExternalLink(targetStore.Store.RegisteredLinkTypes[ArtifactLinkIds.PullRequest],
                                                               $"vstfs:///Git/PullRequestId/{newGitRepo.ProjectReference.Id}%2f{newGitRepo.Id}%2f{oldCommitId}");
                                    break;

                                default:
                                    Trace.WriteLine(String.Format("Skipping unsupported link type {0}", l.ArtifactLinkType.Name));
                                    break;
                                }

                                if (newLink != null)
                                {
                                    var elinks = from Link lq in workitem.Links
                                                 where gitWits.Contains(lq.ArtifactLinkType.Name)
                                                 select(ExternalLink) lq;
                                    var found =
                                        (from Link lq in elinks
                                         where (((ExternalLink)lq).LinkedArtifactUri.ToLower() == newLink.LinkedArtifactUri.ToLower())
                                         select lq).SingleOrDefault();
                                    if (found == null)
                                    {
                                        newEL.Add(newLink);
                                    }
                                    removeEL.Add(el);
                                }
                            }
                            else
                            {
                                Trace.WriteLine($"FAIL: cannot map {oldGitRepo.RemoteUrl} to ???");
                            }
                        }
                        else
                        {
                            Trace.WriteLine($"FAIL could not find source git repo");
                            noteFound++;
                        }
                    }
                }
                // add and remove
                foreach (ExternalLink eln in newEL)
                {
                    try
                    {
                        Trace.WriteLine("Adding " + eln.LinkedArtifactUri, Name);
                        workitem.Links.Add(eln);
                    }
                    catch (Exception)
                    {
                        // eat exception as sometimes TFS thinks this is an attachment
                    }
                }
                foreach (ExternalLink elr in removeEL)
                {
                    if (workitem.Links.Contains(elr))
                    {
                        try
                        {
                            Trace.WriteLine("Removing " + elr.LinkedArtifactUri, Name);
                            workitem.Links.Remove(elr);
                        }
                        catch (Exception)
                        {
                            // eat exception as sometimes TFS thinks this is an attachment
                        }
                    }
                }

                if (workitem.IsDirty)
                {
                    Trace.WriteLine($"Saving {workitem.Id}");
                    workitem.Save();
                }

                witstopwatch.Stop();
                elapsedms = elapsedms + witstopwatch.ElapsedMilliseconds;
                current--;
                count++;
                TimeSpan average   = new TimeSpan(0, 0, 0, 0, (int)(elapsedms / count));
                TimeSpan remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * current));
                Trace.WriteLine(string.Format("Average time of {0} per work item and {1} estimated to completion",
                                              string.Format(@"{0:s\:fff} seconds", average),
                                              string.Format(@"{0:%h} hours {0:%m} minutes {0:s\:fff} seconds", remaining)));
            }
            Trace.WriteLine(string.Format("Did not find old repo for {0} links?", noteFound));
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
Example #28
0
        //public WorkItemPostProcessingContext(MigrationEngine me, WorkItemPostProcessingConfig config, IList<string> wiTypes) : this(me, config)
        //{
        //    _workItemTypes = wiTypes;
        //}

        //public WorkItemPostProcessingContext(MigrationEngine me, WorkItemPostProcessingConfig config, IList<int> wiIDs) : this(me, config)
        //{
        //    _workItemIDs = wiIDs;
        //}

        //public WorkItemPostProcessingContext(MigrationEngine me, WorkItemPostProcessingConfig config, string queryBit) : this (me, config)
        //{
        //    _queryBit = queryBit;
        //}

        internal override void InternalExecute()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            //////////////////////////////////////////////////
            WorkItemStoreContext sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.None);
            TfsQueryContext      tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Config.Name);

            //Builds the constraint part of the query
            string constraints = BuildQueryBitConstraints();

            tfsqc.Query = string.Format(@"SELECT [System.Id] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY [System.Id] ", constraints);

            WorkItemCollection sourceWIS = tfsqc.Execute();

            Trace.WriteLine(string.Format("Migrate {0} work items?", sourceWIS.Count));
            //////////////////////////////////////////////////
            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);
            Project destProject = targetStore.GetProject();

            Trace.WriteLine(string.Format("Found target project as {0}", destProject.Name));


            int  current   = sourceWIS.Count;
            int  count     = 0;
            long elapsedms = 0;

            foreach (WorkItem sourceWI in sourceWIS)
            {
                Stopwatch witstopwatch = Stopwatch.StartNew();
                WorkItem  targetFound;
                targetFound = targetStore.FindReflectedWorkItem(sourceWI, false);
                Trace.WriteLine(string.Format("{0} - Updating: {1}-{2}", current, sourceWI.Id, sourceWI.Type.Name));
                if (targetFound == null)
                {
                    Trace.WriteLine(string.Format("{0} - WARNING: does not exist {1}-{2}", current, sourceWI.Id, sourceWI.Type.Name));
                }
                else
                {
                    Console.WriteLine("...Exists");
                    targetFound.Open();
                    me.ApplyFieldMappings(sourceWI, targetFound);
                    if (targetFound.IsDirty)
                    {
                        try
                        {
                            targetFound.Save();
                            Trace.WriteLine(string.Format("          Updated"));
                        }
                        catch (ValidationException ve)
                        {
                            Trace.WriteLine(string.Format("          [FAILED] {0}", ve.ToString()));
                        }
                    }
                    else
                    {
                        Trace.WriteLine(string.Format("          No changes"));
                    }
                    sourceWI.Close();
                }
                witstopwatch.Stop();
                elapsedms = elapsedms + witstopwatch.ElapsedMilliseconds;
                current--;
                count++;
                TimeSpan average   = new TimeSpan(0, 0, 0, 0, (int)(elapsedms / count));
                TimeSpan remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * current));
                Trace.WriteLine(string.Format("Average time of {0} per work item and {1} estimated to completion", string.Format(@"{0:s\:fff} seconds", average), string.Format(@"{0:%h} hours {0:%m} minutes {0:s\:fff} seconds", remaining)));
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
        internal override void InternalExecute()
        {
            if (_config == null)
            {
                throw new Exception("You must call Configure() first");
            }
            var workItemServer = me.Source.Collection.GetService <WorkItemServer>();

            attachmentOMatic = new AttachmentOMatic(workItemServer, _config.AttachmentWorkingPath, _config.AttachmentMazSize);
            repoOMatic       = new RepoOMatic(me);
            VssClientCredentials adoCreds = new VssClientCredentials();

            _witClient = new WorkItemTrackingHttpClient(me.Target.Collection.Uri, adoCreds);
            //Validation: make sure that the ReflectedWorkItemId field name specified in the config exists in the target process, preferably on each work item type.
            ConfigValidation();
            PopulateIgnoreList();

            var stopwatch = Stopwatch.StartNew();
            //////////////////////////////////////////////////
            var sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.BypassRules, Telemetry);
            var tfsqc       = new TfsQueryContext(sourceStore, Telemetry);

            tfsqc.AddParameter("TeamProject", me.Source.Config.Project);
            tfsqc.Query =
                string.Format(
                    @"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY {1}",
                    _config.QueryBit, _config.OrderBit);
            var sourceQueryResult = tfsqc.Execute();
            var sourceWorkItems   = (from WorkItem swi in sourceQueryResult select swi).ToList();

            contextLog.Information("Replay all revisions of {sourceWorkItemsCount} work items?", sourceWorkItems.Count);
            //////////////////////////////////////////////////
            var targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules, Telemetry);
            var destProject = targetStore.GetProject();

            contextLog.Information("Found target project as {@destProject}", destProject.Name);
            //////////////////////////////////////////////////////////FilterCompletedByQuery
            if (_config.FilterWorkItemsThatAlreadyExistInTarget)
            {
                sourceWorkItems = FilterWorkItemsThatAlreadyExistInTarget(sourceWorkItems, targetStore);
            }
            //////////////////////////////////////////////////
            _current       = 1;
            _count         = sourceWorkItems.Count;
            _elapsedms     = 0;
            _totalWorkItem = sourceWorkItems.Count;
            foreach (WorkItem sourceWorkItem in sourceWorkItems)
            {
                workItemLog = contextLog.ForContext("SourceWorkItemId", sourceWorkItem.Id);
                using (LogContext.PushProperty("sourceWorkItemTypeName", sourceWorkItem.Type.Name))
                    using (LogContext.PushProperty("currentWorkItem", _current))
                        using (LogContext.PushProperty("totalWorkItems", _totalWorkItem))
                            using (LogContext.PushProperty("sourceWorkItemId", sourceWorkItem.Id))
                                using (LogContext.PushProperty("sourceRevisionInt", sourceWorkItem.Revision))
                                    using (LogContext.PushProperty("targetWorkItemId", null))
                                    {
                                        ProcessWorkItem(sourceStore, targetStore, destProject, sourceWorkItem, _config.WorkItemCreateRetryLimit);
                                        if (_config.PauseAfterEachWorkItem)
                                        {
                                            Console.WriteLine("Do you want to continue? (y/n)");
                                            if (Console.ReadKey().Key != ConsoleKey.Y)
                                            {
                                                workItemLog.Warning("USER ABORTED");
                                                break;
                                            }
                                        }
                                    }
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();

            contextLog.Information("DONE in {Elapsed}", stopwatch.Elapsed.ToString("c"));
        }
        internal override void InternalExecute()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            //////////////////////////////////////////////////



            WorkItemStoreContext sourceStore = new WorkItemStoreContext(me.Source, WorkItemStoreFlags.None);
            TfsQueryContext      tfsqc       = new TfsQueryContext(sourceStore);

            tfsqc.AddParameter("TeamProject", me.Source.Name);
            tfsqc.Query = string.Format(@"SELECT [System.Id], [System.Tags] FROM WorkItems WHERE [System.TeamProject] = @TeamProject {0} ORDER BY [System.Id] ", _config.QueryBit);
            WorkItemCollection sourceWIS = tfsqc.Execute();

            int current        = sourceWIS.Count;
            var workItemServer = me.Source.Collection.GetService <WorkItemServer>();

            foreach (WorkItem wi in sourceWIS)
            {
                Trace.Write(string.Format("Attachement Export: {0} of {1} - {2}", current, sourceWIS.Count, wi.Id));
                foreach (Attachment wia in wi.Attachments)
                {
                    string reflectedId            = sourceStore.CreateReflectedWorkItemId(wi);
                    var    attachmentUploadedDate = $"{wia.AttachedTime}";
                    var    attachmentUploaded     = attachmentUploadedDate.Replace("/", "--").Replace(":", "+");

                    // We will create a folder for the work item and place all attachments there.
                    var workitemFolder = reflectedId.Replace("/", "--").Replace(":", "+");
                    Directory.CreateDirectory(Path.Combine(exportPath, workitemFolder));
                    var fpath = Path.Combine(exportPath, workitemFolder, $"{attachmentUploaded}@{wia.Name}");

                    Trace.Write("-");
                    Trace.Write(fpath);
                    if (!File.Exists(fpath))
                    {
                        Trace.Write("...downloading");
                        const int maxRetryCount = 10;
                        var       reTryCount    = 0;
                        while (reTryCount < maxRetryCount)
                        {
                            reTryCount++;
                            try
                            {
                                var fileLocation = workItemServer.DownloadFile(wia.Id);
                                File.Copy(fileLocation, fpath, true);
                                Trace.Write("...done");
                                break;
                            }
                            catch (Exception ex)
                            {
                                Telemetry.Current.TrackException(ex);
                                Trace.Write($"\r\n Attempt {reTryCount} of {maxRetryCount} : Exception downloading attachements {ex.Message}");
                            }
                        }
                    }
                    else
                    {
                        Trace.Write("...skipping");
                    }
                    Trace.WriteLine("...done");
                }
                current--;
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"EXPORT DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }