From 0fc287f36e0a842b04a52ff59560cc4f87beb0ae Mon Sep 17 00:00:00 2001 From: "Martin Hinshelwood nkdAgility.com" Date: Tue, 10 Sep 2024 12:57:47 +0100 Subject: [PATCH] Added custom mapping for new format in TfsNodeStructureTool --- docs/Reference/Generated/MigrationTools.xml | 20 +++++----- .../Tools/TfsNodeStructureToolOptions.cs | 12 +++++- .../Properties/launchSettings.json | 2 +- .../EndpointRegistrationExtensions.cs | 5 +++ .../Options/OptionsConfigurationUpgrader.cs | 37 +++++++++++++++++++ 5 files changed, 63 insertions(+), 13 deletions(-) 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();