diff --git a/docs/Reference/Generated/MigrationTools.xml b/docs/Reference/Generated/MigrationTools.xml
index 96f84cde0..69bffa3ec 100644
--- a/docs/Reference/Generated/MigrationTools.xml
+++ b/docs/Reference/Generated/MigrationTools.xml
@@ -258,37 +258,37 @@
- => @"topic/niggles-v16-4-validation"
+ => @"main"
- => @"f01f930a"
+ => @"e6f3ac01"
- => @"f01f930aae895e462bc63a244b23b03c0e1ca818"
+ => @"e6f3ac01c0784a168439763fc03672a167763b22"
- => @"2024-09-10T10:09:00+01:00"
+ => @"2024-09-10T11:22:58+01:00"
- => @"12"
+ => @"0"
- => @"v16.0.2-Preview.1-12-gf01f930a"
+ => @"v16.0.2-Preview.2"
- => @"v16.0.2-Preview.1"
+ => @"v16.0.2-Preview.2"
@@ -318,17 +318,17 @@
- => @"14"
+ => @"2"
- => @"Preview.1"
+ => @"Preview.2"
- => @"-Preview.1"
+ => @"-Preview.2"
diff --git a/src/MigrationTools.Clients.TfsObjectModel/Tools/TfsNodeStructureToolOptions.cs b/src/MigrationTools.Clients.TfsObjectModel/Tools/TfsNodeStructureToolOptions.cs
index a588a0141..ae267bd2e 100644
--- a/src/MigrationTools.Clients.TfsObjectModel/Tools/TfsNodeStructureToolOptions.cs
+++ b/src/MigrationTools.Clients.TfsObjectModel/Tools/TfsNodeStructureToolOptions.cs
@@ -18,13 +18,21 @@ public sealed class TfsNodeStructureToolOptions : ToolOptions, ITfsNodeStructure
/// Rules to apply to the Area Path. Is an object of NodeOptions e.g. { "Filters": ["*/**"], "Mappings": { "^oldProjectName([\\\\]?.*)$": "targetProjectA$1", } }
///
/// {"Filters": [], "Mappings": { "^migrationSource1([\\\\]?.*)$": "MigrationTest5$1" })
- public NodeOptions Areas { get; set; }
+ public NodeOptions Areas { get; set; } = new NodeOptions
+ {
+ Filters = new List(),
+ Mappings = new Dictionary()
+ };
///
/// Rules to apply to the Area Path. Is an object of NodeOptions e.g. { "Filters": ["*/**"], "Mappings": { "^oldProjectName([\\\\]?.*)$": "targetProjectA$1", } }
///
/// {"Filters": [], "Mappings": { "^migrationSource1([\\\\]?.*)$": "MigrationTest5$1" })
- public NodeOptions Iterations { get; set; }
+ public NodeOptions Iterations { get; set; } = new NodeOptions
+ {
+ Filters = new List(),
+ Mappings = new Dictionary()
+ };
///
/// When set to True the susyem will try to create any missing missing area or iteration paths from the revisions.
diff --git a/src/MigrationTools.ConsoleFull/Properties/launchSettings.json b/src/MigrationTools.ConsoleFull/Properties/launchSettings.json
index 34cf1b991..a295b1b99 100644
--- a/src/MigrationTools.ConsoleFull/Properties/launchSettings.json
+++ b/src/MigrationTools.ConsoleFull/Properties/launchSettings.json
@@ -25,7 +25,7 @@
},
"Upgrade": {
"commandName": "Project",
- "commandLineArgs": "upgrade -c \"C:\\Users\\MartinHinshelwoodNKD\\source\\repos\\azure-devops-migration-tools\\docs\\_includes\\sampleConfig\\configuration-full.json\" --debugTrace"
+ "commandLineArgs": "upgrade -c \"C:\\Users\\MartinHinshelwoodNKD\\source\\Danlewis3.json\" --debugTrace"
},
"Execute Classic": {
"commandName": "Project",
diff --git a/src/MigrationTools/Endpoints/Infrastructure/EndpointRegistrationExtensions.cs b/src/MigrationTools/Endpoints/Infrastructure/EndpointRegistrationExtensions.cs
index 40d51359f..2a366474d 100644
--- a/src/MigrationTools/Endpoints/Infrastructure/EndpointRegistrationExtensions.cs
+++ b/src/MigrationTools/Endpoints/Infrastructure/EndpointRegistrationExtensions.cs
@@ -20,6 +20,11 @@ public static void AddConfiguredEndpoints(this IServiceCollection services, ICon
{
var endpointName = endpointConfig.Key;
var endpointType = endpointConfig.GetValue("EndpointType");
+ if (string.IsNullOrEmpty(endpointType))
+ {
+ Log.Warning("Endpoint '{EndpointName}' does not have a type configured. Skipping.", endpointName);
+ continue;
+ }
AddEndPointSingleton(services, configuration, endpointConfig, endpointName, endpointType);
}
}
diff --git a/src/MigrationTools/Options/OptionsConfigurationUpgrader.cs b/src/MigrationTools/Options/OptionsConfigurationUpgrader.cs
index 1e1bff5da..1c608031d 100644
--- a/src/MigrationTools/Options/OptionsConfigurationUpgrader.cs
+++ b/src/MigrationTools/Options/OptionsConfigurationUpgrader.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
+using System.Dynamic;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -24,6 +25,7 @@
using MigrationTools.Processors.Infrastructure;
using MigrationTools.Services;
using Newtonsoft.Json.Linq;
+using static System.Collections.Specialized.BitVector32;
namespace MigrationTools.Options
{
@@ -153,12 +155,47 @@ private List ParseSectionCollectionWithTypePropertyNameToList(IConfigu
_logger.LogDebug("Upgrading {group} item {old} to {new}", path, optionTypeString, newOptionTypeString);
var option = GetOptionWithDefaults(configuration, newOptionTypeString);
childSection.Bind(option);
+ switch (optionTypeString)
+ {
+ case "TfsNodeStructureOptions":
+ MapTfsNodeStructureOptions(childSection, option);
+ _logger.LogWarning("Empty type string found in {path}", path);
+ break;
+ default:
+ break;
+ }
+
+
options.Add(option);
}
return options;
}
+ private void MapTfsNodeStructureOptions(IConfigurationSection section, dynamic option)
+ {
+ // Map AreaMaps from the old structure to the new Areas.Mappings
+ var areaMaps = section.GetSection("AreaMaps").GetChildren();
+ foreach (var areaMap in areaMaps)
+ {
+ var key = areaMap.Key;
+ var value = areaMap.Value;
+ option.Areas.Mappings.Add(key, value);
+ }
+
+ // Map IterationMaps from the old structure to the new Iterations.Mappings
+ var iterationMaps = section.GetSection("IterationMaps").GetChildren();
+ foreach (var iterationMap in iterationMaps)
+ {
+ var key = iterationMap.Key;
+ var value = iterationMap.Value;
+ option.Iterations.Mappings.Add(key, value);
+ }
+ // Now map the intermediate structure back into the original `option` object
+ _logger.LogDebug("Mapped TfsNodeStructureOptions to TfsNodeStructureTool structure and updated the options object.");
+ }
+
+
private List ParseV1FieldMaps(IConfiguration configuration)
{
List options = new List();