Skip to content

Commit 3351d3f

Browse files
authored
Clean Up on Aisle 4 (#1735)
* Fix the update on the new version loop. It no longer does auto-update as Winget does not support it. * `skipToFinalRevisedWorkItemType` now works more how people expect by jumping to the final type, and then applying the mapping set in the config. This way a work item of the old type is never created. #1734 #1581 * Add a full failure and exit if we fail to create a Source or Target Store. #1712 * This change should enable the tools on pre Git version of TFS. #1577 * Updated the regex to allow for root nodes to ve valid so that they are checked as well. #1738
1 parent 0ad8515 commit 3351d3f

File tree

7 files changed

+87
-58
lines changed

7 files changed

+87
-58
lines changed

docs/Reference/Generated/MigrationTools.Host.xml

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/MigrationTools.Clients.AzureDevops.ObjectModel/Enrichers/TfsGitRepositoryEnricher.cs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,6 @@ public TfsGitRepositoryEnricher(IServiceProvider services, ILogger<TfsGitReposit
3434
{
3535
Engine = Services.GetRequiredService<IMigrationEngine>();
3636
_Logger = logger ?? throw new ArgumentNullException(nameof(logger));
37-
38-
sourceRepoService = Engine.Source.GetService<GitRepositoryService>();
39-
sourceRepos = sourceRepoService.QueryRepositories(Engine.Source.Config.AsTeamProjectConfig().Project);
40-
allSourceRepos = sourceRepoService.QueryRepositories("");
41-
//////////////////////////////////////////////////
42-
targetRepoService = Engine.Target.GetService<GitRepositoryService>();
43-
targetRepos = targetRepoService.QueryRepositories(Engine.Target.Config.AsTeamProjectConfig().Project);
44-
allTargetRepos = targetRepoService.QueryRepositories("");
4537
gitWits = new List<string>
4638
{
4739
"Branch",
@@ -58,6 +50,27 @@ public override void Configure(bool save = true, bool filter = true)
5850
_save = save;
5951
}
6052

53+
public void SetupRepoBits()
54+
{
55+
if (sourceRepoService == null)
56+
{
57+
try
58+
{
59+
sourceRepoService = Engine.Source.GetService<GitRepositoryService>();
60+
sourceRepos = sourceRepoService.QueryRepositories(Engine.Source.Config.AsTeamProjectConfig().Project);
61+
allSourceRepos = sourceRepoService.QueryRepositories("");
62+
//////////////////////////////////////////////////
63+
targetRepoService = Engine.Target.GetService<GitRepositoryService>();
64+
targetRepos = targetRepoService.QueryRepositories(Engine.Target.Config.AsTeamProjectConfig().Project);
65+
allTargetRepos = targetRepoService.QueryRepositories("");
66+
} catch (Exception ex)
67+
{
68+
sourceRepoService = null;
69+
}
70+
71+
}
72+
}
73+
6174
[Obsolete]
6275
public override int Enrich(WorkItemData sourceWorkItem, WorkItemData targetWorkItem)
6376
{
@@ -75,12 +88,18 @@ public override int Enrich(WorkItemData sourceWorkItem, WorkItemData targetWorkI
7588
List<ExternalLink> newEL = new List<ExternalLink>();
7689
List<ExternalLink> removeEL = new List<ExternalLink>();
7790
int count = 0;
91+
SetupRepoBits();
92+
if (sourceRepoService == null)
93+
{
94+
Log.LogWarning("Unable to configure connection to git!");
95+
return -1;
96+
}
7897
foreach (Link l in targetWorkItem.ToWorkItem().Links)
7998
{
8099
if (l is ExternalLink && gitWits.Contains(l.ArtifactLinkType.Name))
81100
{
82101
ExternalLink el = (ExternalLink)l;
83-
102+
84103
TfsGitRepositoryInfo sourceRepoInfo = TfsGitRepositoryInfo.Create(el, sourceRepos, Engine, sourceWorkItem?.ProjectName);
85104

86105
// if sourceRepo is null ignore this link and keep processing further links

src/MigrationTools.Clients.AzureDevops.ObjectModel/ProcessorEnrichers/TfsNodeStructure.cs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -370,15 +370,22 @@ private void CreateNodes(XmlNodeList nodeList, string treeType, TfsNodeStructure
370370

371371
private string GetSystemPath(string newUserPath, TfsNodeStructureType structureType)
372372
{
373-
var match = Regex.Match(newUserPath, @"^(?<projectName>[^\\]+)\\(?<restOfThePath>.*)$");
373+
374+
string matchtext = @"^(?<projectName>[^\\]+)(\\(?<restOfThePath>.*))?$"; //^(?<projectName>[^\\]+)\\(?<restOfThePath>.*)$
375+
var match = Regex.Match(newUserPath, matchtext);
374376
if (!match.Success)
375377
{
376378
throw new InvalidOperationException($"This path is not a valid area or iteration path: {newUserPath}");
377379
}
378380

379381
var structureName = GetTargetLocalizedNodeStructureTypeName(structureType);
380382

381-
return $"\\{match.Groups["projectName"].Value}\\{structureName}\\{match.Groups["restOfThePath"]}";
383+
var systemPath = $"\\{match.Groups["projectName"].Value}\\{structureName}";
384+
if (match.Groups["restOfThePath"].Success)
385+
{
386+
systemPath += $"\\{match.Groups["restOfThePath"]}";
387+
}
388+
return systemPath;
382389
}
383390

384391
private static string GetUserFriendlyPath(string systemNodePath)
@@ -517,23 +524,25 @@ public string GetFieldNameFromTfsNodeStructureType(TfsNodeStructureType nodeType
517524
return fieldName;
518525
}
519526

520-
public List<NodeStructureMissingItem> CheckForMissingPaths(List<WorkItemData> workItems, TfsNodeStructureType nodeType)
527+
public List<NodeStructureItem> CheckForMissingPaths(List<WorkItemData> workItems, TfsNodeStructureType nodeType)
521528
{
522529
EntryForProcessorType(null);
523530
contextLog.Debug("TfsNodeStructure:CheckForMissingPaths");
524531
_targetCommonStructureService.ClearProjectInfoCache();
525532

526533
string fieldName = GetFieldNameFromTfsNodeStructureType(nodeType);
527534

528-
List<NodeStructureMissingItem> areaPaths = workItems.SelectMany(x => x.Revisions.Values)
529-
.Where(x => x.Fields[fieldName].Value.ToString().Contains("\\"))
530-
.Select(x => new NodeStructureMissingItem() { sourcePath = x.Fields[fieldName].Value.ToString(), nodeType = nodeType.ToString() })
535+
List<NodeStructureItem> nodePaths = workItems.SelectMany(x => x.Revisions.Values)
536+
//.Where(x => x.Fields[fieldName].Value.ToString().Contains("\\"))
537+
.Select(x => new NodeStructureItem() { sourcePath = x.Fields[fieldName].Value.ToString(), nodeType = nodeType.ToString() })
531538
.Distinct()
532539
.ToList();
533540

534-
List<NodeStructureMissingItem> missingPaths = new List<NodeStructureMissingItem>();
541+
contextLog.Debug("TfsNodeStructure:CheckForMissingPaths::{nodeType}Nodes::{count}", nodeType.ToString(), nodePaths.Count);
542+
543+
List<NodeStructureItem> missingPaths = new List<NodeStructureItem>();
535544

536-
foreach (var missingItem in areaPaths)
545+
foreach (var missingItem in nodePaths)
537546
{
538547
contextLog.Debug("TfsNodeStructure:CheckForMissingPaths:Checking::{@missingItem}", missingItem);
539548
bool keepProcessing = true;
@@ -586,14 +595,14 @@ public List<NodeStructureMissingItem> CheckForMissingPaths(List<WorkItemData> wo
586595
return missingPaths;
587596
}
588597

589-
public List<NodeStructureMissingItem> GetMissingRevisionNodes(List<WorkItemData> workItems)
598+
public List<NodeStructureItem> GetMissingRevisionNodes(List<WorkItemData> workItems)
590599
{
591-
List<NodeStructureMissingItem> missingPaths = CheckForMissingPaths(workItems, TfsNodeStructureType.Area);
600+
List<NodeStructureItem> missingPaths = CheckForMissingPaths(workItems, TfsNodeStructureType.Area);
592601
missingPaths.AddRange(CheckForMissingPaths(workItems, TfsNodeStructureType.Iteration));
593602
return missingPaths;
594603
}
595604

596-
public List<int> GetWorkItemIDsFromMissingRevisionNodes(List<NodeStructureMissingItem> missingItems)
605+
public List<int> GetWorkItemIDsFromMissingRevisionNodes(List<NodeStructureItem> missingItems)
597606
{
598607
List<int> workItemsNotAncored = missingItems
599608
.Where(x => x.anchored = false)
@@ -604,13 +613,13 @@ public List<int> GetWorkItemIDsFromMissingRevisionNodes(List<NodeStructureMissin
604613
}
605614

606615

607-
public bool ValidateTargetNodesExist(List<NodeStructureMissingItem> missingItems)
616+
public bool ValidateTargetNodesExist(List<NodeStructureItem> missingItems)
608617
{
609618
if (missingItems.Count > 0)
610619
{
611620
contextLog.Warning("!! There are MISSING Area or Iteration Paths");
612621
contextLog.Warning("!! There are {missingAreaPaths} Nodes (Area or Iteration) found in the history of the Source that are missing from the Target! These MUST be added or mapped before we can continue using the instructions on https://nkdagility.com/learn/azure-devops-migration-tools/Reference/v1/Processors/WorkItemMigrationContext/#iteration-maps-and-area-maps", missingItems.Count);
613-
foreach (NodeStructureMissingItem missingItem in missingItems)
622+
foreach (NodeStructureItem missingItem in missingItems)
614623
{
615624
string mapper = GetMappingForMissingItem(missingItem);
616625
bool isMapped = mapper.IsNullOrEmpty()?false:true;
@@ -632,7 +641,7 @@ public bool ValidateTargetNodesExist(List<NodeStructureMissingItem> missingItems
632641
return false;
633642
}
634643

635-
public string GetMappingForMissingItem(NodeStructureMissingItem missingItem)
644+
public string GetMappingForMissingItem(NodeStructureItem missingItem)
636645
{
637646
var mappers = GetMaps((TfsNodeStructureType)Enum.Parse(typeof(TfsNodeStructureType), missingItem.nodeType, true));
638647
foreach (var mapper in mappers)

src/MigrationTools.Clients.AzureDevops.ObjectModel/_Enginev1/Clients/TfsMigrationClient.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ private TfsTeamProjectCollection GetDependantTfsCollection(NetworkCredential cre
110110
{
111111
var startTime = DateTime.UtcNow;
112112
var timer = System.Diagnostics.Stopwatch.StartNew();
113-
TfsTeamProjectCollection y;
113+
TfsTeamProjectCollection y = null;
114114
try
115115
{
116116
Log.Information("TfsMigrationClient::GetDependantTfsCollection:AuthenticationMode({0})", _config.AuthenticationMode.ToString());
@@ -148,7 +148,7 @@ private TfsTeamProjectCollection GetDependantTfsCollection(NetworkCredential cre
148148
break;
149149
}
150150
Log.Information("MigrationClient: Connecting to {CollectionUrl} ", TfsConfig.Collection);
151-
Log.Information("MigrationClient: validating security for {@AuthorizedIdentity} ", y.AuthorizedIdentity);
151+
Log.Debug("MigrationClient: validating security for {@AuthorizedIdentity} ", y.AuthorizedIdentity);
152152
y.EnsureAuthenticated();
153153
timer.Stop();
154154
Log.Information("MigrationClient: Access granted to {CollectionUrl} for {Name} ({Account})", TfsConfig.Collection, y.AuthorizedIdentity.DisplayName, y.AuthorizedIdentity.UniqueName);
@@ -166,8 +166,8 @@ private TfsTeamProjectCollection GetDependantTfsCollection(NetworkCredential cre
166166
new Dictionary<string, double> {
167167
{ "Time",timer.ElapsedMilliseconds }
168168
});
169-
Log.Error(ex, "Unable to configure store");
170-
throw;
169+
Log.Error(ex, "Unable to configure store: Check persmissions and credentials for {AuthenticationMode}", _config.AuthenticationMode);
170+
Environment.Exit(-1);
171171
}
172172
return y;
173173
}

src/MigrationTools.Host/StartupService.cs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,31 +81,32 @@ public void RunStartupLogic(string[] args)
8181
Console.WriteLine("Do you want install the managed version? (y/n)");
8282
if (Console.ReadKey().Key == ConsoleKey.Y)
8383
{
84-
8584
_detectVersionService.UpdateFromSource();
8685
}
8786
}
8887
if (_detectVersionService.IsUpdateAvailable && _detectVersionService.IsPackageInstalled)
8988
{
90-
Log.Information("It looks like an updated version is available from Winget, would you like to update?");
89+
Log.Information("It looks like an updated version is available from Winget, would you like to exit and update?");
9190
Console.WriteLine("Do you want install the managed version? (y/n)");
9291
if (Console.ReadKey().Key == ConsoleKey.Y)
9392
{
94-
_detectVersionService.UpdateFromSource();
95-
}
96-
}
97-
if (_detectVersionService.IsNewLocalVersionAvailable && _detectVersionService.IsPackageInstalled)
98-
{
99-
Log.Information("It looks like this package ({PackageId}) has been updated locally to version {InstalledVersion} and you are not running the latest version?", _detectVersionService.PackageId, _detectVersionService.InstalledVersion);
100-
Console.WriteLine("Do you want to quit and restart? (y/n)");
101-
if (Console.ReadKey().Key == ConsoleKey.Y)
102-
{
103-
Log.Information("Restarting as {CommandLine}", Environment.CommandLine);
104-
Process.Start("devopsmigration", string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));
105-
Thread.Sleep(2000);
106-
Environment.Exit(0);
93+
Thread.Sleep(2000);
94+
Environment.Exit(0);
95+
//_detectVersionService.UpdateFromSource();
10796
}
10897
}
98+
//if (_detectVersionService.IsNewLocalVersionAvailable && _detectVersionService.IsPackageInstalled)
99+
//{
100+
// Log.Information("It looks like this package ({PackageId}) has been updated locally to version {InstalledVersion} and you are not running the latest version?", _detectVersionService.PackageId, _detectVersionService.InstalledVersion);
101+
// Console.WriteLine("Do you want to quit and restart? (y/n)");
102+
// if (Console.ReadKey().Key == ConsoleKey.Y)
103+
// {
104+
// Log.Information("Restarting as {CommandLine}", Environment.CommandLine);
105+
// Process.Start("devopsmigration", string.Join(" ", Environment.GetCommandLineArgs().Skip(1)));
106+
// Thread.Sleep(2000);
107+
// Environment.Exit(0);
108+
// }
109+
//}
109110
} else
110111
{
111112
Log.Information("Running in Debug! No further version checkes.....");

src/MigrationTools/DataContracts/NodeStructureMissingItem.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace MigrationTools.DataContracts
55
{
6-
public class NodeStructureMissingItem
6+
public class NodeStructureItem
77
{
88
public bool anchored { get; set; } = true;
99

@@ -15,7 +15,7 @@ public class NodeStructureMissingItem
1515

1616
public override bool Equals(object obj)
1717
{
18-
var item = obj as NodeStructureMissingItem;
18+
var item = obj as NodeStructureItem;
1919

2020
if (item == null)
2121
{

src/VstsSyncMigrator.Core/Execution/MigrationContext/WorkItemMigrationContext.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ protected override void InternalExecute()
177177

178178
//////////////////////////////////////////////////
179179
contextLog.Information("ValidateTargetNodesExist::Checking all Nodes on Work items");
180-
List<NodeStructureMissingItem> nodeStructureMissingItems = _nodeStructureEnricher.GetMissingRevisionNodes(sourceWorkItems);
180+
List<NodeStructureItem> nodeStructureMissingItems = _nodeStructureEnricher.GetMissingRevisionNodes(sourceWorkItems);
181181
if (_nodeStructureEnricher.ValidateTargetNodesExist(nodeStructureMissingItems))
182182
{
183183
throw new Exception("Missing Iterations in Target preventing progress, check log for list. To continue you MUST configure IterationMaps or AreaMaps that matches the missing paths..");
@@ -658,9 +658,9 @@ private WorkItemData ReplayRevisions(List<RevisionItem> revisionsToMigrate, Work
658658
TraceWriteLine(LogEventLevel.Information, $"WorkItem has changed type at one of the revisions, from {targetType} to {finalDestType}");
659659
}
660660

661-
if (skipToFinalRevisedWorkItemType && Engine.TypeDefinitionMaps.Items.ContainsKey(finalDestType))
661+
if (skipToFinalRevisedWorkItemType)
662662
{
663-
finalDestType = Engine.TypeDefinitionMaps.Items[finalDestType].Map();
663+
targetType = finalDestType;
664664
}
665665

666666
if (Engine.TypeDefinitionMaps.Items.ContainsKey(targetType))

0 commit comments

Comments
 (0)